Importing crypto libraries

- crypto/external/bsd/heimdal
 - crypto/external/bsd/libsaslc
 - crypto/external/bsd/netpgp
 - crypto/external/bsd/openssl

Change-Id: I91dbf05f33e637edf5b9bb408d5baddd7ba8cf75
This commit is contained in:
2015-10-07 00:45:38 +00:00
parent b1d068470b
commit ebfedea0ce
5082 changed files with 1472353 additions and 12 deletions

View File

@@ -0,0 +1,3 @@
## $NetBSD: Makefile.am,v 1.5 2010/08/07 04:16:40 agc Exp $
SUBDIRS = libmj lib netpgp netpgpkeys netpgpverify

View File

@@ -0,0 +1,492 @@
# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/ax_check_openssl.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/src/lib/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOM4TE = @AUTOM4TE@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CANONICAL_HOST = @CANONICAL_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WARNCFLAGS = @WARNCFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = libmj lib netpgp netpgpkeys netpgpverify
all: all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
am__remove_distdir=: \
am__skip_length_check=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
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-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-exec-am:
install-html: install-html-recursive
install-info: install-info-recursive
install-man:
install-pdf: install-pdf-recursive
install-ps: install-ps-recursive
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
install-strip
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am check check-am clean clean-generic clean-libtool \
ctags ctags-recursive distclean distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am
# 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:

View File

@@ -0,0 +1,123 @@
.\" $NetBSD: hkpc.1,v 1.2 2013/07/20 21:39:55 wiz Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This manual page is derived from software contributed to
.\" The NetBSD Foundation by Alistair Crooks (agc@NetBSD.org).
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd September 1, 2010
.Dt HKPC 1
.Os
.Sh NAME
.Nm hkpc
.Nd retrieve public key information via HKP
.Sh SYNOPSIS
.Nm
.Op Fl f address-family
.Op Fl h hostname
.Op Fl p port
.Cm [get|index|vindex]
userid...
.Sh DESCRIPTION
The
.Nm
command retrieves public key information from the key server daemon
using the HKP protocol.
The
.Xr hkpd 8
is normally used to retrieve public key information.
.Pp
Three types of information can be retrieved from the server:
.Bl -tag -width vindex
.It get
The public key, base64-encoded, corresponding to the given userid
is returned.
The userid can be a numeric value, a unique part of the human
identifier, or left blank.
The first matching key will be returned, in a format suitable for
importing to a keyring via the
.Xr netpgpkeys 1
command.
.It index
the information returned from this command is the same as
provided by the
.Xr netpgpkeys 1
command, using the
.Dv --list-keys
modifier.
.It vindex
the information returned from this command is the same as
provided by the
.Xr netpgpkeys 1
command, using the
.Dv --list-sigs
modifier.
.El
.Pp
For this utility to provide the correct results, an hkpd
server must be listening using the correct protocol family,
on the provided port on the appropriate server.
The default port for the HKP server is
.Dv 11371 ,
whilst the hostname defaults to
.Dv localhost .
.Pp
The
.Dv netpgp
suite of libraries and commands provides a copnvenient client
in
.Xr hkpd 1 .
.Pp
The information is sent to the server in the form of
an HTTP
.Dv GET
command, and is returned as a JSON-encoded
HKP packet.
.Xr libmj 3
is used to decode the JSON in the returned HKP packet.
.Sh EXIT STATUS
The
.Nm
utility will return 0 for success,
or 1 for failure.
Output will be printed on stdout.
.Sh SEE ALSO
.Xr hkpd 1 ,
.Xr netpgpkeys 1 ,
.Xr ssh 1 ,
.\" .Xr libbz2 3 ,
.Xr libmj 3 ,
.Xr libnetpgp 3
.Sh STANDARDS
The
.Nm
utility is designed to conform to IETF RFC 4880.
.Sh HISTORY
The
.Nm
command first appeared in
.Nx 6.0 .
.Sh AUTHORS
.An Alistair Crooks Aq Mt agc@NetBSD.org .

View File

@@ -0,0 +1,135 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <inttypes.h>
#include <netdb.h>
#include <netpgp.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "hkpc.h"
/* get a socket and connect it to the server */
int
hkpc_connect(const char *hostname, const int port, const int fam)
{
struct addrinfo hints;
struct addrinfo *res;
char portstr[32];
int sock;
int rc = 0;
(void) memset(&hints, 0, sizeof(hints));
hints.ai_family = (fam == 4) ? PF_INET : PF_INET6;
hints.ai_socktype = SOCK_STREAM;
(void) snprintf(portstr, sizeof(portstr), "%d", port);
if ((rc = getaddrinfo(hostname, portstr, &hints, &res)) != 0) {
hints.ai_flags = 0;
if ((rc = getaddrinfo(hostname, "hkp", &hints, &res)) != 0) {
(void) fprintf(stderr, "getaddrinfo: %s",
gai_strerror(rc));
return -1;
}
}
if ((sock = socket((fam == 4) ? AF_INET : AF_INET6, SOCK_STREAM, 0)) < 0) {
(void) fprintf(stderr, "socket failed %d\n", errno);
freeaddrinfo(res);
return -1;
}
if ((rc = connect(sock, res->ai_addr, res->ai_addrlen)) < 0) {
(void) fprintf(stderr, "connect failed %d\n", errno);
freeaddrinfo(res);
return -1;
}
freeaddrinfo(res);
if (rc < 0) {
(void) fprintf(stderr, "connect() to %s:%d failed (rc %d)\n",
hostname, port, rc);
}
return sock;
}
#define MB(x) ((x) * 1024 * 1024)
/* get required info from the server */
int
hkpc_get(char **info, const char *server, const int port, const int family, const char *type, const char *userid)
{
char buf[MB(1)];
int sock;
int cc;
int rc;
if ((sock = hkpc_connect(server, port, family)) < 0) {
(void) fprintf(stderr, "hkpc_get: can't connect to server '%s'\n", server);
return -1;
}
cc = snprintf(buf, sizeof(buf), "GET /pks/lookup?op=%s&search=%s&options=json", type, userid);
if (write(sock, buf, cc) != cc) {
(void) fprintf(stderr, "hkpc_get: short write\n");
return -1;
}
for (cc = 0 ; (rc = read(sock, &buf[cc], sizeof(buf) - cc)) > 0 ; cc += rc) {
}
*info = calloc(1, cc + 1);
(void) memcpy(*info, buf, cc);
(*info)[cc] = 0x0;
(void) close(sock);
return cc;
}
/* jump over http header, then pass the json to the key-formatting function */
int
hkpc_print_key(FILE *fp, const char *op, const char *res)
{
static regex_t text;
static int compiled;
regmatch_t matches[10];
int ret;
if (!compiled) {
compiled = 1;
(void) regcomp(&text, "\r\n\r\n", REG_EXTENDED);
}
if (regexec(&text, res, 10, matches, 0) != 0) {
return 0;
}
if (strcmp(op, "index") == 0 || strcmp(op, "vindex") == 0) {
ret = netpgp_format_json(fp, &res[(int)matches[0].rm_eo], 1);
} else {
(void) fprintf(fp, "%s\n", &res[(int)matches[0].rm_eo]);
ret = 1;
}
return ret;
}

View File

@@ -0,0 +1,34 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HKPC_H_
#define HKPC_H_ 20100820
#include <stdio.h>
int hkpc_connect(const char *, const int, const int);
int hkpc_get(char **, const char *, const int, const int, const char *, const char *);
int hkpc_print_key(FILE *, const char *, const char *);
#endif

View File

@@ -0,0 +1,74 @@
#! /usr/bin/env lua
--
-- Copyright (c) 2010 The NetBSD Foundation, Inc.
-- All rights reserved.
--
-- This code is derived from software contributed to The NetBSD Foundation
-- by Alistair Crooks (agc@netbsd.org)
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- a short HKP client
require("cURL")
-- command line args
dofile "optparse.lua"
opt = OptionParser{usage="%prog [options] file", version="20100226"}
opt.add_option{"-V", "--version", action="store_true", dest="version",
help="--version"}
opt.add_option{"-m", "--mr", action="store_true", dest="mr", help="-m"}
opt.add_option{"-o", "--op", action="store", dest="op", help="-o op"}
opt.add_option{"-p", "--port", action="store", dest="port", help="-p port"}
opt.add_option{"-s", "--server", action="store", dest="server", help="-s server"}
-- parse command line args
options,args = opt.parse_args()
-- set defaults
local server = options.server or "pgp.mit.edu"
local port = options.port or 11371
local op = options.op or "get"
local mr = ""
if options.mr then mr = "&options=mr" end
-- get output stream
f = io.output()
c = cURL.easy_init()
-- setup url
c:setopt_url("http://" .. server .. ":" .. port ..
"/pks/lookup?op=" .. op .. "&search=" .. args[1] .. mr)
-- perform, invokes callbacks
c:perform({writefunction = function(str)
f:write(str)
end})
-- close output file
f:close()

View File

@@ -0,0 +1,69 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <inttypes.h>
#include <netpgp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "hkpc.h"
int
main(int argc, char **argv)
{
char *res;
char server[BUFSIZ];
int family;
int port;
int i;
port = 11371;
family = 4;
(void) snprintf(server, sizeof(server), "localhost");
while ((i = getopt(argc, argv, "f:h:p:")) != -1) {
switch(i) {
case 'f':
family = atoi(optarg);
break;
case 'h':
(void) snprintf(server, sizeof(server), optarg);
break;
case 'p':
port = atoi(optarg);
break;
default:
break;
}
}
for (i = optind + 1 ; i < argc ; i++) {
if (hkpc_get(&res, server, port, family, argv[optind], argv[i]) >= 0) {
hkpc_print_key(stdout, argv[optind], res);
}
}
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,123 @@
-- Lua command line option parser.
-- Interface based on Pythons optparse.
-- http://docs.python.org/lib/module-optparse.html
-- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license)
--
-- To be used like this:
-- t={usage="<some usage message>", version="<version string>"}
-- op=OptionParser(t)
-- op=add_option{"<opt>", action=<action>, dest=<dest>, help="<help message for this option>"}
--
-- with :
-- <opt> the option string to be used (can be anything, if one letter opt, then should be -x val, more letters: -xy=val )
-- <action> one of
-- - store: store in options as key, val
-- - store_true: stores key, true
-- - store_false: stores key, false
-- <dest> is the key under which the option is saved
--
-- options,args = op.parse_args()
--
-- now options is the table of options (key, val) and args is the table with non-option arguments.
-- You can use op.fail(message) for failing and op.print_help() for printing the usage as you like.
function OptionParser(t)
local usage = t.usage
local version = t.version
local o = {}
local option_descriptions = {}
local option_of = {}
function o.fail(s) -- extension
io.stderr:write(s .. '\n')
os.exit(1)
end
function o.add_option(optdesc)
option_descriptions[#option_descriptions+1] = optdesc
for _,v in ipairs(optdesc) do
option_of[v] = optdesc
end
end
function o.parse_args()
-- expand options (e.g. "--input=file" -> "--input", "file")
local arg = {unpack(arg)}
for i=#arg,1,-1 do local v = arg[i]
local flag, val = v:match('^(%-%-%w+)=(.*)')
if flag then
arg[i] = flag
table.insert(arg, i+1, val)
end
end
local options = {}
local args = {}
local i = 1
while i <= #arg do local v = arg[i]
local optdesc = option_of[v]
if optdesc then
local action = optdesc.action
local val
if action == 'store' or action == nil then
i = i + 1
val = arg[i]
if not val then o.fail('option requires an argument ' .. v) end
elseif action == 'store_true' then
val = true
elseif action == 'store_false' then
val = false
end
options[optdesc.dest] = val
else
if v:match('^%-') then o.fail('invalid option ' .. v) end
args[#args+1] = v
end
i = i + 1
end
if options.help then
o.print_help()
os.exit()
end
if options.version then
io.stdout:write(t.version .. "\n")
os.exit()
end
return options, args
end
local function flags_str(optdesc)
local sflags = {}
local action = optdesc.action
for _,flag in ipairs(optdesc) do
local sflagend
if action == nil or action == 'store' then
local metavar = optdesc.metavar or optdesc.dest:upper()
sflagend = #flag == 2 and ' ' .. metavar
or '=' .. metavar
else
sflagend = ''
end
sflags[#sflags+1] = flag .. sflagend
end
return table.concat(sflags, ', ')
end
function o.print_help()
io.stdout:write("Usage: " .. usage:gsub('%%prog', arg[0]) .. "\n")
io.stdout:write("\n")
io.stdout:write("Options:\n")
for _,optdesc in ipairs(option_descriptions) do
io.stdout:write(" " .. flags_str(optdesc) ..
" " .. optdesc.help .. "\n")
end
end
o.add_option{"--help", action="store_true", dest="help",
help="show this help message and exit"}
if t.version then
o.add_option{"--version", action="store_true", dest="version",
help="output version info."}
end
return o
end

View File

@@ -0,0 +1,25 @@
#! /bin/sh
host=localhost
while [ $# -gt 0 ]; do
case $1 in
-h)
host=$2
shift
;;
*)
break
;;
esac
shift
done
./hkpclient.lua -s ${host} agc@netbsd.org
./hkpclient.lua -s ${host} --mr 0xc0596823
./hkpclient.lua -s ${host} 0xc0596823
./hkpclient.lua --op index -s ${host} 0xc0596823
./hkpclient.lua -o index -s ${host} --mr 0xc0596823
./hkpclient.lua -o index -s ${host} --mr 0xc0596823
./hkpclient.lua -o vindex -s ${host} --mr agc@
./hkpclient.lua -o index -s ${host} dhklsbcldshjkcdlsjhcvdsljhvcdsljhcvdjlshvcdsc

View File

@@ -0,0 +1,19 @@
# $NetBSD: Makefile,v 1.4 2010/09/02 05:58:01 agc Exp $
PROG=hkpd
SRCS=hkpd.c main.c
CPPFLAGS+=-g # -DHAVE_CONFIG_H=1
LDFLAGS+=-g
LDADD+= -lnetpgp
MAN=hkpd.1
WARNS=0 # anything over 0 will fail at the link stage with IDEA errors
.include <bsd.prog.mk>
t: ${PROG}
./${PROG} -D &
sleep 1
ftp -o- 'http://localhost:11371/pks/lookup?op=index&search=agc&options=json'
ftp -o- 'http://localhost:11371/pks/lookup?op=get&search=agc&options=json'
ftp -o- 'http://localhost:11371/pks/lookup?op=get&search=agc&options=mr'
pkill hkpd

View File

@@ -0,0 +1,129 @@
.\" $NetBSD: hkpd.1,v 1.2 2013/07/20 21:39:55 wiz Exp $
.\"
.\" Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This manual page is derived from software contributed to
.\" The NetBSD Foundation by Alistair Crooks (agc@NetBSD.org).
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd September 1, 2010
.Dt HKPD 1
.Os
.Sh NAME
.Nm hkpd
.Nd HTTP key protocol daemon
.Sh SYNOPSIS
.Nm
.Op Fl DV
.Op Fl f families
.Op Fl H homedir
.Op Fl h hostname
.Op Fl p port
.Op Fl S keyfilename
.Op Fl v filename
.Sh DESCRIPTION
The
.Nm
daemon is used to provide public key information on
a socket to client programs.
The client can request the information in two separate ways,
.Dq human
and
.Dq machine readable .
.Pp
The following options can be used to modify the behaviour
of the daemon:
.Bl -tag -width protocol-families
.It Fl D
Do not detach the daemon from the controlling tty, and keep the
.Nm
process running in the foreground.
.It Fl f Ar protocol-families
allows the address families for sockets to be selected.
The argument is the string concatenating the families,
with
.Dq 4
representing
.Dv INET4 ,
and
.Dq 6
representing
.Dv INET6 .
The default value for this parameter is
.Dq 46
which means that both INET4 and INET6 protocol
families are used when setting up the sockets.
.It Fl H Ar homedir
Use the setting of
.Dv homedir
as the directory for the public key keyrings.
.It Fl h Ar hostname
Set the hostname (for use in binding sockets).
.It Fl p Ar port
Set the port number (for use in binding sockets).
The default port number is the
.Dq hkp
service, defined as port
.Dv 11371 .
.It Fl S Ar sshkeyfile
Serve the ssh public keys found in the key file.
The default file for the ssh key is
.Pa $HOME/.ssh/id_rsa.pub .
.It Fl V
Display the version number of the daemon and exit.
.It Fl v Ar filename
Produce extra debugging output from the internal file named
.Dv filename .
.El
.Pp
The
.Nm
daemon is built on
.Xr libnetpgp 3
and returns public key information as held in the
public keyring of the user running the
.Nm
daemon utility by default.
.Pp
The information returned to the HKP client is encoded
in JSON using the
.Xr libmj 3
library.
.Sh EXIT STATUS
In normal operation, the
.Nm
daemon will not return.
.Sh SEE ALSO
.Xr hkpc 1 ,
.Xr netpgpkeys 1 ,
.Xr ssh 1 ,
.Xr libmj 3
.Xr libnetpgp 3
.Sh HISTORY
The
.Nm
command first appeared in
.Nx 6.0 .
.Sh AUTHORS
.An Alistair Crooks Aq Mt agc@NetBSD.org .

View File

@@ -0,0 +1,326 @@
/*-
* Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <netpgp.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "hkpd.h"
/* make the string have %xx -> %c */
static size_t
frompercent(char *in, size_t insize, char *out, size_t outsize)
{
size_t outcc;
char *next;
char *pc;
outcc = 0;
for (pc = in ; (next = strchr(pc, '%')) != NULL ; pc = next + 3) {
(void) memcpy(&out[outcc], pc, (size_t)(next - pc));
outcc += (size_t)(next - pc);
out[outcc++] = (char)strtol(next + 1, NULL, 16);
}
(void) memcpy(&out[outcc], pc, insize - (int)(pc - in));
outcc += insize - (int)(pc - in);
out[outcc] = 0x0;
return outcc;
}
#define HKP_HTTP_LEVEL "HTTP/1.0"
#define HKP_NAME "hkpd"
#define HKP_MIME_GET "application/pgp-keys"
#define HKP_MIME_INDEX "text/plain"
#define HKP_MACHREAD "info:1:1\r\n"
#define HKP_SUCCESS 200
#define HKP_NOT_FOUND 404
/* make into html */
static int
htmlify(char *buf, size_t size, const int code, const int get, const char *title, const char *out, const char *body)
{
return snprintf(buf, size,
"%s %d %s\r\n"
"Server: %s/%d\r\n"
"Content-type: %s\r\n"
"\r\n"
"%s"
"%s",
HKP_HTTP_LEVEL, code, (code == HKP_SUCCESS) ? "OK" : "not found",
HKP_NAME, HKPD_VERSION,
(get) ? HKP_MIME_GET : HKP_MIME_INDEX,
(get || strcmp(out, "mr") != 0) ? "" : HKP_MACHREAD,
body);
}
/* send the response now */
static int
response(int sock, const int code, const char *search, const int get, char *buf, int cc, const char *out)
{
char outbuf[1024 * 512];
char item[BUFSIZ];
int tot;
int wc;
int n;
if (buf == NULL) {
(void) snprintf(item, sizeof(item),
"Error handling request: No keys found for '%s'\r\n", search);
n = htmlify(outbuf, sizeof(outbuf), code, get,
"Error handling request\r\n",
out,
item);
} else {
(void) snprintf(item, sizeof(item), "Search results for '%s'", search);
n = htmlify(outbuf, sizeof(outbuf), code, get,
item,
out,
buf);
}
for (tot = 0 ; (wc = write(sock, &outbuf[tot], n - tot)) > 0 && tot < n ; tot += wc) {
}
return 1;
}
/* get a socket (we'll bind it later) */
static int
hkpd_sock_get(const int fam)
{
int sock;
int on = 1;
sock = socket((fam == 4) ? AF_INET : AF_INET6, SOCK_STREAM, 0);
if (sock < 0) {
(void) fprintf(stderr,"hkpd_sock_get: can't get a socket\n");
return -1;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(void *)&on, sizeof(on)) == -1) {
(void) fprintf(stderr,
"hkpd_sock_get: can't set SO_REUSEADDR\n");
return -1;
}
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
(void *)&on, sizeof(on)) == -1) {
(void) fprintf(stderr,
"hkpd_sock_get: can't set SO_KEEPALIVE\n");
return -1;
}
return sock;
}
/**************************************************************************/
/* get a socket and bind it to the server */
int
hkpd_sock_bind(const char *hostname, const int port, const int fam)
{
struct addrinfo hints;
struct addrinfo *res;
char portstr[32];
int sock;
int rc = 0;
(void) memset(&hints, 0, sizeof(hints));
hints.ai_family = (fam == 4) ? PF_INET : PF_INET6;
hints.ai_socktype = SOCK_STREAM;
(void) snprintf(portstr, sizeof(portstr), "%d", port);
/* Attempt connection */
#ifdef AI_NUMERICSERV
hints.ai_flags = AI_NUMERICSERV;
#endif
if ((rc = getaddrinfo(hostname, portstr, &hints, &res)) != 0) {
hints.ai_flags = 0;
if ((rc = getaddrinfo(hostname, "hkp", &hints, &res)) != 0) {
(void) fprintf(stderr, "getaddrinfo: %s",
gai_strerror(rc));
return -1;
}
}
if ((sock = hkpd_sock_get(fam)) < 0) {
(void) fprintf(stderr, "hkpd_sock_get failed %d\n", errno);
freeaddrinfo(res);
return -1;
}
if ((rc = bind(sock, res->ai_addr, res->ai_addrlen)) < 0) {
(void) fprintf(stderr, "bind failed %d\n", errno);
freeaddrinfo(res);
return -1;
}
freeaddrinfo(res);
if (rc < 0) {
(void) fprintf(stderr, "bind() to %s:%d failed (rc %d)\n",
hostname, port, rc);
}
return sock;
}
/* netpgp key daemon - does not return */
int
hkpd(netpgp_t *netpgp, int sock4, int sock6)
{
struct sockaddr_in from;
regmatch_t searchmatches[10];
regmatch_t opmatches[10];
regmatch_t fmtmatch[3];
socklen_t fromlen;
regex_t searchterm;
regex_t fmtterm;
regex_t opterm;
regex_t get;
fd_set sockets;
char search[BUFSIZ];
char buf[BUFSIZ];
char *cp;
char fmt[10];
int newsock;
int sock;
int code;
int ok;
int cc;
int n;
/* GET /pks/lookup?search=agc%40netbsd.org&op=index&options=mr HTTP/1.1\n */
#define HTTPGET "GET /pks/lookup\\?"
#define OPTERM "op=([a-zA-Z]+)"
#define SEARCHTERM "search=([^ \t&]+)"
#define FMT "options=(mr|json)"
(void) regcomp(&get, HTTPGET, REG_EXTENDED);
(void) regcomp(&opterm, OPTERM, REG_EXTENDED);
(void) regcomp(&searchterm, SEARCHTERM, REG_EXTENDED);
(void) regcomp(&fmtterm, FMT, REG_EXTENDED);
if (sock4 >= 0) {
listen(sock4, 32);
}
if (sock6 >= 0) {
listen(sock6, 32);
}
for (;;) {
/* find out which socket we have data on */
FD_ZERO(&sockets);
if (sock4 >= 0) {
FD_SET(sock4, &sockets);
}
if (sock6 >= 0) {
FD_SET(sock6, &sockets);
}
if (select(32, &sockets, NULL, NULL, NULL) < 0) {
(void) fprintf(stderr, "bad select call\n");
continue;
}
sock = (sock4 >= 0 && FD_ISSET(sock4, &sockets)) ? sock4 : sock6;
/* read data from socket */
fromlen = sizeof(from);
newsock = accept(sock, (struct sockaddr *) &from, &fromlen);
cc = read(newsock, buf, sizeof(buf));
/* parse the request */
ok = 1;
if (regexec(&get, buf, 10, opmatches, 0) != 0) {
(void) fprintf(stderr, "not a valid get request\n");
ok = 0;
}
if (ok && regexec(&opterm, buf, 10, opmatches, 0) != 0) {
(void) fprintf(stderr, "no operation in request\n");
ok = 0;
}
if (ok && regexec(&fmtterm, buf, 3, fmtmatch, 0) == 0) {
(void) snprintf(fmt, sizeof(fmt), "%.*s",
(int)(fmtmatch[1].rm_eo - fmtmatch[1].rm_so),
&buf[(int)fmtmatch[1].rm_so]);
} else {
fmt[0] = 0x0;
}
if (ok && regexec(&searchterm, buf, 10, searchmatches, 0) != 0) {
(void) fprintf(stderr, "no search term in request\n");
ok = 0;
}
if (!ok) {
(void) close(newsock);
continue;
}
/* convert from %2f to / etc */
n = frompercent(&buf[searchmatches[1].rm_so],
(int)(searchmatches[1].rm_eo - searchmatches[1].rm_so),
search,
sizeof(search));
code = HKP_NOT_FOUND;
cc = 0;
if (strncmp(&buf[opmatches[1].rm_so], "vindex", 6) == 0) {
cc = 0;
netpgp_setvar(netpgp, "subkey sigs", "yes");
if (strcmp(fmt, "json") == 0) {
if (netpgp_match_keys_json(netpgp, &cp, search, "human", 1)) {
cc = strlen(cp);
code = HKP_SUCCESS;
}
} else if ((cp = netpgp_get_key(netpgp, search, fmt)) != NULL) {
cc = strlen(cp);
code = HKP_SUCCESS;
}
response(newsock, code, search, 0, cp, cc, fmt);
netpgp_unsetvar(netpgp, "subkey sigs");
} else if (strncmp(&buf[opmatches[1].rm_so], "index", 5) == 0) {
cc = 0;
netpgp_unsetvar(netpgp, "subkey sigs");
if (strcmp(fmt, "json") == 0) {
if (netpgp_match_keys_json(netpgp, &cp, search, "human", 0)) {
cc = strlen(cp);
code = HKP_SUCCESS;
}
} else if ((cp = netpgp_get_key(netpgp, search, fmt)) != NULL) {
cc = strlen(cp);
code = HKP_SUCCESS;
}
response(newsock, code, search, 0, cp, cc, fmt);
} else if (strncmp(&buf[opmatches[1].rm_so], "get", 3) == 0) {
if ((cp = netpgp_export_key(netpgp, search)) != NULL) {
cc = strlen(cp);
code = HKP_SUCCESS;
}
response(newsock, code, search, 1, cp, cc, fmt);
}
free(cp);
(void) close(newsock);
}
}

View File

@@ -0,0 +1,39 @@
/*-
* Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HKPD_H_
#define HKPD_H_ 20100315
#include <netpgp.h>
#define HKPD_VERSION 20100315
int hkpd_sock_bind(const char */*hostname*/, const int /*port*/, const int /*family*/);
int hkpd(netpgp_t */*netpgp*/, int /*sock4*/, int /*sock6*/);
#endif

View File

@@ -0,0 +1,153 @@
/*-
* Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "hkpd.h"
#define HAVE_DAEMON 1
/* set the home directory value to "home/subdir" */
static int
set_homedir(netpgp_t *netpgp, char *home, const char *subdir, const int quiet)
{
struct stat st;
char d[MAXPATHLEN];
if (home == NULL) {
if (!quiet) {
(void) fprintf(stderr, "NULL HOME directory\n");
}
return 0;
}
(void) snprintf(d, sizeof(d), "%s%s", home, (subdir) ? subdir : "");
if (stat(d, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFDIR) {
netpgp_setvar(netpgp, "homedir", d);
return 1;
}
(void) fprintf(stderr, "netpgp: homedir \"%s\" is not a dir\n",
d);
return 0;
}
if (!quiet) {
(void) fprintf(stderr,
"netpgp: warning homedir \"%s\" not found\n", d);
}
return 1;
}
int
main(int argc, char **argv)
{
netpgp_t netpgp;
char *family;
char *host;
int daemonise;
int port;
int sock6;
int sock4;
int i;
(void) memset(&netpgp, 0x0, sizeof(netpgp));
/* set some defaults */
set_homedir(&netpgp, getenv("HOME"), "/.gnupg", 1);
port = 11371;
host = strdup("localhost");
daemonise = 1;
family = strdup("46");
while ((i = getopt(argc, argv, "DH:S:Vf:h:p:v:")) != -1) {
switch(i) {
case 'D':
daemonise = 0;
break;
case 'H':
set_homedir(&netpgp, optarg, NULL, 0);
break;
case 'S':
netpgp_setvar(&netpgp, "ssh keys", "1");
netpgp_setvar(&netpgp, "sshkeyfile", optarg);
break;
case 'V':
printf("%s: Version %d\n", *argv, HKPD_VERSION);
exit(EXIT_SUCCESS);
case 'f':
(void) free(family);
family = strdup(optarg);
break;
case 'h':
(void) free(host);
host = strdup(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'v':
netpgp_set_debug(optarg);
break;
default:
break;
}
}
#ifdef HAVE_DAEMON
/* if we are supposed to be a daemon, detach from controlling tty */
if (daemonise && daemon(0, 0) < 0) {
(void) fprintf(stderr, "daemon() failed\n");
exit(EXIT_FAILURE);
}
#endif
if (!netpgp_init(&netpgp)) {
(void) fprintf(stderr, "can't initialise\n");
exit(EXIT_FAILURE);
}
sock4 = sock6 = -1;
if (strchr(family, '4') != NULL &&
(sock4 = hkpd_sock_bind(host, port, 4)) < 0) {
(void) fprintf(stderr,"hkpd: can't bind inet4 socket\n");
}
if (strchr(family, '6') != NULL &&
(sock6 = hkpd_sock_bind(host, port, 6)) < 0) {
(void) fprintf(stderr,"hkpd: can't bind inet6 socket\n");
}
if (sock4 < 0 && sock6 < 0) {
(void) fprintf(stderr,"hkpd: no sockets available\n");
exit(EXIT_FAILURE);
}
hkpd(&netpgp, sock4, sock6);
}

View File

@@ -0,0 +1,30 @@
## $NetBSD: Makefile.am,v 1.10 2010/11/29 06:21:40 agc Exp $
AM_CFLAGS = $(WARNCFLAGS)
lib_LTLIBRARIES = libnetpgp.la
libnetpgp_la_CPPFLAGS = -I$(top_srcdir)/include -I../libmj
libnetpgp_la_SOURCES = \
bufgap.c \
compress.c \
create.c \
crypto.c \
keyring.c \
misc.c \
netpgp.c \
openssl_crypto.c \
packet-parse.c \
packet-print.c \
packet-show.c \
reader.c \
signature.c \
ssh2pgp.c \
symmetric.c \
validate.c \
writer.c
libnetpgp_la_LIBADD = ../libmj/libmj.la
dist_man_MANS = libnetpgp.3

View File

@@ -0,0 +1,710 @@
# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/lib
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in mkinstalldirs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/ax_check_openssl.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libnetpgp_la_DEPENDENCIES = ../libmj/libmj.la
am_libnetpgp_la_OBJECTS = libnetpgp_la-bufgap.lo \
libnetpgp_la-compress.lo libnetpgp_la-create.lo \
libnetpgp_la-crypto.lo \
libnetpgp_la-keyring.lo libnetpgp_la-misc.lo \
libnetpgp_la-netpgp.lo libnetpgp_la-openssl_crypto.lo \
libnetpgp_la-packet-parse.lo libnetpgp_la-packet-print.lo \
libnetpgp_la-packet-show.lo libnetpgp_la-reader.lo \
libnetpgp_la-signature.lo libnetpgp_la-ssh2pgp.lo \
libnetpgp_la-symmetric.lo libnetpgp_la-validate.lo \
libnetpgp_la-writer.lo
libnetpgp_la_OBJECTS = $(am_libnetpgp_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/buildaux/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libnetpgp_la_SOURCES)
DIST_SOURCES = $(libnetpgp_la_SOURCES)
man3dir = $(mandir)/man3
NROFF = nroff
MANS = $(dist_man_MANS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOM4TE = @AUTOM4TE@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CANONICAL_HOST = @CANONICAL_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WARNCFLAGS = @WARNCFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CFLAGS = $(WARNCFLAGS)
lib_LTLIBRARIES = libnetpgp.la
libnetpgp_la_CPPFLAGS = -I$(top_srcdir)/include -I../libmj
libnetpgp_la_SOURCES = \
bufgap.c \
compress.c \
create.c \
crypto.c \
keyring.c \
misc.c \
netpgp.c \
openssl_crypto.c \
packet-parse.c \
packet-print.c \
packet-show.c \
reader.c \
signature.c \
ssh2pgp.c \
symmetric.c \
validate.c \
writer.c
libnetpgp_la_LIBADD = ../libmj/libmj.la
dist_man_MANS = libnetpgp.3
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/lib/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign src/lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status src/lib/config.h
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libnetpgp.la: $(libnetpgp_la_OBJECTS) $(libnetpgp_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libnetpgp_la_OBJECTS) $(libnetpgp_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-bufgap.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-compress.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-create.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-crypto.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-keyring.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-misc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-netpgp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-openssl_crypto.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-packet-parse.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-packet-print.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-packet-show.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-reader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-signature.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-ssh2pgp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-symmetric.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-validate.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetpgp_la-writer.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
libnetpgp_la-bufgap.lo: bufgap.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-bufgap.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-bufgap.Tpo -c -o libnetpgp_la-bufgap.lo `test -f 'bufgap.c' || echo '$(srcdir)/'`bufgap.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-bufgap.Tpo $(DEPDIR)/libnetpgp_la-bufgap.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bufgap.c' object='libnetpgp_la-bufgap.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-bufgap.lo `test -f 'bufgap.c' || echo '$(srcdir)/'`bufgap.c
libnetpgp_la-compress.lo: compress.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-compress.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-compress.Tpo -c -o libnetpgp_la-compress.lo `test -f 'compress.c' || echo '$(srcdir)/'`compress.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-compress.Tpo $(DEPDIR)/libnetpgp_la-compress.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='compress.c' object='libnetpgp_la-compress.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-compress.lo `test -f 'compress.c' || echo '$(srcdir)/'`compress.c
libnetpgp_la-create.lo: create.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-create.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-create.Tpo -c -o libnetpgp_la-create.lo `test -f 'create.c' || echo '$(srcdir)/'`create.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-create.Tpo $(DEPDIR)/libnetpgp_la-create.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='create.c' object='libnetpgp_la-create.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-create.lo `test -f 'create.c' || echo '$(srcdir)/'`create.c
libnetpgp_la-crypto.lo: crypto.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-crypto.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-crypto.Tpo -c -o libnetpgp_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-crypto.Tpo $(DEPDIR)/libnetpgp_la-crypto.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto.c' object='libnetpgp_la-crypto.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c
libnetpgp_la-keyring.lo: keyring.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-keyring.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-keyring.Tpo -c -o libnetpgp_la-keyring.lo `test -f 'keyring.c' || echo '$(srcdir)/'`keyring.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-keyring.Tpo $(DEPDIR)/libnetpgp_la-keyring.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyring.c' object='libnetpgp_la-keyring.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-keyring.lo `test -f 'keyring.c' || echo '$(srcdir)/'`keyring.c
libnetpgp_la-misc.lo: misc.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-misc.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-misc.Tpo -c -o libnetpgp_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-misc.Tpo $(DEPDIR)/libnetpgp_la-misc.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc.c' object='libnetpgp_la-misc.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
libnetpgp_la-netpgp.lo: netpgp.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-netpgp.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-netpgp.Tpo -c -o libnetpgp_la-netpgp.lo `test -f 'netpgp.c' || echo '$(srcdir)/'`netpgp.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-netpgp.Tpo $(DEPDIR)/libnetpgp_la-netpgp.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='netpgp.c' object='libnetpgp_la-netpgp.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-netpgp.lo `test -f 'netpgp.c' || echo '$(srcdir)/'`netpgp.c
libnetpgp_la-openssl_crypto.lo: openssl_crypto.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-openssl_crypto.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-openssl_crypto.Tpo -c -o libnetpgp_la-openssl_crypto.lo `test -f 'openssl_crypto.c' || echo '$(srcdir)/'`openssl_crypto.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-openssl_crypto.Tpo $(DEPDIR)/libnetpgp_la-openssl_crypto.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='openssl_crypto.c' object='libnetpgp_la-openssl_crypto.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-openssl_crypto.lo `test -f 'openssl_crypto.c' || echo '$(srcdir)/'`openssl_crypto.c
libnetpgp_la-packet-parse.lo: packet-parse.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-packet-parse.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-packet-parse.Tpo -c -o libnetpgp_la-packet-parse.lo `test -f 'packet-parse.c' || echo '$(srcdir)/'`packet-parse.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-packet-parse.Tpo $(DEPDIR)/libnetpgp_la-packet-parse.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet-parse.c' object='libnetpgp_la-packet-parse.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-packet-parse.lo `test -f 'packet-parse.c' || echo '$(srcdir)/'`packet-parse.c
libnetpgp_la-packet-print.lo: packet-print.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-packet-print.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-packet-print.Tpo -c -o libnetpgp_la-packet-print.lo `test -f 'packet-print.c' || echo '$(srcdir)/'`packet-print.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-packet-print.Tpo $(DEPDIR)/libnetpgp_la-packet-print.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet-print.c' object='libnetpgp_la-packet-print.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-packet-print.lo `test -f 'packet-print.c' || echo '$(srcdir)/'`packet-print.c
libnetpgp_la-packet-show.lo: packet-show.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-packet-show.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-packet-show.Tpo -c -o libnetpgp_la-packet-show.lo `test -f 'packet-show.c' || echo '$(srcdir)/'`packet-show.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-packet-show.Tpo $(DEPDIR)/libnetpgp_la-packet-show.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='packet-show.c' object='libnetpgp_la-packet-show.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-packet-show.lo `test -f 'packet-show.c' || echo '$(srcdir)/'`packet-show.c
libnetpgp_la-reader.lo: reader.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-reader.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-reader.Tpo -c -o libnetpgp_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-reader.Tpo $(DEPDIR)/libnetpgp_la-reader.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='reader.c' object='libnetpgp_la-reader.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c
libnetpgp_la-signature.lo: signature.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-signature.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-signature.Tpo -c -o libnetpgp_la-signature.lo `test -f 'signature.c' || echo '$(srcdir)/'`signature.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-signature.Tpo $(DEPDIR)/libnetpgp_la-signature.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='signature.c' object='libnetpgp_la-signature.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-signature.lo `test -f 'signature.c' || echo '$(srcdir)/'`signature.c
libnetpgp_la-ssh2pgp.lo: ssh2pgp.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-ssh2pgp.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-ssh2pgp.Tpo -c -o libnetpgp_la-ssh2pgp.lo `test -f 'ssh2pgp.c' || echo '$(srcdir)/'`ssh2pgp.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-ssh2pgp.Tpo $(DEPDIR)/libnetpgp_la-ssh2pgp.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ssh2pgp.c' object='libnetpgp_la-ssh2pgp.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-ssh2pgp.lo `test -f 'ssh2pgp.c' || echo '$(srcdir)/'`ssh2pgp.c
libnetpgp_la-symmetric.lo: symmetric.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-symmetric.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-symmetric.Tpo -c -o libnetpgp_la-symmetric.lo `test -f 'symmetric.c' || echo '$(srcdir)/'`symmetric.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-symmetric.Tpo $(DEPDIR)/libnetpgp_la-symmetric.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='symmetric.c' object='libnetpgp_la-symmetric.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-symmetric.lo `test -f 'symmetric.c' || echo '$(srcdir)/'`symmetric.c
libnetpgp_la-validate.lo: validate.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-validate.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-validate.Tpo -c -o libnetpgp_la-validate.lo `test -f 'validate.c' || echo '$(srcdir)/'`validate.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-validate.Tpo $(DEPDIR)/libnetpgp_la-validate.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='validate.c' object='libnetpgp_la-validate.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-validate.lo `test -f 'validate.c' || echo '$(srcdir)/'`validate.c
libnetpgp_la-writer.lo: writer.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnetpgp_la-writer.lo -MD -MP -MF $(DEPDIR)/libnetpgp_la-writer.Tpo -c -o libnetpgp_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libnetpgp_la-writer.Tpo $(DEPDIR)/libnetpgp_la-writer.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writer.c' object='libnetpgp_la-writer.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnetpgp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnetpgp_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-man3: $(man3_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.3*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
*) ext='3' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \
done
uninstall-man3:
@$(NORMAL_UNINSTALL)
@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.3*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
*) ext='3' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \
rm -f "$(DESTDIR)$(man3dir)/$$inst"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(MANS) config.h
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-info: install-info-am
install-man: install-man3
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES uninstall-man
uninstall-man: uninstall-man3
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man \
install-man3 install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-libLTLIBRARIES uninstall-man \
uninstall-man3
# 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:

View File

@@ -0,0 +1,519 @@
/* $NetBSD: bufgap.c,v 1.5 2010/11/29 06:21:40 agc Exp $ */
/*-
* Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "bufgap.h"
#include "defs.h"
/* macros to get subscripts in buffer */
#define AFTSUB(bp, n) ((bp)->buf[(int)n])
#define BEFSUB(bp, n) ((bp)->buf[(int)((bp)->size - (n) - 1)])
/* initial allocation size */
#ifndef CHUNKSIZE
#define CHUNKSIZE 256
#endif
#ifndef KiB
#define KiB(x) ((x) * 1024)
#endif
#define BGCHUNKSIZE KiB(4)
#ifndef __UNCONST
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#endif
#ifndef USE_UTF
#define USE_UTF 0
#endif
#if !USE_UTF
#define Rune char
#define utfbytes(x) strlen(x)
#define utfrune(a, b) strchr(a, b)
#define utfnlen(a, b) bounded_strlen(a, b)
static size_t
bounded_strlen(const char *s, size_t maxlen)
{
size_t n;
for (n = 0 ; n < maxlen && s[n] != 0x0 ; n++) {
}
return n;
}
static int
chartorune(Rune *rp, char *s)
{
*rp = s[0];
return 1;
}
static int
priorrune(Rune *rp, char *s)
{
*rp = s[0];
return 1;
}
#else
#include "ure.h"
#endif
/* save `n' chars of `s' in malloc'd memory */
static char *
strnsave(char *s, int n)
{
char *cp;
if (n < 0) {
n = (int)strlen(s);
}
NEWARRAY(char, cp, n + 1, "strnsave", return NULL);
(void) memcpy(cp, s, (size_t)n);
cp[n] = 0x0;
return cp;
}
/* open a file in a buffer gap structure */
int
bufgap_open(bufgap_t *bp, const char *f)
{
struct stat s;
int64_t cc;
FILE *filep;
char *cp;
(void) memset(bp, 0x0, sizeof(*bp));
filep = NULL;
if (f != NULL && (filep = fopen(f, "r")) == NULL) {
return 0;
}
if (f == NULL) {
bp->size = BGCHUNKSIZE;
NEWARRAY(char, bp->buf, bp->size, "f_open", return 0);
} else {
(void) fstat(fileno(filep), &s);
bp->size = (int) ((s.st_size / BGCHUNKSIZE) + 1) * BGCHUNKSIZE;
NEWARRAY(char, bp->buf, bp->size, "f_open", return 0);
cc = fread(&BEFSUB(bp, s.st_size), sizeof(char),
(size_t)s.st_size, filep);
(void) fclose(filep);
if (cc != s.st_size) {
FREE(bp->buf);
FREE(bp);
return 0;
}
bp->name = strnsave(__UNCONST(f), (int)utfbytes(__UNCONST(f)));
bp->bbc = s.st_size;
cp = &BEFSUB(bp, cc);
for (;;) {
if ((cp = utfrune(cp, '\n')) == NULL) {
break;
}
bp->blc++;
cp++;
}
bp->bcc = utfnlen(&BEFSUB(bp, cc), (size_t)cc);
}
return 1;
}
/* close a buffer gapped file */
void
bufgap_close(bufgap_t *bp)
{
FREE(bp->buf);
}
/* move forwards `n' chars/bytes in a buffer gap */
int
bufgap_forwards(bufgap_t *bp, uint64_t n, int type)
{
Rune r;
int rlen;
switch(type) {
case BGChar:
if (bp->bcc >= n) {
while (n-- > 0) {
rlen = chartorune(&r, &BEFSUB(bp, bp->bbc));
if (rlen == 1) {
AFTSUB(bp, bp->abc) = BEFSUB(bp, bp->bbc);
} else {
(void) memmove(&AFTSUB(bp, bp->abc),
&BEFSUB(bp, bp->bbc),
(size_t)rlen);
}
bp->acc++;
bp->bcc--;
bp->abc += rlen;
bp->bbc -= rlen;
if (r == '\n') {
bp->alc++;
bp->blc--;
}
}
return 1;
}
break;
case BGByte:
if (bp->bbc >= n) {
for ( ; n > 0 ; n -= rlen) {
rlen = chartorune(&r, &BEFSUB(bp, bp->bbc));
if (rlen == 1) {
AFTSUB(bp, bp->abc) = BEFSUB(bp, bp->bbc);
} else {
(void) memmove(&AFTSUB(bp, bp->abc),
&BEFSUB(bp, bp->bbc),
(size_t)rlen);
}
bp->acc++;
bp->bcc--;
bp->abc += rlen;
bp->bbc -= rlen;
if (r == '\n') {
bp->alc++;
bp->blc--;
}
}
return 1;
}
}
return 0;
}
/* move backwards `n' chars in a buffer gap */
int
bufgap_backwards(bufgap_t *bp, uint64_t n, int type)
{
Rune r;
int rlen;
switch(type) {
case BGChar:
if (bp->acc >= n) {
while (n-- > 0) {
rlen = priorrune(&r, &AFTSUB(bp, bp->abc));
bp->bcc++;
bp->acc--;
bp->bbc += rlen;
bp->abc -= rlen;
if (rlen == 1) {
BEFSUB(bp, bp->bbc) = AFTSUB(bp, bp->abc);
} else {
(void) memmove(&BEFSUB(bp, bp->bbc),
&AFTSUB(bp, bp->abc),
(size_t)rlen);
}
if (r == '\n') {
bp->blc++;
bp->alc--;
}
}
return 1;
}
break;
case BGByte:
if (bp->acc >= n) {
for ( ; n > 0 ; n -= rlen) {
rlen = priorrune(&r, &AFTSUB(bp, bp->abc));
bp->bcc++;
bp->acc--;
bp->bbc += rlen;
bp->abc -= rlen;
if (rlen == 1) {
BEFSUB(bp, bp->bbc) = AFTSUB(bp, bp->abc);
} else {
(void) memmove(&BEFSUB(bp, bp->bbc),
&AFTSUB(bp, bp->abc),
(size_t)rlen);
}
if (r == '\n') {
bp->blc++;
bp->alc--;
}
}
return 1;
}
}
return 0;
}
/* move within a buffer gap */
int
bufgap_seek(bufgap_t *bp, int64_t off, int whence, int type)
{
switch(type) {
case BGLine:
switch(whence) {
case BGFromBOF:
if (off < 0 || off > (int64_t)(bp->alc + bp->blc)) {
return 0;
}
if (off < (int64_t)bp->alc) {
while (off <= (int64_t)bp->alc && bufgap_backwards(bp, 1, BGChar)) {
}
if (off > 0) {
(void) bufgap_forwards(bp, 1, BGChar);
}
} else if (off > (int64_t)bp->alc) {
while (off > (int64_t)bp->alc && bufgap_forwards(bp, 1, BGChar)) {
}
}
return 1;
case BGFromHere:
return bufgap_seek(bp, (int64_t)(bp->alc + off), BGFromBOF, BGLine);
case BGFromEOF:
return bufgap_seek(bp, (int64_t)(bp->alc + bp->blc + off), BGFromBOF, BGLine);
}
break;
case BGChar:
switch(whence) {
case BGFromBOF:
if (off < 0 || off > (int64_t)(bp->acc + bp->bcc)) {
return 0;
}
if (off < (int64_t)bp->acc) {
return bufgap_backwards(bp, bp->acc - off, BGChar);
} else if (off > (int64_t)bp->acc) {
return bufgap_forwards(bp, off - bp->acc, BGChar);
}
return 1;
case BGFromHere:
return bufgap_seek(bp, (int64_t)(bp->acc + off), BGFromBOF, BGChar);
case BGFromEOF:
return bufgap_seek(bp, (int64_t)(bp->acc + bp->bcc + off), BGFromBOF, BGChar);
}
break;
case BGByte:
switch(whence) {
case BGFromBOF:
if (off < 0 || off > (int64_t)(bp->abc + bp->bbc)) {
return 0;
}
if (off < (int64_t)bp->abc) {
return bufgap_backwards(bp, bp->abc - off, BGByte);
} else if (off > (int64_t)bp->abc) {
return bufgap_forwards(bp, off - bp->abc, BGByte);
}
return 1;
case BGFromHere:
return bufgap_seek(bp, (int64_t)(bp->abc + off), BGFromBOF, BGByte);
case BGFromEOF:
return bufgap_seek(bp, (int64_t)(bp->abc + bp->bbc + off), BGFromBOF, BGByte);
}
break;
}
return 0;
}
/* return a pointer to the text in the buffer gap */
char *
bufgap_getstr(bufgap_t *bp)
{
return &BEFSUB(bp, bp->bbc);
}
/* return the binary text in the buffer gap */
int
bufgap_getbin(bufgap_t *bp, void *dst, size_t len)
{
int cc;
cc = (bp->bcc < len) ? (int)bp->bcc : (int)len;
(void) memcpy(dst, &BEFSUB(bp, bp->bbc), len);
return cc;
}
/* return offset (from beginning/end) in a buffer gap */
int64_t
bufgap_tell(bufgap_t *bp, int whence, int type)
{
switch(whence) {
case BGFromBOF:
return (type == BGLine) ? bp->alc :
(type == BGByte) ? bp->abc : bp->acc;
case BGFromEOF:
return (type == BGLine) ? bp->blc :
(type == BGByte) ? bp->bbc : bp->bcc;
default:
(void) fprintf(stderr, "weird whence in bufgap_tell\n");
break;
}
return (int64_t)0;
}
/* return size of buffer gap */
int64_t
bufgap_size(bufgap_t *bp, int type)
{
return (type == BGLine) ? bp->alc + bp->blc :
(type == BGChar) ? bp->acc + bp->bcc :
bp->abc + bp->bbc;
}
/* insert `n' chars of `s' in a buffer gap */
int
bufgap_insert(bufgap_t *bp, const char *s, int n)
{
int64_t off;
Rune r;
int rlen;
int i;
if (n < 0) {
n = (int)strlen(s);
}
for (i = 0 ; i < n ; i += rlen) {
if (bp->bbc + bp->abc == bp->size) {
off = bufgap_tell(bp, BGFromBOF, BGChar);
(void) bufgap_seek(bp, 0, BGFromEOF, BGChar);
bp->size *= 2;
RENEW(char, bp->buf, bp->size, "bufgap_insert", return 0);
(void) bufgap_seek(bp, off, BGFromBOF, BGChar);
}
if ((rlen = chartorune(&r, __UNCONST(s))) == 1) {
AFTSUB(bp, bp->abc) = *s;
} else {
(void) memmove(&AFTSUB(bp, bp->abc), s, (size_t)rlen);
}
if (r == '\n') {
bp->alc++;
}
bp->modified = 1;
bp->abc += rlen;
bp->acc++;
s += rlen;
}
return 1;
}
/* delete `n' bytes from the buffer gap */
int
bufgap_delete(bufgap_t *bp, uint64_t n)
{
uint64_t i;
Rune r;
int rlen;
if (n <= bp->bbc) {
for (i = 0 ; i < n ; i += rlen) {
rlen = chartorune(&r, &BEFSUB(bp, bp->bbc));
if (r == '\n') {
bp->blc--;
}
bp->bbc -= rlen;
bp->bcc--;
bp->modified = 1;
}
return 1;
}
return 0;
}
/* look at a character in a buffer gap `delta' UTF chars away */
int
bufgap_peek(bufgap_t *bp, int64_t delta)
{
int ch;
if (delta != 0) {
if (!bufgap_seek(bp, delta, BGFromHere, BGChar)) {
return -1;
}
}
ch = BEFSUB(bp, bp->bbc);
if (delta != 0) {
(void) bufgap_seek(bp, -delta, BGFromHere, BGChar);
}
return ch;
}
/* return, in malloc'd storage, text from the buffer gap */
char *
bufgap_gettext(bufgap_t *bp, int64_t from, int64_t to)
{
int64_t off;
int64_t n;
char *text;
off = bufgap_tell(bp, BGFromBOF, BGChar);
NEWARRAY(char, text, (to - from + 1), "bufgap_gettext", return NULL);
(void) bufgap_seek(bp, from, BGFromBOF, BGChar);
for (n = 0 ; n < to - from ; n++) {
text[(int)n] = BEFSUB(bp, bp->bbc - n);
}
text[(int)n] = 0x0;
(void) bufgap_seek(bp, off, BGFromBOF, BGChar);
return text;
}
/* return 1 if we wrote the file correctly */
int
bufgap_write(bufgap_t *bp, FILE *filep)
{
if (fwrite(bp->buf, sizeof(char), (size_t)bp->abc, filep) != (size_t)bp->abc) {
return 0;
}
if (fwrite(&BEFSUB(bp, bp->bbc), sizeof(char), (size_t)bp->bbc, filep) != (size_t)bp->bbc) {
return 0;
}
return 1;
}
/* tell if the buffer gap is dirty - has been modified */
int
bufgap_dirty(bufgap_t *bp)
{
return (int)bp->modified;
}

View File

@@ -0,0 +1,88 @@
/* $NetBSD: bufgap.h,v 1.2 2009/12/06 17:43:05 agc Exp $ */
/*-
* Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BUFGAP_H_
#define BUFGAP_H_ 20091023
#include <sys/types.h>
#include <inttypes.h>
#include <stdio.h>
#ifndef BUFGAP_VERSION_STRING
#define BUFGAP_VERSION_STRING "20091022"
#endif
#ifndef BUFGAP_AUTHOR_STRING
#define BUFGAP_AUTHOR_STRING "Alistair Crooks (agc@netbsd.org)"
#endif
/* Constants for Buffer Gap routines */
enum {
BGByte,
BGChar,
BGLine,
BGFromBOF,
BGFromHere,
BGFromEOF
};
/* this struct describes a file in memory */
typedef struct bufgap_t {
uint64_t size; /* size of file */
uint64_t abc; /* # of bytes after the gap */
uint64_t bbc; /* # of bytes before the gap */
uint64_t acc; /* # of utf chars after the gap */
uint64_t bcc; /* # of utf chars before the gap */
uint64_t alc; /* # of records after the gap */
uint64_t blc; /* # of records before the gap */
char *name; /* file name - perhaps null */
char *buf; /* buffer-gap buffer */
char modified; /* file has been modified */
} bufgap_t;
int bufgap_open(bufgap_t *, const char *);
void bufgap_close(bufgap_t *);
int bufgap_forwards(bufgap_t *, uint64_t, int);
int bufgap_backwards(bufgap_t *, uint64_t, int);
int bufgap_seek(bufgap_t *, int64_t, int, int);
char *bufgap_getstr(bufgap_t *);
int bufgap_getbin(bufgap_t *, void *, size_t);
int64_t bufgap_tell(bufgap_t *, int, int);
int64_t bufgap_size(bufgap_t *, int);
int bufgap_insert(bufgap_t *, const char *, int);
int bufgap_delete(bufgap_t *, uint64_t);
int bufgap_peek(bufgap_t *, int64_t);
char *bufgap_gettext(bufgap_t *, int64_t, int64_t);
int bufgap_write(bufgap_t *, FILE *);
int bufgap_dirty(bufgap_t *);
#endif /* !BUFGAP_H_ */

View File

@@ -0,0 +1,489 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#include "config.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: compress.c,v 1.23 2012/03/05 02:20:18 christos Exp $");
#endif
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
#ifdef HAVE_BZLIB_H
#include <bzlib.h>
#endif
#include <string.h>
#include "packet-parse.h"
#include "errors.h"
#include "netpgpdefs.h"
#include "crypto.h"
#include "memory.h"
#include "writer.h"
#define DECOMPRESS_BUFFER 1024
typedef struct {
pgp_compression_type_t type;
pgp_region_t *region;
uint8_t in[DECOMPRESS_BUFFER];
uint8_t out[DECOMPRESS_BUFFER];
z_stream zstream;/* ZIP and ZLIB */
size_t offset;
int inflate_ret;
} z_decompress_t;
#ifdef HAVE_BZLIB_H
typedef struct {
pgp_compression_type_t type;
pgp_region_t *region;
char in[DECOMPRESS_BUFFER];
char out[DECOMPRESS_BUFFER];
bz_stream bzstream; /* BZIP2 */
size_t offset;
int inflate_ret;
} bz_decompress_t;
#endif
typedef struct {
z_stream stream;
uint8_t *src;
uint8_t *dst;
} compress_t;
/*
* \todo remove code duplication between this and
* bzip2_compressed_data_reader
*/
static int
zlib_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length,
pgp_error_t **errors,
pgp_reader_t *readinfo,
pgp_cbdata_t *cbinfo)
{
z_decompress_t *z = pgp_reader_get_arg(readinfo);
size_t len;
size_t cc;
char *cdest = dest;
if (z->type != PGP_C_ZIP && z->type != PGP_C_ZLIB) {
(void) fprintf(stderr,
"zlib_compressed_data_reader: weird type %d\n",
z->type);
return 0;
}
if (z->inflate_ret == Z_STREAM_END &&
z->zstream.next_out == &z->out[z->offset]) {
return 0;
}
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(stderr,
"zlib_compressed_data_reader: length %" PRIsize "d\n",
length);
}
for (cc = 0 ; cc < length ; cc += len) {
if (&z->out[z->offset] == z->zstream.next_out) {
int ret;
z->zstream.next_out = z->out;
z->zstream.avail_out = sizeof(z->out);
z->offset = 0;
if (z->zstream.avail_in == 0) {
unsigned n = z->region->length;
if (!z->region->indeterminate) {
n -= z->region->readc;
if (n > sizeof(z->in)) {
n = sizeof(z->in);
}
} else {
n = sizeof(z->in);
}
if (!pgp_stacked_limited_read(stream, z->in, n,
z->region,
errors, readinfo, cbinfo)) {
return -1;
}
z->zstream.next_in = z->in;
z->zstream.avail_in = (z->region->indeterminate) ?
z->region->last_read : n;
}
ret = inflate(&z->zstream, Z_SYNC_FLUSH);
if (ret == Z_STREAM_END) {
if (!z->region->indeterminate &&
z->region->readc != z->region->length) {
PGP_ERROR_1(cbinfo->errors,
PGP_E_P_DECOMPRESSION_ERROR,
"%s",
"Compressed stream ended before packet end.");
}
} else if (ret != Z_OK) {
(void) fprintf(stderr, "ret=%d\n", ret);
PGP_ERROR_1(cbinfo->errors,
PGP_E_P_DECOMPRESSION_ERROR, "%s",
z->zstream.msg);
}
z->inflate_ret = ret;
}
if (z->zstream.next_out <= &z->out[z->offset]) {
(void) fprintf(stderr, "Out of memory in buffer\n");
return 0;
}
len = (size_t)(z->zstream.next_out - &z->out[z->offset]);
if (len > length) {
len = length;
}
(void) memcpy(&cdest[cc], &z->out[z->offset], len);
z->offset += len;
}
return (int)length;
}
#ifdef HAVE_BZLIB_H
/* \todo remove code duplication between this and zlib_compressed_data_reader */
static int
bzip2_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length,
pgp_error_t **errors,
pgp_reader_t *readinfo,
pgp_cbdata_t *cbinfo)
{
bz_decompress_t *bz = pgp_reader_get_arg(readinfo);
size_t len;
size_t cc;
char *cdest = dest;
if (bz->type != PGP_C_BZIP2) {
(void) fprintf(stderr, "Weird type %d\n", bz->type);
return 0;
}
if (bz->inflate_ret == BZ_STREAM_END &&
bz->bzstream.next_out == &bz->out[bz->offset]) {
return 0;
}
for (cc = 0 ; cc < length ; cc += len) {
if (&bz->out[bz->offset] == bz->bzstream.next_out) {
int ret;
bz->bzstream.next_out = (char *) bz->out;
bz->bzstream.avail_out = sizeof(bz->out);
bz->offset = 0;
if (bz->bzstream.avail_in == 0) {
unsigned n = bz->region->length;
if (!bz->region->indeterminate) {
n -= bz->region->readc;
if (n > sizeof(bz->in))
n = sizeof(bz->in);
} else
n = sizeof(bz->in);
if (!pgp_stacked_limited_read(stream,
(uint8_t *) bz->in,
n, bz->region,
errors, readinfo, cbinfo))
return -1;
bz->bzstream.next_in = bz->in;
bz->bzstream.avail_in =
(bz->region->indeterminate) ?
bz->region->last_read : n;
}
ret = BZ2_bzDecompress(&bz->bzstream);
if (ret == BZ_STREAM_END) {
if (!bz->region->indeterminate &&
bz->region->readc != bz->region->length)
PGP_ERROR_1(cbinfo->errors,
PGP_E_P_DECOMPRESSION_ERROR,
"%s",
"Compressed stream ended before packet end.");
} else if (ret != BZ_OK) {
PGP_ERROR_1(cbinfo->errors,
PGP_E_P_DECOMPRESSION_ERROR,
"Invalid return %d from BZ2_bzDecompress", ret);
}
bz->inflate_ret = ret;
}
if (bz->bzstream.next_out <= &bz->out[bz->offset]) {
(void) fprintf(stderr, "Out of bz memroy\n");
return 0;
}
len = (size_t)(bz->bzstream.next_out - &bz->out[bz->offset]);
if (len > length) {
len = length;
}
(void) memcpy(&cdest[cc], &bz->out[bz->offset], len);
bz->offset += len;
}
return (int)length;
}
#endif
/**
* \ingroup Core_Compress
*
* \param *region Pointer to a region
* \param *stream How to parse
* \param type Which compression type to expect
*/
int
pgp_decompress(pgp_region_t *region, pgp_stream_t *stream,
pgp_compression_type_t type)
{
z_decompress_t z;
#ifdef HAVE_BZLIB_H
bz_decompress_t bz;
#endif
const int printerrors = 1;
int ret;
switch (type) {
case PGP_C_ZIP:
case PGP_C_ZLIB:
(void) memset(&z, 0x0, sizeof(z));
z.region = region;
z.offset = 0;
z.type = type;
z.zstream.next_in = Z_NULL;
z.zstream.avail_in = 0;
z.zstream.next_out = z.out;
z.zstream.zalloc = Z_NULL;
z.zstream.zfree = Z_NULL;
z.zstream.opaque = Z_NULL;
break;
#ifdef HAVE_BZLIB_H
case PGP_C_BZIP2:
(void) memset(&bz, 0x0, sizeof(bz));
bz.region = region;
bz.offset = 0;
bz.type = type;
bz.bzstream.next_in = NULL;
bz.bzstream.avail_in = 0;
bz.bzstream.next_out = bz.out;
bz.bzstream.bzalloc = NULL;
bz.bzstream.bzfree = NULL;
bz.bzstream.opaque = NULL;
#endif
break;
default:
PGP_ERROR_1(&stream->errors,
PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG,
"Compression algorithm %d is not yet supported", type);
return 0;
}
switch (type) {
case PGP_C_ZIP:
/* LINTED */ /* this is a lint problem in zlib.h header */
ret = (int)inflateInit2(&z.zstream, -15);
break;
case PGP_C_ZLIB:
/* LINTED */ /* this is a lint problem in zlib.h header */
ret = (int)inflateInit(&z.zstream);
break;
#ifdef HAVE_BZLIB_H
case PGP_C_BZIP2:
ret = BZ2_bzDecompressInit(&bz.bzstream, 1, 0);
break;
#endif
default:
PGP_ERROR_1(&stream->errors,
PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG,
"Compression algorithm %d is not yet supported", type);
return 0;
}
switch (type) {
case PGP_C_ZIP:
case PGP_C_ZLIB:
if (ret != Z_OK) {
PGP_ERROR_1(&stream->errors,
PGP_E_P_DECOMPRESSION_ERROR,
"Cannot initialise ZIP or ZLIB stream for decompression: error=%d", ret);
return 0;
}
pgp_reader_push(stream, zlib_compressed_data_reader,
NULL, &z);
break;
#ifdef HAVE_BZLIB_H
case PGP_C_BZIP2:
if (ret != BZ_OK) {
PGP_ERROR_1(&stream->errors,
PGP_E_P_DECOMPRESSION_ERROR,
"Cannot initialise BZIP2 stream for decompression: error=%d", ret);
return 0;
}
pgp_reader_push(stream, bzip2_compressed_data_reader,
NULL, &bz);
break;
#endif
default:
PGP_ERROR_1(&stream->errors,
PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG,
"Compression algorithm %d is not yet supported", type);
return 0;
}
ret = pgp_parse(stream, !printerrors);
pgp_reader_pop(stream);
return ret;
}
/**
\ingroup Core_WritePackets
\brief Writes Compressed packet
\param data Data to write out
\param len Length of data
\param output Write settings
\return 1 if OK; else 0
*/
unsigned
pgp_writez(pgp_output_t *out, const uint8_t *data, const unsigned len)
{
compress_t *zip;
size_t sz_in;
size_t sz_out;
int ret;
int r = 0;
/* compress the data */
const int level = Z_DEFAULT_COMPRESSION; /* \todo allow varying
* levels */
if ((zip = calloc(1, sizeof(*zip))) == NULL) {
(void) fprintf(stderr, "pgp_writez: bad alloc\n");
return 0;
}
zip->stream.zalloc = Z_NULL;
zip->stream.zfree = Z_NULL;
zip->stream.opaque = NULL;
/* all other fields set to zero by use of calloc */
/* LINTED */ /* this is a lint problem in zlib.h header */
if ((int)deflateInit(&zip->stream, level) != Z_OK) {
(void) fprintf(stderr, "pgp_writez: can't initialise\n");
return 0;
}
/* do necessary transformation */
/* copy input to maintain const'ness of src */
if (zip->src != NULL || zip->dst != NULL) {
(void) fprintf(stderr, "pgp_writez: non-null streams\n");
return 0;
}
sz_in = len * sizeof(uint8_t);
sz_out = ((101 * sz_in) / 100) + 12; /* from zlib webpage */
if ((zip->src = calloc(1, sz_in)) == NULL) {
free(zip);
(void) fprintf(stderr, "pgp_writez: bad alloc2\n");
return 0;
}
if ((zip->dst = calloc(1, sz_out)) == NULL) {
free(zip->src);
free(zip);
(void) fprintf(stderr, "pgp_writez: bad alloc3\n");
return 0;
}
(void) memcpy(zip->src, data, len);
/* setup stream */
zip->stream.next_in = zip->src;
zip->stream.avail_in = (unsigned)sz_in;
zip->stream.total_in = 0;
zip->stream.next_out = zip->dst;
zip->stream.avail_out = (unsigned)sz_out;
zip->stream.total_out = 0;
do {
r = deflate(&zip->stream, Z_FINISH);
} while (r != Z_STREAM_END);
/* write it out */
ret = pgp_write_ptag(out, PGP_PTAG_CT_COMPRESSED) &&
pgp_write_length(out, (unsigned)(zip->stream.total_out + 1))&&
pgp_write_scalar(out, PGP_C_ZLIB, 1) &&
pgp_write(out, zip->dst, (unsigned)zip->stream.total_out);
free(zip->src);
free(zip->dst);
free(zip);
return ret;
}

View File

@@ -0,0 +1,180 @@
/* src/lib/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <bzlib.h> header file. */
#undef HAVE_BZLIB_H
/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */
#undef HAVE_COMMONCRYPTO_COMMONDIGEST_H
/* Define to 1 if you have the <direct.h> header file. */
#undef HAVE_DIRECT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <dmalloc.h> header file. */
#undef HAVE_DMALLOC_H
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if the system has the type `long long int'. */
#undef HAVE_LONG_LONG_INT
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <openssl/aes.h> header file. */
#undef HAVE_OPENSSL_AES_H
/* Define to 1 if you have the <openssl/bn.h> header file. */
#undef HAVE_OPENSSL_BN_H
/* Define to 1 if you have the <openssl/camellia.h> header file. */
#undef HAVE_OPENSSL_CAMELLIA_H
/* Define to 1 if you have the <openssl/cast.h> header file. */
#undef HAVE_OPENSSL_CAST_H
/* Define to 1 if you have the <openssl/des.h> header file. */
#undef HAVE_OPENSSL_DES_H
/* Define to 1 if you have the <openssl/dsa.h> header file. */
#undef HAVE_OPENSSL_DSA_H
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define to 1 if you have the <openssl/idea.h> header file. */
#undef HAVE_OPENSSL_IDEA_H
/* Define to 1 if you have the <openssl/md5.h> header file. */
#undef HAVE_OPENSSL_MD5_H
/* Define to 1 if you have the <openssl/rand.h> header file. */
#undef HAVE_OPENSSL_RAND_H
/* Define to 1 if you have the <openssl/rsa.h> header file. */
#undef HAVE_OPENSSL_RSA_H
/* Define to 1 if you have the <openssl/sha.h> header file. */
#undef HAVE_OPENSSL_SHA_H
/* Define to 1 if the system has the type `SHA256_CTX'. */
#undef HAVE_SHA256_CTX
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#undef HAVE_SYS_CDEFS_H
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT32_T
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT64_T
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT8_T
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define to the type of an unsigned integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
#undef uint16_t
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
#undef uint32_t
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#undef uint64_t
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
#undef uint8_t

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef CREATE_H_
#define CREATE_H_
#include "types.h"
#include "packet.h"
#include "crypto.h"
#include "errors.h"
#include "keyring.h"
#include "writer.h"
#include "memory.h"
/**
* \ingroup Create
* This struct contains the required information about how to write this stream
*/
struct pgp_output_t {
pgp_writer_t writer;
pgp_error_t *errors; /* error stack */
};
pgp_output_t *pgp_output_new(void);
void pgp_output_delete(pgp_output_t *);
int pgp_filewrite(const char *, const char *, const size_t, const unsigned);
void pgp_build_pubkey(pgp_memory_t *, const pgp_pubkey_t *, unsigned);
unsigned pgp_calc_sesskey_checksum(pgp_pk_sesskey_t *, uint8_t *);
unsigned pgp_write_struct_userid(pgp_output_t *, const uint8_t *);
unsigned pgp_write_ss_header(pgp_output_t *, unsigned, pgp_content_enum);
unsigned pgp_write_struct_seckey(const pgp_seckey_t *,
const uint8_t *,
const size_t,
pgp_output_t *);
unsigned pgp_write_one_pass_sig(pgp_output_t *,
const pgp_seckey_t *,
const pgp_hash_alg_t,
const pgp_sig_type_t);
unsigned pgp_write_litdata(pgp_output_t *,
const uint8_t *,
const int,
const pgp_litdata_enum);
pgp_pk_sesskey_t *pgp_create_pk_sesskey(const pgp_key_t *, const char *);
unsigned pgp_write_pk_sesskey(pgp_output_t *, pgp_pk_sesskey_t *);
unsigned pgp_write_xfer_pubkey(pgp_output_t *,
const pgp_key_t *, const unsigned);
unsigned pgp_write_xfer_seckey(pgp_output_t *,
const pgp_key_t *,
const uint8_t *,
const size_t,
const unsigned);
void pgp_fast_create_userid(uint8_t **, uint8_t *);
unsigned pgp_write_userid(const uint8_t *, pgp_output_t *);
void pgp_fast_create_rsa_pubkey(pgp_pubkey_t *, time_t, BIGNUM *, BIGNUM *);
unsigned pgp_write_rsa_pubkey(time_t, const BIGNUM *, const BIGNUM *,
pgp_output_t *);
void pgp_fast_create_rsa_seckey(pgp_seckey_t *, time_t, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *,
BIGNUM *, BIGNUM *);
unsigned encode_m_buf(const uint8_t *, size_t, const pgp_pubkey_t *,
uint8_t *);
unsigned pgp_fileread_litdata(const char *, const pgp_litdata_enum,
pgp_output_t *);
unsigned pgp_write_symm_enc_data(const uint8_t *, const int,
pgp_output_t *);
#endif /* CREATE_H_ */

View File

@@ -0,0 +1,609 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: crypto.c,v 1.35 2011/01/02 18:13:10 agc Exp $");
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include "types.h"
#include "crypto.h"
#include "readerwriter.h"
#include "memory.h"
#include "netpgpdefs.h"
#include "signature.h"
/**
\ingroup Core_MPI
\brief Decrypt and unencode MPI
\param buf Buffer in which to write decrypted unencoded MPI
\param buflen Length of buffer
\param encmpi
\param seckey
\return length of MPI
\note only RSA at present
*/
int
pgp_decrypt_decode_mpi(uint8_t *buf,
unsigned buflen,
const BIGNUM *g_to_k,
const BIGNUM *encmpi,
const pgp_seckey_t *seckey)
{
unsigned mpisize;
uint8_t encmpibuf[NETPGP_BUFSIZ];
uint8_t mpibuf[NETPGP_BUFSIZ];
uint8_t gkbuf[NETPGP_BUFSIZ];
int i;
int n;
mpisize = (unsigned)BN_num_bytes(encmpi);
/* MPI can't be more than 65,536 */
if (mpisize > sizeof(encmpibuf)) {
(void) fprintf(stderr, "mpisize too big %u\n", mpisize);
return -1;
}
switch (seckey->pubkey.alg) {
case PGP_PKA_RSA:
BN_bn2bin(encmpi, encmpibuf);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "encrypted", encmpibuf, 16);
}
n = pgp_rsa_private_decrypt(mpibuf, encmpibuf,
(unsigned)(BN_num_bits(encmpi) + 7) / 8,
&seckey->key.rsa, &seckey->pubkey.key.rsa);
if (n == -1) {
(void) fprintf(stderr, "ops_rsa_private_decrypt failure\n");
return -1;
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "decrypted", mpibuf, 16);
}
if (n <= 0) {
return -1;
}
/* Decode EME-PKCS1_V1_5 (RFC 2437). */
if (mpibuf[0] != 0 || mpibuf[1] != 2) {
return -1;
}
/* Skip the random bytes. */
for (i = 2; i < n && mpibuf[i]; ++i) {
}
if (i == n || i < 10) {
return -1;
}
/* Skip the zero */
i += 1;
/* this is the unencoded m buf */
if ((unsigned) (n - i) <= buflen) {
(void) memcpy(buf, mpibuf + i, (unsigned)(n - i)); /* XXX - Flexelint */
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "decoded m", buf, (size_t)(n - i));
}
return n - i;
case PGP_PKA_DSA:
case PGP_PKA_ELGAMAL:
(void) BN_bn2bin(g_to_k, gkbuf);
(void) BN_bn2bin(encmpi, encmpibuf);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "encrypted", encmpibuf, 16);
}
n = pgp_elgamal_private_decrypt(mpibuf, gkbuf, encmpibuf,
(unsigned)BN_num_bytes(encmpi),
&seckey->key.elgamal, &seckey->pubkey.key.elgamal);
if (n == -1) {
(void) fprintf(stderr, "ops_elgamal_private_decrypt failure\n");
return -1;
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "decrypted", mpibuf, 16);
}
if (n <= 0) {
return -1;
}
/* Decode EME-PKCS1_V1_5 (RFC 2437). */
if (mpibuf[0] != 2) {
fprintf(stderr, "mpibuf mismatch\n");
return -1;
}
/* Skip the random bytes. */
for (i = 1; i < n && mpibuf[i]; ++i) {
}
if (i == n || i < 10) {
fprintf(stderr, "175 n %d\n", n);
return -1;
}
/* Skip the zero */
i += 1;
/* this is the unencoded m buf */
if ((unsigned) (n - i) <= buflen) {
(void) memcpy(buf, mpibuf + i, (unsigned)(n - i)); /* XXX - Flexelint */
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "decoded m", buf, (size_t)(n - i));
}
return n - i;
default:
(void) fprintf(stderr, "pubkey algorithm wrong\n");
return -1;
}
}
/**
\ingroup Core_MPI
\brief RSA-encrypt an MPI
*/
unsigned
pgp_rsa_encrypt_mpi(const uint8_t *encoded_m_buf,
const size_t sz_encoded_m_buf,
const pgp_pubkey_t * pubkey,
pgp_pk_sesskey_params_t * skp)
{
uint8_t encmpibuf[NETPGP_BUFSIZ];
int n;
if (sz_encoded_m_buf != (size_t)BN_num_bytes(pubkey->key.rsa.n)) {
(void) fprintf(stderr, "sz_encoded_m_buf wrong\n");
return 0;
}
n = pgp_rsa_public_encrypt(encmpibuf, encoded_m_buf,
sz_encoded_m_buf, &pubkey->key.rsa);
if (n == -1) {
(void) fprintf(stderr, "pgp_rsa_public_encrypt failure\n");
return 0;
}
if (n <= 0)
return 0;
skp->rsa.encrypted_m = BN_bin2bn(encmpibuf, n, NULL);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "encrypted mpi", encmpibuf, 16);
}
return 1;
}
/**
\ingroup Core_MPI
\brief Elgamal-encrypt an MPI
*/
unsigned
pgp_elgamal_encrypt_mpi(const uint8_t *encoded_m_buf,
const size_t sz_encoded_m_buf,
const pgp_pubkey_t * pubkey,
pgp_pk_sesskey_params_t * skp)
{
uint8_t encmpibuf[NETPGP_BUFSIZ];
uint8_t g_to_k[NETPGP_BUFSIZ];
int n;
if (sz_encoded_m_buf != (size_t)BN_num_bytes(pubkey->key.elgamal.p)) {
(void) fprintf(stderr, "sz_encoded_m_buf wrong\n");
return 0;
}
n = pgp_elgamal_public_encrypt(g_to_k, encmpibuf, encoded_m_buf,
sz_encoded_m_buf, &pubkey->key.elgamal);
if (n == -1) {
(void) fprintf(stderr, "pgp_elgamal_public_encrypt failure\n");
return 0;
}
if (n <= 0)
return 0;
skp->elgamal.g_to_k = BN_bin2bn(g_to_k, n / 2, NULL);
skp->elgamal.encrypted_m = BN_bin2bn(encmpibuf, n / 2, NULL);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "encrypted mpi", encmpibuf, 16);
}
return 1;
}
static pgp_cb_ret_t
write_parsed_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
if (pgp_get_debug_level(__FILE__)) {
printf("write_parsed_cb: ");
pgp_print_packet(&cbinfo->printstate, pkt);
}
if (pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT && cbinfo->printstate.skipping) {
puts("...end of skip");
cbinfo->printstate.skipping = 0;
}
switch (pkt->tag) {
case PGP_PTAG_CT_UNARMOURED_TEXT:
printf("PGP_PTAG_CT_UNARMOURED_TEXT\n");
if (!cbinfo->printstate.skipping) {
puts("Skipping...");
cbinfo->printstate.skipping = 1;
}
fwrite(content->unarmoured_text.data, 1,
content->unarmoured_text.length, stdout);
break;
case PGP_PTAG_CT_PK_SESSION_KEY:
return pgp_pk_sesskey_cb(pkt, cbinfo);
case PGP_GET_SECKEY:
if (cbinfo->sshseckey) {
*content->get_seckey.seckey = cbinfo->sshseckey;
return PGP_KEEP_MEMORY;
}
return pgp_get_seckey_cb(pkt, cbinfo);
case PGP_GET_PASSPHRASE:
return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo);
case PGP_PTAG_CT_LITDATA_BODY:
return pgp_litdata_cb(pkt, cbinfo);
case PGP_PTAG_CT_ARMOUR_HEADER:
case PGP_PTAG_CT_ARMOUR_TRAILER:
case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
case PGP_PTAG_CT_COMPRESSED:
case PGP_PTAG_CT_LITDATA_HEADER:
case PGP_PTAG_CT_SE_IP_DATA_BODY:
case PGP_PTAG_CT_SE_IP_DATA_HEADER:
case PGP_PTAG_CT_SE_DATA_BODY:
case PGP_PTAG_CT_SE_DATA_HEADER:
/* Ignore these packets */
/* They're handled in parse_packet() */
/* and nothing else needs to be done */
break;
default:
if (pgp_get_debug_level(__FILE__)) {
fprintf(stderr, "Unexpected packet tag=%d (0x%x)\n",
pkt->tag,
pkt->tag);
}
break;
}
return PGP_RELEASE_MEMORY;
}
/**
\ingroup HighLevel_Crypto
Encrypt a file
\param infile Name of file to be encrypted
\param outfile Name of file to write to. If NULL, name is constructed from infile
\param pubkey Public Key to encrypt file for
\param use_armour Write armoured text, if set
\param allow_overwrite Allow output file to be overwrwritten if it exists
\return 1 if OK; else 0
*/
unsigned
pgp_encrypt_file(pgp_io_t *io,
const char *infile,
const char *outfile,
const pgp_key_t *key,
const unsigned use_armour,
const unsigned allow_overwrite,
const char *cipher)
{
pgp_output_t *output;
pgp_memory_t *inmem;
int fd_out;
__PGP_USED(io);
inmem = pgp_memory_new();
if (!pgp_mem_readfile(inmem, infile)) {
return 0;
}
fd_out = pgp_setup_file_write(&output, outfile, allow_overwrite);
if (fd_out < 0) {
pgp_memory_free(inmem);
return 0;
}
/* set armoured/not armoured here */
if (use_armour) {
pgp_writer_push_armor_msg(output);
}
/* Push the encrypted writer */
if (!pgp_push_enc_se_ip(output, key, cipher)) {
pgp_memory_free(inmem);
return 0;
}
/* This does the writing */
pgp_write(output, pgp_mem_data(inmem), (unsigned)pgp_mem_len(inmem));
/* tidy up */
pgp_memory_free(inmem);
pgp_teardown_file_write(output, fd_out);
return 1;
}
/* encrypt the contents of the input buffer, and return the mem structure */
pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *io,
const void *input,
const size_t insize,
const pgp_key_t *pubkey,
const unsigned use_armour,
const char *cipher)
{
pgp_output_t *output;
pgp_memory_t *outmem;
__PGP_USED(io);
if (input == NULL) {
(void) fprintf(io->errs,
"pgp_encrypt_buf: null memory\n");
return 0;
}
pgp_setup_memory_write(&output, &outmem, insize);
/* set armoured/not armoured here */
if (use_armour) {
pgp_writer_push_armor_msg(output);
}
/* Push the encrypted writer */
pgp_push_enc_se_ip(output, pubkey, cipher);
/* This does the writing */
pgp_write(output, input, (unsigned)insize);
/* tidy up */
pgp_writer_close(output);
pgp_output_delete(output);
return outmem;
}
/**
\ingroup HighLevel_Crypto
\brief Decrypt a file.
\param infile Name of file to be decrypted
\param outfile Name of file to write to. If NULL, the filename is constructed from the input filename, following GPG conventions.
\param keyring Keyring to use
\param use_armour Expect armoured text, if set
\param allow_overwrite Allow output file to overwritten, if set.
\param getpassfunc Callback to use to get passphrase
*/
unsigned
pgp_decrypt_file(pgp_io_t *io,
const char *infile,
const char *outfile,
pgp_keyring_t *secring,
pgp_keyring_t *pubring,
const unsigned use_armour,
const unsigned allow_overwrite,
const unsigned sshkeys,
void *passfp,
int numtries,
pgp_cbfunc_t *getpassfunc)
{
pgp_stream_t *parse = NULL;
const int printerrors = 1;
char *filename = NULL;
int fd_in;
int fd_out;
/* setup for reading from given input file */
fd_in = pgp_setup_file_read(io, &parse, infile,
NULL,
write_parsed_cb,
0);
if (fd_in < 0) {
perror(infile);
return 0;
}
/* setup output filename */
if (outfile) {
fd_out = pgp_setup_file_write(&parse->cbinfo.output, outfile,
allow_overwrite);
if (fd_out < 0) {
perror(outfile);
pgp_teardown_file_read(parse, fd_in);
return 0;
}
} else {
const int suffixlen = 4;
const char *suffix = infile + strlen(infile) - suffixlen;
unsigned filenamelen;
if (strcmp(suffix, ".gpg") == 0 ||
strcmp(suffix, ".asc") == 0) {
filenamelen = (unsigned)(strlen(infile) - strlen(suffix));
if ((filename = calloc(1, filenamelen + 1)) == NULL) {
(void) fprintf(stderr, "can't allocate %" PRIsize "d bytes\n",
(size_t)(filenamelen + 1));
return 0;
}
(void) strncpy(filename, infile, filenamelen);
filename[filenamelen] = 0x0;
}
fd_out = pgp_setup_file_write(&parse->cbinfo.output,
filename, allow_overwrite);
if (fd_out < 0) {
perror(filename);
free(filename);
pgp_teardown_file_read(parse, fd_in);
return 0;
}
}
/* \todo check for suffix matching armour param */
/* setup for writing decrypted contents to given output file */
/* setup keyring and passphrase callback */
parse->cbinfo.cryptinfo.secring = secring;
parse->cbinfo.passfp = passfp;
parse->cbinfo.cryptinfo.getpassphrase = getpassfunc;
parse->cbinfo.cryptinfo.pubring = pubring;
parse->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL;
parse->cbinfo.numtries = numtries;
/* Set up armour/passphrase options */
if (use_armour) {
pgp_reader_push_dearmour(parse);
}
/* Do it */
pgp_parse(parse, printerrors);
/* Unsetup */
if (use_armour) {
pgp_reader_pop_dearmour(parse);
}
/* if we didn't get the passphrase, unlink output file */
if (!parse->cbinfo.gotpass) {
(void) unlink((filename) ? filename : outfile);
}
if (filename) {
pgp_teardown_file_write(parse->cbinfo.output, fd_out);
free(filename);
}
pgp_teardown_file_read(parse, fd_in);
/* \todo cleardown crypt */
return 1;
}
/* decrypt an area of memory */
pgp_memory_t *
pgp_decrypt_buf(pgp_io_t *io,
const void *input,
const size_t insize,
pgp_keyring_t *secring,
pgp_keyring_t *pubring,
const unsigned use_armour,
const unsigned sshkeys,
void *passfp,
int numtries,
pgp_cbfunc_t *getpassfunc)
{
pgp_stream_t *parse = NULL;
pgp_memory_t *outmem;
pgp_memory_t *inmem;
const int printerrors = 1;
if (input == NULL) {
(void) fprintf(io->errs,
"pgp_encrypt_buf: null memory\n");
return 0;
}
inmem = pgp_memory_new();
pgp_memory_add(inmem, input, insize);
/* set up to read from memory */
pgp_setup_memory_read(io, &parse, inmem,
NULL,
write_parsed_cb,
0);
/* setup for writing decrypted contents to given output file */
pgp_setup_memory_write(&parse->cbinfo.output, &outmem, insize);
/* setup keyring and passphrase callback */
parse->cbinfo.cryptinfo.secring = secring;
parse->cbinfo.cryptinfo.pubring = pubring;
parse->cbinfo.passfp = passfp;
parse->cbinfo.cryptinfo.getpassphrase = getpassfunc;
parse->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL;
parse->cbinfo.numtries = numtries;
/* Set up armour/passphrase options */
if (use_armour) {
pgp_reader_push_dearmour(parse);
}
/* Do it */
pgp_parse(parse, printerrors);
/* Unsetup */
if (use_armour) {
pgp_reader_pop_dearmour(parse);
}
/* tidy up */
pgp_teardown_memory_read(parse, inmem);
pgp_writer_close(parse->cbinfo.output);
pgp_output_delete(parse->cbinfo.output);
/* if we didn't get the passphrase, return NULL */
return (parse->cbinfo.gotpass) ? outmem : NULL;
}

View File

@@ -0,0 +1,315 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef CRYPTO_H_
#define CRYPTO_H_
#include "keyring.h"
#include "packet.h"
#include "memory.h"
#include "packet-parse.h"
#include <openssl/dsa.h>
#define PGP_MIN_HASH_SIZE 16
/** pgp_hash_t */
struct pgp_hash_t {
pgp_hash_alg_t alg; /* algorithm */
size_t size; /* size */
const char *name; /* what it's known as */
int (*init)(pgp_hash_t *);
void (*add)(pgp_hash_t *, const uint8_t *, unsigned);
unsigned (*finish)(pgp_hash_t *, uint8_t *);
void *data; /* blob for data */
};
/** pgp_crypt_t */
struct pgp_crypt_t {
pgp_symm_alg_t alg;
size_t blocksize;
size_t keysize;
void (*set_iv)(pgp_crypt_t *, const uint8_t *);
void (*set_crypt_key)(pgp_crypt_t *, const uint8_t *);
int (*base_init)(pgp_crypt_t *);
void (*decrypt_resync)(pgp_crypt_t *);
/* encrypt/decrypt one block */
void (*block_encrypt)(pgp_crypt_t *, void *, const void *);
void (*block_decrypt)(pgp_crypt_t *, void *, const void *);
/* Standard CFB encrypt/decrypt (as used by Sym Enc Int Prot packets) */
void (*cfb_encrypt)(pgp_crypt_t *, void *, const void *, size_t);
void (*cfb_decrypt)(pgp_crypt_t *, void *, const void *, size_t);
void (*decrypt_finish)(pgp_crypt_t *);
uint8_t iv[PGP_MAX_BLOCK_SIZE];
uint8_t civ[PGP_MAX_BLOCK_SIZE];
uint8_t siv[PGP_MAX_BLOCK_SIZE];
/* siv is needed for weird v3 resync */
uint8_t key[PGP_MAX_KEY_SIZE];
int num;
/* num is offset - see openssl _encrypt doco */
void *encrypt_key;
void *decrypt_key;
};
void pgp_crypto_finish(void);
void pgp_hash_md5(pgp_hash_t *);
void pgp_hash_sha1(pgp_hash_t *);
void pgp_hash_sha256(pgp_hash_t *);
void pgp_hash_sha512(pgp_hash_t *);
void pgp_hash_sha384(pgp_hash_t *);
void pgp_hash_sha224(pgp_hash_t *);
void pgp_hash_any(pgp_hash_t *, pgp_hash_alg_t);
pgp_hash_alg_t pgp_str_to_hash_alg(const char *);
const char *pgp_text_from_hash(pgp_hash_t *);
unsigned pgp_hash_size(pgp_hash_alg_t);
unsigned pgp_hash(uint8_t *, pgp_hash_alg_t, const void *, size_t);
void pgp_hash_add_int(pgp_hash_t *, unsigned, unsigned);
unsigned pgp_dsa_verify(const uint8_t *, size_t,
const pgp_dsa_sig_t *,
const pgp_dsa_pubkey_t *);
int pgp_rsa_public_decrypt(uint8_t *, const uint8_t *, size_t,
const pgp_rsa_pubkey_t *);
int pgp_rsa_public_encrypt(uint8_t *, const uint8_t *, size_t,
const pgp_rsa_pubkey_t *);
int pgp_rsa_private_encrypt(uint8_t *, const uint8_t *, size_t,
const pgp_rsa_seckey_t *, const pgp_rsa_pubkey_t *);
int pgp_rsa_private_decrypt(uint8_t *, const uint8_t *, size_t,
const pgp_rsa_seckey_t *, const pgp_rsa_pubkey_t *);
int pgp_elgamal_public_encrypt(uint8_t *, uint8_t *, const uint8_t *, size_t,
const pgp_elgamal_pubkey_t *);
int pgp_elgamal_private_decrypt(uint8_t *, const uint8_t *, const uint8_t *, size_t,
const pgp_elgamal_seckey_t *, const pgp_elgamal_pubkey_t *);
pgp_symm_alg_t pgp_str_to_cipher(const char *);
unsigned pgp_block_size(pgp_symm_alg_t);
unsigned pgp_key_size(pgp_symm_alg_t);
int pgp_decrypt_data(pgp_content_enum, pgp_region_t *,
pgp_stream_t *);
int pgp_crypt_any(pgp_crypt_t *, pgp_symm_alg_t);
void pgp_decrypt_init(pgp_crypt_t *);
void pgp_encrypt_init(pgp_crypt_t *);
size_t pgp_decrypt_se(pgp_crypt_t *, void *, const void *, size_t);
size_t pgp_encrypt_se(pgp_crypt_t *, void *, const void *, size_t);
size_t pgp_decrypt_se_ip(pgp_crypt_t *, void *, const void *, size_t);
size_t pgp_encrypt_se_ip(pgp_crypt_t *, void *, const void *, size_t);
unsigned pgp_is_sa_supported(pgp_symm_alg_t);
void pgp_reader_push_decrypt(pgp_stream_t *, pgp_crypt_t *,
pgp_region_t *);
void pgp_reader_pop_decrypt(pgp_stream_t *);
/* Hash everything that's read */
void pgp_reader_push_hash(pgp_stream_t *, pgp_hash_t *);
void pgp_reader_pop_hash(pgp_stream_t *);
int pgp_decrypt_decode_mpi(uint8_t *, unsigned, const BIGNUM *,
const BIGNUM *, const pgp_seckey_t *);
unsigned pgp_rsa_encrypt_mpi(const uint8_t *, const size_t,
const pgp_pubkey_t *,
pgp_pk_sesskey_params_t *);
unsigned pgp_elgamal_encrypt_mpi(const uint8_t *, const size_t,
const pgp_pubkey_t *,
pgp_pk_sesskey_params_t *);
/* Encrypt everything that's written */
struct pgp_key_data;
void pgp_writer_push_encrypt(pgp_output_t *,
const struct pgp_key_data *);
unsigned pgp_encrypt_file(pgp_io_t *, const char *, const char *,
const pgp_key_t *,
const unsigned, const unsigned, const char *);
unsigned pgp_decrypt_file(pgp_io_t *,
const char *,
const char *,
pgp_keyring_t *,
pgp_keyring_t *,
const unsigned,
const unsigned,
const unsigned,
void *,
int,
pgp_cbfunc_t *);
pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *, const void *, const size_t,
const pgp_key_t *,
const unsigned, const char *);
pgp_memory_t *
pgp_decrypt_buf(pgp_io_t *,
const void *,
const size_t,
pgp_keyring_t *,
pgp_keyring_t *,
const unsigned,
const unsigned,
void *,
int,
pgp_cbfunc_t *);
/* Keys */
pgp_key_t *pgp_rsa_new_selfsign_key(const int,
const unsigned long, uint8_t *, const char *,
const char *);
int pgp_dsa_size(const pgp_dsa_pubkey_t *);
DSA_SIG *pgp_dsa_sign(uint8_t *, unsigned,
const pgp_dsa_seckey_t *,
const pgp_dsa_pubkey_t *);
int openssl_read_pem_seckey(const char *, pgp_key_t *, const char *, int);
/** pgp_reader_t */
struct pgp_reader_t {
pgp_reader_func_t *reader; /* reader func to get parse data */
pgp_reader_destroyer_t *destroyer;
void *arg; /* args to pass to reader function */
unsigned accumulate:1; /* set to gather packet data */
uint8_t *accumulated; /* the accumulated data */
unsigned asize; /* size of the buffer */
unsigned alength;/* used buffer */
unsigned position; /* reader-specific offset */
pgp_reader_t *next;
pgp_stream_t *parent;/* parent parse_info structure */
};
/** pgp_cryptinfo_t
Encrypt/decrypt settings
*/
struct pgp_cryptinfo_t {
char *passphrase;
pgp_keyring_t *secring;
const pgp_key_t *keydata;
pgp_cbfunc_t *getpassphrase;
pgp_keyring_t *pubring;
};
/** pgp_cbdata_t */
struct pgp_cbdata_t {
pgp_cbfunc_t *cbfunc; /* callback function */
void *arg; /* args to pass to callback func */
pgp_error_t **errors; /* address of error stack */
pgp_cbdata_t *next;
pgp_output_t *output; /* when writing out parsed info */
pgp_io_t *io; /* error/output messages */
void *passfp; /* fp for passphrase input */
pgp_cryptinfo_t cryptinfo; /* used when decrypting */
pgp_printstate_t printstate; /* used to keep printing state */
pgp_seckey_t *sshseckey; /* secret key for ssh */
int numtries; /* # of passphrase attempts */
int gotpass; /* when passphrase entered */
};
/** pgp_hashtype_t */
typedef struct {
pgp_hash_t hash; /* hashes we should hash data with */
uint8_t keyid[PGP_KEY_ID_SIZE];
} pgp_hashtype_t;
#define NTAGS 0x100 /* == 256 */
/** \brief Structure to hold information about a packet parse.
*
* This information includes options about the parse:
* - whether the packet contents should be accumulated or not
* - whether signature subpackets should be parsed or left raw
*
* It contains options specific to the parsing of armoured data:
* - whether headers are allowed in armoured data without a gap
* - whether a blank line is allowed at the start of the armoured data
*
* It also specifies :
* - the callback function to use and its arguments
* - the reader function to use and its arguments
*
* It also contains information about the current state of the parse:
* - offset from the beginning
* - the accumulated data, if any
* - the size of the buffer, and how much has been used
*
* It has a linked list of errors.
*/
struct pgp_stream_t {
uint8_t ss_raw[NTAGS / 8];
/* 1 bit / sig-subpkt type; set to get raw data */
uint8_t ss_parsed[NTAGS / 8];
/* 1 bit / sig-subpkt type; set to get parsed data */
pgp_reader_t readinfo;
pgp_cbdata_t cbinfo;
pgp_error_t *errors;
void *io; /* io streams */
pgp_crypt_t decrypt;
pgp_cryptinfo_t cryptinfo;
size_t hashc;
pgp_hashtype_t *hashes;
unsigned reading_v3_secret:1;
unsigned reading_mpi_len:1;
unsigned exact_read:1;
unsigned partial_read:1;
unsigned coalescing:1;
/* used for partial length coalescing */
unsigned virtualc;
unsigned virtualoff;
uint8_t *virtualpkt;
};
#endif /* CRYPTO_H_ */

View File

@@ -0,0 +1,92 @@
/* $NetBSD: defs.h,v 1.2 2009/12/06 17:43:05 agc Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEFS_H_
#define DEFS_H_
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NEWARRAY(type,ptr,size,where,action) do { \
if ((ptr = calloc(sizeof(type), (unsigned)(size))) == NULL) { \
(void) fprintf(stderr, "%s: can't allocate %lu bytes\n", \
where, (unsigned long)(size * sizeof(type))); \
action; \
} \
} while( /* CONSTCOND */ 0)
#define RENEW(type,ptr,size,where,action) do { \
type *_newptr; \
_newptr = realloc(ptr, (size_t)(sizeof(type) * (size))); \
if (_newptr == NULL) { \
(void) fprintf(stderr, "%s: can't realloc %lu bytes\n", \
where, (unsigned long)(size * sizeof(type))); \
action; \
} else { \
ptr = _newptr; \
} \
} while( /* CONSTCOND */ 0)
#define NEW(type, ptr, where, action) NEWARRAY(type, ptr, 1, where, action)
#define FREE(ptr) (void) free(ptr)
#define ALLOC(type, v, size, c, init, incr, where, action) do { \
uint32_t _newsize = size; \
if (size == 0) { \
_newsize = init; \
NEWARRAY(type, v, _newsize, where ": new", action); \
} else if (c == size) { \
_newsize = size + incr; \
RENEW(type, v, _newsize, where ": renew", action); \
} \
size = _newsize; \
} while( /* CONSTCOND */ 0)
#define DEFINE_ARRAY(name, type) \
typedef struct name { \
uint32_t c; \
uint32_t size; \
type *v; \
} name
#endif /* !DEFS_H_ */

View File

@@ -0,0 +1,166 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef ERRORS_H_
#define ERRORS_H_
#include <errno.h>
/** error codes */
/* Remember to add names to map in errors.c */
typedef enum {
PGP_E_OK = 0x0000, /* no error */
PGP_E_FAIL = 0x0001, /* general error */
PGP_E_SYSTEM_ERROR = 0x0002, /* system error, look at errno for
* details */
PGP_E_UNIMPLEMENTED = 0x0003, /* feature not yet implemented */
/* reader errors */
PGP_E_R = 0x1000, /* general reader error */
PGP_E_R_READ_FAILED = PGP_E_R + 1,
PGP_E_R_EARLY_EOF = PGP_E_R + 2,
PGP_E_R_BAD_FORMAT = PGP_E_R + 3, /* For example, malformed
* armour */
PGP_E_R_UNSUPPORTED = PGP_E_R + 4,
PGP_E_R_UNCONSUMED_DATA = PGP_E_R + 5,
/* writer errors */
PGP_E_W = 0x2000, /* general writer error */
PGP_E_W_WRITE_FAILED = PGP_E_W + 1,
PGP_E_W_WRITE_TOO_SHORT = PGP_E_W + 2,
/* parser errors */
PGP_E_P = 0x3000, /* general parser error */
PGP_E_P_NOT_ENOUGH_DATA = PGP_E_P + 1,
PGP_E_P_UNKNOWN_TAG = PGP_E_P + 2,
PGP_E_P_PACKET_CONSUMED = PGP_E_P + 3,
PGP_E_P_MPI_FORMAT_ERROR = PGP_E_P + 4,
PGP_E_P_PACKET_NOT_CONSUMED = PGP_E_P + 5,
PGP_E_P_DECOMPRESSION_ERROR = PGP_E_P + 6,
PGP_E_P_NO_USERID = PGP_E_P + 7,
/* creator errors */
PGP_E_C = 0x4000, /* general creator error */
/* validation errors */
PGP_E_V = 0x5000, /* general validation error */
PGP_E_V_BAD_SIGNATURE = PGP_E_V + 1,
PGP_E_V_NO_SIGNATURE = PGP_E_V + 2,
PGP_E_V_UNKNOWN_SIGNER = PGP_E_V + 3,
PGP_E_V_BAD_HASH = PGP_E_V + 4,
/* Algorithm support errors */
PGP_E_ALG = 0x6000, /* general algorithm error */
PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG = PGP_E_ALG + 1,
PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG = PGP_E_ALG + 2,
PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG = PGP_E_ALG + 3,
PGP_E_ALG_UNSUPPORTED_HASH_ALG = PGP_E_ALG + 4,
PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG = PGP_E_ALG + 5,
/* Protocol errors */
PGP_E_PROTO = 0x7000, /* general protocol error */
PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT = PGP_E_PROTO + 2,
PGP_E_PROTO_UNKNOWN_SS = PGP_E_PROTO + 3,
PGP_E_PROTO_CRITICAL_SS_IGNORED = PGP_E_PROTO + 4,
PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN = PGP_E_PROTO + 5,
PGP_E_PROTO_BAD_SIGNATURE_VRSN = PGP_E_PROTO + 6,
PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN = PGP_E_PROTO + 7,
PGP_E_PROTO_BAD_PKSK_VRSN = PGP_E_PROTO + 8,
PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN = PGP_E_PROTO + 9,
PGP_E_PROTO_BAD_SK_CHECKSUM = PGP_E_PROTO + 10
} pgp_errcode_t;
/** one entry in a linked list of errors */
typedef struct pgp_error {
pgp_errcode_t errcode;
int sys_errno; /* irrelevent unless errcode ==
* PGP_E_SYSTEM_ERROR */
char *comment;
const char *file;
int line;
struct pgp_error *next;
} pgp_error_t;
const char *pgp_errcode(const pgp_errcode_t);
void
pgp_push_error(pgp_error_t **, pgp_errcode_t,
int,
const char *, int, const char *,...);
void pgp_print_error(pgp_error_t *);
void pgp_print_errors(pgp_error_t *);
void pgp_free_errors(pgp_error_t *);
int pgp_has_error(pgp_error_t *, pgp_errcode_t);
#define PGP_SYSTEM_ERROR_1(err,code,sys,fmt,arg) do { \
pgp_push_error(err,PGP_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,sys);\
pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); \
} while(/*CONSTCOND*/0)
#define PGP_MEMORY_ERROR(err) { \
fprintf(stderr, "Memory error\n"); \
} /* \todo placeholder for better error
* handling */
#define PGP_ERROR_1(err,code,fmt,arg) do { \
pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); \
} while(/*CONSTCOND*/0)
#define PGP_ERROR_2(err,code,fmt,arg,arg2) do { \
pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2); \
} while(/*CONSTCOND*/0)
#define PGP_ERROR_3(err,code,fmt,arg,arg2,arg3) do { \
pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3); \
} while(/*CONSTCOND*/0)
#define PGP_ERROR_4(err,code,fmt,arg,arg2,arg3,arg4) do { \
pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3,arg4); \
} while(/*CONSTCOND*/0)
#endif /* ERRORS_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef KEYRING_H_
#define KEYRING_H_
#include "packet.h"
#include "packet-parse.h"
#include "mj.h"
enum {
MAX_ID_LENGTH = 128,
MAX_PASSPHRASE_LENGTH = 256
};
typedef struct pgp_key_t pgp_key_t;
/** \struct pgp_keyring_t
* A keyring
*/
typedef struct pgp_keyring_t {
DYNARRAY(pgp_key_t, key);
pgp_hash_alg_t hashtype;
} pgp_keyring_t;
const pgp_key_t *pgp_getkeybyid(pgp_io_t *,
const pgp_keyring_t *,
const uint8_t *,
unsigned *,
pgp_pubkey_t **);
const pgp_key_t *pgp_getkeybyname(pgp_io_t *,
const pgp_keyring_t *,
const char *);
const pgp_key_t *pgp_getnextkeybyname(pgp_io_t *,
const pgp_keyring_t *,
const char *,
unsigned *);
void pgp_keydata_free(pgp_key_t *);
void pgp_keyring_free(pgp_keyring_t *);
void pgp_dump_keyring(const pgp_keyring_t *);
const pgp_pubkey_t *pgp_get_pubkey(const pgp_key_t *);
unsigned pgp_is_key_secret(const pgp_key_t *);
const pgp_seckey_t *pgp_get_seckey(const pgp_key_t *);
pgp_seckey_t *pgp_get_writable_seckey(pgp_key_t *);
pgp_seckey_t *pgp_decrypt_seckey(const pgp_key_t *, void *);
unsigned pgp_keyring_fileread(pgp_keyring_t *, const unsigned,
const char *);
int pgp_keyring_list(pgp_io_t *, const pgp_keyring_t *, const int);
int pgp_keyring_json(pgp_io_t *, const pgp_keyring_t *, mj_t *, const int);
void pgp_set_seckey(pgp_contents_t *, const pgp_key_t *);
void pgp_forget(void *, unsigned);
const uint8_t *pgp_get_key_id(const pgp_key_t *);
unsigned pgp_get_userid_count(const pgp_key_t *);
const uint8_t *pgp_get_userid(const pgp_key_t *, unsigned);
unsigned pgp_is_key_supported(const pgp_key_t *);
uint8_t *pgp_add_userid(pgp_key_t *, const uint8_t *);
pgp_subpacket_t *pgp_add_subpacket(pgp_key_t *,
const pgp_subpacket_t *);
unsigned pgp_add_selfsigned_userid(pgp_key_t *, uint8_t *);
pgp_key_t *pgp_keydata_new(void);
void pgp_keydata_init(pgp_key_t *, const pgp_content_enum);
int pgp_parse_and_accumulate(pgp_keyring_t *, pgp_stream_t *);
int pgp_sprint_keydata(pgp_io_t *, const pgp_keyring_t *,
const pgp_key_t *, char **, const char *,
const pgp_pubkey_t *, const int);
int pgp_sprint_mj(pgp_io_t *, const pgp_keyring_t *,
const pgp_key_t *, mj_t *, const char *,
const pgp_pubkey_t *, const int);
int pgp_hkp_sprint_keydata(pgp_io_t *, const pgp_keyring_t *,
const pgp_key_t *, char **,
const pgp_pubkey_t *, const int);
void pgp_print_keydata(pgp_io_t *, const pgp_keyring_t *, const pgp_key_t *,
const char *, const pgp_pubkey_t *, const int);
void pgp_print_sig(pgp_io_t *, const pgp_key_t *, const char *,
const pgp_pubkey_t *);
void pgp_print_pubkey(const pgp_pubkey_t *);
int pgp_sprint_pubkey(const pgp_key_t *, char *, size_t);
int pgp_list_packets(pgp_io_t *,
char *,
unsigned,
pgp_keyring_t *,
pgp_keyring_t *,
void *,
pgp_cbfunc_t *);
char *pgp_export_key(pgp_io_t *, const pgp_key_t *, uint8_t *);
int pgp_add_to_pubring(pgp_keyring_t *, const pgp_pubkey_t *, pgp_content_enum tag);
int pgp_add_to_secring(pgp_keyring_t *, const pgp_seckey_t *);
int pgp_append_keyring(pgp_keyring_t *, pgp_keyring_t *);
#endif /* KEYRING_H_ */

View File

@@ -0,0 +1,342 @@
.\" $NetBSD: libnetpgp.3,v 1.15 2013/07/20 21:39:55 wiz Exp $
.\"
.\" Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This manual page is derived from software contributed to The
.\" NetBSD Foundation by Alistair Crooks (agc@NetBSD.org)
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd June 17, 2010
.Dt LIBNETPGP 3
.Os
.Sh NAME
.Nm libnetpgp
.Nd digital signing and verification, encryption and decryption
.Sh LIBRARY
.Lb libnetpgp
.Sh SYNOPSIS
.In netpgp.h
.Pp
The following functions relate to initialisations and finalisations:
.Ft int
.Fo netpgp_init
.Fa "netpgp_t *netpgp"
.Fc
.Ft int
.Fo netpgp_end
.Fa "netpgp_t *netpgp"
.Fc
.Pp
The following functions are for debugging, reflection and information:
.Ft int
.Fo netpgp_set_debug
.Fa "const char *filename"
.Fc
.Ft int
.Fo netpgp_get_debug
.Fa "const char *filename"
.Fc
.Ft int
.Fo netpgp_get_info
.Fa "const char *type"
.Fc
.Ft int
.Fo netpgp_list_packets
.Fa "netpgp_t *netpgp" "char *filename" "int armour" "char *pubringname"
.Fc
.Pp
The following functions are for variable management:
.Ft int
.Fo netpgp_setvar
.Fa "netpgp_t *netpgp" "const char *name" "const char *value"
.Fc
.Ft char *
.Fo netpgp_getvar
.Fa "netpgp_t *netpgp" "const char *name"
.Fc
.Ft int
.Fo netpgp_incvar
.Fa "netpgp_t *netpgp" "const char *name" "const int delta"
.Fc
.Pp
The following function sets the home directory:
.Ft int
.Fo netpgp_set_homedir
.Fa "netpgp_t *netpgp" "char *homedir" "char *subdir" "const int quiet"
.Fc
.Pp
The following functions are used for key management:
.Ft int
.Fo netpgp_list_keys
.Fa "netpgp_t *netpgp" "const int printsigs"
.Fc
.Ft int
.Fo netpgp_match_list_keys
.Fa "netpgp_t *netpgp" "char *pattern"
.Fc
.Ft int
.Fo netpgp_find_key
.Fa "netpgp_t *netpgp" "char *userid"
.Fc
.Ft char *
.Fo netpgp_get_key
.Fa "netpgp_t *netpgp" "const char *id"
.Fc
.Ft int
.Fo netpgp_export_key
.Fa "netpgp_t *netpgp" "char *userid"
.Fc
.Ft int
.Fo netpgp_import_key
.Fa "netpgp_t *netpgp" "char *file"
.Fc
.Ft int
.Fo netpgp_generate_key
.Fa "netpgp_t *netpgp" "char *userid" "int numbits"
.Fc
.Pp
The following functions are used for file management:
.Ft int
.Fo netpgp_encrypt_file
.Fa "netpgp_t *netpgp" "char *userid" "char *filename" "char *out"
.Fa "int armored"
.Fc
.Ft int
.Fo netpgp_decrypt_file
.Fa "netpgp_t *netpgp" "char *filename" "char *out" "int armored"
.Fc
.Ft int
.Fo netpgp_sign_file
.Fa "netpgp_t *netpgp" "char *userid" "char *filename" "char *out"
.Fa "int armored" "int cleartext" "int detached"
.Fc
.Ft int
.Fo netpgp_verify_file
.Fa "netpgp_t *netpgp" "char *f" "int armored"
.Fc
.Pp
The following functions are used for memory signing and encryption:
.Ft int
.Fo netpgp_encrypt_memory
.Fa "netpgp_t *netpgp" "char *userid" "void *in" "const size_t insize"
.Fa "char *out" "size_t outsize" "int armored"
.Fc
.Ft int
.Fo netpgp_decrypt_memory
.Fa "netpgp_t *netpgp" "const void *input" "const size_t insize"
.Fa "char *out" "size_t outsize" "const int armored"
.Fc
.Ft int
.Fo netpgp_sign_memory
.Fa "netpgp_t *netpgp" "const char *userid" "char *mem"
.Fa "size_t size" "char *out" "size_t outsize"
.Fa "const unsigned armored" "const unsigned cleartext"
.Fc
.Ft int
.Fo netpgp_verify_memory
.Fa "netpgp_t *netpgp" "const void *in" "const size_t insize"
.Fa "void *out" "size_t outsize" "const int armored"
.Fc
.Sh DESCRIPTION
.Nm
is a library interface to enable digital signatures to be created and
verified, and also for files and memory to be encrypted and decrypted.
Functions are also provided for management of user keys.
.Pp
The library uses functions from the openssl library for multi-precision
integer arithmetic, and for RSA and DSA key signing and verification,
encryption and decryption.
.Pp
Normal operation sees the
.Nm
process be initialised using the
.Fn netpgp_init
function, which will set up the public and private keyrings, and set the
user identity to the
.Ar userid
argument passed stored in the
.Dv netpgp_t
structure, and set using the
.Fn netpgp_setvar
function.
If no public key ring file is set, initial values will be taken from those
in the
.Pa .gnupg/pubring.gpg
file in the user's home directory.
Similarily, if no secret key ring file is set,
initial values will be taken from those
in the
.Pa .gnupg/secring.gpg
file in the user's home directory.
The
.Fn netpgp_init
returns 1 on sucess, 0 on failure.
.Pp
To list all the keys in a keyring, the
.Fn netpgp_list_keys
function is used.
The signature subkey fields can also be displayed
using this function.
The
.Fn netpgp_match_list_keys
function is used to match (via regular expression)
a subset of the keys in the keyring.
If the expression to match is NULL,
the search will degenerate into a
listing of all keys in the keyring.
.Pp
The home directory is specified as an internal variable,
and its existence is checked using the
.Fn netpgp_set_homedir
function.
This function can operate in a verbose or quiet
manner, depending on the value of the argument provided.
If the subdirectory argument is provided, this subdirectory
is appended to the home directory in order to search for
the keyrings.
.Pp
To export a key, the
.Fn netpgp_export_key
is used.
Output is sent to the standard output.
.Pp
To import a key onto the public keyring, the
.Fn netpgp_import_key
is used.
The name of the file containing the key to be imported is provided
as the filename argument.
.Pp
To generate a key, the
.Fn netpgp_generate_key
is used.
It takes an argument of the number of bits to use in the key.
At the time that this manual page was created (April 2009),
the recommendations are that the bare minimum key size
of at least 2048 bits is used, and it would be much better
to use at least 4096 or 8192 bits.
This situation should be monitored to ensure that it does
not go out of date.
.Pp
Encryption, decryption, signing and verification of
files are the lifeblood of the
.Nm
library.
To encrypt a file, the
.Fn netpgp_encrypt_file
and the
.Fn netpgp_decrypt_file
is used to decrypt the results of the encryption.
To sign a file, the
.Fn netpgp_sign_file
is used, and the resulting signed file can be verified
using the
.Fn netpgp_verify_file
function.
.Pp
.Fn netpgp_sign_memory
is a function which can sign an area
of memory, and
.Fn netpgp_verify_memory
verifies the digital signature produced.
.Pp
Internally, an encrypted or signed file
is made up of
.Dq packets
which hold information pertaining to the signature,
encryption method, and the data which is being protected.
This information can be displayed in a verbose manner using
the
.Fn netpgp_list_packets
function.
.Pp
The
.Fn netpgp_setvar
and
.Fn netpgp_getvar
functions are used to manage the hash algorithm that
is used with RSA signatures.
These functions are general purpose functions, and
are used to set and retrieve values for internal variables.
For example, they
can be used to set and to retrieve the
value of the user id
which has been set,
the home directory from which to find the keyrings,
the verbosity settings, and many more.
The
.Fn netpgp_incvar
function is used to add a numeric increment to the
internal variable.
This incremental value can be negative.
It is primarily used to increase the verbosity settings.
.Pp
In
.Nm
files are encrypted using the public key of the userid.
The secret key is used to decrypt the results of that encryption.
Files are signed using the secret key of the userid.
The public key is used to verify that the file was signed,
who signed the file, and the date and time at which it was signed.
.Pp
Some utility functions are also provided for debugging, and for
finding out version and maintainer information from calling programs.
These are the
.Fn netpgp_set_debug
and the
.Fn netpgp_get_debug
functions (for getting verbose debugging information on a per-source
file basis).
.Pp
The
.Fn netpgp_get_info
returns the version or maintainer information depending upon the
.Ar type
argument.
At the present time, two types are defined:
.Dq version
and
.Dq maintainer .
A failure to present a known
.Ar type
argument to
.Fn netpgp_get_info
will result in the string
.Dq [unknown]
being returned.
.Sh SEE ALSO
.Xr netpgp 1 ,
.Xr ssl 3
.Sh HISTORY
The
.Nm
library first appeared in
.Nx 6.0 .
.Sh AUTHORS
.An Ben Laurie ,
.An Rachel Willmer .
.An Alistair Crooks Aq Mt agc@NetBSD.org
wrote this high-level interface.
.Pp
This manual page was written by
.An Alistair Crooks .

View File

@@ -0,0 +1,87 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef MEMORY_H_
#define MEMORY_H_
#include <sys/types.h>
#include "packet.h"
/** pgp_memory_t
*/
typedef struct pgp_memory_t {
uint8_t *buf;
size_t length;
size_t allocated;
unsigned mmapped;
} pgp_memory_t;
pgp_memory_t *pgp_memory_new(void);
void pgp_memory_free(pgp_memory_t *);
void pgp_memory_init(pgp_memory_t *, size_t);
void pgp_memory_pad(pgp_memory_t *, size_t);
void pgp_memory_add(pgp_memory_t *, const uint8_t *, size_t);
void pgp_memory_place_int(pgp_memory_t *, unsigned, unsigned, size_t);
void pgp_memory_make_packet(pgp_memory_t *, pgp_content_enum);
void pgp_memory_clear(pgp_memory_t *);
void pgp_memory_release(pgp_memory_t *);
void pgp_writer_set_memory(pgp_output_t *, pgp_memory_t *);
size_t pgp_mem_len(const pgp_memory_t *);
void *pgp_mem_data(pgp_memory_t *);
int pgp_mem_readfile(pgp_memory_t *, const char *);
void pgp_random(void *, size_t);
#endif /* MEMORY_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.1.1.1 2009/04/23 06:32:03 agc Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@netbsd.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NETPGPDEFS_H_
#define NETPGPDEFS_H_ 1
#define PRItime "ll"
#ifdef WIN32
#define PRIsize "I"
#else
#define PRIsize "z"
#endif
/* for silencing unused parameter warnings */
#define __PGP_USED(x) /*LINTED*/(void)&(x)
#ifndef __UNCONST
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
#endif
/* number of elements in an array */
#define PGP_ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
void hexdump(FILE *, const char *, const uint8_t *, size_t);
const char *pgp_str_from_map(int, pgp_map_t *);
int pgp_set_debug_level(const char *);
int pgp_get_debug_level(const char *);
void *pgp_new(size_t);
#define NETPGP_BUFSIZ 8192
#define CALLBACK(t, cbinfo, pkt) do { \
(pkt)->tag = (t); \
if (pgp_callback(pkt, cbinfo) == PGP_RELEASE_MEMORY) { \
pgp_parser_content_free(pkt); \
} \
} while(/* CONSTCOND */0)
#endif /* !NETPGPDEFS_H_ */

View File

@@ -0,0 +1,55 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@netbsd.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NETPGPDIGEST_H_
#define NETPGPDIGEST_H_
/* header file to define the sizes for various digest arrays */
#ifdef HAVE_OPENSSL_MD5_H
#include <openssl/md5.h>
#endif
#ifdef HAVE_OPENSSL_SHA_H
#include <openssl/sha.h>
#endif
/* Apple */
#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
#undef MD5_DIGEST_LENGTH
#undef SHA_DIGEST_LENGTH
#define COMMON_DIGEST_FOR_OPENSSL 1
#include <CommonCrypto/CommonDigest.h>
#endif
/* SHA1 Hash Size */
#define PGP_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
#define PGP_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH
#define PGP_CHECKHASH_SIZE PGP_SHA1_HASH_SIZE
#endif /* NETPGPDIGEST_H_ */

View File

@@ -0,0 +1,74 @@
/*-
* Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NETPGPSDK_H_
#define NETPGPSDK_H_
#include "keyring.h"
#include "crypto.h"
#include "signature.h"
#include "packet-show.h"
typedef struct pgp_validation_t {
unsigned validc;
pgp_sig_info_t *valid_sigs;
unsigned invalidc;
pgp_sig_info_t *invalid_sigs;
unsigned unknownc;
pgp_sig_info_t *unknown_sigs;
time_t birthtime;
time_t duration;
} pgp_validation_t;
void pgp_validate_result_free(pgp_validation_t *);
unsigned
pgp_validate_key_sigs(pgp_validation_t *,
const pgp_key_t *,
const pgp_keyring_t *,
pgp_cb_ret_t cb(const pgp_packet_t *, pgp_cbdata_t *));
unsigned
pgp_validate_all_sigs(pgp_validation_t *,
const pgp_keyring_t *,
pgp_cb_ret_t cb(const pgp_packet_t *, pgp_cbdata_t *));
unsigned pgp_check_sig(const uint8_t *,
unsigned, const pgp_sig_t *, const pgp_pubkey_t *);
const char *pgp_get_info(const char *type);
int pgp_asprintf(char **, const char *, ...);
void netpgp_log(const char *, ...);
int netpgp_strcasecmp(const char *, const char *);
char *netpgp_strdup(const char *);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,169 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
* Parser for OpenPGP packets - headers.
*/
#ifndef PACKET_PARSE_H_
#define PACKET_PARSE_H_
#include "types.h"
#include "packet.h"
/** pgp_region_t */
typedef struct pgp_region_t {
struct pgp_region_t *parent;
unsigned length;
unsigned readc; /* length read */
unsigned last_read;
/* length of last read, only valid in deepest child */
unsigned indeterminate:1;
} pgp_region_t;
void pgp_init_subregion(pgp_region_t *, pgp_region_t *);
/** pgp_cb_ret_t */
typedef enum {
PGP_RELEASE_MEMORY,
PGP_KEEP_MEMORY,
PGP_FINISHED
} pgp_cb_ret_t;
typedef struct pgp_cbdata_t pgp_cbdata_t;
typedef pgp_cb_ret_t pgp_cbfunc_t(const pgp_packet_t *,
pgp_cbdata_t *);
pgp_cb_ret_t
get_passphrase_cb(const pgp_packet_t *, pgp_cbdata_t *);
typedef struct pgp_stream_t pgp_stream_t;
typedef struct pgp_reader_t pgp_reader_t;
typedef struct pgp_cryptinfo_t pgp_cryptinfo_t;
/*
A reader MUST read at least one byte if it can, and should read up
to the number asked for. Whether it reads more for efficiency is
its own decision, but if it is a stacked reader it should never
read more than the length of the region it operates in (which it
would have to be given when it is stacked).
If a read is short because of EOF, then it should return the short
read (obviously this will be zero on the second attempt, if not the
first). Because a reader is not obliged to do a full read, only a
zero return can be taken as an indication of EOF.
If there is an error, then the callback should be notified, the
error stacked, and -1 should be returned.
Note that although length is a size_t, a reader will never be asked
to read more than INT_MAX in one go.
*/
typedef int pgp_reader_func_t(pgp_stream_t *, void *, size_t, pgp_error_t **,
pgp_reader_t *, pgp_cbdata_t *);
typedef void pgp_reader_destroyer_t(pgp_reader_t *);
void pgp_stream_delete(pgp_stream_t *);
pgp_error_t *pgp_stream_get_errors(pgp_stream_t *);
pgp_crypt_t *pgp_get_decrypt(pgp_stream_t *);
void pgp_set_callback(pgp_stream_t *, pgp_cbfunc_t *, void *);
void pgp_callback_push(pgp_stream_t *, pgp_cbfunc_t *, void *);
void *pgp_callback_arg(pgp_cbdata_t *);
void *pgp_callback_errors(pgp_cbdata_t *);
void pgp_reader_set(pgp_stream_t *, pgp_reader_func_t *,
pgp_reader_destroyer_t *, void *);
void pgp_reader_push(pgp_stream_t *, pgp_reader_func_t *,
pgp_reader_destroyer_t *, void *);
void pgp_reader_pop(pgp_stream_t *);
void *pgp_reader_get_arg(pgp_reader_t *);
pgp_cb_ret_t pgp_callback(const pgp_packet_t *,
pgp_cbdata_t *);
pgp_cb_ret_t pgp_stacked_callback(const pgp_packet_t *,
pgp_cbdata_t *);
pgp_reader_t *pgp_readinfo(pgp_stream_t *);
int pgp_parse(pgp_stream_t *, const int);
/** Used to specify whether subpackets should be returned raw, parsed
* or ignored. */
typedef enum {
PGP_PARSE_RAW, /* Callback Raw */
PGP_PARSE_PARSED, /* Callback Parsed */
PGP_PARSE_IGNORE /* Don't callback */
} pgp_parse_type_t;
void pgp_parse_options(pgp_stream_t *, pgp_content_enum,
pgp_parse_type_t);
unsigned pgp_limited_read(pgp_stream_t *, uint8_t *, size_t, pgp_region_t *,
pgp_error_t **, pgp_reader_t *,
pgp_cbdata_t *);
unsigned pgp_stacked_limited_read(pgp_stream_t *, uint8_t *, unsigned,
pgp_region_t *, pgp_error_t **,
pgp_reader_t *, pgp_cbdata_t *);
void pgp_parse_hash_init(pgp_stream_t *, pgp_hash_alg_t,
const uint8_t *);
void pgp_parse_hash_data(pgp_stream_t *, const void *, size_t);
void pgp_parse_hash_finish(pgp_stream_t *);
pgp_hash_t *pgp_parse_hash_find(pgp_stream_t *, const uint8_t *);
pgp_reader_func_t pgp_stacked_read;
int pgp_decompress(pgp_region_t *, pgp_stream_t *,
pgp_compression_type_t);
unsigned pgp_writez(pgp_output_t *, const uint8_t *,
const unsigned);
#endif /* PACKET_PARSE_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,914 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*
* Creates printable text strings from packet contents
*
*/
#include "config.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: packet-show.c,v 1.21 2011/08/14 11:19:51 christos Exp $");
#endif
#include <stdlib.h>
#include <string.h>
#include "packet-show.h"
#include "netpgpsdk.h"
#include "netpgpdefs.h"
/*
* Arrays of value->text maps
*/
static pgp_map_t packet_tag_map[] =
{
{PGP_PTAG_CT_RESERVED, "Reserved"},
{PGP_PTAG_CT_PK_SESSION_KEY, "Public-Key Encrypted Session Key"},
{PGP_PTAG_CT_SIGNATURE, "Signature"},
{PGP_PTAG_CT_SK_SESSION_KEY, "Symmetric-Key Encrypted Session Key"},
{PGP_PTAG_CT_1_PASS_SIG, "One-Pass Signature"},
{PGP_PTAG_CT_SECRET_KEY, "Secret Key"},
{PGP_PTAG_CT_PUBLIC_KEY, "Public Key"},
{PGP_PTAG_CT_SECRET_SUBKEY, "Secret Subkey"},
{PGP_PTAG_CT_COMPRESSED, "Compressed Data"},
{PGP_PTAG_CT_SE_DATA, "Symmetrically Encrypted Data"},
{PGP_PTAG_CT_MARKER, "Marker"},
{PGP_PTAG_CT_LITDATA, "Literal Data"},
{PGP_PTAG_CT_TRUST, "Trust"},
{PGP_PTAG_CT_USER_ID, "User ID"},
{PGP_PTAG_CT_PUBLIC_SUBKEY, "Public Subkey"},
{PGP_PTAG_CT_RESERVED2, "reserved2"},
{PGP_PTAG_CT_RESERVED3, "reserved3"},
{PGP_PTAG_CT_USER_ATTR, "User Attribute"},
{PGP_PTAG_CT_SE_IP_DATA,
"Symmetric Encrypted and Integrity Protected Data"},
{PGP_PTAG_CT_MDC, "Modification Detection Code"},
{PGP_PARSER_PTAG, "PGP_PARSER_PTAG"},
{PGP_PTAG_RAW_SS, "PGP_PTAG_RAW_SS"},
{PGP_PTAG_SS_ALL, "PGP_PTAG_SS_ALL"},
{PGP_PARSER_PACKET_END, "PGP_PARSER_PACKET_END"},
{PGP_PTAG_SIG_SUBPKT_BASE, "PGP_PTAG_SIG_SUBPKT_BASE"},
{PGP_PTAG_SS_CREATION_TIME, "SS: Signature Creation Time"},
{PGP_PTAG_SS_EXPIRATION_TIME, "SS: Signature Expiration Time"},
{PGP_PTAG_SS_EXPORT_CERT, "SS: Exportable Certification"},
{PGP_PTAG_SS_TRUST, "SS: Trust Signature"},
{PGP_PTAG_SS_REGEXP, "SS: Regular Expression"},
{PGP_PTAG_SS_REVOCABLE, "SS: Revocable"},
{PGP_PTAG_SS_KEY_EXPIRY, "SS: Key Expiration Time"},
{PGP_PTAG_SS_RESERVED, "SS: Reserved"},
{PGP_PTAG_SS_PREFERRED_SKA, "SS: Preferred Secret Key Algorithm"},
{PGP_PTAG_SS_REVOCATION_KEY, "SS: Revocation Key"},
{PGP_PTAG_SS_ISSUER_KEY_ID, "SS: Issuer Key Id"},
{PGP_PTAG_SS_NOTATION_DATA, "SS: Notation Data"},
{PGP_PTAG_SS_PREFERRED_HASH, "SS: Preferred Hash Algorithm"},
{PGP_PTAG_SS_PREF_COMPRESS, "SS: Preferred Compression Algorithm"},
{PGP_PTAG_SS_KEYSERV_PREFS, "SS: Key Server Preferences"},
{PGP_PTAG_SS_PREF_KEYSERV, "SS: Preferred Key Server"},
{PGP_PTAG_SS_PRIMARY_USER_ID, "SS: Primary User ID"},
{PGP_PTAG_SS_POLICY_URI, "SS: Policy URI"},
{PGP_PTAG_SS_KEY_FLAGS, "SS: Key Flags"},
{PGP_PTAG_SS_SIGNERS_USER_ID, "SS: Signer's User ID"},
{PGP_PTAG_SS_REVOCATION_REASON, "SS: Reason for Revocation"},
{PGP_PTAG_SS_FEATURES, "SS: Features"},
{PGP_PTAG_SS_SIGNATURE_TARGET, "SS: Signature Target"},
{PGP_PTAG_SS_EMBEDDED_SIGNATURE, "SS: Embedded Signature"},
{PGP_PTAG_CT_LITDATA_HEADER, "CT: Literal Data Header"},
{PGP_PTAG_CT_LITDATA_BODY, "CT: Literal Data Body"},
{PGP_PTAG_CT_SIGNATURE_HEADER, "CT: Signature Header"},
{PGP_PTAG_CT_SIGNATURE_FOOTER, "CT: Signature Footer"},
{PGP_PTAG_CT_ARMOUR_HEADER, "CT: Armour Header"},
{PGP_PTAG_CT_ARMOUR_TRAILER, "CT: Armour Trailer"},
{PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER, "CT: Signed Cleartext Header"},
{PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY, "CT: Signed Cleartext Body"},
{PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, "CT: Signed Cleartext Trailer"},
{PGP_PTAG_CT_UNARMOURED_TEXT, "CT: Unarmoured Text"},
{PGP_PTAG_CT_ENCRYPTED_SECRET_KEY, "CT: Encrypted Secret Key"},
{PGP_PTAG_CT_SE_DATA_HEADER, "CT: Sym Encrypted Data Header"},
{PGP_PTAG_CT_SE_DATA_BODY, "CT: Sym Encrypted Data Body"},
{PGP_PTAG_CT_SE_IP_DATA_HEADER, "CT: Sym Encrypted IP Data Header"},
{PGP_PTAG_CT_SE_IP_DATA_BODY, "CT: Sym Encrypted IP Data Body"},
{PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, "CT: Encrypted PK Session Key"},
{PGP_GET_PASSPHRASE, "CMD: Get Secret Key Passphrase"},
{PGP_GET_SECKEY, "CMD: Get Secret Key"},
{PGP_PARSER_ERROR, "PGP_PARSER_ERROR"},
{PGP_PARSER_ERRCODE, "PGP_PARSER_ERRCODE"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_map_t ss_type_map[] =
{
{PGP_PTAG_SS_CREATION_TIME, "Signature Creation Time"},
{PGP_PTAG_SS_EXPIRATION_TIME, "Signature Expiration Time"},
{PGP_PTAG_SS_TRUST, "Trust Signature"},
{PGP_PTAG_SS_REGEXP, "Regular Expression"},
{PGP_PTAG_SS_REVOCABLE, "Revocable"},
{PGP_PTAG_SS_KEY_EXPIRY, "Key Expiration Time"},
{PGP_PTAG_SS_PREFERRED_SKA, "Preferred Symmetric Algorithms"},
{PGP_PTAG_SS_REVOCATION_KEY, "Revocation Key"},
{PGP_PTAG_SS_ISSUER_KEY_ID, "Issuer key ID"},
{PGP_PTAG_SS_NOTATION_DATA, "Notation Data"},
{PGP_PTAG_SS_PREFERRED_HASH, "Preferred Hash Algorithms"},
{PGP_PTAG_SS_PREF_COMPRESS, "Preferred Compression Algorithms"},
{PGP_PTAG_SS_KEYSERV_PREFS, "Key Server Preferences"},
{PGP_PTAG_SS_PREF_KEYSERV, "Preferred Key Server"},
{PGP_PTAG_SS_PRIMARY_USER_ID, "Primary User ID"},
{PGP_PTAG_SS_POLICY_URI, "Policy URI"},
{PGP_PTAG_SS_KEY_FLAGS, "Key Flags"},
{PGP_PTAG_SS_REVOCATION_REASON, "Reason for Revocation"},
{PGP_PTAG_SS_FEATURES, "Features"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_map_t ss_rr_code_map[] =
{
{0x00, "No reason specified"},
{0x01, "Key is superseded"},
{0x02, "Key material has been compromised"},
{0x03, "Key is retired and no longer used"},
{0x20, "User ID information is no longer valid"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_map_t sig_type_map[] =
{
{PGP_SIG_BINARY, "Signature of a binary document"},
{PGP_SIG_TEXT, "Signature of a canonical text document"},
{PGP_SIG_STANDALONE, "Standalone signature"},
{PGP_CERT_GENERIC, "Generic certification of a User ID and Public Key packet"},
{PGP_CERT_PERSONA, "Personal certification of a User ID and Public Key packet"},
{PGP_CERT_CASUAL, "Casual certification of a User ID and Public Key packet"},
{PGP_CERT_POSITIVE, "Positive certification of a User ID and Public Key packet"},
{PGP_SIG_SUBKEY, "Subkey Binding Signature"},
{PGP_SIG_PRIMARY, "Primary Key Binding Signature"},
{PGP_SIG_DIRECT, "Signature directly on a key"},
{PGP_SIG_REV_KEY, "Key revocation signature"},
{PGP_SIG_REV_SUBKEY, "Subkey revocation signature"},
{PGP_SIG_REV_CERT, "Certification revocation signature"},
{PGP_SIG_TIMESTAMP, "Timestamp signature"},
{PGP_SIG_3RD_PARTY, "Third-Party Confirmation signature"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_map_t pubkey_alg_map[] =
{
{PGP_PKA_RSA, "RSA (Encrypt or Sign)"},
{PGP_PKA_RSA_ENCRYPT_ONLY, "RSA Encrypt-Only"},
{PGP_PKA_RSA_SIGN_ONLY, "RSA Sign-Only"},
{PGP_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"},
{PGP_PKA_DSA, "DSA"},
{PGP_PKA_RESERVED_ELLIPTIC_CURVE, "Reserved for Elliptic Curve"},
{PGP_PKA_RESERVED_ECDSA, "Reserved for ECDSA"},
{PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign"},
{PGP_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)"},
{PGP_PKA_PRIVATE00, "Private/Experimental"},
{PGP_PKA_PRIVATE01, "Private/Experimental"},
{PGP_PKA_PRIVATE02, "Private/Experimental"},
{PGP_PKA_PRIVATE03, "Private/Experimental"},
{PGP_PKA_PRIVATE04, "Private/Experimental"},
{PGP_PKA_PRIVATE05, "Private/Experimental"},
{PGP_PKA_PRIVATE06, "Private/Experimental"},
{PGP_PKA_PRIVATE07, "Private/Experimental"},
{PGP_PKA_PRIVATE08, "Private/Experimental"},
{PGP_PKA_PRIVATE09, "Private/Experimental"},
{PGP_PKA_PRIVATE10, "Private/Experimental"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_map_t symm_alg_map[] =
{
{PGP_SA_PLAINTEXT, "Plaintext or unencrypted data"},
{PGP_SA_IDEA, "IDEA"},
{PGP_SA_TRIPLEDES, "TripleDES"},
{PGP_SA_CAST5, "CAST5"},
{PGP_SA_BLOWFISH, "Blowfish"},
{PGP_SA_AES_128, "AES (128-bit key)"},
{PGP_SA_AES_192, "AES (192-bit key)"},
{PGP_SA_AES_256, "AES (256-bit key)"},
{PGP_SA_TWOFISH, "Twofish(256-bit key)"},
{PGP_SA_CAMELLIA_128, "Camellia (128-bit key)"},
{PGP_SA_CAMELLIA_192, "Camellia (192-bit key)"},
{PGP_SA_CAMELLIA_256, "Camellia (256-bit key)"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_map_t hash_alg_map[] =
{
{PGP_HASH_MD5, "MD5"},
{PGP_HASH_SHA1, "SHA1"},
{PGP_HASH_RIPEMD, "RIPEMD160"},
{PGP_HASH_SHA256, "SHA256"},
{PGP_HASH_SHA384, "SHA384"},
{PGP_HASH_SHA512, "SHA512"},
{PGP_HASH_SHA224, "SHA224"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_map_t compression_alg_map[] =
{
{PGP_C_NONE, "Uncompressed"},
{PGP_C_ZIP, "ZIP(RFC1951)"},
{PGP_C_ZLIB, "ZLIB(RFC1950)"},
{PGP_C_BZIP2, "Bzip2(BZ2)"},
{0x00, NULL}, /* this is the end-of-array marker */
};
static pgp_bit_map_t ss_notation_map_byte0[] =
{
{0x80, "Human-readable"},
{0x00, NULL},
};
static pgp_bit_map_t *ss_notation_map[] =
{
ss_notation_map_byte0,
};
static pgp_bit_map_t ss_feature_map_byte0[] =
{
{0x01, "Modification Detection"},
{0x00, NULL},
};
static pgp_bit_map_t *ss_feature_map[] =
{
ss_feature_map_byte0,
};
static pgp_bit_map_t ss_key_flags_map[] =
{
{0x01, "May be used to certify other keys"},
{0x02, "May be used to sign data"},
{0x04, "May be used to encrypt communications"},
{0x08, "May be used to encrypt storage"},
{0x10, "Private component may have been split by a secret-sharing mechanism"},
{0x80, "Private component may be in possession of more than one person"},
{0x00, NULL},
};
static pgp_bit_map_t ss_key_server_prefs_map[] =
{
{0x80, "Key holder requests that this key only be modified or updated by the key holder or an administrator of the key server"},
{0x00, NULL},
};
/*
* Private functions
*/
static void
list_init(pgp_list_t *list)
{
list->size = 0;
list->used = 0;
list->strings = NULL;
}
static void
list_free_strings(pgp_list_t *list)
{
unsigned i;
for (i = 0; i < list->used; i++) {
free(list->strings[i]);
list->strings[i] = NULL;
}
}
static void
list_free(pgp_list_t *list)
{
if (list->strings)
free(list->strings);
list_init(list);
}
static unsigned
list_resize(pgp_list_t *list)
{
/*
* We only resize in one direction - upwards. Algorithm used : double
* the current size then add 1
*/
char **newstrings;
int newsize;
newsize = (list->size * 2) + 1;
newstrings = realloc(list->strings, newsize * sizeof(char *));
if (newstrings) {
list->strings = newstrings;
list->size = newsize;
return 1;
}
(void) fprintf(stderr, "list_resize - bad alloc\n");
return 0;
}
static unsigned
add_str(pgp_list_t *list, const char *str)
{
if (list->size == list->used && !list_resize(list)) {
return 0;
}
list->strings[list->used++] = __UNCONST(str);
return 1;
}
/* find a bitfield in a map - serial search */
static const char *
find_bitfield(pgp_bit_map_t *map, uint8_t octet)
{
pgp_bit_map_t *row;
for (row = map; row->string != NULL && row->mask != octet ; row++) {
}
return (row->string) ? row->string : "Unknown";
}
/* ! generic function to initialise pgp_text_t structure */
void
pgp_text_init(pgp_text_t *text)
{
list_init(&text->known);
list_init(&text->unknown);
}
/**
* \ingroup Core_Print
*
* pgp_text_free() frees the memory used by an pgp_text_t structure
*
* \param text Pointer to a previously allocated structure. This structure and its contents will be freed.
*/
void
pgp_text_free(pgp_text_t *text)
{
/* Strings in "known" array will be constants, so don't free them */
list_free(&text->known);
/*
* Strings in "unknown" array will be dynamically allocated, so do
* free them
*/
list_free_strings(&text->unknown);
list_free(&text->unknown);
free(text);
}
/* XXX: should this (and many others) be unsigned? */
/* ! generic function which adds text derived from single octet map to text */
static unsigned
add_str_from_octet_map(pgp_text_t *map, char *str, uint8_t octet)
{
if (str && !add_str(&map->known, str)) {
/*
* value recognised, but there was a problem adding it to the
* list
*/
/* XXX - should print out error msg here, Ben? - rachel */
return 0;
} else if (!str) {
/*
* value not recognised and there was a problem adding it to
* the unknown list
*/
unsigned len = 2 + 2 + 1; /* 2 for "0x", 2 for
* single octet in hex
* format, 1 for NUL */
if ((str = calloc(1, len)) == NULL) {
(void) fprintf(stderr, "add_str_from_octet_map: bad alloc\n");
return 0;
}
(void) snprintf(str, len, "0x%x", octet);
if (!add_str(&map->unknown, str)) {
return 0;
}
free(str);
}
return 1;
}
/* ! generic function which adds text derived from single bit map to text */
static unsigned
add_bitmap_entry(pgp_text_t *map, const char *str, uint8_t bit)
{
if (str && !add_str(&map->known, str)) {
/*
* value recognised, but there was a problem adding it to the
* list
*/
/* XXX - should print out error msg here, Ben? - rachel */
return 0;
} else if (!str) {
/*
* value not recognised and there was a problem adding it to
* the unknown list
* 2 chars of the string are the format definition, this will
* be replaced in the output by 2 chars of hex, so the length
* will be correct
*/
char *newstr;
if (asprintf(&newstr, "Unknown bit(0x%x)", bit) == -1) {
(void) fprintf(stderr, "add_bitmap_entry: bad alloc\n");
return 0;
}
if (!add_str(&map->unknown, newstr)) {
return 0;
}
free(newstr);
}
return 1;
}
/**
* Produce a structure containing human-readable textstrings
* representing the recognised and unrecognised contents
* of this byte array. text_fn() will be called on each octet in turn.
* Each octet will generate one string representing the whole byte.
*
*/
static pgp_text_t *
text_from_bytemapped_octets(const pgp_data_t *data,
const char *(*text_fn)(uint8_t octet))
{
pgp_text_t *text;
const char *str;
unsigned i;
/*
* ! allocate and initialise pgp_text_t structure to store derived
* strings
*/
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* ! for each octet in field ... */
for (i = 0; i < data->len; i++) {
/* ! derive string from octet */
str = (*text_fn) (data->contents[i]);
/* ! and add to text */
if (!add_str_from_octet_map(text, netpgp_strdup(str),
data->contents[i])) {
pgp_text_free(text);
return NULL;
}
}
/*
* ! All values have been added to either the known or the unknown
* list
*/
return text;
}
/**
* Produce a structure containing human-readable textstrings
* representing the recognised and unrecognised contents
* of this byte array, derived from each bit of each octet.
*
*/
static pgp_text_t *
showall_octets_bits(pgp_data_t *data, pgp_bit_map_t **map, size_t nmap)
{
pgp_text_t *text;
const char *str;
unsigned i;
uint8_t mask, bit;
int j = 0;
/*
* ! allocate and initialise pgp_text_t structure to store derived
* strings
*/
if ((text = calloc(1, sizeof(pgp_text_t))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* ! for each octet in field ... */
for (i = 0; i < data->len; i++) {
/* ! for each bit in octet ... */
mask = 0x80;
for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
bit = data->contents[i] & mask;
if (bit) {
str = (i >= nmap) ? "Unknown" :
find_bitfield(map[i], bit);
if (!add_bitmap_entry(text, str, bit)) {
pgp_text_free(text);
return NULL;
}
}
}
}
return text;
}
/*
* Public Functions
*/
/**
* \ingroup Core_Print
* returns description of the Packet Tag
* \param packet_tag
* \return string or "Unknown"
*/
const char *
pgp_show_packet_tag(pgp_content_enum packet_tag)
{
const char *ret;
ret = pgp_str_from_map(packet_tag, packet_tag_map);
if (!ret) {
ret = "Unknown Tag";
}
return ret;
}
/**
* \ingroup Core_Print
*
* returns description of the Signature Sub-Packet type
* \param ss_type Signature Sub-Packet type
* \return string or "Unknown"
*/
const char *
pgp_show_ss_type(pgp_content_enum ss_type)
{
return pgp_str_from_map(ss_type, ss_type_map);
}
/**
* \ingroup Core_Print
*
* returns description of the Revocation Reason code
* \param ss_rr_code Revocation Reason code
* \return string or "Unknown"
*/
const char *
pgp_show_ss_rr_code(pgp_ss_rr_code_t ss_rr_code)
{
return pgp_str_from_map(ss_rr_code, ss_rr_code_map);
}
/**
* \ingroup Core_Print
*
* returns description of the given Signature type
* \param sig_type Signature type
* \return string or "Unknown"
*/
const char *
pgp_show_sig_type(pgp_sig_type_t sig_type)
{
return pgp_str_from_map(sig_type, sig_type_map);
}
/**
* \ingroup Core_Print
*
* returns description of the given Public Key Algorithm
* \param pka Public Key Algorithm type
* \return string or "Unknown"
*/
const char *
pgp_show_pka(pgp_pubkey_alg_t pka)
{
return pgp_str_from_map(pka, pubkey_alg_map);
}
/**
* \ingroup Core_Print
* returns description of the Preferred Compression
* \param octet Preferred Compression
* \return string or "Unknown"
*/
const char *
pgp_show_ss_zpref(uint8_t octet)
{
return pgp_str_from_map(octet, compression_alg_map);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Compression Algorithms
* \param ss_zpref Array of Preferred Compression Algorithms
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_zpref(const pgp_data_t *ss_zpref)
{
return text_from_bytemapped_octets(ss_zpref,
&pgp_show_ss_zpref);
}
/**
* \ingroup Core_Print
*
* returns description of the Hash Algorithm type
* \param hash Hash Algorithm type
* \return string or "Unknown"
*/
const char *
pgp_show_hash_alg(uint8_t hash)
{
return pgp_str_from_map(hash, hash_alg_map);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Hash Algorithms
* \param ss_hashpref Array of Preferred Hash Algorithms
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_hashpref(const pgp_data_t *ss_hashpref)
{
return text_from_bytemapped_octets(ss_hashpref,
&pgp_show_hash_alg);
}
const char *
pgp_show_symm_alg(uint8_t hash)
{
return pgp_str_from_map(hash, symm_alg_map);
}
/**
* \ingroup Core_Print
* returns description of the given Preferred Symmetric Key Algorithm
* \param octet
* \return string or "Unknown"
*/
const char *
pgp_show_ss_skapref(uint8_t octet)
{
return pgp_str_from_map(octet, symm_alg_map);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Symmetric Key Algorithms
* \param ss_skapref Array of Preferred Symmetric Key Algorithms
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_skapref(const pgp_data_t *ss_skapref)
{
return text_from_bytemapped_octets(ss_skapref,
&pgp_show_ss_skapref);
}
/**
* \ingroup Core_Print
* returns description of one SS Feature
* \param octet
* \return string or "Unknown"
*/
static const char *
show_ss_feature(uint8_t octet, unsigned offset)
{
if (offset >= PGP_ARRAY_SIZE(ss_feature_map)) {
return "Unknown";
}
return find_bitfield(ss_feature_map[offset], octet);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given SS Features
* \param ss_features Signature Sub-Packet Features
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
/* XXX: shouldn't this use show_all_octets_bits? */
pgp_text_t *
pgp_showall_ss_features(pgp_data_t ss_features)
{
pgp_text_t *text;
const char *str;
unsigned i;
uint8_t mask, bit;
int j;
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
for (i = 0; i < ss_features.len; i++) {
mask = 0x80;
for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
bit = ss_features.contents[i] & mask;
if (bit) {
str = show_ss_feature(bit, i);
if (!add_bitmap_entry(text, str, bit)) {
pgp_text_free(text);
return NULL;
}
}
}
}
return text;
}
/**
* \ingroup Core_Print
* returns description of SS Key Flag
* \param octet
* \param map
* \return
*/
const char *
pgp_show_ss_key_flag(uint8_t octet, pgp_bit_map_t *map)
{
return find_bitfield(map, octet);
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given Preferred Key Flags
* \param ss_key_flags Array of Key Flags
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_ss_key_flags(const pgp_data_t *ss_key_flags)
{
pgp_text_t *text;
const char *str;
uint8_t mask, bit;
int i;
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* xxx - TBD: extend to handle multiple octets of bits - rachel */
for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
bit = ss_key_flags->contents[0] & mask;
if (bit) {
str = pgp_show_ss_key_flag(bit, ss_key_flags_map);
if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
pgp_text_free(text);
return NULL;
}
}
}
/*
* xxx - must add error text if more than one octet. Only one
* currently specified -- rachel
*/
return text;
}
/**
* \ingroup Core_Print
*
* returns description of one given Key Server Preference
*
* \param prefs Byte containing bitfield of preferences
* \param map
* \return string or "Unknown"
*/
const char *
pgp_show_keyserv_pref(uint8_t prefs, pgp_bit_map_t *map)
{
return find_bitfield(map, prefs);
}
/**
* \ingroup Core_Print
* returns set of descriptions of given Key Server Preferences
* \param ss_key_server_prefs
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*
*/
pgp_text_t *
pgp_show_keyserv_prefs(const pgp_data_t *prefs)
{
pgp_text_t *text;
const char *str;
uint8_t mask, bit;
int i = 0;
if ((text = calloc(1, sizeof(*text))) == NULL) {
return NULL;
}
pgp_text_init(text);
/* xxx - TBD: extend to handle multiple octets of bits - rachel */
for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
bit = prefs->contents[0] & mask;
if (bit) {
str = pgp_show_keyserv_pref(bit,
ss_key_server_prefs_map);
if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
pgp_text_free(text);
return NULL;
}
}
}
/*
* xxx - must add error text if more than one octet. Only one
* currently specified -- rachel
*/
return text;
}
/**
* \ingroup Core_Print
*
* returns set of descriptions of the given SS Notation Data Flags
* \param ss_notation Signature Sub-Packet Notation Data
* \return NULL if cannot allocate memory or other error
* \return pointer to structure, if no error
*/
pgp_text_t *
pgp_showall_notation(pgp_ss_notation_t ss_notation)
{
return showall_octets_bits(&ss_notation.flags,
ss_notation_map,
PGP_ARRAY_SIZE(ss_notation_map));
}

View File

@@ -0,0 +1,111 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef PACKET_SHOW_H_
#define PACKET_SHOW_H_
#include "packet.h"
/** pgp_list_t
*/
typedef struct {
unsigned size; /* num of array slots allocated */
unsigned used; /* num of array slots currently used */
char **strings;
} pgp_list_t;
/** pgp_text_t
*/
typedef struct {
pgp_list_t known;
pgp_list_t unknown;
} pgp_text_t;
/** pgp_bit_map_t
*/
typedef struct {
uint8_t mask;
const char *string;
} pgp_bit_map_t;
void pgp_text_init(pgp_text_t *);
void pgp_text_free(pgp_text_t *);
const char *pgp_show_packet_tag(pgp_content_enum);
const char *pgp_show_ss_type(pgp_content_enum);
const char *pgp_show_sig_type(pgp_sig_type_t);
const char *pgp_show_pka(pgp_pubkey_alg_t);
pgp_text_t *pgp_showall_ss_zpref(const pgp_data_t *);
const char *pgp_show_ss_zpref(uint8_t);
pgp_text_t *pgp_showall_ss_hashpref(const pgp_data_t *);
const char *pgp_show_hash_alg(uint8_t);
const char *pgp_show_symm_alg(uint8_t);
pgp_text_t *pgp_showall_ss_skapref(const pgp_data_t *);
const char *pgp_show_ss_skapref(uint8_t);
const char *pgp_show_ss_rr_code(pgp_ss_rr_code_t);
pgp_text_t *pgp_showall_ss_features(pgp_data_t);
pgp_text_t *pgp_showall_ss_key_flags(const pgp_data_t *);
const char *pgp_show_ss_key_flag(uint8_t, pgp_bit_map_t *);
pgp_text_t *pgp_show_keyserv_prefs(const pgp_data_t *);
const char *pgp_show_keyserv_pref(uint8_t, pgp_bit_map_t *);
pgp_text_t *pgp_showall_notation(pgp_ss_notation_t);
#endif /* PACKET_SHOW_H_ */

View File

@@ -0,0 +1,972 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
* packet related headers.
*/
#ifndef PACKET_H_
#define PACKET_H_
#include <time.h>
#ifdef HAVE_OPENSSL_BN_H
#include <openssl/bn.h>
#endif
#include "types.h"
#include "errors.h"
/* structure to keep track of printing state variables */
typedef struct pgp_printstate_t {
unsigned unarmoured;
unsigned skipping;
int indent;
} pgp_printstate_t;
/** General-use structure for variable-length data
*/
typedef struct {
size_t len;
uint8_t *contents;
uint8_t mmapped; /* contents need an munmap(2) */
} pgp_data_t;
/************************************/
/* Packet Tags - RFC4880, 4.2 */
/************************************/
/** Packet Tag - Bit 7 Mask (this bit is always set).
* The first byte of a packet is the "Packet Tag". It always
* has bit 7 set. This is the mask for it.
*
* \see RFC4880 4.2
*/
#define PGP_PTAG_ALWAYS_SET 0x80
/** Packet Tag - New Format Flag.
* Bit 6 of the Packet Tag is the packet format indicator.
* If it is set, the new format is used, if cleared the
* old format is used.
*
* \see RFC4880 4.2
*/
#define PGP_PTAG_NEW_FORMAT 0x40
/** Old Packet Format: Mask for content tag.
* In the old packet format bits 5 to 2 (including)
* are the content tag. This is the mask to apply
* to the packet tag. Note that you need to
* shift by #PGP_PTAG_OF_CONTENT_TAG_SHIFT bits.
*
* \see RFC4880 4.2
*/
#define PGP_PTAG_OF_CONTENT_TAG_MASK 0x3c
/** Old Packet Format: Offset for the content tag.
* As described at #PGP_PTAG_OF_CONTENT_TAG_MASK the
* content tag needs to be shifted after being masked
* out from the Packet Tag.
*
* \see RFC4880 4.2
*/
#define PGP_PTAG_OF_CONTENT_TAG_SHIFT 2
/** Old Packet Format: Mask for length type.
* Bits 1 and 0 of the packet tag are the length type
* in the old packet format.
*
* See #pgp_ptag_of_lt_t for the meaning of the values.
*
* \see RFC4880 4.2
*/
#define PGP_PTAG_OF_LENGTH_TYPE_MASK 0x03
/** Old Packet Format Lengths.
* Defines the meanings of the 2 bits for length type in the
* old packet format.
*
* \see RFC4880 4.2.1
*/
typedef enum {
PGP_PTAG_OLD_LEN_1 = 0x00, /* Packet has a 1 byte length -
* header is 2 bytes long. */
PGP_PTAG_OLD_LEN_2 = 0x01, /* Packet has a 2 byte length -
* header is 3 bytes long. */
PGP_PTAG_OLD_LEN_4 = 0x02, /* Packet has a 4 byte
* length - header is 5 bytes
* long. */
PGP_PTAG_OLD_LEN_INDETERMINATE = 0x03 /* Packet has a
* indeterminate length. */
} pgp_ptag_of_lt_t;
/** New Packet Format: Mask for content tag.
* In the new packet format the 6 rightmost bits
* are the content tag. This is the mask to apply
* to the packet tag. Note that you need to
* shift by #PGP_PTAG_NF_CONTENT_TAG_SHIFT bits.
*
* \see RFC4880 4.2
*/
#define PGP_PTAG_NF_CONTENT_TAG_MASK 0x3f
/** New Packet Format: Offset for the content tag.
* As described at #PGP_PTAG_NF_CONTENT_TAG_MASK the
* content tag needs to be shifted after being masked
* out from the Packet Tag.
*
* \see RFC4880 4.2
*/
#define PGP_PTAG_NF_CONTENT_TAG_SHIFT 0
/* PTag Content Tags */
/***************************/
/** Package Tags (aka Content Tags) and signature subpacket types.
* This enumerates all rfc-defined packet tag values and the
* signature subpacket type values that we understand.
*
* \see RFC4880 4.3
* \see RFC4880 5.2.3.1
*/
typedef enum {
PGP_PTAG_CT_RESERVED = 0, /* Reserved - a packet tag must
* not have this value */
PGP_PTAG_CT_PK_SESSION_KEY = 1, /* Public-Key Encrypted Session
* Key Packet */
PGP_PTAG_CT_SIGNATURE = 2, /* Signature Packet */
PGP_PTAG_CT_SK_SESSION_KEY = 3, /* Symmetric-Key Encrypted Session
* Key Packet */
PGP_PTAG_CT_1_PASS_SIG = 4, /* One-Pass Signature
* Packet */
PGP_PTAG_CT_SECRET_KEY = 5, /* Secret Key Packet */
PGP_PTAG_CT_PUBLIC_KEY = 6, /* Public Key Packet */
PGP_PTAG_CT_SECRET_SUBKEY = 7, /* Secret Subkey Packet */
PGP_PTAG_CT_COMPRESSED = 8, /* Compressed Data Packet */
PGP_PTAG_CT_SE_DATA = 9,/* Symmetrically Encrypted Data Packet */
PGP_PTAG_CT_MARKER = 10,/* Marker Packet */
PGP_PTAG_CT_LITDATA = 11, /* Literal Data Packet */
PGP_PTAG_CT_TRUST = 12, /* Trust Packet */
PGP_PTAG_CT_USER_ID = 13, /* User ID Packet */
PGP_PTAG_CT_PUBLIC_SUBKEY = 14, /* Public Subkey Packet */
PGP_PTAG_CT_RESERVED2 = 15, /* reserved */
PGP_PTAG_CT_RESERVED3 = 16, /* reserved */
PGP_PTAG_CT_USER_ATTR = 17, /* User Attribute Packet */
PGP_PTAG_CT_SE_IP_DATA = 18, /* Sym. Encrypted and Integrity
* Protected Data Packet */
PGP_PTAG_CT_MDC = 19, /* Modification Detection Code Packet */
PGP_PARSER_PTAG = 0x100,/* Internal Use: The packet is the "Packet
* Tag" itself - used when callback sends
* back the PTag. */
PGP_PTAG_RAW_SS = 0x101,/* Internal Use: content is raw sig subtag */
PGP_PTAG_SS_ALL = 0x102,/* Internal Use: select all subtags */
PGP_PARSER_PACKET_END = 0x103,
/* signature subpackets (0x200-2ff) (type+0x200) */
/* only those we can parse are listed here */
PGP_PTAG_SIG_SUBPKT_BASE = 0x200, /* Base for signature
* subpacket types - All
* signature type values
* are relative to this
* value. */
PGP_PTAG_SS_CREATION_TIME = 0x200 + 2, /* signature creation time */
PGP_PTAG_SS_EXPIRATION_TIME = 0x200 + 3, /* signature
* expiration time */
PGP_PTAG_SS_EXPORT_CERT = 0x200 + 4, /* exportable certification */
PGP_PTAG_SS_TRUST = 0x200 + 5, /* trust signature */
PGP_PTAG_SS_REGEXP = 0x200 + 6, /* regular expression */
PGP_PTAG_SS_REVOCABLE = 0x200 + 7, /* revocable */
PGP_PTAG_SS_KEY_EXPIRY = 0x200 + 9, /* key expiration
* time */
PGP_PTAG_SS_RESERVED = 0x200 + 10, /* reserved */
PGP_PTAG_SS_PREFERRED_SKA = 0x200 + 11, /* preferred symmetric
* algs */
PGP_PTAG_SS_REVOCATION_KEY = 0x200 + 12, /* revocation key */
PGP_PTAG_SS_ISSUER_KEY_ID = 0x200 + 16, /* issuer key ID */
PGP_PTAG_SS_NOTATION_DATA = 0x200 + 20, /* notation data */
PGP_PTAG_SS_PREFERRED_HASH = 0x200 + 21, /* preferred hash
* algs */
PGP_PTAG_SS_PREF_COMPRESS = 0x200 + 22, /* preferred
* compression
* algorithms */
PGP_PTAG_SS_KEYSERV_PREFS = 0x200 + 23, /* key server
* preferences */
PGP_PTAG_SS_PREF_KEYSERV = 0x200 + 24, /* Preferred Key
* Server */
PGP_PTAG_SS_PRIMARY_USER_ID = 0x200 + 25, /* primary User ID */
PGP_PTAG_SS_POLICY_URI = 0x200 + 26, /* Policy URI */
PGP_PTAG_SS_KEY_FLAGS = 0x200 + 27, /* key flags */
PGP_PTAG_SS_SIGNERS_USER_ID = 0x200 + 28, /* Signer's User ID */
PGP_PTAG_SS_REVOCATION_REASON = 0x200 + 29, /* reason for
* revocation */
PGP_PTAG_SS_FEATURES = 0x200 + 30, /* features */
PGP_PTAG_SS_SIGNATURE_TARGET = 0x200 + 31, /* signature target */
PGP_PTAG_SS_EMBEDDED_SIGNATURE = 0x200 + 32, /* embedded signature */
PGP_PTAG_SS_USERDEFINED00 = 0x200 + 100, /* internal or
* user-defined */
PGP_PTAG_SS_USERDEFINED01 = 0x200 + 101,
PGP_PTAG_SS_USERDEFINED02 = 0x200 + 102,
PGP_PTAG_SS_USERDEFINED03 = 0x200 + 103,
PGP_PTAG_SS_USERDEFINED04 = 0x200 + 104,
PGP_PTAG_SS_USERDEFINED05 = 0x200 + 105,
PGP_PTAG_SS_USERDEFINED06 = 0x200 + 106,
PGP_PTAG_SS_USERDEFINED07 = 0x200 + 107,
PGP_PTAG_SS_USERDEFINED08 = 0x200 + 108,
PGP_PTAG_SS_USERDEFINED09 = 0x200 + 109,
PGP_PTAG_SS_USERDEFINED10 = 0x200 + 110,
/* pseudo content types */
PGP_PTAG_CT_LITDATA_HEADER = 0x300,
PGP_PTAG_CT_LITDATA_BODY = 0x300 + 1,
PGP_PTAG_CT_SIGNATURE_HEADER = 0x300 + 2,
PGP_PTAG_CT_SIGNATURE_FOOTER = 0x300 + 3,
PGP_PTAG_CT_ARMOUR_HEADER = 0x300 + 4,
PGP_PTAG_CT_ARMOUR_TRAILER = 0x300 + 5,
PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER = 0x300 + 6,
PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY = 0x300 + 7,
PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER = 0x300 + 8,
PGP_PTAG_CT_UNARMOURED_TEXT = 0x300 + 9,
PGP_PTAG_CT_ENCRYPTED_SECRET_KEY = 0x300 + 10, /* In this case the
* algorithm specific
* fields will not be
* initialised */
PGP_PTAG_CT_SE_DATA_HEADER = 0x300 + 11,
PGP_PTAG_CT_SE_DATA_BODY = 0x300 + 12,
PGP_PTAG_CT_SE_IP_DATA_HEADER = 0x300 + 13,
PGP_PTAG_CT_SE_IP_DATA_BODY = 0x300 + 14,
PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY = 0x300 + 15,
/* commands to the callback */
PGP_GET_PASSPHRASE = 0x400,
PGP_GET_SECKEY = 0x400 + 1,
/* Errors */
PGP_PARSER_ERROR = 0x500, /* Internal Use: Parser Error */
PGP_PARSER_ERRCODE = 0x500 + 1 /* Internal Use: Parser Error
* with errcode returned */
} pgp_content_enum;
enum {
PGP_REVOCATION_NO_REASON = 0,
PGP_REVOCATION_SUPERSEDED = 1,
PGP_REVOCATION_COMPROMISED = 2,
PGP_REVOCATION_RETIRED = 3,
PGP_REVOCATION_NO_LONGER_VALID = 0x20
};
/** Structure to hold one error code */
typedef struct {
pgp_errcode_t errcode;
} pgp_parser_errcode_t;
/** Structure to hold one packet tag.
* \see RFC4880 4.2
*/
typedef struct {
unsigned new_format; /* Whether this packet tag is new
* (1) or old format (0) */
unsigned type; /* content_tag value - See
* #pgp_content_enum for meanings */
pgp_ptag_of_lt_t length_type; /* Length type (#pgp_ptag_of_lt_t)
* - only if this packet tag is old
* format. Set to 0 if new format. */
unsigned length; /* The length of the packet. This value
* is set when we read and compute the length
* information, not at the same moment we
* create the packet tag structure. Only
* defined if #readc is set. *//* XXX: Ben, is this correct? */
unsigned position; /* The position (within the
* current reader) of the packet */
unsigned size; /* number of bits */
} pgp_ptag_t;
/** Public Key Algorithm Numbers.
* OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP.
*
* This lists algorithm numbers for public key algorithms.
*
* \see RFC4880 9.1
*/
typedef enum {
PGP_PKA_NOTHING = 0, /* No PKA */
PGP_PKA_RSA = 1, /* RSA (Encrypt or Sign) */
PGP_PKA_RSA_ENCRYPT_ONLY = 2, /* RSA Encrypt-Only (deprecated -
* \see RFC4880 13.5) */
PGP_PKA_RSA_SIGN_ONLY = 3, /* RSA Sign-Only (deprecated -
* \see RFC4880 13.5) */
PGP_PKA_ELGAMAL = 16, /* Elgamal (Encrypt-Only) */
PGP_PKA_DSA = 17, /* DSA (Digital Signature Algorithm) */
PGP_PKA_RESERVED_ELLIPTIC_CURVE = 18, /* Reserved for Elliptic
* Curve */
PGP_PKA_RESERVED_ECDSA = 19, /* Reserved for ECDSA */
PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN = 20, /* Deprecated. */
PGP_PKA_RESERVED_DH = 21, /* Reserved for Diffie-Hellman
* (X9.42, as defined for
* IETF-S/MIME) */
PGP_PKA_PRIVATE00 = 100,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE01 = 101,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE02 = 102,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE03 = 103,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE04 = 104,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE05 = 105,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE06 = 106,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE07 = 107,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE08 = 108,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE09 = 109,/* Private/Experimental Algorithm */
PGP_PKA_PRIVATE10 = 110 /* Private/Experimental Algorithm */
} pgp_pubkey_alg_t;
/** Structure to hold one DSA public key params.
*
* \see RFC4880 5.5.2
*/
typedef struct {
BIGNUM *p; /* DSA prime p */
BIGNUM *q; /* DSA group order q */
BIGNUM *g; /* DSA group generator g */
BIGNUM *y; /* DSA public key value y (= g^x mod p
* with x being the secret) */
} pgp_dsa_pubkey_t;
/** Structure to hold an RSA public key.
*
* \see RFC4880 5.5.2
*/
typedef struct {
BIGNUM *n; /* RSA public modulus n */
BIGNUM *e; /* RSA public encryption exponent e */
} pgp_rsa_pubkey_t;
/** Structure to hold an ElGamal public key params.
*
* \see RFC4880 5.5.2
*/
typedef struct {
BIGNUM *p; /* ElGamal prime p */
BIGNUM *g; /* ElGamal group generator g */
BIGNUM *y; /* ElGamal public key value y (= g^x mod p
* with x being the secret) */
} pgp_elgamal_pubkey_t;
/** Version.
* OpenPGP has two different protocol versions: version 3 and version 4.
*
* \see RFC4880 5.2
*/
typedef enum {
PGP_V2 = 2, /* Version 2 (essentially the same as v3) */
PGP_V3 = 3, /* Version 3 */
PGP_V4 = 4 /* Version 4 */
} pgp_version_t;
/** Structure to hold a pgp public key */
typedef struct {
pgp_version_t version;/* version of the key (v3, v4...) */
time_t birthtime;
time_t duration;
/* validity period of the key in days since
* creation. A value of 0 has a special meaning
* indicating this key does not expire. Only used with
* v3 keys. */
unsigned days_valid; /* v4 duration */
pgp_pubkey_alg_t alg; /* Public Key Algorithm type */
union {
pgp_dsa_pubkey_t dsa; /* A DSA public key */
pgp_rsa_pubkey_t rsa; /* An RSA public key */
pgp_elgamal_pubkey_t elgamal; /* An ElGamal public key */
} key; /* Public Key Parameters */
} pgp_pubkey_t;
/** Structure to hold data for one RSA secret key
*/
typedef struct {
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *u;
} pgp_rsa_seckey_t;
/** pgp_dsa_seckey_t */
typedef struct {
BIGNUM *x;
} pgp_dsa_seckey_t;
/** pgp_elgamal_seckey_t */
typedef struct {
BIGNUM *x;
} pgp_elgamal_seckey_t;
/** s2k_usage_t
*/
typedef enum {
PGP_S2KU_NONE = 0,
PGP_S2KU_ENCRYPTED_AND_HASHED = 254,
PGP_S2KU_ENCRYPTED = 255
} pgp_s2k_usage_t;
/** s2k_specifier_t
*/
typedef enum {
PGP_S2KS_SIMPLE = 0,
PGP_S2KS_SALTED = 1,
PGP_S2KS_ITERATED_AND_SALTED = 3
} pgp_s2k_specifier_t;
/** Symmetric Key Algorithm Numbers.
* OpenPGP assigns a unique Algorithm Number to each algorithm that is
* part of OpenPGP.
*
* This lists algorithm numbers for symmetric key algorithms.
*
* \see RFC4880 9.2
*/
typedef enum {
PGP_SA_PLAINTEXT = 0, /* Plaintext or unencrypted data */
PGP_SA_IDEA = 1, /* IDEA */
PGP_SA_TRIPLEDES = 2, /* TripleDES */
PGP_SA_CAST5 = 3, /* CAST5 */
PGP_SA_BLOWFISH = 4, /* Blowfish */
PGP_SA_AES_128 = 7, /* AES with 128-bit key (AES) */
PGP_SA_AES_192 = 8, /* AES with 192-bit key */
PGP_SA_AES_256 = 9, /* AES with 256-bit key */
PGP_SA_TWOFISH = 10, /* Twofish with 256-bit key (TWOFISH) */
PGP_SA_CAMELLIA_128 = 100, /* Camellia with 128-bit key (CAMELLIA) */
PGP_SA_CAMELLIA_192 = 101, /* Camellia with 192-bit key */
PGP_SA_CAMELLIA_256 = 102 /* Camellia with 256-bit key */
} pgp_symm_alg_t;
#define PGP_SA_DEFAULT_CIPHER PGP_SA_CAST5
/** Hashing Algorithm Numbers.
* OpenPGP assigns a unique Algorithm Number to each algorithm that is
* part of OpenPGP.
*
* This lists algorithm numbers for hash algorithms.
*
* \see RFC4880 9.4
*/
typedef enum {
PGP_HASH_UNKNOWN = -1, /* used to indicate errors */
PGP_HASH_MD5 = 1, /* MD5 */
PGP_HASH_SHA1 = 2, /* SHA-1 */
PGP_HASH_RIPEMD = 3, /* RIPEMD160 */
PGP_HASH_SHA256 = 8, /* SHA256 */
PGP_HASH_SHA384 = 9, /* SHA384 */
PGP_HASH_SHA512 = 10, /* SHA512 */
PGP_HASH_SHA224 = 11 /* SHA224 */
} pgp_hash_alg_t;
#define PGP_DEFAULT_HASH_ALGORITHM PGP_HASH_SHA256
void pgp_calc_mdc_hash(const uint8_t *,
const size_t,
const uint8_t *,
const unsigned,
uint8_t *);
unsigned pgp_is_hash_alg_supported(const pgp_hash_alg_t *);
/* Maximum block size for symmetric crypto */
#define PGP_MAX_BLOCK_SIZE 16
/* Maximum key size for symmetric crypto */
#define PGP_MAX_KEY_SIZE 32
/* Salt size for hashing */
#define PGP_SALT_SIZE 8
/* Max hash size */
#define PGP_MAX_HASH_SIZE 64
/** pgp_seckey_t
*/
typedef struct pgp_seckey_t {
pgp_pubkey_t pubkey; /* public key */
pgp_s2k_usage_t s2k_usage;
pgp_s2k_specifier_t s2k_specifier;
pgp_symm_alg_t alg; /* symmetric alg */
pgp_hash_alg_t hash_alg; /* hash algorithm */
uint8_t salt[PGP_SALT_SIZE];
unsigned octetc;
uint8_t iv[PGP_MAX_BLOCK_SIZE];
union {
pgp_rsa_seckey_t rsa;
pgp_dsa_seckey_t dsa;
pgp_elgamal_seckey_t elgamal;
} key;
unsigned checksum;
uint8_t *checkhash;
} pgp_seckey_t;
/** Signature Type.
* OpenPGP defines different signature types that allow giving
* different meanings to signatures. Signature types include 0x10 for
* generitc User ID certifications (used when Ben signs Weasel's key),
* Subkey binding signatures, document signatures, key revocations,
* etc.
*
* Different types are used in different places, and most make only
* sense in their intended location (for instance a subkey binding has
* no place on a UserID).
*
* \see RFC4880 5.2.1
*/
typedef enum {
PGP_SIG_BINARY = 0x00, /* Signature of a binary document */
PGP_SIG_TEXT = 0x01, /* Signature of a canonical text document */
PGP_SIG_STANDALONE = 0x02, /* Standalone signature */
PGP_CERT_GENERIC = 0x10,/* Generic certification of a User ID and
* Public Key packet */
PGP_CERT_PERSONA = 0x11,/* Persona certification of a User ID and
* Public Key packet */
PGP_CERT_CASUAL = 0x12, /* Casual certification of a User ID and
* Public Key packet */
PGP_CERT_POSITIVE = 0x13, /* Positive certification of a
* User ID and Public Key packet */
PGP_SIG_SUBKEY = 0x18, /* Subkey Binding Signature */
PGP_SIG_PRIMARY = 0x19, /* Primary Key Binding Signature */
PGP_SIG_DIRECT = 0x1f, /* Signature directly on a key */
PGP_SIG_REV_KEY = 0x20, /* Key revocation signature */
PGP_SIG_REV_SUBKEY = 0x28, /* Subkey revocation signature */
PGP_SIG_REV_CERT = 0x30,/* Certification revocation signature */
PGP_SIG_TIMESTAMP = 0x40, /* Timestamp signature */
PGP_SIG_3RD_PARTY = 0x50/* Third-Party Confirmation signature */
} pgp_sig_type_t;
/** Struct to hold params of an RSA signature */
typedef struct pgp_rsa_sig_t {
BIGNUM *sig; /* the signature value (m^d % n) */
} pgp_rsa_sig_t;
/** Struct to hold params of a DSA signature */
typedef struct pgp_dsa_sig_t {
BIGNUM *r; /* DSA value r */
BIGNUM *s; /* DSA value s */
} pgp_dsa_sig_t;
/** pgp_elgamal_signature_t */
typedef struct pgp_elgamal_sig_t {
BIGNUM *r;
BIGNUM *s;
} pgp_elgamal_sig_t;
#define PGP_KEY_ID_SIZE 8
#define PGP_FINGERPRINT_SIZE 20
/** Struct to hold a signature packet.
*
* \see RFC4880 5.2.2
* \see RFC4880 5.2.3
*/
typedef struct pgp_sig_info_t {
pgp_version_t version;/* signature version number */
pgp_sig_type_t type; /* signature type value */
time_t birthtime; /* creation time of the signature */
time_t duration; /* number of seconds it's valid for */
uint8_t signer_id[PGP_KEY_ID_SIZE]; /* Eight-octet key ID
* of signer */
pgp_pubkey_alg_t key_alg; /* public key algorithm number */
pgp_hash_alg_t hash_alg; /* hashing algorithm number */
union {
pgp_rsa_sig_t rsa; /* An RSA Signature */
pgp_dsa_sig_t dsa; /* A DSA Signature */
pgp_elgamal_sig_t elgamal; /* deprecated */
pgp_data_t unknown; /* private or experimental */
} sig; /* signature params */
size_t v4_hashlen;
uint8_t *v4_hashed;
unsigned birthtime_set:1;
unsigned signer_id_set:1;
unsigned duration_set:1;
} pgp_sig_info_t;
/** Struct used when parsing a signature */
typedef struct pgp_sig_t {
pgp_sig_info_t info; /* The signature information */
/* The following fields are only used while parsing the signature */
uint8_t hash2[2]; /* high 2 bytes of hashed value */
size_t v4_hashstart; /* only valid if accumulate is set */
pgp_hash_t *hash; /* the hash filled in for the data so far */
} pgp_sig_t;
/** The raw bytes of a signature subpacket */
typedef struct pgp_ss_raw_t {
pgp_content_enum tag;
size_t length;
uint8_t *raw;
} pgp_ss_raw_t;
/** Signature Subpacket : Trust Level */
typedef struct pgp_ss_trust_t {
uint8_t level; /* Trust Level */
uint8_t amount; /* Amount */
} pgp_ss_trust_t;
/** Signature Subpacket : Notation Data */
typedef struct pgp_ss_notation_t {
pgp_data_t flags;
pgp_data_t name;
pgp_data_t value;
} pgp_ss_notation_t;
/** Signature Subpacket : Signature Target */
typedef struct pgp_ss_sig_target_t {
pgp_pubkey_alg_t pka_alg;
pgp_hash_alg_t hash_alg;
pgp_data_t hash;
} pgp_ss_sig_target_t;
/** pgp_subpacket_t */
typedef struct pgp_subpacket_t {
size_t length;
uint8_t *raw;
} pgp_subpacket_t;
/** Types of Compression */
typedef enum {
PGP_C_NONE = 0,
PGP_C_ZIP = 1,
PGP_C_ZLIB = 2,
PGP_C_BZIP2 = 3
} pgp_compression_type_t;
/** pgp_one_pass_sig_t */
typedef struct {
uint8_t version;
pgp_sig_type_t sig_type;
pgp_hash_alg_t hash_alg;
pgp_pubkey_alg_t key_alg;
uint8_t keyid[PGP_KEY_ID_SIZE];
unsigned nested;
} pgp_one_pass_sig_t;
/** Signature Subpacket : Revocation Key */
typedef struct {
uint8_t class;
uint8_t algid;
uint8_t fingerprint[PGP_FINGERPRINT_SIZE];
} pgp_ss_revocation_key_t;
/** Signature Subpacket : Revocation Reason */
typedef struct {
uint8_t code;
char *reason;
} pgp_ss_revocation_t;
/** litdata_type_t */
typedef enum {
PGP_LDT_BINARY = 'b',
PGP_LDT_TEXT = 't',
PGP_LDT_UTF8 = 'u',
PGP_LDT_LOCAL = 'l',
PGP_LDT_LOCAL2 = '1'
} pgp_litdata_enum;
/** pgp_litdata_header_t */
typedef struct {
pgp_litdata_enum format;
char filename[256];
time_t mtime;
} pgp_litdata_header_t;
/** pgp_litdata_body_t */
typedef struct {
unsigned length;
uint8_t *data;
void *mem; /* pgp_memory_t pointer */
} pgp_litdata_body_t;
/** pgp_header_var_t */
typedef struct {
char *key;
char *value;
} pgp_header_var_t;
/** pgp_headers_t */
typedef struct {
pgp_header_var_t *headers;
unsigned headerc;
} pgp_headers_t;
/** pgp_armour_header_t */
typedef struct {
const char *type;
pgp_headers_t headers;
} pgp_armour_header_t;
/** pgp_fixed_body_t */
typedef struct pgp_fixed_body_t {
unsigned length;
uint8_t data[8192]; /* \todo fix hard-coded value? */
} pgp_fixed_body_t;
/** pgp_dyn_body_t */
typedef struct pgp_dyn_body_t {
unsigned length;
uint8_t *data;
} pgp_dyn_body_t;
enum {
PGP_SE_IP_DATA_VERSION = 1,
PGP_PKSK_V3 = 3
};
/** pgp_pk_sesskey_params_rsa_t */
typedef struct {
BIGNUM *encrypted_m;
BIGNUM *m;
} pgp_pk_sesskey_params_rsa_t;
/** pgp_pk_sesskey_params_elgamal_t */
typedef struct {
BIGNUM *g_to_k;
BIGNUM *encrypted_m;
} pgp_pk_sesskey_params_elgamal_t;
/** pgp_pk_sesskey_params_t */
typedef union {
pgp_pk_sesskey_params_rsa_t rsa;
pgp_pk_sesskey_params_elgamal_t elgamal;
} pgp_pk_sesskey_params_t;
/** pgp_pk_sesskey_t */
typedef struct {
unsigned version;
uint8_t key_id[PGP_KEY_ID_SIZE];
pgp_pubkey_alg_t alg;
pgp_pk_sesskey_params_t params;
pgp_symm_alg_t symm_alg;
uint8_t key[PGP_MAX_KEY_SIZE];
uint16_t checksum;
} pgp_pk_sesskey_t;
/** pgp_seckey_passphrase_t */
typedef struct {
const pgp_seckey_t *seckey;
char **passphrase; /* point somewhere that gets filled
* in to work around constness of
* content */
} pgp_seckey_passphrase_t;
/** pgp_get_seckey_t */
typedef struct {
const pgp_seckey_t **seckey;
const pgp_pk_sesskey_t *pk_sesskey;
} pgp_get_seckey_t;
/** pgp_parser_union_content_t */
typedef union {
const char *error;
pgp_parser_errcode_t errcode;
pgp_ptag_t ptag;
pgp_pubkey_t pubkey;
pgp_data_t trust;
uint8_t *userid;
pgp_data_t userattr;
pgp_sig_t sig;
pgp_ss_raw_t ss_raw;
pgp_ss_trust_t ss_trust;
unsigned ss_revocable;
time_t ss_time;
uint8_t ss_issuer[PGP_KEY_ID_SIZE];
pgp_ss_notation_t ss_notation;
pgp_subpacket_t packet;
pgp_compression_type_t compressed;
pgp_one_pass_sig_t one_pass_sig;
pgp_data_t ss_skapref;
pgp_data_t ss_hashpref;
pgp_data_t ss_zpref;
pgp_data_t ss_key_flags;
pgp_data_t ss_key_server_prefs;
unsigned ss_primary_userid;
char *ss_regexp;
char *ss_policy;
char *ss_keyserv;
pgp_ss_revocation_key_t ss_revocation_key;
pgp_data_t ss_userdef;
pgp_data_t ss_unknown;
pgp_litdata_header_t litdata_header;
pgp_litdata_body_t litdata_body;
pgp_dyn_body_t mdc;
pgp_data_t ss_features;
pgp_ss_sig_target_t ss_sig_target;
pgp_data_t ss_embedded_sig;
pgp_ss_revocation_t ss_revocation;
pgp_seckey_t seckey;
uint8_t *ss_signer;
pgp_armour_header_t armour_header;
const char *armour_trailer;
pgp_headers_t cleartext_head;
pgp_fixed_body_t cleartext_body;
struct pgp_hash_t *cleartext_trailer;
pgp_dyn_body_t unarmoured_text;
pgp_pk_sesskey_t pk_sesskey;
pgp_seckey_passphrase_t skey_passphrase;
unsigned se_ip_data_header;
pgp_dyn_body_t se_ip_data_body;
pgp_fixed_body_t se_data_body;
pgp_get_seckey_t get_seckey;
} pgp_contents_t;
/** pgp_packet_t */
struct pgp_packet_t {
pgp_content_enum tag; /* type of contents */
uint8_t critical; /* for sig subpackets */
pgp_contents_t u; /* union for contents */
};
/** pgp_fingerprint_t */
typedef struct {
uint8_t fingerprint[PGP_FINGERPRINT_SIZE];
unsigned length;
pgp_hash_alg_t hashtype;
} pgp_fingerprint_t;
int pgp_keyid(uint8_t *, const size_t, const pgp_pubkey_t *, pgp_hash_alg_t);
int pgp_fingerprint(pgp_fingerprint_t *, const pgp_pubkey_t *, pgp_hash_alg_t);
void pgp_finish(void);
void pgp_pubkey_free(pgp_pubkey_t *);
void pgp_userid_free(uint8_t **);
void pgp_data_free(pgp_data_t *);
void pgp_sig_free(pgp_sig_t *);
void pgp_ss_notation_free(pgp_ss_notation_t *);
void pgp_ss_revocation_free(pgp_ss_revocation_t *);
void pgp_ss_sig_target_free(pgp_ss_sig_target_t *);
void pgp_subpacket_free(pgp_subpacket_t *);
void pgp_parser_content_free(pgp_packet_t *);
void pgp_seckey_free(pgp_seckey_t *);
void pgp_pk_sesskey_free(pgp_pk_sesskey_t *);
int pgp_print_packet(pgp_printstate_t *, const pgp_packet_t *);
#define DYNARRAY(type, arr) \
unsigned arr##c; unsigned arr##vsize; type *arr##s
#define EXPAND_ARRAY(str, arr) do { \
if (str->arr##c == str->arr##vsize) { \
void *__newarr; \
char *__newarrc; \
unsigned __newsize; \
__newsize = (str->arr##vsize * 2) + 10; \
if ((__newarrc = __newarr = realloc(str->arr##s, \
__newsize * sizeof(*str->arr##s))) == NULL) { \
(void) fprintf(stderr, "EXPAND_ARRAY - bad realloc\n"); \
} else { \
(void) memset(&__newarrc[str->arr##vsize * sizeof(*str->arr##s)], \
0x0, (__newsize - str->arr##vsize) * sizeof(*str->arr##s)); \
str->arr##s = __newarr; \
str->arr##vsize = __newsize; \
} \
} \
} while(/*CONSTCOND*/0)
/** pgp_keydata_key_t
*/
typedef union {
pgp_pubkey_t pubkey;
pgp_seckey_t seckey;
} pgp_keydata_key_t;
/* sigpacket_t */
typedef struct {
uint8_t **userid;
pgp_subpacket_t *packet;
} sigpacket_t;
/* user revocation info */
typedef struct pgp_revoke_t {
uint32_t uid; /* index in uid array */
uint8_t code; /* revocation code */
char *reason; /* c'mon, spill the beans */
} pgp_revoke_t;
/** signature subpackets */
typedef struct pgp_subsig_t {
uint32_t uid; /* index in userid array in key */
pgp_sig_t sig; /* trust signature */
uint8_t trustlevel; /* level of trust */
uint8_t trustamount; /* amount of trust */
} pgp_subsig_t;
/* describes a user's key */
struct pgp_key_t {
DYNARRAY(uint8_t *, uid); /* array of user ids */
DYNARRAY(pgp_subpacket_t, packet); /* array of raw subpackets */
DYNARRAY(pgp_subsig_t, subsig); /* array of signature subkeys */
DYNARRAY(pgp_revoke_t, revoke); /* array of signature revocations */
pgp_content_enum type; /* type of key */
pgp_keydata_key_t key; /* pubkey/seckey data */
pgp_pubkey_t sigkey; /* signature key */
uint8_t sigid[PGP_KEY_ID_SIZE];
pgp_fingerprint_t sigfingerprint; /* pgp signature fingerprint */
pgp_pubkey_t enckey; /* encryption key */
uint8_t encid[PGP_KEY_ID_SIZE];
pgp_fingerprint_t encfingerprint; /* pgp encryption id fingerprint */
uint32_t uid0; /* primary uid index in uids array */
uint8_t revoked; /* key has been revoked */
pgp_revoke_t revocation; /* revocation reason */
};
#define MDC_PKT_TAG 0xd3
#endif /* PACKET_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,126 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef READERWRITER_H_
#define READERWRITER_H_
#include "create.h"
#include "memory.h"
/* if this is defined, we'll use mmap in preference to file ops */
#define USE_MMAP_FOR_FILES 1
void pgp_reader_set_fd(pgp_stream_t *, int);
void pgp_reader_set_mmap(pgp_stream_t *, int);
void pgp_reader_set_memory(pgp_stream_t *, const void *, size_t);
/* Do a sum mod 65536 of all bytes read (as needed for secret keys) */
void pgp_reader_push_sum16(pgp_stream_t *);
uint16_t pgp_reader_pop_sum16(pgp_stream_t *);
void pgp_reader_push_se_ip_data(pgp_stream_t *, pgp_crypt_t *,
pgp_region_t *);
void pgp_reader_pop_se_ip_data(pgp_stream_t *);
/* */
unsigned pgp_write_mdc(pgp_output_t *, const uint8_t *);
unsigned pgp_write_se_ip_pktset(pgp_output_t *, const uint8_t *,
const unsigned,
pgp_crypt_t *);
void pgp_push_enc_crypt(pgp_output_t *, pgp_crypt_t *);
int pgp_push_enc_se_ip(pgp_output_t *, const pgp_key_t *, const char *);
/* Secret Key checksum */
void pgp_push_checksum_writer(pgp_output_t *, pgp_seckey_t *);
unsigned pgp_pop_skey_checksum_writer(pgp_output_t *);
/* memory writing */
void pgp_setup_memory_write(pgp_output_t **, pgp_memory_t **, size_t);
void pgp_teardown_memory_write(pgp_output_t *, pgp_memory_t *);
/* memory reading */
void pgp_setup_memory_read(pgp_io_t *,
pgp_stream_t **,
pgp_memory_t *,
void *,
pgp_cb_ret_t callback(const pgp_packet_t *,
pgp_cbdata_t *),
unsigned);
void pgp_teardown_memory_read(pgp_stream_t *, pgp_memory_t *);
/* file writing */
int pgp_setup_file_write(pgp_output_t **, const char *, unsigned);
void pgp_teardown_file_write(pgp_output_t *, int);
/* file appending */
int pgp_setup_file_append(pgp_output_t **, const char *);
void pgp_teardown_file_append(pgp_output_t *, int);
/* file reading */
int pgp_setup_file_read(pgp_io_t *,
pgp_stream_t **,
const char *,
void *,
pgp_cb_ret_t callback(const pgp_packet_t *,
pgp_cbdata_t *),
unsigned);
void pgp_teardown_file_read(pgp_stream_t *, int);
unsigned pgp_reader_set_accumulate(pgp_stream_t *, unsigned);
/* useful callbacks */
pgp_cb_ret_t pgp_litdata_cb(const pgp_packet_t *, pgp_cbdata_t *);
pgp_cb_ret_t pgp_pk_sesskey_cb(const pgp_packet_t *, pgp_cbdata_t *);
pgp_cb_ret_t pgp_get_seckey_cb(const pgp_packet_t *, pgp_cbdata_t *);
int pgp_getpassphrase(void *, char *, size_t);
#endif /* READERWRITER_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef SIGNATURE_H_
#define SIGNATURE_H_
#include <sys/types.h>
#include <inttypes.h>
#include "packet.h"
#include "create.h"
#include "memory.h"
typedef struct pgp_create_sig_t pgp_create_sig_t;
pgp_create_sig_t *pgp_create_sig_new(void);
void pgp_create_sig_delete(pgp_create_sig_t *);
unsigned pgp_check_useridcert_sig(const pgp_pubkey_t *,
const uint8_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
unsigned pgp_check_userattrcert_sig(const pgp_pubkey_t *,
const pgp_data_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
unsigned pgp_check_subkey_sig(const pgp_pubkey_t *,
const pgp_pubkey_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
unsigned pgp_check_direct_sig(const pgp_pubkey_t *,
const pgp_sig_t *,
const pgp_pubkey_t *,
const uint8_t *);
unsigned pgp_check_hash_sig(pgp_hash_t *,
const pgp_sig_t *,
const pgp_pubkey_t *);
void pgp_sig_start_key_sig(pgp_create_sig_t *,
const pgp_pubkey_t *,
const uint8_t *,
pgp_sig_type_t);
void pgp_start_sig(pgp_create_sig_t *,
const pgp_seckey_t *,
const pgp_hash_alg_t,
const pgp_sig_type_t);
void pgp_sig_add_data(pgp_create_sig_t *, const void *, size_t);
pgp_hash_t *pgp_sig_get_hash(pgp_create_sig_t *);
unsigned pgp_end_hashed_subpkts(pgp_create_sig_t *);
unsigned pgp_write_sig(pgp_output_t *, pgp_create_sig_t *,
const pgp_pubkey_t *, const pgp_seckey_t *);
unsigned pgp_add_time(pgp_create_sig_t *, int64_t, const char *);
unsigned pgp_add_issuer_keyid(pgp_create_sig_t *,
const uint8_t *);
void pgp_add_primary_userid(pgp_create_sig_t *, unsigned);
/* Standard Interface */
unsigned pgp_sign_file(pgp_io_t *,
const char *,
const char *,
const pgp_seckey_t *,
const char *,
const int64_t,
const uint64_t,
const unsigned,
const unsigned,
const unsigned);
int pgp_sign_detached(pgp_io_t *,
const char *,
char *,
pgp_seckey_t *,
const char *,
const int64_t,
const uint64_t,
const unsigned,
const unsigned);
/* armoured stuff */
unsigned pgp_crc24(unsigned, uint8_t);
void pgp_reader_push_dearmour(pgp_stream_t *);
void pgp_reader_pop_dearmour(pgp_stream_t *);
unsigned pgp_writer_push_clearsigned(pgp_output_t *, pgp_create_sig_t *);
void pgp_writer_push_armor_msg(pgp_output_t *);
typedef enum {
PGP_PGP_MESSAGE = 1,
PGP_PGP_PUBLIC_KEY_BLOCK,
PGP_PGP_PRIVATE_KEY_BLOCK,
PGP_PGP_MULTIPART_MESSAGE_PART_X_OF_Y,
PGP_PGP_MULTIPART_MESSAGE_PART_X,
PGP_PGP_SIGNATURE
} pgp_armor_type_t;
#define CRC24_INIT 0xb704ceL
unsigned pgp_writer_use_armored_sig(pgp_output_t *);
void pgp_writer_push_armoured(pgp_output_t *, pgp_armor_type_t);
pgp_memory_t *pgp_sign_buf(pgp_io_t *,
const void *,
const size_t,
const pgp_seckey_t *,
const int64_t,
const uint64_t,
const char *,
const unsigned,
const unsigned);
unsigned pgp_keyring_read_from_mem(pgp_io_t *,
pgp_keyring_t *,
const unsigned,
pgp_memory_t *);
#endif /* SIGNATURE_H_ */

View File

@@ -0,0 +1,473 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_OPENSSL_CAST_H
#include <openssl/cast.h>
#endif
#include <openssl/pem.h>
#include "bufgap.h"
#include "packet-parse.h"
#include "netpgpdefs.h"
#include "netpgpsdk.h"
#include "crypto.h"
#include "netpgpdigest.h"
#include "ssh2pgp.h"
/* structure for earching for constant strings */
typedef struct str_t {
const char *s; /* string */
size_t len; /* its length */
int type; /* return type */
} str_t;
#ifndef USE_ARG
#define USE_ARG(x) /*LINTED*/(void)&x
#endif
static const uint8_t base64s[] =
/* 000 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 016 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 032 */ "\0\0\0\0\0\0\0\0\0\0\0?\0\0\0@"
/* 048 */ "56789:;<=>\0\0\0\0\0\0"
/* 064 */ "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17"
/* 080 */ "\20\21\22\23\24\25\26\27\30\31\32\0\0\0\0\0"
/* 096 */ "\0\33\34\35\36\37 !\"#$%&'()"
/* 112 */ "*+,-./01234\0\0\0\0\0"
/* 128 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 144 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 160 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 176 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 192 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 208 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 224 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/* 240 */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
/* short function to decode from base64 */
/* inspired by an ancient copy of b64.c, then rewritten, the bugs are all mine */
static int
frombase64(char *dst, const char *src, size_t size, int flag)
{
uint8_t out[3];
uint8_t in[4];
uint8_t b;
size_t srcc;
int dstc;
int gotc;
int i;
USE_ARG(flag);
for (dstc = 0, srcc = 0 ; srcc < size; ) {
for (gotc = 0, i = 0; i < 4 && srcc < size; i++) {
for (b = 0x0; srcc < size && b == 0x0 ; ) {
b = base64s[(unsigned)src[srcc++]];
}
if (srcc < size) {
gotc += 1;
if (b) {
in[i] = (uint8_t)(b - 1);
}
} else {
in[i] = 0x0;
}
}
if (gotc) {
out[0] = (uint8_t)((unsigned)in[0] << 2 |
(unsigned)in[1] >> 4);
out[1] = (uint8_t)((unsigned)in[1] << 4 |
(unsigned)in[2] >> 2);
out[2] = (uint8_t)(((in[2] << 6) & 0xc0) | in[3]);
for (i = 0; i < gotc - 1; i++) {
*dst++ = out[i];
}
dstc += gotc - 1;
}
}
return dstc;
}
/* get a bignum from the buffer gap */
static BIGNUM *
getbignum(bufgap_t *bg, char *buf, const char *header)
{
uint32_t len;
BIGNUM *bignum;
(void) bufgap_getbin(bg, &len, sizeof(len));
len = ntohl(len);
(void) bufgap_seek(bg, sizeof(len), BGFromHere, BGByte);
(void) bufgap_getbin(bg, buf, len);
bignum = BN_bin2bn((const uint8_t *)buf, (int)len, NULL);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, header, (const uint8_t *)(void *)buf, len);
}
(void) bufgap_seek(bg, len, BGFromHere, BGByte);
return bignum;
}
#if 0
static int
putbignum(bufgap_t *bg, BIGNUM *bignum)
{
uint32_t len;
len = BN_num_bytes(bignum);
(void) bufgap_insert(bg, &len, sizeof(len));
(void) bufgap_insert(bg, buf, len);
bignum = BN_bin2bn((const uint8_t *)buf, (int)len, NULL);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, header, buf, (int)len);
}
(void) bufgap_seek(bg, len, BGFromHere, BGByte);
return bignum;
}
#endif
static str_t pkatypes[] = {
{ "ssh-rsa", 7, PGP_PKA_RSA },
{ "ssh-dss", 7, PGP_PKA_DSA },
{ "ssh-dsa", 7, PGP_PKA_DSA },
{ NULL, 0, 0 }
};
/* look for a string in the given array */
static int
findstr(str_t *array, const char *name)
{
str_t *sp;
for (sp = array ; sp->s ; sp++) {
if (strncmp(name, sp->s, sp->len) == 0) {
return sp->type;
}
}
return -1;
}
/* convert an ssh (host) pubkey to a pgp pubkey */
int
pgp_ssh2pubkey(pgp_io_t *io, const char *f, pgp_key_t *key, pgp_hash_alg_t hashtype)
{
pgp_pubkey_t *pubkey;
struct stat st;
bufgap_t bg;
uint32_t len;
int64_t off;
uint8_t *userid;
char hostname[256];
char owner[256];
char *space;
char *buf;
char *bin;
int ok;
int cc;
(void) memset(&bg, 0x0, sizeof(bg));
if (!bufgap_open(&bg, f)) {
(void) fprintf(stderr, "pgp_ssh2pubkey: can't open '%s'\n", f);
return 0;
}
(void)stat(f, &st);
if ((buf = calloc(1, (size_t)st.st_size)) == NULL) {
(void) fprintf(stderr, "can't calloc %zu bytes for '%s'\n", (size_t)st.st_size, f);
bufgap_close(&bg);
return 0;
}
if ((bin = calloc(1, (size_t)st.st_size)) == NULL) {
(void) fprintf(stderr, "can't calloc %zu bytes for '%s'\n", (size_t)st.st_size, f);
(void) free(buf);
bufgap_close(&bg);
return 0;
}
/* move past ascii type of key */
while (bufgap_peek(&bg, 0) != ' ') {
bufgap_seek(&bg, 1, BGFromHere, BGByte);
}
bufgap_seek(&bg, 1, BGFromHere, BGByte);
off = bufgap_tell(&bg, BGFromBOF, BGByte);
if (bufgap_size(&bg, BGByte) - off < 10) {
(void) fprintf(stderr, "bad key file '%s'\n", f);
(void) free(buf);
bufgap_close(&bg);
return 0;
}
/* convert from base64 to binary */
cc = bufgap_getbin(&bg, buf, (size_t)bg.bcc);
if ((space = strchr(buf, ' ')) != NULL) {
cc = (int)(space - buf);
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, NULL, (const uint8_t *)(const void *)buf, (size_t)cc);
}
cc = frombase64(bin, buf, (size_t)cc, 0);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "decoded base64:", (const uint8_t *)(const void *)bin, (size_t)cc);
}
bufgap_delete(&bg, (uint64_t)bufgap_tell(&bg, BGFromEOF, BGByte));
bufgap_insert(&bg, bin, cc);
bufgap_seek(&bg, off, BGFromBOF, BGByte);
/* get the type of key */
(void) bufgap_getbin(&bg, &len, sizeof(len));
len = ntohl(len);
(void) bufgap_seek(&bg, sizeof(len), BGFromHere, BGByte);
(void) bufgap_getbin(&bg, buf, len);
(void) bufgap_seek(&bg, len, BGFromHere, BGByte);
(void) memset(key, 0x0, sizeof(*key));
pubkey = &key->key.seckey.pubkey;
pubkey->version = PGP_V4;
pubkey->birthtime = st.st_mtime;
/* get key type */
ok = 1;
switch (pubkey->alg = findstr(pkatypes, buf)) {
case PGP_PKA_RSA:
/* get the 'e' param of the key */
pubkey->key.rsa.e = getbignum(&bg, buf, "RSA E");
/* get the 'n' param of the key */
pubkey->key.rsa.n = getbignum(&bg, buf, "RSA N");
break;
case PGP_PKA_DSA:
/* get the 'p' param of the key */
pubkey->key.dsa.p = getbignum(&bg, buf, "DSA P");
/* get the 'q' param of the key */
pubkey->key.dsa.q = getbignum(&bg, buf, "DSA Q");
/* get the 'g' param of the key */
pubkey->key.dsa.g = getbignum(&bg, buf, "DSA G");
/* get the 'y' param of the key */
pubkey->key.dsa.y = getbignum(&bg, buf, "DSA Y");
break;
default:
(void) fprintf(stderr, "Unrecognised pubkey type %d for '%s'\n",
pubkey->alg, f);
ok = 0;
break;
}
/* check for stragglers */
if (ok && bufgap_tell(&bg, BGFromEOF, BGByte) > 0) {
printf("%"PRIi64" bytes left\n", bufgap_tell(&bg, BGFromEOF, BGByte));
printf("[%s]\n", bufgap_getstr(&bg));
ok = 0;
}
if (ok) {
(void) memset(&userid, 0x0, sizeof(userid));
(void) gethostname(hostname, sizeof(hostname));
if (strlen(space + 1) - 1 == 0) {
(void) snprintf(owner, sizeof(owner), "<root@%s>",
hostname);
} else {
(void) snprintf(owner, sizeof(owner), "<%.*s>",
(int)strlen(space + 1) - 1,
space + 1);
}
(void) pgp_asprintf((char **)(void *)&userid,
"%s (%s) %s",
hostname,
f,
owner);
pgp_keyid(key->sigid, sizeof(key->sigid), pubkey, hashtype);
pgp_add_userid(key, userid);
pgp_fingerprint(&key->sigfingerprint, pubkey, hashtype);
free(userid);
if (pgp_get_debug_level(__FILE__)) {
/*pgp_print_keydata(io, keyring, key, "pub", pubkey, 0);*/
__PGP_USED(io); /* XXX */
}
}
(void) free(bin);
(void) free(buf);
bufgap_close(&bg);
return ok;
}
/* convert an ssh (host) seckey to a pgp seckey */
int
pgp_ssh2seckey(pgp_io_t *io, const char *f, pgp_key_t *key, pgp_pubkey_t *pubkey, pgp_hash_alg_t hashtype)
{
pgp_crypt_t crypted;
pgp_hash_t hash;
unsigned done = 0;
unsigned i = 0;
uint8_t sesskey[CAST_KEY_LENGTH];
uint8_t hashed[PGP_SHA1_HASH_SIZE];
BIGNUM *tmp;
__PGP_USED(io);
/* XXX - check for rsa/dsa */
if (!openssl_read_pem_seckey(f, key, "ssh-rsa", 0)) {
return 0;
}
if (pgp_get_debug_level(__FILE__)) {
/*pgp_print_keydata(io, key, "sec", &key->key.seckey.pubkey, 0);*/
/* XXX */
}
/* let's add some sane defaults */
(void) memcpy(&key->key.seckey.pubkey, pubkey, sizeof(*pubkey));
key->key.seckey.s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
key->key.seckey.alg = PGP_SA_CAST5;
key->key.seckey.s2k_specifier = PGP_S2KS_SALTED;
key->key.seckey.hash_alg = PGP_HASH_SHA1;
if (key->key.seckey.pubkey.alg == PGP_PKA_RSA) {
/* openssh and openssl have p and q swapped */
tmp = key->key.seckey.key.rsa.p;
key->key.seckey.key.rsa.p = key->key.seckey.key.rsa.q;
key->key.seckey.key.rsa.q = tmp;
}
for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) {
unsigned j;
uint8_t zero = 0;
int needed;
int size;
needed = CAST_KEY_LENGTH - done;
size = MIN(needed, PGP_SHA1_HASH_SIZE);
pgp_hash_any(&hash, key->key.seckey.hash_alg);
if (!hash.init(&hash)) {
(void) fprintf(stderr, "write_seckey_body: bad alloc\n");
return 0;
}
/* preload if iterating */
for (j = 0; j < i; j++) {
/*
* Coverity shows a DEADCODE error on this
* line. This is expected since the hardcoded
* use of SHA1 and CAST5 means that it will
* not used. This will change however when
* other algorithms are supported.
*/
hash.add(&hash, &zero, 1);
}
if (key->key.seckey.s2k_specifier == PGP_S2KS_SALTED) {
hash.add(&hash, key->key.seckey.salt, PGP_SALT_SIZE);
}
hash.finish(&hash, hashed);
/*
* if more in hash than is needed by session key, use
* the leftmost octets
*/
(void) memcpy(&sesskey[i * PGP_SHA1_HASH_SIZE],
hashed, (unsigned)size);
done += (unsigned)size;
if (done > CAST_KEY_LENGTH) {
(void) fprintf(stderr,
"write_seckey_body: short add\n");
return 0;
}
}
pgp_crypt_any(&crypted, key->key.seckey.alg);
crypted.set_iv(&crypted, key->key.seckey.iv);
crypted.set_crypt_key(&crypted, sesskey);
pgp_encrypt_init(&crypted);
key->key.seckey.pubkey.alg = PGP_PKA_RSA;
pgp_fingerprint(&key->sigfingerprint, pubkey, hashtype);
pgp_keyid(key->sigid, sizeof(key->sigid), pubkey, hashtype);
return 1;
}
/* read a key from the ssh file, and add it to a keyring */
int
pgp_ssh2_readkeys(pgp_io_t *io, pgp_keyring_t *pubring,
pgp_keyring_t *secring, const char *pubfile,
const char *secfile, unsigned hashtype)
{
pgp_key_t *pubkey;
pgp_key_t *seckey;
pgp_key_t key;
pubkey = NULL;
(void) memset(&key, 0x0, sizeof(key));
if (pubfile) {
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(io->errs, "pgp_ssh2_readkeys: pubfile '%s'\n", pubfile);
}
if (!pgp_ssh2pubkey(io, pubfile, &key, (pgp_hash_alg_t)hashtype)) {
(void) fprintf(io->errs, "pgp_ssh2_readkeys: can't read pubkeys '%s'\n", pubfile);
return 0;
}
EXPAND_ARRAY(pubring, key);
pubkey = &pubring->keys[pubring->keyc++];
(void) memcpy(pubkey, &key, sizeof(key));
pubkey->type = PGP_PTAG_CT_PUBLIC_KEY;
}
if (secfile) {
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(io->errs, "pgp_ssh2_readkeys: secfile '%s'\n", secfile);
}
if (pubkey == NULL) {
pubkey = &pubring->keys[0];
}
if (!pgp_ssh2seckey(io, secfile, &key, &pubkey->key.pubkey, (pgp_hash_alg_t)hashtype)) {
(void) fprintf(io->errs, "pgp_ssh2_readkeys: can't read seckeys '%s'\n", secfile);
return 0;
}
EXPAND_ARRAY(secring, key);
seckey = &secring->keys[secring->keyc++];
(void) memcpy(seckey, &key, sizeof(key));
seckey->type = PGP_PTAG_CT_SECRET_KEY;
}
return 1;
}

View File

@@ -0,0 +1,41 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SSH2PGP_H_
#define SSH2PGP_H_
#include "keyring.h"
#include "types.h"
int pgp_ssh2pubkey(pgp_io_t *, const char *, pgp_key_t *, pgp_hash_alg_t);
int pgp_ssh2seckey(pgp_io_t *, const char *, pgp_key_t *, pgp_pubkey_t *, pgp_hash_alg_t);
int pgp_ssh2_readkeys(pgp_io_t *, pgp_keyring_t *, pgp_keyring_t *,
const char *, const char *, unsigned);
#endif

View File

@@ -0,0 +1,802 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: symmetric.c,v 1.18 2010/11/07 08:39:59 agc Exp $");
#endif
#include "crypto.h"
#include "packet-show.h"
#include <string.h>
#ifdef HAVE_OPENSSL_CAST_H
#include <openssl/cast.h>
#endif
#ifdef HAVE_OPENSSL_IDEA_H
#include <openssl/idea.h>
#endif
#ifdef HAVE_OPENSSL_AES_H
#include <openssl/aes.h>
#endif
#ifdef HAVE_OPENSSL_DES_H
#include <openssl/des.h>
#endif
#ifdef HAVE_OPENSSL_CAMELLIA_H
#include <openssl/camellia.h>
#endif
#include "crypto.h"
#include "netpgpdefs.h"
static void
std_set_iv(pgp_crypt_t *crypt, const uint8_t *iv)
{
(void) memcpy(crypt->iv, iv, crypt->blocksize);
crypt->num = 0;
}
static void
std_set_key(pgp_crypt_t *crypt, const uint8_t *key)
{
(void) memcpy(crypt->key, key, crypt->keysize);
}
static void
std_resync(pgp_crypt_t *decrypt)
{
if ((size_t) decrypt->num == decrypt->blocksize) {
return;
}
memmove(decrypt->civ + decrypt->blocksize - decrypt->num, decrypt->civ,
(unsigned)decrypt->num);
(void) memcpy(decrypt->civ, decrypt->siv + decrypt->num,
decrypt->blocksize - decrypt->num);
decrypt->num = 0;
}
static void
std_finish(pgp_crypt_t *crypt)
{
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
crypt->encrypt_key = NULL;
}
if (crypt->decrypt_key) {
free(crypt->decrypt_key);
crypt->decrypt_key = NULL;
}
}
static int
cast5_init(pgp_crypt_t *crypt)
{
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
}
if ((crypt->encrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) {
(void) fprintf(stderr, "cast5_init: alloc failure\n");
return 0;
}
CAST_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key);
if ((crypt->decrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) {
(void) fprintf(stderr, "cast5_init: alloc failure\n");
return 0;
}
CAST_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key);
return 1;
}
static void
cast5_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_ENCRYPT);
}
static void
cast5_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_DECRYPT);
}
static void
cast5_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
CAST_cfb64_encrypt(in, out, (long)count,
crypt->encrypt_key, crypt->iv, &crypt->num,
CAST_ENCRYPT);
}
static void
cast5_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
CAST_cfb64_encrypt(in, out, (long)count,
crypt->encrypt_key, crypt->iv, &crypt->num,
CAST_DECRYPT);
}
#define TRAILER "","","","",0,NULL,NULL
static pgp_crypt_t cast5 =
{
PGP_SA_CAST5,
CAST_BLOCK,
CAST_KEY_LENGTH,
std_set_iv,
std_set_key,
cast5_init,
std_resync,
cast5_block_encrypt,
cast5_block_decrypt,
cast5_cfb_encrypt,
cast5_cfb_decrypt,
std_finish,
TRAILER
};
#ifndef OPENSSL_NO_IDEA
static int
idea_init(pgp_crypt_t *crypt)
{
if (crypt->keysize != IDEA_KEY_LENGTH) {
(void) fprintf(stderr, "idea_init: keysize wrong\n");
return 0;
}
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
}
if ((crypt->encrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) {
(void) fprintf(stderr, "idea_init: alloc failure\n");
return 0;
}
/* note that we don't invert the key when decrypting for CFB mode */
idea_set_encrypt_key(crypt->key, crypt->encrypt_key);
if (crypt->decrypt_key) {
free(crypt->decrypt_key);
}
if ((crypt->decrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) {
(void) fprintf(stderr, "idea_init: alloc failure\n");
return 0;
}
idea_set_decrypt_key(crypt->encrypt_key, crypt->decrypt_key);
return 1;
}
static void
idea_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
idea_ecb_encrypt(in, out, crypt->encrypt_key);
}
static void
idea_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
idea_ecb_encrypt(in, out, crypt->decrypt_key);
}
static void
idea_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
idea_cfb64_encrypt(in, out, (long)count,
crypt->encrypt_key, crypt->iv, &crypt->num,
CAST_ENCRYPT);
}
static void
idea_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
idea_cfb64_encrypt(in, out, (long)count,
crypt->decrypt_key, crypt->iv, &crypt->num,
CAST_DECRYPT);
}
static const pgp_crypt_t idea =
{
PGP_SA_IDEA,
IDEA_BLOCK,
IDEA_KEY_LENGTH,
std_set_iv,
std_set_key,
idea_init,
std_resync,
idea_block_encrypt,
idea_block_decrypt,
idea_cfb_encrypt,
idea_cfb_decrypt,
std_finish,
TRAILER
};
#endif /* OPENSSL_NO_IDEA */
/* AES with 128-bit key (AES) */
#define KEYBITS_AES128 128
static int
aes128_init(pgp_crypt_t *crypt)
{
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
}
if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
(void) fprintf(stderr, "aes128_init: alloc failure\n");
return 0;
}
if (AES_set_encrypt_key(crypt->key, KEYBITS_AES128,
crypt->encrypt_key)) {
fprintf(stderr, "aes128_init: Error setting encrypt_key\n");
}
if (crypt->decrypt_key) {
free(crypt->decrypt_key);
}
if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
(void) fprintf(stderr, "aes128_init: alloc failure\n");
return 0;
}
if (AES_set_decrypt_key(crypt->key, KEYBITS_AES128,
crypt->decrypt_key)) {
fprintf(stderr, "aes128_init: Error setting decrypt_key\n");
}
return 1;
}
static void
aes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
AES_encrypt(in, out, crypt->encrypt_key);
}
static void
aes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
AES_decrypt(in, out, crypt->decrypt_key);
}
static void
aes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
AES_cfb128_encrypt(in, out, (unsigned)count,
crypt->encrypt_key, crypt->iv, &crypt->num,
AES_ENCRYPT);
}
static void
aes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
AES_cfb128_encrypt(in, out, (unsigned)count,
crypt->encrypt_key, crypt->iv, &crypt->num,
AES_DECRYPT);
}
static const pgp_crypt_t aes128 =
{
PGP_SA_AES_128,
AES_BLOCK_SIZE,
KEYBITS_AES128 / 8,
std_set_iv,
std_set_key,
aes128_init,
std_resync,
aes_block_encrypt,
aes_block_decrypt,
aes_cfb_encrypt,
aes_cfb_decrypt,
std_finish,
TRAILER
};
/* AES with 256-bit key */
#define KEYBITS_AES256 256
static int
aes256_init(pgp_crypt_t *crypt)
{
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
}
if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
(void) fprintf(stderr, "aes256_init: alloc failure\n");
return 0;
}
if (AES_set_encrypt_key(crypt->key, KEYBITS_AES256,
crypt->encrypt_key)) {
fprintf(stderr, "aes256_init: Error setting encrypt_key\n");
free(crypt->encrypt_key);
crypt->encrypt_key = NULL;
return 0;
}
if (crypt->decrypt_key) {
free(crypt->decrypt_key);
}
if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
(void) fprintf(stderr, "aes256_init: alloc failure\n");
free(crypt->encrypt_key);
crypt->encrypt_key = NULL;
return 0;
}
if (AES_set_decrypt_key(crypt->key, KEYBITS_AES256,
crypt->decrypt_key)) {
fprintf(stderr, "aes256_init: Error setting decrypt_key\n");
free(crypt->encrypt_key);
crypt->encrypt_key = NULL;
free(crypt->decrypt_key);
crypt->decrypt_key = NULL;
return 0;
}
return 1;
}
static const pgp_crypt_t aes256 =
{
PGP_SA_AES_256,
AES_BLOCK_SIZE,
KEYBITS_AES256 / 8,
std_set_iv,
std_set_key,
aes256_init,
std_resync,
aes_block_encrypt,
aes_block_decrypt,
aes_cfb_encrypt,
aes_cfb_decrypt,
std_finish,
TRAILER
};
/* Triple DES */
static int
tripledes_init(pgp_crypt_t *crypt)
{
DES_key_schedule *keys;
int n;
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
}
if ((keys = crypt->encrypt_key = calloc(1, 3 * sizeof(DES_key_schedule))) == NULL) {
(void) fprintf(stderr, "tripledes_init: alloc failure\n");
return 0;
}
for (n = 0; n < 3; ++n) {
DES_set_key((DES_cblock *)(void *)(crypt->key + n * 8),
&keys[n]);
}
return 1;
}
static void
tripledes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
DES_key_schedule *keys = crypt->encrypt_key;
DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2],
DES_ENCRYPT);
}
static void
tripledes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
DES_key_schedule *keys = crypt->encrypt_key;
DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2],
DES_DECRYPT);
}
static void
tripledes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in,
size_t count)
{
DES_key_schedule *keys = crypt->encrypt_key;
DES_ede3_cfb64_encrypt(in, out, (long)count,
&keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv,
&crypt->num, DES_ENCRYPT);
}
static void
tripledes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in,
size_t count)
{
DES_key_schedule *keys = crypt->encrypt_key;
DES_ede3_cfb64_encrypt(in, out, (long)count,
&keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv,
&crypt->num, DES_DECRYPT);
}
static const pgp_crypt_t tripledes =
{
PGP_SA_TRIPLEDES,
8,
24,
std_set_iv,
std_set_key,
tripledes_init,
std_resync,
tripledes_block_encrypt,
tripledes_block_decrypt,
tripledes_cfb_encrypt,
tripledes_cfb_decrypt,
std_finish,
TRAILER
};
#if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
/* Camellia with 128-bit key (CAMELLIA) */
#define KEYBITS_CAMELLIA128 128
static int
camellia128_init(pgp_crypt_t *crypt)
{
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
}
if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
(void) fprintf(stderr, "camellia128_init: alloc failure\n");
return 0;
}
if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->encrypt_key)) {
fprintf(stderr, "camellia128_init: Error setting encrypt_key\n");
}
if (crypt->decrypt_key) {
free(crypt->decrypt_key);
}
if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
(void) fprintf(stderr, "camellia128_init: alloc failure\n");
return 0;
}
if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->decrypt_key)) {
fprintf(stderr, "camellia128_init: Error setting decrypt_key\n");
}
return 1;
}
static void
camellia_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
Camellia_encrypt(in, out, crypt->encrypt_key);
}
static void
camellia_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
{
Camellia_decrypt(in, out, crypt->decrypt_key);
}
static void
camellia_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
Camellia_cfb128_encrypt(in, out, (unsigned)count,
crypt->encrypt_key, crypt->iv, &crypt->num,
CAMELLIA_ENCRYPT);
}
static void
camellia_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
{
Camellia_cfb128_encrypt(in, out, (unsigned)count,
crypt->encrypt_key, crypt->iv, &crypt->num,
CAMELLIA_DECRYPT);
}
static const pgp_crypt_t camellia128 =
{
PGP_SA_CAMELLIA_128,
CAMELLIA_BLOCK_SIZE,
KEYBITS_CAMELLIA128 / 8,
std_set_iv,
std_set_key,
camellia128_init,
std_resync,
camellia_block_encrypt,
camellia_block_decrypt,
camellia_cfb_encrypt,
camellia_cfb_decrypt,
std_finish,
TRAILER
};
/* Camellia with 256-bit key (CAMELLIA) */
#define KEYBITS_CAMELLIA256 256
static int
camellia256_init(pgp_crypt_t *crypt)
{
if (crypt->encrypt_key) {
free(crypt->encrypt_key);
}
if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
(void) fprintf(stderr, "camellia256_init: alloc failure\n");
return 0;
}
if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->encrypt_key)) {
fprintf(stderr, "camellia256_init: Error setting encrypt_key\n");
}
if (crypt->decrypt_key) {
free(crypt->decrypt_key);
}
if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
(void) fprintf(stderr, "camellia256_init: alloc failure\n");
return 0;
}
if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->decrypt_key)) {
fprintf(stderr, "camellia256_init: Error setting decrypt_key\n");
}
return 1;
}
static const pgp_crypt_t camellia256 =
{
PGP_SA_CAMELLIA_256,
CAMELLIA_BLOCK_SIZE,
KEYBITS_CAMELLIA256 / 8,
std_set_iv,
std_set_key,
camellia256_init,
std_resync,
camellia_block_encrypt,
camellia_block_decrypt,
camellia_cfb_encrypt,
camellia_cfb_decrypt,
std_finish,
TRAILER
};
#endif
static const pgp_crypt_t *
get_proto(pgp_symm_alg_t alg)
{
switch (alg) {
case PGP_SA_CAST5:
return &cast5;
#ifndef OPENSSL_NO_IDEA
case PGP_SA_IDEA:
return &idea;
#endif /* OPENSSL_NO_IDEA */
case PGP_SA_AES_128:
return &aes128;
case PGP_SA_AES_256:
return &aes256;
#if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
case PGP_SA_CAMELLIA_128:
return &camellia128;
case PGP_SA_CAMELLIA_256:
return &camellia256;
#endif
case PGP_SA_TRIPLEDES:
return &tripledes;
default:
(void) fprintf(stderr, "Unknown algorithm: %d (%s)\n",
alg, pgp_show_symm_alg(alg));
}
return NULL;
}
int
pgp_crypt_any(pgp_crypt_t *crypt, pgp_symm_alg_t alg)
{
const pgp_crypt_t *ptr = get_proto(alg);
if (ptr) {
*crypt = *ptr;
return 1;
} else {
(void) memset(crypt, 0x0, sizeof(*crypt));
return 0;
}
}
unsigned
pgp_block_size(pgp_symm_alg_t alg)
{
const pgp_crypt_t *p = get_proto(alg);
return (p == NULL) ? 0 : (unsigned)p->blocksize;
}
unsigned
pgp_key_size(pgp_symm_alg_t alg)
{
const pgp_crypt_t *p = get_proto(alg);
return (p == NULL) ? 0 : (unsigned)p->keysize;
}
void
pgp_encrypt_init(pgp_crypt_t *encrypt)
{
/* \todo should there be a separate pgp_encrypt_init? */
pgp_decrypt_init(encrypt);
}
void
pgp_decrypt_init(pgp_crypt_t *decrypt)
{
decrypt->base_init(decrypt);
decrypt->block_encrypt(decrypt, decrypt->siv, decrypt->iv);
(void) memcpy(decrypt->civ, decrypt->siv, decrypt->blocksize);
decrypt->num = 0;
}
size_t
pgp_decrypt_se(pgp_crypt_t *decrypt, void *outvoid, const void *invoid,
size_t count)
{
const uint8_t *in = invoid;
uint8_t *out = outvoid;
int saved = (int)count;
/*
* in order to support v3's weird resyncing we have to implement CFB
* mode ourselves
*/
while (count-- > 0) {
uint8_t t;
if ((size_t) decrypt->num == decrypt->blocksize) {
(void) memcpy(decrypt->siv, decrypt->civ,
decrypt->blocksize);
decrypt->block_decrypt(decrypt, decrypt->civ,
decrypt->civ);
decrypt->num = 0;
}
t = decrypt->civ[decrypt->num];
*out++ = t ^ (decrypt->civ[decrypt->num++] = *in++);
}
return (size_t)saved;
}
size_t
pgp_encrypt_se(pgp_crypt_t *encrypt, void *outvoid, const void *invoid,
size_t count)
{
const uint8_t *in = invoid;
uint8_t *out = outvoid;
int saved = (int)count;
/*
* in order to support v3's weird resyncing we have to implement CFB
* mode ourselves
*/
while (count-- > 0) {
if ((size_t) encrypt->num == encrypt->blocksize) {
(void) memcpy(encrypt->siv, encrypt->civ,
encrypt->blocksize);
encrypt->block_encrypt(encrypt, encrypt->civ,
encrypt->civ);
encrypt->num = 0;
}
encrypt->civ[encrypt->num] = *out++ =
encrypt->civ[encrypt->num] ^ *in++;
++encrypt->num;
}
return (size_t)saved;
}
/**
\ingroup HighLevel_Supported
\brief Is this Symmetric Algorithm supported?
\param alg Symmetric Algorithm to check
\return 1 if supported; else 0
*/
unsigned
pgp_is_sa_supported(pgp_symm_alg_t alg)
{
switch (alg) {
case PGP_SA_AES_128:
case PGP_SA_AES_256:
case PGP_SA_CAST5:
case PGP_SA_TRIPLEDES:
#if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
case PGP_SA_CAMELLIA_128:
case PGP_SA_CAMELLIA_256:
#endif
#ifndef OPENSSL_NO_IDEA
case PGP_SA_IDEA:
#endif
return 1;
default:
fprintf(stderr, "\nWarning: %s not supported\n",
pgp_show_symm_alg(alg));
return 0;
}
}
size_t
pgp_encrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in,
size_t count)
{
if (!pgp_is_sa_supported(crypt->alg)) {
return 0;
}
crypt->cfb_encrypt(crypt, out, in, count);
/* \todo test this number was encrypted */
return count;
}
size_t
pgp_decrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in,
size_t count)
{
if (!pgp_is_sa_supported(crypt->alg)) {
return 0;
}
crypt->cfb_decrypt(crypt, out, in, count);
/* \todo check this number was in fact decrypted */
return count;
}

View File

@@ -0,0 +1,94 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TYPES_H_
#define TYPES_H_
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
typedef struct pgp_io_t {
void *outs; /* output file stream */
void *errs; /* file stream to put error messages */
void *res; /* file stream to put results */
} pgp_io_t;
/** pgp_map_t
*/
typedef struct {
int type;
const char *string;
} pgp_map_t;
/** pgp_errcode_name_map_t */
typedef pgp_map_t pgp_errcode_name_map_t;
typedef struct pgp_crypt_t pgp_crypt_t;
/** pgp_hash_t */
typedef struct pgp_hash_t pgp_hash_t;
/** Revocation Reason type */
typedef uint8_t pgp_ss_rr_code_t;
/** pgp_packet_t */
typedef struct pgp_packet_t pgp_packet_t;
/** Writer flags */
typedef enum {
PGP_WF_DUMMY
} pgp_writer_flags_t;
/**
* \ingroup Create
* Contains the required information about how to write
*/
typedef struct pgp_output_t pgp_output_t;
#endif /* TYPES_H_ */

View File

@@ -0,0 +1,971 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config.h"
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if defined(__NetBSD__)
__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: validate.c,v 1.44 2012/03/05 02:20:18 christos Exp $");
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "packet-parse.h"
#include "packet-show.h"
#include "keyring.h"
#include "signature.h"
#include "netpgpsdk.h"
#include "readerwriter.h"
#include "netpgpdefs.h"
#include "memory.h"
#include "packet.h"
#include "crypto.h"
#include "validate.h"
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
static int
keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
pgp_reader_t *readinfo,
pgp_cbdata_t *cbinfo)
{
validate_reader_t *reader = pgp_reader_get_arg(readinfo);
__PGP_USED(stream);
__PGP_USED(errors);
__PGP_USED(cbinfo);
if (reader->offset == reader->key->packets[reader->packet].length) {
reader->packet += 1;
reader->offset = 0;
}
if (reader->packet == reader->key->packetc) {
return 0;
}
/*
* we should never be asked to cross a packet boundary in a single
* read
*/
if (reader->key->packets[reader->packet].length <
reader->offset + length) {
(void) fprintf(stderr, "keydata_reader: weird length\n");
return 0;
}
(void) memcpy(dest,
&reader->key->packets[reader->packet].raw[reader->offset],
length);
reader->offset += (unsigned)length;
return (int)length;
}
static void
free_sig_info(pgp_sig_info_t *sig)
{
free(sig->v4_hashed);
free(sig);
}
static void
copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src)
{
(void) memcpy(dst, src, sizeof(*src));
if ((dst->v4_hashed = calloc(1, src->v4_hashlen)) == NULL) {
(void) fprintf(stderr, "copy_sig_info: bad alloc\n");
} else {
(void) memcpy(dst->v4_hashed, src->v4_hashed, src->v4_hashlen);
}
}
static int
add_sig_to_list(const pgp_sig_info_t *sig, pgp_sig_info_t **sigs,
unsigned *count)
{
pgp_sig_info_t *newsigs;
if (*count == 0) {
newsigs = calloc(*count + 1, sizeof(pgp_sig_info_t));
} else {
newsigs = realloc(*sigs,
(*count + 1) * sizeof(pgp_sig_info_t));
}
if (newsigs == NULL) {
(void) fprintf(stderr, "add_sig_to_list: alloc failure\n");
return 0;
}
*sigs = newsigs;
copy_sig_info(&(*sigs)[*count], sig);
*count += 1;
return 1;
}
/*
The hash value is calculated by the following method:
+ hash the data using the given digest algorithm
+ hash the hash value onto the end
+ hash the trailer - 6 bytes
[PGP_V4][0xff][len >> 24][len >> 16][len >> 8][len & 0xff]
to give the final hash value that is checked against the one in the signature
*/
/* Does the signed hash match the given hash? */
unsigned
check_binary_sig(const uint8_t *data,
const unsigned len,
const pgp_sig_t *sig,
const pgp_pubkey_t *signer)
{
unsigned hashedlen;
pgp_hash_t hash;
unsigned n;
uint8_t hashout[PGP_MAX_HASH_SIZE];
uint8_t trailer[6];
pgp_hash_any(&hash, sig->info.hash_alg);
if (!hash.init(&hash)) {
(void) fprintf(stderr, "check_binary_sig: bad hash init\n");
return 0;
}
hash.add(&hash, data, len);
switch (sig->info.version) {
case PGP_V3:
trailer[0] = sig->info.type;
trailer[1] = (unsigned)(sig->info.birthtime) >> 24;
trailer[2] = (unsigned)(sig->info.birthtime) >> 16;
trailer[3] = (unsigned)(sig->info.birthtime) >> 8;
trailer[4] = (uint8_t)(sig->info.birthtime);
hash.add(&hash, trailer, 5);
break;
case PGP_V4:
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "v4 hash", sig->info.v4_hashed,
sig->info.v4_hashlen);
}
hash.add(&hash, sig->info.v4_hashed, (unsigned)sig->info.v4_hashlen);
trailer[0] = 0x04; /* version */
trailer[1] = 0xFF;
hashedlen = (unsigned)sig->info.v4_hashlen;
trailer[2] = (uint8_t)(hashedlen >> 24);
trailer[3] = (uint8_t)(hashedlen >> 16);
trailer[4] = (uint8_t)(hashedlen >> 8);
trailer[5] = (uint8_t)(hashedlen);
hash.add(&hash, trailer, 6);
break;
default:
(void) fprintf(stderr, "Invalid signature version %d\n",
sig->info.version);
return 0;
}
n = hash.finish(&hash, hashout);
if (pgp_get_debug_level(__FILE__)) {
hexdump(stdout, "hash out", hashout, n);
}
return pgp_check_sig(hashout, n, sig, signer);
}
pgp_cb_ret_t
pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
const pgp_key_t *signer;
validate_key_cb_t *key;
pgp_pubkey_t *sigkey;
pgp_error_t **errors;
pgp_io_t *io;
unsigned from;
unsigned valid = 0;
io = cbinfo->io;
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(io->errs, "%s\n",
pgp_show_packet_tag(pkt->tag));
}
key = pgp_callback_arg(cbinfo);
errors = pgp_callback_errors(cbinfo);
switch (pkt->tag) {
case PGP_PTAG_CT_PUBLIC_KEY:
if (key->pubkey.version != 0) {
(void) fprintf(io->errs,
"pgp_validate_key_cb: version bad\n");
return PGP_FINISHED;
}
key->pubkey = content->pubkey;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_PUBLIC_SUBKEY:
if (key->subkey.version) {
pgp_pubkey_free(&key->subkey);
}
key->subkey = content->pubkey;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SECRET_KEY:
key->seckey = content->seckey;
key->pubkey = key->seckey.pubkey;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_USER_ID:
if (key->userid) {
pgp_userid_free(&key->userid);
}
key->userid = content->userid;
key->last_seen = ID;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_USER_ATTR:
if (content->userattr.len == 0) {
(void) fprintf(io->errs,
"pgp_validate_key_cb: user attribute length 0");
return PGP_FINISHED;
}
(void) fprintf(io->outs, "user attribute, length=%d\n",
(int) content->userattr.len);
if (key->userattr.len) {
pgp_data_free(&key->userattr);
}
key->userattr = content->userattr;
key->last_seen = ATTRIBUTE;
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */
case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */
from = 0;
signer = pgp_getkeybyid(io, key->keyring,
content->sig.info.signer_id,
&from, &sigkey);
if (!signer) {
if (!add_sig_to_list(&content->sig.info,
&key->result->unknown_sigs,
&key->result->unknownc)) {
(void) fprintf(io->errs,
"pgp_validate_key_cb: user attribute length 0");
return PGP_FINISHED;
}
break;
}
if (sigkey == &signer->enckey) {
(void) fprintf(io->errs,
"WARNING: signature made with encryption key\n");
}
switch (content->sig.info.type) {
case PGP_CERT_GENERIC:
case PGP_CERT_PERSONA:
case PGP_CERT_CASUAL:
case PGP_CERT_POSITIVE:
case PGP_SIG_REV_CERT:
valid = (key->last_seen == ID) ?
pgp_check_useridcert_sig(&key->pubkey,
key->userid,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw) :
pgp_check_userattrcert_sig(&key->pubkey,
&key->userattr,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw);
break;
case PGP_SIG_SUBKEY:
/*
* XXX: we should also check that the signer is the
* key we are validating, I think.
*/
valid = pgp_check_subkey_sig(&key->pubkey,
&key->subkey,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw);
break;
case PGP_SIG_DIRECT:
valid = pgp_check_direct_sig(&key->pubkey,
&content->sig,
pgp_get_pubkey(signer),
key->reader->key->packets[
key->reader->packet].raw);
break;
case PGP_SIG_STANDALONE:
case PGP_SIG_PRIMARY:
case PGP_SIG_REV_KEY:
case PGP_SIG_REV_SUBKEY:
case PGP_SIG_TIMESTAMP:
case PGP_SIG_3RD_PARTY:
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
"Sig Verification type 0x%02x not done yet\n",
content->sig.info.type);
break;
default:
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
"Unexpected signature type 0x%02x\n",
content->sig.info.type);
}
if (valid) {
if (!add_sig_to_list(&content->sig.info,
&key->result->valid_sigs,
&key->result->validc)) {
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
"Can't add good sig to list\n");
}
} else {
PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s",
"Bad Sig");
if (!add_sig_to_list(&content->sig.info,
&key->result->invalid_sigs,
&key->result->invalidc)) {
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s",
"Can't add good sig to list\n");
}
}
break;
/* ignore these */
case PGP_PARSER_PTAG:
case PGP_PTAG_CT_SIGNATURE_HEADER:
case PGP_PARSER_PACKET_END:
break;
case PGP_GET_PASSPHRASE:
if (key->getpassphrase) {
return key->getpassphrase(pkt, cbinfo);
}
break;
case PGP_PTAG_CT_TRUST:
/* 1 byte for level (depth), 1 byte for trust amount */
printf("trust dump\n");
printf("Got trust\n");
//hexdump(stdout, (const uint8_t *)content->trust.data, 10, " ");
//hexdump(stdout, (const uint8_t *)&content->ss_trust, 2, " ");
//printf("Trust level %d, amount %d\n", key->trust.level, key->trust.amount);
break;
default:
(void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag);
return PGP_FINISHED;
}
return PGP_RELEASE_MEMORY;
}
pgp_cb_ret_t
validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
{
const pgp_contents_t *content = &pkt->u;
const pgp_key_t *signer;
validate_data_cb_t *data;
pgp_pubkey_t *sigkey;
pgp_error_t **errors;
pgp_io_t *io;
unsigned from;
unsigned valid = 0;
io = cbinfo->io;
if (pgp_get_debug_level(__FILE__)) {
(void) fprintf(io->errs, "validate_data_cb: %s\n",
pgp_show_packet_tag(pkt->tag));
}
data = pgp_callback_arg(cbinfo);
errors = pgp_callback_errors(cbinfo);
switch (pkt->tag) {
case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
/*
* ignore - this gives us the "Armor Header" line "Hash:
* SHA1" or similar
*/
break;
case PGP_PTAG_CT_LITDATA_HEADER:
/* ignore */
break;
case PGP_PTAG_CT_LITDATA_BODY:
data->data.litdata_body = content->litdata_body;
data->type = LITDATA;
pgp_memory_add(data->mem, data->data.litdata_body.data,
data->data.litdata_body.length);
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY:
data->data.cleartext_body = content->cleartext_body;
data->type = SIGNED_CLEARTEXT;
pgp_memory_add(data->mem, data->data.cleartext_body.data,
data->data.cleartext_body.length);
return PGP_KEEP_MEMORY;
case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
/* this gives us an pgp_hash_t struct */
break;
case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */
case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */
if (pgp_get_debug_level(__FILE__)) {
hexdump(io->outs, "hashed data", content->sig.info.v4_hashed,
content->sig.info.v4_hashlen);
hexdump(io->outs, "signer id", content->sig.info.signer_id,
sizeof(content->sig.info.signer_id));
}
from = 0;
signer = pgp_getkeybyid(io, data->keyring,
content->sig.info.signer_id, &from, &sigkey);
if (!signer) {
PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER,
"%s", "Unknown Signer");
if (!add_sig_to_list(&content->sig.info,
&data->result->unknown_sigs,
&data->result->unknownc)) {
PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER,
"%s", "Can't add unknown sig to list");
}
break;
}
if (sigkey == &signer->enckey) {
(void) fprintf(io->errs,
"WARNING: signature made with encryption key\n");
}
if (content->sig.info.birthtime_set) {
data->result->birthtime = content->sig.info.birthtime;
}
if (content->sig.info.duration_set) {
data->result->duration = content->sig.info.duration;
}
switch (content->sig.info.type) {
case PGP_SIG_BINARY:
case PGP_SIG_TEXT:
if (pgp_mem_len(data->mem) == 0 &&
data->detachname) {
/* check we have seen some data */
/* if not, need to read from detached name */
(void) fprintf(io->errs,
"netpgp: assuming signed data in \"%s\"\n",
data->detachname);
data->mem = pgp_memory_new();
pgp_mem_readfile(data->mem, data->detachname);
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "sig dump", (const uint8_t *)(const void *)&content->sig,
sizeof(content->sig));
}
valid = check_binary_sig(pgp_mem_data(data->mem),
(const unsigned)pgp_mem_len(data->mem),
&content->sig,
pgp_get_pubkey(signer));
break;
default:
PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED,
"No Sig Verification type 0x%02x yet\n",
content->sig.info.type);
break;
}
if (valid) {
if (!add_sig_to_list(&content->sig.info,
&data->result->valid_sigs,
&data->result->validc)) {
PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE,
"%s", "Can't add good sig to list");
}
} else {
PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE,
"%s", "Bad Signature");
if (!add_sig_to_list(&content->sig.info,
&data->result->invalid_sigs,
&data->result->invalidc)) {
PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s",
"Can't add good sig to list");
}
}
break;
/* ignore these */
case PGP_PARSER_PTAG:
case PGP_PTAG_CT_SIGNATURE_HEADER:
case PGP_PTAG_CT_ARMOUR_HEADER:
case PGP_PTAG_CT_ARMOUR_TRAILER:
case PGP_PTAG_CT_1_PASS_SIG:
break;
case PGP_PARSER_PACKET_END:
break;
default:
PGP_ERROR_1(errors, PGP_E_V_NO_SIGNATURE, "%s", "No signature");
break;
}
return PGP_RELEASE_MEMORY;
}
static void
keydata_destroyer(pgp_reader_t *readinfo)
{
free(pgp_reader_get_arg(readinfo));
}
void
pgp_keydata_reader_set(pgp_stream_t *stream, const pgp_key_t *key)
{
validate_reader_t *data;
if ((data = calloc(1, sizeof(*data))) == NULL) {
(void) fprintf(stderr, "pgp_keydata_reader_set: bad alloc\n");
} else {
data->key = key;
data->packet = 0;
data->offset = 0;
pgp_reader_set(stream, keydata_reader, keydata_destroyer, data);
}
}
static char *
fmtsecs(int64_t n, char *buf, size_t size)
{
if (n > 365 * 24 * 60 * 60) {
n /= (365 * 24 * 60 * 60);
(void) snprintf(buf, size, "%" PRId64 " year%s", n, (n == 1) ? "" : "s");
return buf;
}
if (n > 30 * 24 * 60 * 60) {
n /= (30 * 24 * 60 * 60);
(void) snprintf(buf, size, "%" PRId64 " month%s", n, (n == 1) ? "" : "s");
return buf;
}
if (n > 24 * 60 * 60) {
n /= (24 * 60 * 60);
(void) snprintf(buf, size, "%" PRId64 " day%s", n, (n == 1) ? "" : "s");
return buf;
}
if (n > 60 * 60) {
n /= (60 * 60);
(void) snprintf(buf, size, "%" PRId64 " hour%s", n, (n == 1) ? "" : "s");
return buf;
}
if (n > 60) {
n /= 60;
(void) snprintf(buf, size, "%" PRId64 " minute%s", n, (n == 1) ? "" : "s");
return buf;
}
(void) snprintf(buf, size, "%" PRId64 " second%s", n, (n == 1) ? "" : "s");
return buf;
}
/**
* \ingroup HighLevel_Verify
* \brief Indicicates whether any errors were found
* \param result Validation result to check
* \return 0 if any invalid signatures or unknown signers
or no valid signatures; else 1
*/
static unsigned
validate_result_status(FILE *errs, const char *f, pgp_validation_t *val)
{
time_t now;
time_t t;
char buf[128];
now = time(NULL);
if (now < val->birthtime) {
/* signature is not valid yet! */
if (f) {
(void) fprintf(errs, "\"%s\": ", f);
} else {
(void) fprintf(errs, "memory ");
}
(void) fprintf(errs,
"signature not valid until %.24s (%s)\n",
ctime(&val->birthtime),
fmtsecs((int64_t)(val->birthtime - now), buf, sizeof(buf)));
return 0;
}
if (val->duration != 0 && now > val->birthtime + val->duration) {
/* signature has expired */
t = val->duration + val->birthtime;
if (f) {
(void) fprintf(errs, "\"%s\": ", f);
} else {
(void) fprintf(errs, "memory ");
}
(void) fprintf(errs,
"signature not valid after %.24s (%s ago)\n",
ctime(&t),
fmtsecs((int64_t)(now - t), buf, sizeof(buf)));
return 0;
}
return val->validc && !val->invalidc && !val->unknownc;
}
/**
* \ingroup HighLevel_Verify
* \brief Validate all signatures on a single key against the given keyring
* \param result Where to put the result
* \param key Key to validate
* \param keyring Keyring to use for validation
* \param cb_get_passphrase Callback to use to get passphrase
* \return 1 if all signatures OK; else 0
* \note It is the caller's responsiblity to free result after use.
* \sa pgp_validate_result_free()
*/
unsigned
pgp_validate_key_sigs(pgp_validation_t *result,
const pgp_key_t *key,
const pgp_keyring_t *keyring,
pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
pgp_cbdata_t *))
{
pgp_stream_t *stream;
validate_key_cb_t keysigs;
const int printerrors = 1;
(void) memset(&keysigs, 0x0, sizeof(keysigs));
keysigs.result = result;
keysigs.getpassphrase = cb_get_passphrase;
stream = pgp_new(sizeof(*stream));
/* pgp_parse_options(&opt,PGP_PTAG_CT_SIGNATURE,PGP_PARSE_PARSED); */
keysigs.keyring = keyring;
pgp_set_callback(stream, pgp_validate_key_cb, &keysigs);
stream->readinfo.accumulate = 1;
pgp_keydata_reader_set(stream, key);
/* Note: Coverity incorrectly reports an error that keysigs.reader */
/* is never used. */
keysigs.reader = stream->readinfo.arg;
pgp_parse(stream, !printerrors);
pgp_pubkey_free(&keysigs.pubkey);
if (keysigs.subkey.version) {
pgp_pubkey_free(&keysigs.subkey);
}
pgp_userid_free(&keysigs.userid);
pgp_data_free(&keysigs.userattr);
pgp_stream_delete(stream);
return (!result->invalidc && !result->unknownc && result->validc);
}
/**
\ingroup HighLevel_Verify
\param result Where to put the result
\param ring Keyring to use
\param cb_get_passphrase Callback to use to get passphrase
\note It is the caller's responsibility to free result after use.
\sa pgp_validate_result_free()
*/
unsigned
pgp_validate_all_sigs(pgp_validation_t *result,
const pgp_keyring_t *ring,
pgp_cb_ret_t cb_get_passphrase(const pgp_packet_t *,
pgp_cbdata_t *))
{
unsigned n;
(void) memset(result, 0x0, sizeof(*result));
for (n = 0; n < ring->keyc; ++n) {
pgp_validate_key_sigs(result, &ring->keys[n], ring,
cb_get_passphrase);
}
return validate_result_status(stderr, "keyring", result);
}
/**
\ingroup HighLevel_Verify
\brief Frees validation result and associated memory
\param result Struct to be freed
\note Must be called after validation functions
*/
void
pgp_validate_result_free(pgp_validation_t *result)
{
if (result != NULL) {
if (result->valid_sigs) {
free_sig_info(result->valid_sigs);
}
if (result->invalid_sigs) {
free_sig_info(result->invalid_sigs);
}
if (result->unknown_sigs) {
free_sig_info(result->unknown_sigs);
}
free(result);
/* result = NULL; - XXX unnecessary */
}
}
/**
\ingroup HighLevel_Verify
\brief Verifies the signatures in a signed file
\param result Where to put the result
\param filename Name of file to be validated
\param armoured Treat file as armoured, if set
\param keyring Keyring to use
\return 1 if signatures validate successfully;
0 if signatures fail or there are no signatures
\note After verification, result holds the details of all keys which
have passed, failed and not been recognised.
\note It is the caller's responsiblity to call
pgp_validate_result_free(result) after use.
*/
unsigned
pgp_validate_file(pgp_io_t *io,
pgp_validation_t *result,
const char *infile,
const char *outfile,
const int user_says_armoured,
const pgp_keyring_t *keyring)
{
validate_data_cb_t validation;
pgp_stream_t *parse = NULL;
struct stat st;
const char *signame;
const int printerrors = 1;
unsigned ret;
char f[MAXPATHLEN];
char *dataname;
int realarmour;
int outfd = 0;
int infd;
int cc;
if (stat(infile, &st) < 0) {
(void) fprintf(io->errs,
"pgp_validate_file: can't open '%s'\n", infile);
return 0;
}
realarmour = user_says_armoured;
dataname = NULL;
signame = NULL;
cc = snprintf(f, sizeof(f), "%s", infile);
if (strcmp(&f[cc - 4], ".sig") == 0) {
/* we've been given a sigfile as infile */
f[cc - 4] = 0x0;
/* set dataname to name of file which was signed */
dataname = f;
signame = infile;
} else if (strcmp(&f[cc - 4], ".asc") == 0) {
/* we've been given an armored sigfile as infile */
f[cc - 4] = 0x0;
/* set dataname to name of file which was signed */
dataname = f;
signame = infile;
realarmour = 1;
} else {
signame = infile;
}
(void) memset(&validation, 0x0, sizeof(validation));
infd = pgp_setup_file_read(io, &parse, signame, &validation,
validate_data_cb, 1);
if (infd < 0) {
return 0;
}
if (dataname) {
validation.detachname = netpgp_strdup(dataname);
}
/* Set verification reader and handling options */
validation.result = result;
validation.keyring = keyring;
validation.mem = pgp_memory_new();
pgp_memory_init(validation.mem, 128);
/* Note: Coverity incorrectly reports an error that validation.reader */
/* is never used. */
validation.reader = parse->readinfo.arg;
if (realarmour) {
pgp_reader_push_dearmour(parse);
}
/* Do the verification */
pgp_parse(parse, !printerrors);
/* Tidy up */
if (realarmour) {
pgp_reader_pop_dearmour(parse);
}
pgp_teardown_file_read(parse, infd);
ret = validate_result_status(io->errs, infile, result);
/* this is triggered only for --cat output */
if (outfile) {
/* need to send validated output somewhere */
if (strcmp(outfile, "-") == 0) {
outfd = STDOUT_FILENO;
} else {
outfd = open(outfile, O_WRONLY | O_CREAT, 0666);
}
if (outfd < 0) {
/* even if the signature was good, we can't
* write the file, so send back a bad return
* code */
ret = 0;
} else if (validate_result_status(io->errs, infile, result)) {
unsigned len;
char *cp;
int i;
len = (unsigned)pgp_mem_len(validation.mem);
cp = pgp_mem_data(validation.mem);
for (i = 0 ; i < (int)len ; i += cc) {
cc = (int)write(outfd, &cp[i], (unsigned)(len - i));
if (cc < 0) {
(void) fprintf(io->errs,
"netpgp: short write\n");
ret = 0;
break;
}
}
if (strcmp(outfile, "-") != 0) {
(void) close(outfd);
}
}
}
pgp_memory_free(validation.mem);
return ret;
}
/**
\ingroup HighLevel_Verify
\brief Verifies the signatures in a pgp_memory_t struct
\param result Where to put the result
\param mem Memory to be validated
\param user_says_armoured Treat data as armoured, if set
\param keyring Keyring to use
\return 1 if signature validates successfully; 0 if not
\note After verification, result holds the details of all keys which
have passed, failed and not been recognised.
\note It is the caller's responsiblity to call
pgp_validate_result_free(result) after use.
*/
unsigned
pgp_validate_mem(pgp_io_t *io,
pgp_validation_t *result,
pgp_memory_t *mem,
pgp_memory_t **cat,
const int user_says_armoured,
const pgp_keyring_t *keyring)
{
validate_data_cb_t validation;
pgp_stream_t *stream = NULL;
const int printerrors = 1;
int realarmour;
pgp_setup_memory_read(io, &stream, mem, &validation, validate_data_cb, 1);
/* Set verification reader and handling options */
(void) memset(&validation, 0x0, sizeof(validation));
validation.result = result;
validation.keyring = keyring;
validation.mem = pgp_memory_new();
pgp_memory_init(validation.mem, 128);
/* Note: Coverity incorrectly reports an error that validation.reader */
/* is never used. */
validation.reader = stream->readinfo.arg;
if ((realarmour = user_says_armoured) != 0 ||
strncmp(pgp_mem_data(mem),
"-----BEGIN PGP MESSAGE-----", 27) == 0) {
realarmour = 1;
}
if (realarmour) {
pgp_reader_push_dearmour(stream);
}
/* Do the verification */
pgp_parse(stream, !printerrors);
/* Tidy up */
if (realarmour) {
pgp_reader_pop_dearmour(stream);
}
pgp_teardown_memory_read(stream, mem);
/* this is triggered only for --cat output */
if (cat) {
/* need to send validated output somewhere */
*cat = validation.mem;
} else {
pgp_memory_free(validation.mem);
}
return validate_result_status(io->errs, NULL, result);
}

View File

@@ -0,0 +1,120 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef VALIDATE_H_
#define VALIDATE_H_ 1
typedef struct {
const pgp_key_t *key;
unsigned packet;
unsigned offset;
} validate_reader_t;
/** Struct used with the validate_key_cb callback */
typedef struct {
pgp_pubkey_t pubkey;
pgp_pubkey_t subkey;
pgp_seckey_t seckey;
enum {
ATTRIBUTE = 1,
ID
} last_seen;
uint8_t *userid;
pgp_data_t userattr;
uint8_t hash[PGP_MAX_HASH_SIZE];
const pgp_keyring_t *keyring;
validate_reader_t *reader;
pgp_validation_t *result;
pgp_cb_ret_t(*getpassphrase) (const pgp_packet_t *,
pgp_cbdata_t *);
} validate_key_cb_t;
/** Struct use with the validate_data_cb callback */
typedef struct {
enum {
LITDATA,
SIGNED_CLEARTEXT
} type;
union {
pgp_litdata_body_t litdata_body;
pgp_fixed_body_t cleartext_body;
} data;
uint8_t hash[PGP_MAX_HASH_SIZE];
pgp_memory_t *mem;
const pgp_keyring_t *keyring;
validate_reader_t *reader;/* reader-specific arg */
pgp_validation_t *result;
char *detachname;
} validate_data_cb_t;
void pgp_keydata_reader_set(pgp_stream_t *, const pgp_key_t *);
pgp_cb_ret_t pgp_validate_key_cb(const pgp_packet_t *, pgp_cbdata_t *);
unsigned check_binary_sig(const uint8_t *,
const unsigned,
const pgp_sig_t *,
const pgp_pubkey_t *);
unsigned pgp_validate_file(pgp_io_t *,
pgp_validation_t *,
const char *,
const char *,
const int,
const pgp_keyring_t *);
unsigned pgp_validate_mem(pgp_io_t *,
pgp_validation_t *,
pgp_memory_t *,
pgp_memory_t **,
const int,
const pgp_keyring_t *);
pgp_cb_ret_t validate_data_cb(const pgp_packet_t *, pgp_cbdata_t *);
#endif /* !VALIDATE_H_ */

View File

@@ -0,0 +1,67 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef VERSION_H_
#define VERSION_H_ 1
#ifndef NETPGP_AUTOCONF_VERSION
#define NETPGP_AUTOCONF_VERSION PACKAGE_VERSION
#endif
#ifndef NETPGP_MAINTAINER
#define NETPGP_MAINTAINER PACKAGE_BUGREPORT
#endif
/* development versions have .99 suffix */
#define NETPGP_BASE_VERSION "3.99.15"
#define NETPGP_VERSION_CAT(a, b) "NetPGP portable " a "/[" b "]"
#define NETPGP_VERSION_STRING \
NETPGP_VERSION_CAT(NETPGP_BASE_VERSION, NETPGP_AUTOCONF_VERSION)
#endif /* !VERSION_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
* All rights reserved.
* Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
* their moral rights under the UK Copyright Design and Patents Act 1988 to
* be recorded as the authors of this copyright work.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \file
*/
#ifndef WRITER_H_
#define WRITER_H_
#include "types.h"
#include "packet.h"
#include "crypto.h"
#include "errors.h"
#include "keyring.h"
/**
* \ingroup Writer
* the writer function prototype
*/
typedef struct pgp_writer_t pgp_writer_t;
typedef unsigned pgp_writer_func_t(const uint8_t *,
unsigned,
pgp_error_t **,
pgp_writer_t *);
typedef unsigned
pgp_writer_finaliser_t(pgp_error_t **, pgp_writer_t *);
typedef void pgp_writer_destroyer_t(pgp_writer_t *);
/** Writer settings */
struct pgp_writer_t {
pgp_writer_func_t *writer; /* the writer itself */
pgp_writer_finaliser_t *finaliser; /* the writer's finaliser */
pgp_writer_destroyer_t *destroyer; /* the writer's destroyer */
void *arg; /* writer-specific argument */
pgp_writer_t *next; /* next writer in the stack */
pgp_io_t *io; /* IO for errors and output */
};
void *pgp_writer_get_arg(pgp_writer_t *);
void pgp_writer_set(pgp_output_t *,
pgp_writer_func_t *,
pgp_writer_finaliser_t *,
pgp_writer_destroyer_t *,
void *);
void pgp_writer_push(pgp_output_t *,
pgp_writer_func_t *,
pgp_writer_finaliser_t *,
pgp_writer_destroyer_t *,
void *);
void pgp_writer_pop(pgp_output_t *);
unsigned pgp_writer_passthrough(const uint8_t *,
unsigned,
pgp_error_t **,
pgp_writer_t *);
void pgp_writer_set_fd(pgp_output_t *, int);
unsigned pgp_writer_close(pgp_output_t *);
unsigned pgp_write(pgp_output_t *, const void *, unsigned);
unsigned pgp_write_length(pgp_output_t *, unsigned);
unsigned pgp_write_ptag(pgp_output_t *, pgp_content_enum);
unsigned pgp_write_scalar(pgp_output_t *, unsigned, unsigned);
unsigned pgp_write_mpi(pgp_output_t *, const BIGNUM *);
void pgp_writer_info_delete(pgp_writer_t *);
unsigned pgp_writer_info_finalise(pgp_error_t **, pgp_writer_t *);
void pgp_push_stream_enc_se_ip(pgp_output_t *, const pgp_key_t *, const char *);
#endif /* WRITER_H_ */

View File

@@ -0,0 +1,13 @@
LIB=netbn
SRCS= bignum.c digest.c misc.c rand.c
SRCS+= stubs.c
MKMAN=no
WARNS=4
CPPFLAGS+=-I${EXTDIST}
INCS=bn.h digest.h
INCSDIR=/usr/include/netpgp
EXTDIST= ${.CURDIR}/../cipher
.include <bsd.lib.mk>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,146 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FAUXBN_H_
#define FAUXBN_H_ 20100108
#include <sys/types.h>
#ifndef _KERNEL
# include <inttypes.h>
# include <stdio.h>
#endif
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
/* should be 32bit on ILP32, 64bit on LP64 */
typedef unsigned long mp_digit;
typedef uint64_t mp_word;
/* multi-precision integer */
typedef struct mp_int {
mp_digit *dp; /* array of digits */
int used; /* # of digits used */
int alloc; /* # of digits allocated */
int sign; /* non-zero if negative */
} mp_int;
#define BIGNUM mp_int
#define BN_ULONG mp_digit
/* a "context" of mp integers - never really used */
typedef struct bn_ctx_t {
size_t count;
size_t arraysize;
BIGNUM **v;
} BN_CTX;
#define MP_LT -1
#define MP_EQ 0
#define MP_GT 1
#define MP_ZPOS 0
#define MP_NEG 1
#define MP_OKAY 0
#define MP_MEM -2
#define MP_VAL -3
#define MP_RANGE MP_VAL
/*********************************/
#define BN_is_negative(x) ((x)->sign == MP_NEG)
#define BN_is_zero(a) (((a)->used == 0) ? 1 : 0)
#define BN_is_odd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? 1 : 0)
#define BN_is_even(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? 1 : 0)
BIGNUM *BN_new(void);
BIGNUM *BN_dup(const BIGNUM */*a*/);
int BN_copy(BIGNUM */*b*/, const BIGNUM */*a*/);
void BN_init(BIGNUM */*a*/);
void BN_free(BIGNUM */*a*/);
void BN_clear(BIGNUM */*a*/);
void BN_clear_free(BIGNUM */*a*/);
int BN_cmp(BIGNUM */*a*/, BIGNUM */*b*/);
BIGNUM *BN_bin2bn(const uint8_t */*buf*/, int /*size*/, BIGNUM */*bn*/);
int BN_bn2bin(const BIGNUM */*a*/, unsigned char */*b*/);
char *BN_bn2hex(const BIGNUM */*a*/);
char *BN_bn2dec(const BIGNUM */*a*/);
int BN_hex2bn(BIGNUM **/*a*/, const char */*str*/);
int BN_dec2bn(BIGNUM **/*a*/, const char */*str*/);
#ifndef _KERNEL
int BN_print_fp(FILE */*fp*/, const BIGNUM */*a*/);
#endif
int BN_add(BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/);
int BN_sub(BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/);
int BN_mul(BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/, BN_CTX */*ctx*/);
int BN_div(BIGNUM */*q*/, BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/, BN_CTX */*ctx*/);
void BN_swap(BIGNUM */*a*/, BIGNUM */*b*/);
int BN_lshift(BIGNUM */*r*/, const BIGNUM */*a*/, int /*n*/);
int BN_lshift1(BIGNUM */*r*/, BIGNUM */*a*/);
int BN_rshift(BIGNUM */*r*/, const BIGNUM */*a*/, int /*n*/);
int BN_rshift1(BIGNUM */*r*/, BIGNUM */*a*/);
int BN_set_word(BIGNUM */*a*/, BN_ULONG /*w*/);
void BN_set_negative(BIGNUM */*a*/, int /*n*/);
int BN_num_bytes(const BIGNUM */*a*/);
int BN_num_bits(const BIGNUM */*a*/);
int BN_mod_exp(BIGNUM */*r*/, BIGNUM */*a*/, BIGNUM */*p*/, BIGNUM */*m*/, BN_CTX */*ctx*/);
BIGNUM *BN_mod_inverse(BIGNUM */*ret*/, BIGNUM */*a*/, const BIGNUM */*n*/, BN_CTX */*ctx*/);
int BN_mod_mul(BIGNUM */*ret*/, BIGNUM */*a*/, BIGNUM */*b*/, const BIGNUM */*m*/, BN_CTX */*ctx*/);
int BN_mod_sub(BIGNUM */*r*/, BIGNUM */*a*/, BIGNUM */*b*/, const BIGNUM */*m*/, BN_CTX */*ctx*/);
BN_CTX *BN_CTX_new(void);
BIGNUM *BN_CTX_get(BN_CTX */*ctx*/);
void BN_CTX_start(BN_CTX */*ctx*/);
void BN_CTX_end(BN_CTX */*ctx*/);
void BN_CTX_init(BN_CTX */*c*/);
void BN_CTX_free(BN_CTX */*c*/);
int BN_rand(BIGNUM */*rnd*/, int /*bits*/, int /*top*/, int /*bottom*/);
int BN_rand_range(BIGNUM */*rnd*/, BIGNUM */*range*/);
int BN_is_prime(const BIGNUM */*a*/, int /*checks*/, void (*callback)(int, int, void *), BN_CTX */*ctx*/, void */*cb_arg*/);
const BIGNUM *BN_value_one(void);
int BN_is_bit_set(const BIGNUM */*a*/, int /*n*/);
__END_DECLS
#endif

View File

@@ -0,0 +1,304 @@
.\" $NetBSD: libnetpgpbn.3,v 1.3 2013/07/20 21:39:56 wiz Exp $
.\"
.\" Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd April 13, 2012
.Dt LIBNETPGPBN 3
.Os
.Sh NAME
.Nm libnetpgpbn
.Nd BIGNUM library of multi-precision integers
.Sh LIBRARY
.Lb libnetpgpbn
.Sh SYNOPSIS
.In netpgp/bn.h
.Ft BIGNUM *
.Fo BN_new
.Fa "void"
.Fc
.Ft BIGNUM *
.Fo BN_dup
.Fa "const BIGNUM *orig"
.Fc
.Ft int
.Fo BN_copy
.Fa "BIGNUM *to" "const BIGNUM *from"
.Fc
.Ft void
.Fo BN_swap
.Fa "BIGNUM *a" "BIGNUM *b"
.Fc
.Pp
.Ft void
.Fo BN_init
.Fa "BIGNUM *bn"
.Fc
.Ft void
.Fo BN_free
.Fa "BIGNUM *bn"
.Fc
.Ft void
.Fo BN_clear
.Fa "BIGNUM *bn"
.Fc
.Ft void
.Fo BN_clear_free
.Fa "BIGNUM *bn"
.Fc
.Pp
.Ft void
.Fo BN_clear_free
.Fa "BIGNUM *bn"
.Fc
.Pp
.Ft int
.Fo BN_cmp
.Fa "BIGNUM *lhs" "BIGNUM *rhs"
.Fc
.Ft int
.Fo BN_is_negative
.Fa "BIGNUM *bn"
.Fc
.Ft int
.Fo BN_is_zero
.Fa "BIGNUM *bn"
.Fc
.Ft int
.Fo BN_is_odd
.Fa "BIGNUM *bn"
.Fc
.Ft int
.Fo BN_is_even
.Fa "BIGNUM *bn"
.Fc
.Pp
.Ft BIGNUM *
.Fo BN_bin2bn
.Fa "const uint8_t *buf" "int size" "BIGNUM *bn"
.Fc
.Ft int
.Fo BN_bn2bin
.Fa "BIGNUM *bn" "uint8_t *buf"
.Fc
.Ft int
.Fo BN_bn2bin
.Fa "BIGNUM *bn" "uint8_t *buf"
.Fc
.Ft char *
.Fo BN_bn2hex
.Fa "const BIGNUM *bn"
.Fc
.Ft char *
.Fo BN_bn2dec
.Fa "const BIGNUM *bn"
.Fc
.Ft int
.Fo BN_hex2bn
.Fa "BIGNUM **bn" "const char *str"
.Fc
.Ft int
.Fo BN_dec2bn
.Fa "BIGNUM **bn" "const char *str"
.Fc
.Ft int
.Fo BN_print_fp
.Fa "FILE *fp" "const BIGNUM *bn"
.Fc
.Pp
.Ft int
.Fo BN_add
.Fa "BIGNUM *sum" "const BIGNUM *a" "const BIGNUM *b"
.Fc
.Ft int
.Fo BN_sub
.Fa "BIGNUM *sum" "const BIGNUM *a" "const BIGNUM *b"
.Fc
.Ft int
.Fo BN_mul
.Fa "BIGNUM *product" "const BIGNUM *a" "const BIGNUM *b" "BN_CTX *context"
.Fc
.Ft int
.Fo BN_div
.Fa "BIGNUM *quotient" "BIGNUM *remainder" "const BIGNUM *a" "const BIGNUM *b" "BN_CTX *context"
.Fc
.Pp
.Ft int
.Fo BN_lshift
.Fa "BIGNUM *result" "const BIGNUM *bn" "int n"
.Fc
.Ft int
.Fo BN_lshift1
.Fa "BIGNUM *result" "const BIGNUM *bn"
.Fc
.Ft int
.Fo BN_rshift
.Fa "BIGNUM *result" "const BIGNUM *bn" "int n"
.Fc
.Ft int
.Fo BN_rshift1
.Fa "BIGNUM *result" "const BIGNUM *bn"
.Fc
.Pp
.Ft int
.Fo BN_set_word
.Fa "BIGNUM *result" "unsigned long val"
.Fc
.Ft int
.Fo BN_set_negative
.Fa "BIGNUM *result" "int val"
.Fc
.Pp
.Ft int
.Fo BN_num_bytes
.Fa "const BIGNUM *bn"
.Fc
.Ft int
.Fo BN_num_bits
.Fa "const BIGNUM *bn"
.Fc
.Pp
.Ft int
.Fo BN_mod_exp
.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *p" "BIGNUM *m" "BN_CTX *context"
.Fc
.Ft BIGNUM *
.Fo BN_mod_inverse
.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *n" "BN_CTX *context"
.Fc
.Ft int
.Fo BN_mod_mul
.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *b" "BIGNUM *m" "BN_CTX *context"
.Fc
.Ft int
.Fo BN_mod_sub
.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *b" "BIGNUM *m" "BN_CTX *context"
.Fc
.Pp
.Ft BN_CTX *
.Fo BN_CTX_new
.Fa "void"
.Fc
.Ft BIGNUM *
.Fo BN_CTX_get
.Fa "BN_CTX *context"
.Fc
.Ft void
.Fo BN_CTX_start
.Fa "BN_CTX *context"
.Fc
.Ft void
.Fo BN_CTX_end
.Fa "BN_CTX *context"
.Fc
.Ft void
.Fo BN_CTX_init
.Fa "BN_CTX *context"
.Fc
.Ft void
.Fo BN_CTX_free
.Fa "BN_CTX *context"
.Fc
.Ft int
.Fo BN_rand
.Fa "BIGNUM *result" "int bits" "int top" "int bottom"
.Fc
.Ft int
.Fo BN_rand_range
.Fa "BIGNUM *result" "BIGNUM *range"
.Fc
.Ft int
.Fo BN_is_prime
.Fa "const BIGNUM *bn" "int checks" "void (*callback)(int int void)"
.Fa "BN_CTX *context" "void *callbackarg"
.Fc
.Pp
.Ft const BIGNUM *
.Fo BN_value_one
.Fa "void"
.Fc
.Ft int
.Fo BN_is_bit_set
.Fa "const BIGNUM *bn" "int n"
.Fc
.Sh DESCRIPTION
.Nm
emulates the API of the openssl
.Xr bn 3
library.
It is implemented using Tom St Denis
.Dq libtommath
library.
.Sh EXAMPLES
The follow code fragment will make a JSON object
out of the string
.Dq Hello <USERNAME>\en
in the
buffer called
.Dq buf
where
.Dq USERNAME
is the name of the user taken from the runtime environment.
The encoded text will be in an allocated buffer called
.Dq s
.Bd -literal -offset indent
mj_t atom;
char buf[BUFSIZ];
char *s;
int cc;
(void) memset(\*[Am]atom, 0x0, sizeof(atom));
cc = snprintf(buf, sizeof(buf), "Hello %s\en", getenv("USER"));
mj_create(\*[Am]atom, "string", buf, cc);
cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_JSON_ENCODE);
.Ed
.Pp
and the following example will take the (binary) text which has been encoded into
JSON and is in the buffer
.Dq buf ,
such as in the previous example, and re-create the original text:
.Bd -literal -offset indent
int from, to, tok, cc;
char *s;
mj_t atom;
(void) memset(\*[Am]atom, 0x0, sizeof(atom));
from = to = tok = 0;
mj_parse(\*[Am]atom, buf, \*[Am]from, \*[Am]to, \*[Am]tok);
cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_HUMAN);
printf("%.*s", cc, s);
.Ed
.Pp
The
.Dv s
pointer points to allocated storage with the original NUL-terminated string
in it.
.Sh SEE ALSO
.Xr bn 3
.Sh HISTORY
The
.Nm
library first appeared in
.Nx 7.0 .
.Sh AUTHORS
.An Alistair Crooks Aq Mt agc@NetBSD.org

View File

@@ -0,0 +1,82 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#ifdef _KERNEL
# include <sys/kmem.h>
#else
# include <ctype.h>
# include <inttypes.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
# include <unistd.h>
#endif
#include "misc.h"
#ifndef USE_ARG
#define USE_ARG(x) /*LINTED*/(void)&(x)
#endif
void *
netpgp_allocate(size_t n, size_t nels)
{
#ifdef _KERNEL
return kmem_zalloc(n * nels, KM_SLEEP);
#else
return calloc(n, nels);
#endif
}
void
netpgp_deallocate(void *ptr, size_t size)
{
#ifdef _KERNEL
kmem_free(ptr, size);
#else
USE_ARG(size);
free(ptr);
#endif
}
#ifndef _KERNEL
void
logmessage(const int level, const char *fmt, ...)
{
va_list args;
USE_ARG(level);
if (fmt != NULL) {
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
}
#endif

View File

@@ -0,0 +1,53 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MISC_H_
#define MISC_H_ 20110705
#include <sys/types.h>
#include <inttypes.h>
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
void *netpgp_allocate(size_t /*n*/, size_t /*nels*/);
void netpgp_deallocate(void */*ptr*/, size_t /*size*/);
#ifndef _KERNEL
void logmessage(const int /*level*/, const char */*fmt*/, ...);
#endif
__END_DECLS
#endif

View File

@@ -0,0 +1,60 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#ifdef _KERNEL
# include <sys/kmem.h>
#else
# include <arpa/inet.h>
# include <ctype.h>
# include <inttypes.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
# include <unistd.h>
#endif
#include "rand.h"
int
RAND_bytes(unsigned char *buf, int num)
{
uint32_t r;
size_t cc;
int i;
if (buf == NULL || num < 0) {
return 0;
}
for (i = 0 ; i < num ; i += sizeof(r)) {
r = arc4random();
cc = MIN(sizeof(r), (size_t)(num - i));
(void) memcpy(&buf[i], &r, cc);
}
return 1;
}

View File

@@ -0,0 +1,44 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RAND_H_
#define RAND_H_ 20120327
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
int RAND_bytes(unsigned char */*buf*/, int /*len*/);
__END_DECLS
#endif

View File

@@ -0,0 +1,217 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/param.h>
#ifdef _KERNEL
# include <sys/kmem.h>
#else
# include <arpa/inet.h>
# include <ctype.h>
# include <inttypes.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
# include <unistd.h>
#endif
#include "misc.h"
#include "bn.h"
#include "stubs.h"
#ifndef USE_ARG
#define USE_ARG(x) /*LINTED*/(void)&(x)
#endif
void
OpenSSL_add_all_algorithms(void)
{
}
void
OPENSSL_add_all_algorithms_noconf(void)
{
}
void
CRYPTO_cleanup_all_ex_data(void)
{
}
BIO *
BIO_new_fd(int fd, int close_flag)
{
USE_ARG(fd);
USE_ARG(close_flag);
return NULL;
}
unsigned long
ERR_get_error(void)
{
return 0;
}
char *
ERR_error_string(unsigned long e, char *buf)
{
static char staticbuf[120];
if (buf == NULL) {
buf = staticbuf;
}
snprintf(buf, 120, "error:%lu:netssl:[unknown function]:[unknown error]", e);
return buf;
}
void
ERR_remove_state(unsigned long pid)
{
USE_ARG(pid);
}
void
ERR_print_errors(BIO *bp)
{
USE_ARG(bp);
}
void
idea_set_encrypt_key(uint8_t *key, IDEA_KEY_SCHEDULE *ks)
{
printf("idea_set_encrypt_key stubbed\n");
USE_ARG(key);
USE_ARG(ks);
}
void
idea_set_decrypt_key(IDEA_KEY_SCHEDULE *encrypt_ks, IDEA_KEY_SCHEDULE *decrypt_ks)
{
printf("idea_set_decrypt_key stubbed\n");
USE_ARG(encrypt_ks);
USE_ARG(decrypt_ks);
}
void
idea_cfb64_encrypt(uint8_t *in, uint8_t *out, long length, des_key_schedule *ks, des_cblock *ivec, int *num, int enc)
{
printf("idea_cfb64_encrypt stubbed\n");
USE_ARG(in);
USE_ARG(out);
USE_ARG(length);
USE_ARG(ks);
USE_ARG(ivec);
USE_ARG(num);
USE_ARG(enc);
}
void
idea_ecb_encrypt(uint8_t *in, uint8_t *out, IDEA_KEY_SCHEDULE *ks)
{
printf("idea_cfb64_decrypt stubbed\n");
USE_ARG(in);
USE_ARG(out);
USE_ARG(ks);
}
int
Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key)
{
printf("Camellia_set_key stubbed\n");
USE_ARG(userKey);
USE_ARG(bits);
USE_ARG(key);
return 0;
}
void
Camellia_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key)
{
printf("Camellia_encrypt stubbed\n");
USE_ARG(in);
USE_ARG(out);
USE_ARG(key);
}
void
Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc)
{
printf("Camellia_cfb128_encrypt stubbed\n");
USE_ARG(in);
USE_ARG(out);
USE_ARG(length);
USE_ARG(key);
USE_ARG(ivec);
USE_ARG(num);
USE_ARG(enc);
}
void
Camellia_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key)
{
printf("Camellia_decrypt stubbed\n");
USE_ARG(in);
USE_ARG(out);
USE_ARG(key);
}
int
DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
{
printf("DES_set_key stubbed\n");
USE_ARG(key);
USE_ARG(schedule);
return 0;
}
void
DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_key_schedule *ks3, int enc)
{
printf("DES_ecb3_encrypt stubbed\n");
USE_ARG(input);
USE_ARG(output);
USE_ARG(ks1);
USE_ARG(ks2);
USE_ARG(ks3);
USE_ARG(enc);
}
void
DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out, long length,DES_key_schedule *ks1, DES_key_schedule *ks2,DES_key_schedule *ks3, DES_cblock *ivec,int *num,int enc)
{
printf("DES_ede3_cfb64_encrypt stubbed\n");
USE_ARG(in);
USE_ARG(out);
USE_ARG(length);
USE_ARG(ks1);
USE_ARG(ks2);
USE_ARG(ks3);
USE_ARG(ivec);
USE_ARG(num);
USE_ARG(enc);
}

View File

@@ -0,0 +1,94 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STUBS_H_
#define STUBS_H_ 20120327
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
/*********************************/
/* stubs */
/*********************************/
void OpenSSL_add_all_algorithms(void);
void OPENSSL_add_all_algorithms_noconf(void);
void CRYPTO_cleanup_all_ex_data(void);
#include <stdio.h>
#define BIO FILE
BIO *BIO_new_fd(int /*fd*/, int /*close_flag*/);
unsigned long ERR_get_error(void);
char *ERR_error_string(unsigned long /*e*/, char */*buf*/);
void ERR_remove_state(unsigned long /*pid*/);
void ERR_print_errors(BIO */*bp*/);
#define IDEA_KEY_SCHEDULE void
#define des_key_schedule void
#define des_cblock void
#define IDEA_DECRYPT 0
#define IDEA_ENCRYPT 1
#define IDEA_BLOCK 8
#define IDEA_KEY_LENGTH 16
void idea_set_encrypt_key(uint8_t *key, IDEA_KEY_SCHEDULE *ks);
void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *encrypt_ks, IDEA_KEY_SCHEDULE *decrypt_ks);
void idea_cfb64_encrypt(uint8_t *in, uint8_t *out, long length, des_key_schedule *ks, des_cblock *ivec, int *num, int enc);
void idea_ecb_encrypt(uint8_t *in, uint8_t *out, IDEA_KEY_SCHEDULE *ks);
#define CAMELLIA_KEY void
#define CAMELLIA_DECRYPT 0
#define CAMELLIA_ENCRYPT 1
#define CAMELLIA_BLOCK_SIZE 16
int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key);
void Camellia_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key);
void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc);
void Camellia_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key);
#define const_DES_cblock void
#define DES_cblock void
#define DES_key_schedule void
#define DES_DECRYPT 0
#define DES_ENCRYPT 1
int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule);
void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_key_schedule *ks3, int enc);
void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out, long length,DES_key_schedule *ks1, DES_key_schedule *ks2,DES_key_schedule *ks3, DES_cblock *ivec,int *num,int enc);
__END_DECLS
#endif

View File

@@ -0,0 +1,16 @@
LIB=netdigest
SRCS= tiger.c digest.c
MKMAN=no
WARNS=4
CPPFLAGS+=-I${EXTDIST}
INCS=digest.h tiger.h
INCSDIR=/usr/include/netpgp
EXTDIST=${.CURDIR}
.include <bsd.lib.mk>
.if ${HAVE_GCC} >= 45
#COPTS.isns_pdu.c+= -fno-strict-aliasing
CPPFLAGS+= -fno-strict-aliasing
.endif

View File

@@ -0,0 +1,383 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/syslog.h>
#ifdef _KERNEL
# include <sys/md5.h>
# include <sys/sha1.h>
# include <sys/sha2.h>
# include <sys/rmd160.h>
# include <sys/kmem.h>
#else
# include <arpa/inet.h>
# include <ctype.h>
# include <inttypes.h>
# include <md5.h>
# include <rmd160.h>
# include <sha1.h>
# include <sha2.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
# include <unistd.h>
#endif
#include "digest.h"
static uint8_t prefix_md5[] = {
0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
};
static uint8_t prefix_sha1[] = {
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02,
0x1A, 0x05, 0x00, 0x04, 0x14
};
static uint8_t prefix_sha256[] = {
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
};
static uint64_t prefix_tiger[] = {
0x0123456789ABCDEFLL,
0xFEDCBA9876543210LL,
0xF096A5B4C3B2E187LL
};
static uint8_t prefix_rmd160[] = {
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24,
0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14
};
static uint8_t prefix_sha512[] = {
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
};
#define V4_SIGNATURE 4
/*************************************************************************/
void
MD5_Init(MD5_CTX *context)
{
if (context) {
MD5Init(context);
}
}
void
MD5_Update(MD5_CTX *context, const unsigned char *data, unsigned int len)
{
if (context && data) {
MD5Update(context, data, len);
}
}
void
MD5_Final(unsigned char digest[16], MD5_CTX *context)
{
if (digest && context) {
MD5Final(digest, context);
}
}
void
SHA1_Init(SHA1_CTX *context)
{
if (context) {
SHA1Init(context);
}
}
void
SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
{
if (context && data) {
SHA1Update(context, data, len);
}
}
void
SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
{
if (digest && context) {
SHA1Final(digest, context);
}
}
void
RMD160_Init(RMD160_CTX *context)
{
if (context) {
RMD160Init(context);
}
}
void
RMD160_Update(RMD160_CTX *context, const unsigned char *data, unsigned int len)
{
if (context && data) {
RMD160Update(context, data, len);
}
}
void
RMD160_Final(unsigned char digest[20], RMD160_CTX *context)
{
if (context && digest) {
RMD160Final(digest, context);
}
}
/* algorithm size (raw) */
int
digest_alg_size(unsigned alg)
{
switch(alg) {
case MD5_HASH_ALG:
return 16;
case SHA1_HASH_ALG:
return 20;
case RIPEMD_HASH_ALG:
return RMD160_DIGEST_LENGTH;
case SHA256_HASH_ALG:
return 32;
case SHA512_HASH_ALG:
return 64;
case TIGER_HASH_ALG:
case TIGER2_HASH_ALG:
return TIGER_DIGEST_LENGTH;
default:
printf("hash_any: bad algorithm\n");
return 0;
}
}
/* initialise the hash structure */
int
digest_init(digest_t *hash, const uint32_t hashalg)
{
if (hash == NULL) {
return 0;
}
switch(hash->alg = hashalg) {
case MD5_HASH_ALG:
MD5Init(&hash->u.md5ctx);
hash->size = 16;
hash->prefix = prefix_md5;
hash->len = sizeof(prefix_md5);
hash->ctx = &hash->u.md5ctx;
return 1;
case SHA1_HASH_ALG:
SHA1Init(&hash->u.sha1ctx);
hash->size = 20;
hash->prefix = prefix_sha1;
hash->len = sizeof(prefix_sha1);
hash->ctx = &hash->u.sha1ctx;
return 1;
case RIPEMD_HASH_ALG:
RMD160Init(&hash->u.rmd160ctx);
hash->size = 20;
hash->prefix = prefix_rmd160;
hash->len = sizeof(prefix_rmd160);
hash->ctx = &hash->u.rmd160ctx;
return 1;
case SHA256_HASH_ALG:
SHA256_Init(&hash->u.sha256ctx);
hash->size = 32;
hash->prefix = prefix_sha256;
hash->len = sizeof(prefix_sha256);
hash->ctx = &hash->u.sha256ctx;
return 1;
case SHA512_HASH_ALG:
SHA512_Init(&hash->u.sha512ctx);
hash->size = 64;
hash->prefix = prefix_sha512;
hash->len = sizeof(prefix_sha512);
hash->ctx = &hash->u.sha512ctx;
return 1;
case TIGER_HASH_ALG:
TIGER_Init(&hash->u.tigerctx);
hash->size = TIGER_DIGEST_LENGTH;
hash->prefix = prefix_tiger;
hash->len = sizeof(prefix_tiger);
hash->ctx = &hash->u.tigerctx;
return 1;
case TIGER2_HASH_ALG:
TIGER2_Init(&hash->u.tigerctx);
hash->size = TIGER_DIGEST_LENGTH;
hash->prefix = prefix_tiger;
hash->len = sizeof(prefix_tiger);
hash->ctx = &hash->u.tigerctx;
return 1;
default:
printf("hash_any: bad algorithm\n");
return 0;
}
}
typedef struct rec_t {
const char *s;
const unsigned alg;
} rec_t;
static rec_t hashalgs[] = {
{ "md5", MD5_HASH_ALG },
{ "sha1", SHA1_HASH_ALG },
{ "ripemd", RIPEMD_HASH_ALG },
{ "sha256", SHA256_HASH_ALG },
{ "sha512", SHA512_HASH_ALG },
{ "tiger", TIGER_HASH_ALG },
{ "tiger2", TIGER2_HASH_ALG },
{ NULL, 0 }
};
/* initialise by string alg name */
unsigned
digest_get_alg(const char *hashalg)
{
rec_t *r;
for (r = hashalgs ; hashalg && r->s ; r++) {
if (strcasecmp(r->s, hashalg) == 0) {
return r->alg;
}
}
return 0;
}
int
digest_update(digest_t *hash, const uint8_t *data, size_t length)
{
if (hash == NULL || data == NULL) {
return 0;
}
switch(hash->alg) {
case MD5_HASH_ALG:
MD5Update(hash->ctx, data, (unsigned)length);
return 1;
case SHA1_HASH_ALG:
SHA1Update(hash->ctx, data, (unsigned)length);
return 1;
case RIPEMD_HASH_ALG:
RMD160Update(hash->ctx, data, (unsigned)length);
return 1;
case SHA256_HASH_ALG:
SHA256_Update(hash->ctx, data, length);
return 1;
case SHA512_HASH_ALG:
SHA512_Update(hash->ctx, data, length);
return 1;
case TIGER_HASH_ALG:
case TIGER2_HASH_ALG:
TIGER_Update(hash->ctx, data, length);
return 1;
default:
printf("hash_any: bad algorithm\n");
return 0;
}
}
unsigned
digest_final(uint8_t *out, digest_t *hash)
{
if (hash == NULL || out == NULL) {
return 0;
}
switch(hash->alg) {
case MD5_HASH_ALG:
MD5Final(out, hash->ctx);
break;
case SHA1_HASH_ALG:
SHA1Final(out, hash->ctx);
break;
case RIPEMD_HASH_ALG:
RMD160Final(out, hash->ctx);
break;
case SHA256_HASH_ALG:
SHA256_Final(out, hash->ctx);
break;
case SHA512_HASH_ALG:
SHA512_Final(out, hash->ctx);
break;
case TIGER_HASH_ALG:
TIGER_Final(out, hash->ctx);
break;
default:
printf("hash_any: bad algorithm\n");
return 0;
}
(void) memset(hash->ctx, 0x0, hash->size);
return (unsigned)hash->size;
}
int
digest_length(digest_t *hash, unsigned hashedlen)
{
uint8_t trailer[6];
if (hash == NULL) {
return 0;
}
trailer[0] = V4_SIGNATURE;
trailer[1] = 0xFF;
trailer[2] = (uint8_t)((hashedlen >> 24) & 0xff);
trailer[3] = (uint8_t)((hashedlen >> 16) & 0xff);
trailer[4] = (uint8_t)((hashedlen >> 8) & 0xff);
trailer[5] = (uint8_t)(hashedlen & 0xff);
digest_update(hash, trailer, sizeof(trailer));
return 1;
}
unsigned
digest_get_prefix(unsigned hashalg, uint8_t *prefix, size_t size)
{
if (prefix == NULL) {
return 0;
}
switch (hashalg) {
case MD5_HASH_ALG:
memcpy(prefix, prefix_md5, sizeof(prefix_md5));
return sizeof(prefix_md5);
case SHA1_HASH_ALG:
memcpy(prefix, prefix_sha1, sizeof(prefix_sha1));
return sizeof(prefix_sha1);
case SHA256_HASH_ALG:
memcpy(prefix, prefix_sha256, sizeof(prefix_sha256));
return sizeof(prefix_sha256);
default:
printf("digest_get_prefix: unknown hash algorithm: %d\n", hashalg);
return 0;
}
}

View File

@@ -0,0 +1,109 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DIGEST_H_
#define DIGEST_H_ 20100108
#include <sys/types.h>
#ifdef _KERNEL
# include <sys/md5.h>
# include <sys/sha1.h>
# include <sys/sha2.h>
# include <sys/rmd160.h>
#else
# include <md5.h>
# include <sha1.h>
# include <sha2.h>
# include <rmd160.h>
# include <inttypes.h>
#endif
#include "tiger.h"
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
#define MD5_HASH_ALG 1
#define SHA1_HASH_ALG 2
#define RIPEMD_HASH_ALG 3
#define TIGER_HASH_ALG 6 /* from rfc2440 */
#define SHA256_HASH_ALG 8
#define SHA384_HASH_ALG 9
#define SHA512_HASH_ALG 10
#define SHA224_HASH_ALG 11
#define TIGER2_HASH_ALG 100 /* private/experimental from rfc4880 */
/* structure to describe digest methods */
typedef struct digest_t {
uint32_t alg; /* algorithm */
size_t size; /* size */
union {
MD5_CTX md5ctx; /* MD5 */
SHA1_CTX sha1ctx; /* SHA1 */
RMD160_CTX rmd160ctx; /* RIPEMD */
SHA256_CTX sha256ctx; /* SHA256 */
SHA512_CTX sha512ctx; /* SHA512 */
TIGER_CTX tigerctx; /* TIGER/TIGER2 */
} u;
void *prefix; /* points to specific prefix */
uint32_t len; /* prefix length */
void *ctx; /* pointer to context array */
} digest_t;
unsigned digest_get_alg(const char */*hashalg*/);
int digest_init(digest_t */*digest*/, const uint32_t /*hashalg*/);
int digest_update(digest_t */*digest*/, const uint8_t */*data*/, size_t /*size*/);
unsigned digest_final(uint8_t */*out*/, digest_t */*digest*/);
int digest_alg_size(unsigned /*alg*/);
int digest_length(digest_t */*hash*/, unsigned /*hashedlen*/);
void MD5_Init(MD5_CTX */*context*/);
void MD5_Update(MD5_CTX */*context*/, const unsigned char */*data*/, unsigned int /*len*/);
void MD5_Final(unsigned char /*digest*/[16], MD5_CTX */*context*/);
void SHA1_Init(SHA1_CTX */*context*/);
void SHA1_Update(SHA1_CTX */*context*/, const unsigned char */*data*/, unsigned int /*len*/);
void SHA1_Final(unsigned char /*digest*/[20], SHA1_CTX */*context*/);
void RMD160_Init(RMD160_CTX */*ctx*/);
void RMD160_Update(RMD160_CTX */*ctx*/, const unsigned char */*data*/, uint32_t /*len*/);
void RMD160_Final(unsigned char /*digest*/[RMD160_DIGEST_LENGTH], RMD160_CTX */*ctx*/);
unsigned digest_get_prefix(unsigned /*hashalg*/, uint8_t */*prefix*/, size_t /*size*/);
__END_DECLS
#endif

View File

@@ -0,0 +1,219 @@
.\" $NetBSD: tiger.3,v 1.3 2013/07/20 21:39:56 wiz Exp $
.\"
.\" Copyright (c) 2011 Alistair Crooks <agc@NetBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd May 30, 2011
.Dt TIGER 3
.Os
.Sh NAME
.Nm TIGER_Init ,
.Nm TIGER_Update ,
.Nm TIGER_Final ,
.Nm TIGER_End ,
.Nm TIGER_File ,
.Nm TIGER_Data
.Nd calculate TIGER message digests
.Sh SYNOPSIS
.In tiger.h
.Ft void
.Fo TIGER_Init
.Fa "TIGER_CTX *context"
.Fc
.Ft void
.Fo TIGER_Update
.Fa "TIGER_CTX *context" "const uint8_t *data" "u_int len"
.Fc
.Ft void
.Fo TIGER_Final
.Fa "uint8_t digest[20]" "TIGER_CTX *context"
.Fc
.Ft "char *"
.Fo TIGER_End
.Fa "TIGER_CTX *context" "char *buf"
.Fc
.Ft "char *"
.Fo TIGER_File
.Fa "char *filename" "char *buf"
.Fc
.Ft "char *"
.Fo TIGER_Data
.Fa "uint8_t *data" "size_t len" "char *buf"
.Fc
.Sh DESCRIPTION
The TIGER functions calculate TIGER message digest functions,
as defined by Ross Anderson and Eli Biham.
The algorithm takes a
message less than 2^64 bits as input and produces a 192-bit digest
suitable for use as a digital signature.
.Pp
At the time of writing,
May 2011,
no attacks or pre-imaging have been discovered against the
.Nm
message digests, whilst the same cannot be said of
.Xr md5 3
or
.Xr sha1 3 .
.Pp
The
.Fn TIGER_Init
function initializes a TIGER_CTX
.Ar context
for use with
.Fn TIGER_Update ,
and
.Fn TIGER_Final .
The
.Fn TIGER_Update
function adds
.Ar data
of length
.Ar len
to the TIGER_CTX specified by
.Ar context .
.Fn TIGER_Final
is called when all data has been added via
.Fn TIGER_Update
and stores a message digest in the
.Ar digest
parameter.
When a
.Dv NULL
pointer is passed to
.Fn TIGER_Final
as first argument only the final padding will be applied and the
current context can still be used with
.Fn TIGER_Update .
.Pp
The core of the TIGER message digest is performed by
.Fn TIGER_Update .
Most programs should use the interface provided by
.Fn TIGER_Init ,
.Fn TIGER_Update ,
and
.Fn TIGER_Final .
.Pp
The
.Fn TIGER_End
function is a front end for
.Fn TIGER_Final
which converts the digest into an
.Tn ASCII
representation of the 160 bit digest in hexadecimal.
.Pp
The
.Fn TIGER_File
function calculates the digest for a file and returns the result via
.Fn TIGER_End .
If
.Fn TIGER_File
is unable to open the file a
.Dv NULL
pointer is returned.
.Pp
The
.Fn TIGER_Data
function
calculates the digest of an arbitrary string and returns the result via
.Fn TIGER_End .
.Pp
For each of the
.Fn TIGER_End ,
.Fn TIGER_File ,
and
.Fn TIGER_Data
functions the
.Ar buf
parameter should either be a string of at least 41 characters in
size or a
.Dv NULL
pointer.
In the latter case, space will be dynamically allocated via
.Xr malloc 3
and should be freed using
.Xr free 3
when it is no longer needed.
.Sh EXAMPLES
The follow code fragment will calculate the digest for the string
"The quick brown fox jumps over the lazy dog"
which is
.Dq 6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075 .
.Bd -literal -offset indent
TIGER_CTX tiger;
uint8_t results[24];
char *buf;
int n;
buf = "The quick brown fox jumps over the lazy dog";
n = strlen(buf);
TIGER_Init(\*[Am]tiger);
TIGER_Update(\*[Am]tiger, (uint8_t *)buf, n);
TIGER_Final(results, \*[Am]tiger);
/* Print the digest as one long hex value */
printf("0x");
for (n = 0; n \*[Lt] 24; n++)
printf("%02x", results[n]);
putchar('\en');
.Ed
.Pp
Alternately, the helper functions could be used in the following way:
.Bd -literal -offset indent
TIGER_CTX tiger;
uint8_t output[49];
char *buf = "The quick brown fox jumps over the lazy dog";
printf("0x%s", TIGER_Data(buf, strlen(buf), output));
.Ed
.Sh SEE ALSO
.Xr md5 3 ,
.Xr sha1 3
.Pp
.Rs
.%A Ross Anderson
.%A Eli Biham
.%T "Tiger - A Fast New Hash Function"
.%B Proceedings of Fast Software Encryption 3, Cambridge
.%D 1996
.Re
.Sh HISTORY
The TIGER functions appeared in
.Nx 6.0 .
.Sh AUTHORS
.An -nosplit
This implementation of TIGER was adapted by
.An Alistair Crooks Aq Mt agc@NetBSD.org
from the original reference code.
.Pp
The
.Fn TIGER_End ,
.Fn TIGER_File ,
and
.Fn TIGER_Data
helper functions are derived from code written by Poul-Henning Kamp.
.Sh BUGS
All attempts have bene made to optimise for the underlying hardware,
as well as to format the digest properly in an endian-neutral manner.
The author has no VAX hardware on which to test, and so it is not known
whether that platform is supported.

View File

@@ -0,0 +1,906 @@
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tiger.h"
#ifndef IS_LITTLE_ENDIAN
#define IS_LITTLE_ENDIAN(x) (*(char *)(void *)&x)
#define IS_BIG_ENDIAN(x) !(*(char *)(void *)&x)
#endif
#define BSWAP64(x) ((((x) & 0xffULL) << 56) | \
(((x) & 0xff00ULL) << 40) | \
(((x) & 0xff0000ULL) << 24) | \
(((x) & 0xff000000ULL) << 8) | \
(((x) & 0xff00000000ULL) >> 8) | \
(((x) & 0xff0000000000ULL) >> 24) | \
(((x) & 0xff000000000000ULL) >> 40) | \
(((x) & 0xff00000000000000ULL) >> 56))
/* sboxes.c: Tiger S boxes */
static uint64_t table[4*256] = {
0x02AAB17CF7E90C5ELL /* 0 */, 0xAC424B03E243A8ECLL /* 1 */,
0x72CD5BE30DD5FCD3LL /* 2 */, 0x6D019B93F6F97F3ALL /* 3 */,
0xCD9978FFD21F9193LL /* 4 */, 0x7573A1C9708029E2LL /* 5 */,
0xB164326B922A83C3LL /* 6 */, 0x46883EEE04915870LL /* 7 */,
0xEAACE3057103ECE6LL /* 8 */, 0xC54169B808A3535CLL /* 9 */,
0x4CE754918DDEC47CLL /* 10 */, 0x0AA2F4DFDC0DF40CLL /* 11 */,
0x10B76F18A74DBEFALL /* 12 */, 0xC6CCB6235AD1AB6ALL /* 13 */,
0x13726121572FE2FFLL /* 14 */, 0x1A488C6F199D921ELL /* 15 */,
0x4BC9F9F4DA0007CALL /* 16 */, 0x26F5E6F6E85241C7LL /* 17 */,
0x859079DBEA5947B6LL /* 18 */, 0x4F1885C5C99E8C92LL /* 19 */,
0xD78E761EA96F864BLL /* 20 */, 0x8E36428C52B5C17DLL /* 21 */,
0x69CF6827373063C1LL /* 22 */, 0xB607C93D9BB4C56ELL /* 23 */,
0x7D820E760E76B5EALL /* 24 */, 0x645C9CC6F07FDC42LL /* 25 */,
0xBF38A078243342E0LL /* 26 */, 0x5F6B343C9D2E7D04LL /* 27 */,
0xF2C28AEB600B0EC6LL /* 28 */, 0x6C0ED85F7254BCACLL /* 29 */,
0x71592281A4DB4FE5LL /* 30 */, 0x1967FA69CE0FED9FLL /* 31 */,
0xFD5293F8B96545DBLL /* 32 */, 0xC879E9D7F2A7600BLL /* 33 */,
0x860248920193194ELL /* 34 */, 0xA4F9533B2D9CC0B3LL /* 35 */,
0x9053836C15957613LL /* 36 */, 0xDB6DCF8AFC357BF1LL /* 37 */,
0x18BEEA7A7A370F57LL /* 38 */, 0x037117CA50B99066LL /* 39 */,
0x6AB30A9774424A35LL /* 40 */, 0xF4E92F02E325249BLL /* 41 */,
0x7739DB07061CCAE1LL /* 42 */, 0xD8F3B49CECA42A05LL /* 43 */,
0xBD56BE3F51382F73LL /* 44 */, 0x45FAED5843B0BB28LL /* 45 */,
0x1C813D5C11BF1F83LL /* 46 */, 0x8AF0E4B6D75FA169LL /* 47 */,
0x33EE18A487AD9999LL /* 48 */, 0x3C26E8EAB1C94410LL /* 49 */,
0xB510102BC0A822F9LL /* 50 */, 0x141EEF310CE6123BLL /* 51 */,
0xFC65B90059DDB154LL /* 52 */, 0xE0158640C5E0E607LL /* 53 */,
0x884E079826C3A3CFLL /* 54 */, 0x930D0D9523C535FDLL /* 55 */,
0x35638D754E9A2B00LL /* 56 */, 0x4085FCCF40469DD5LL /* 57 */,
0xC4B17AD28BE23A4CLL /* 58 */, 0xCAB2F0FC6A3E6A2ELL /* 59 */,
0x2860971A6B943FCDLL /* 60 */, 0x3DDE6EE212E30446LL /* 61 */,
0x6222F32AE01765AELL /* 62 */, 0x5D550BB5478308FELL /* 63 */,
0xA9EFA98DA0EDA22ALL /* 64 */, 0xC351A71686C40DA7LL /* 65 */,
0x1105586D9C867C84LL /* 66 */, 0xDCFFEE85FDA22853LL /* 67 */,
0xCCFBD0262C5EEF76LL /* 68 */, 0xBAF294CB8990D201LL /* 69 */,
0xE69464F52AFAD975LL /* 70 */, 0x94B013AFDF133E14LL /* 71 */,
0x06A7D1A32823C958LL /* 72 */, 0x6F95FE5130F61119LL /* 73 */,
0xD92AB34E462C06C0LL /* 74 */, 0xED7BDE33887C71D2LL /* 75 */,
0x79746D6E6518393ELL /* 76 */, 0x5BA419385D713329LL /* 77 */,
0x7C1BA6B948A97564LL /* 78 */, 0x31987C197BFDAC67LL /* 79 */,
0xDE6C23C44B053D02LL /* 80 */, 0x581C49FED002D64DLL /* 81 */,
0xDD474D6338261571LL /* 82 */, 0xAA4546C3E473D062LL /* 83 */,
0x928FCE349455F860LL /* 84 */, 0x48161BBACAAB94D9LL /* 85 */,
0x63912430770E6F68LL /* 86 */, 0x6EC8A5E602C6641CLL /* 87 */,
0x87282515337DDD2BLL /* 88 */, 0x2CDA6B42034B701BLL /* 89 */,
0xB03D37C181CB096DLL /* 90 */, 0xE108438266C71C6FLL /* 91 */,
0x2B3180C7EB51B255LL /* 92 */, 0xDF92B82F96C08BBCLL /* 93 */,
0x5C68C8C0A632F3BALL /* 94 */, 0x5504CC861C3D0556LL /* 95 */,
0xABBFA4E55FB26B8FLL /* 96 */, 0x41848B0AB3BACEB4LL /* 97 */,
0xB334A273AA445D32LL /* 98 */, 0xBCA696F0A85AD881LL /* 99 */,
0x24F6EC65B528D56CLL /* 100 */, 0x0CE1512E90F4524ALL /* 101 */,
0x4E9DD79D5506D35ALL /* 102 */, 0x258905FAC6CE9779LL /* 103 */,
0x2019295B3E109B33LL /* 104 */, 0xF8A9478B73A054CCLL /* 105 */,
0x2924F2F934417EB0LL /* 106 */, 0x3993357D536D1BC4LL /* 107 */,
0x38A81AC21DB6FF8BLL /* 108 */, 0x47C4FBF17D6016BFLL /* 109 */,
0x1E0FAADD7667E3F5LL /* 110 */, 0x7ABCFF62938BEB96LL /* 111 */,
0xA78DAD948FC179C9LL /* 112 */, 0x8F1F98B72911E50DLL /* 113 */,
0x61E48EAE27121A91LL /* 114 */, 0x4D62F7AD31859808LL /* 115 */,
0xECEBA345EF5CEAEBLL /* 116 */, 0xF5CEB25EBC9684CELL /* 117 */,
0xF633E20CB7F76221LL /* 118 */, 0xA32CDF06AB8293E4LL /* 119 */,
0x985A202CA5EE2CA4LL /* 120 */, 0xCF0B8447CC8A8FB1LL /* 121 */,
0x9F765244979859A3LL /* 122 */, 0xA8D516B1A1240017LL /* 123 */,
0x0BD7BA3EBB5DC726LL /* 124 */, 0xE54BCA55B86ADB39LL /* 125 */,
0x1D7A3AFD6C478063LL /* 126 */, 0x519EC608E7669EDDLL /* 127 */,
0x0E5715A2D149AA23LL /* 128 */, 0x177D4571848FF194LL /* 129 */,
0xEEB55F3241014C22LL /* 130 */, 0x0F5E5CA13A6E2EC2LL /* 131 */,
0x8029927B75F5C361LL /* 132 */, 0xAD139FABC3D6E436LL /* 133 */,
0x0D5DF1A94CCF402FLL /* 134 */, 0x3E8BD948BEA5DFC8LL /* 135 */,
0xA5A0D357BD3FF77ELL /* 136 */, 0xA2D12E251F74F645LL /* 137 */,
0x66FD9E525E81A082LL /* 138 */, 0x2E0C90CE7F687A49LL /* 139 */,
0xC2E8BCBEBA973BC5LL /* 140 */, 0x000001BCE509745FLL /* 141 */,
0x423777BBE6DAB3D6LL /* 142 */, 0xD1661C7EAEF06EB5LL /* 143 */,
0xA1781F354DAACFD8LL /* 144 */, 0x2D11284A2B16AFFCLL /* 145 */,
0xF1FC4F67FA891D1FLL /* 146 */, 0x73ECC25DCB920ADALL /* 147 */,
0xAE610C22C2A12651LL /* 148 */, 0x96E0A810D356B78ALL /* 149 */,
0x5A9A381F2FE7870FLL /* 150 */, 0xD5AD62EDE94E5530LL /* 151 */,
0xD225E5E8368D1427LL /* 152 */, 0x65977B70C7AF4631LL /* 153 */,
0x99F889B2DE39D74FLL /* 154 */, 0x233F30BF54E1D143LL /* 155 */,
0x9A9675D3D9A63C97LL /* 156 */, 0x5470554FF334F9A8LL /* 157 */,
0x166ACB744A4F5688LL /* 158 */, 0x70C74CAAB2E4AEADLL /* 159 */,
0xF0D091646F294D12LL /* 160 */, 0x57B82A89684031D1LL /* 161 */,
0xEFD95A5A61BE0B6BLL /* 162 */, 0x2FBD12E969F2F29ALL /* 163 */,
0x9BD37013FEFF9FE8LL /* 164 */, 0x3F9B0404D6085A06LL /* 165 */,
0x4940C1F3166CFE15LL /* 166 */, 0x09542C4DCDF3DEFBLL /* 167 */,
0xB4C5218385CD5CE3LL /* 168 */, 0xC935B7DC4462A641LL /* 169 */,
0x3417F8A68ED3B63FLL /* 170 */, 0xB80959295B215B40LL /* 171 */,
0xF99CDAEF3B8C8572LL /* 172 */, 0x018C0614F8FCB95DLL /* 173 */,
0x1B14ACCD1A3ACDF3LL /* 174 */, 0x84D471F200BB732DLL /* 175 */,
0xC1A3110E95E8DA16LL /* 176 */, 0x430A7220BF1A82B8LL /* 177 */,
0xB77E090D39DF210ELL /* 178 */, 0x5EF4BD9F3CD05E9DLL /* 179 */,
0x9D4FF6DA7E57A444LL /* 180 */, 0xDA1D60E183D4A5F8LL /* 181 */,
0xB287C38417998E47LL /* 182 */, 0xFE3EDC121BB31886LL /* 183 */,
0xC7FE3CCC980CCBEFLL /* 184 */, 0xE46FB590189BFD03LL /* 185 */,
0x3732FD469A4C57DCLL /* 186 */, 0x7EF700A07CF1AD65LL /* 187 */,
0x59C64468A31D8859LL /* 188 */, 0x762FB0B4D45B61F6LL /* 189 */,
0x155BAED099047718LL /* 190 */, 0x68755E4C3D50BAA6LL /* 191 */,
0xE9214E7F22D8B4DFLL /* 192 */, 0x2ADDBF532EAC95F4LL /* 193 */,
0x32AE3909B4BD0109LL /* 194 */, 0x834DF537B08E3450LL /* 195 */,
0xFA209DA84220728DLL /* 196 */, 0x9E691D9B9EFE23F7LL /* 197 */,
0x0446D288C4AE8D7FLL /* 198 */, 0x7B4CC524E169785BLL /* 199 */,
0x21D87F0135CA1385LL /* 200 */, 0xCEBB400F137B8AA5LL /* 201 */,
0x272E2B66580796BELL /* 202 */, 0x3612264125C2B0DELL /* 203 */,
0x057702BDAD1EFBB2LL /* 204 */, 0xD4BABB8EACF84BE9LL /* 205 */,
0x91583139641BC67BLL /* 206 */, 0x8BDC2DE08036E024LL /* 207 */,
0x603C8156F49F68EDLL /* 208 */, 0xF7D236F7DBEF5111LL /* 209 */,
0x9727C4598AD21E80LL /* 210 */, 0xA08A0896670A5FD7LL /* 211 */,
0xCB4A8F4309EBA9CBLL /* 212 */, 0x81AF564B0F7036A1LL /* 213 */,
0xC0B99AA778199ABDLL /* 214 */, 0x959F1EC83FC8E952LL /* 215 */,
0x8C505077794A81B9LL /* 216 */, 0x3ACAAF8F056338F0LL /* 217 */,
0x07B43F50627A6778LL /* 218 */, 0x4A44AB49F5ECCC77LL /* 219 */,
0x3BC3D6E4B679EE98LL /* 220 */, 0x9CC0D4D1CF14108CLL /* 221 */,
0x4406C00B206BC8A0LL /* 222 */, 0x82A18854C8D72D89LL /* 223 */,
0x67E366B35C3C432CLL /* 224 */, 0xB923DD61102B37F2LL /* 225 */,
0x56AB2779D884271DLL /* 226 */, 0xBE83E1B0FF1525AFLL /* 227 */,
0xFB7C65D4217E49A9LL /* 228 */, 0x6BDBE0E76D48E7D4LL /* 229 */,
0x08DF828745D9179ELL /* 230 */, 0x22EA6A9ADD53BD34LL /* 231 */,
0xE36E141C5622200ALL /* 232 */, 0x7F805D1B8CB750EELL /* 233 */,
0xAFE5C7A59F58E837LL /* 234 */, 0xE27F996A4FB1C23CLL /* 235 */,
0xD3867DFB0775F0D0LL /* 236 */, 0xD0E673DE6E88891ALL /* 237 */,
0x123AEB9EAFB86C25LL /* 238 */, 0x30F1D5D5C145B895LL /* 239 */,
0xBB434A2DEE7269E7LL /* 240 */, 0x78CB67ECF931FA38LL /* 241 */,
0xF33B0372323BBF9CLL /* 242 */, 0x52D66336FB279C74LL /* 243 */,
0x505F33AC0AFB4EAALL /* 244 */, 0xE8A5CD99A2CCE187LL /* 245 */,
0x534974801E2D30BBLL /* 246 */, 0x8D2D5711D5876D90LL /* 247 */,
0x1F1A412891BC038ELL /* 248 */, 0xD6E2E71D82E56648LL /* 249 */,
0x74036C3A497732B7LL /* 250 */, 0x89B67ED96361F5ABLL /* 251 */,
0xFFED95D8F1EA02A2LL /* 252 */, 0xE72B3BD61464D43DLL /* 253 */,
0xA6300F170BDC4820LL /* 254 */, 0xEBC18760ED78A77ALL /* 255 */,
0xE6A6BE5A05A12138LL /* 256 */, 0xB5A122A5B4F87C98LL /* 257 */,
0x563C6089140B6990LL /* 258 */, 0x4C46CB2E391F5DD5LL /* 259 */,
0xD932ADDBC9B79434LL /* 260 */, 0x08EA70E42015AFF5LL /* 261 */,
0xD765A6673E478CF1LL /* 262 */, 0xC4FB757EAB278D99LL /* 263 */,
0xDF11C6862D6E0692LL /* 264 */, 0xDDEB84F10D7F3B16LL /* 265 */,
0x6F2EF604A665EA04LL /* 266 */, 0x4A8E0F0FF0E0DFB3LL /* 267 */,
0xA5EDEEF83DBCBA51LL /* 268 */, 0xFC4F0A2A0EA4371ELL /* 269 */,
0xE83E1DA85CB38429LL /* 270 */, 0xDC8FF882BA1B1CE2LL /* 271 */,
0xCD45505E8353E80DLL /* 272 */, 0x18D19A00D4DB0717LL /* 273 */,
0x34A0CFEDA5F38101LL /* 274 */, 0x0BE77E518887CAF2LL /* 275 */,
0x1E341438B3C45136LL /* 276 */, 0xE05797F49089CCF9LL /* 277 */,
0xFFD23F9DF2591D14LL /* 278 */, 0x543DDA228595C5CDLL /* 279 */,
0x661F81FD99052A33LL /* 280 */, 0x8736E641DB0F7B76LL /* 281 */,
0x15227725418E5307LL /* 282 */, 0xE25F7F46162EB2FALL /* 283 */,
0x48A8B2126C13D9FELL /* 284 */, 0xAFDC541792E76EEALL /* 285 */,
0x03D912BFC6D1898FLL /* 286 */, 0x31B1AAFA1B83F51BLL /* 287 */,
0xF1AC2796E42AB7D9LL /* 288 */, 0x40A3A7D7FCD2EBACLL /* 289 */,
0x1056136D0AFBBCC5LL /* 290 */, 0x7889E1DD9A6D0C85LL /* 291 */,
0xD33525782A7974AALL /* 292 */, 0xA7E25D09078AC09BLL /* 293 */,
0xBD4138B3EAC6EDD0LL /* 294 */, 0x920ABFBE71EB9E70LL /* 295 */,
0xA2A5D0F54FC2625CLL /* 296 */, 0xC054E36B0B1290A3LL /* 297 */,
0xF6DD59FF62FE932BLL /* 298 */, 0x3537354511A8AC7DLL /* 299 */,
0xCA845E9172FADCD4LL /* 300 */, 0x84F82B60329D20DCLL /* 301 */,
0x79C62CE1CD672F18LL /* 302 */, 0x8B09A2ADD124642CLL /* 303 */,
0xD0C1E96A19D9E726LL /* 304 */, 0x5A786A9B4BA9500CLL /* 305 */,
0x0E020336634C43F3LL /* 306 */, 0xC17B474AEB66D822LL /* 307 */,
0x6A731AE3EC9BAAC2LL /* 308 */, 0x8226667AE0840258LL /* 309 */,
0x67D4567691CAECA5LL /* 310 */, 0x1D94155C4875ADB5LL /* 311 */,
0x6D00FD985B813FDFLL /* 312 */, 0x51286EFCB774CD06LL /* 313 */,
0x5E8834471FA744AFLL /* 314 */, 0xF72CA0AEE761AE2ELL /* 315 */,
0xBE40E4CDAEE8E09ALL /* 316 */, 0xE9970BBB5118F665LL /* 317 */,
0x726E4BEB33DF1964LL /* 318 */, 0x703B000729199762LL /* 319 */,
0x4631D816F5EF30A7LL /* 320 */, 0xB880B5B51504A6BELL /* 321 */,
0x641793C37ED84B6CLL /* 322 */, 0x7B21ED77F6E97D96LL /* 323 */,
0x776306312EF96B73LL /* 324 */, 0xAE528948E86FF3F4LL /* 325 */,
0x53DBD7F286A3F8F8LL /* 326 */, 0x16CADCE74CFC1063LL /* 327 */,
0x005C19BDFA52C6DDLL /* 328 */, 0x68868F5D64D46AD3LL /* 329 */,
0x3A9D512CCF1E186ALL /* 330 */, 0x367E62C2385660AELL /* 331 */,
0xE359E7EA77DCB1D7LL /* 332 */, 0x526C0773749ABE6ELL /* 333 */,
0x735AE5F9D09F734BLL /* 334 */, 0x493FC7CC8A558BA8LL /* 335 */,
0xB0B9C1533041AB45LL /* 336 */, 0x321958BA470A59BDLL /* 337 */,
0x852DB00B5F46C393LL /* 338 */, 0x91209B2BD336B0E5LL /* 339 */,
0x6E604F7D659EF19FLL /* 340 */, 0xB99A8AE2782CCB24LL /* 341 */,
0xCCF52AB6C814C4C7LL /* 342 */, 0x4727D9AFBE11727BLL /* 343 */,
0x7E950D0C0121B34DLL /* 344 */, 0x756F435670AD471FLL /* 345 */,
0xF5ADD442615A6849LL /* 346 */, 0x4E87E09980B9957ALL /* 347 */,
0x2ACFA1DF50AEE355LL /* 348 */, 0xD898263AFD2FD556LL /* 349 */,
0xC8F4924DD80C8FD6LL /* 350 */, 0xCF99CA3D754A173ALL /* 351 */,
0xFE477BACAF91BF3CLL /* 352 */, 0xED5371F6D690C12DLL /* 353 */,
0x831A5C285E687094LL /* 354 */, 0xC5D3C90A3708A0A4LL /* 355 */,
0x0F7F903717D06580LL /* 356 */, 0x19F9BB13B8FDF27FLL /* 357 */,
0xB1BD6F1B4D502843LL /* 358 */, 0x1C761BA38FFF4012LL /* 359 */,
0x0D1530C4E2E21F3BLL /* 360 */, 0x8943CE69A7372C8ALL /* 361 */,
0xE5184E11FEB5CE66LL /* 362 */, 0x618BDB80BD736621LL /* 363 */,
0x7D29BAD68B574D0BLL /* 364 */, 0x81BB613E25E6FE5BLL /* 365 */,
0x071C9C10BC07913FLL /* 366 */, 0xC7BEEB7909AC2D97LL /* 367 */,
0xC3E58D353BC5D757LL /* 368 */, 0xEB017892F38F61E8LL /* 369 */,
0xD4EFFB9C9B1CC21ALL /* 370 */, 0x99727D26F494F7ABLL /* 371 */,
0xA3E063A2956B3E03LL /* 372 */, 0x9D4A8B9A4AA09C30LL /* 373 */,
0x3F6AB7D500090FB4LL /* 374 */, 0x9CC0F2A057268AC0LL /* 375 */,
0x3DEE9D2DEDBF42D1LL /* 376 */, 0x330F49C87960A972LL /* 377 */,
0xC6B2720287421B41LL /* 378 */, 0x0AC59EC07C00369CLL /* 379 */,
0xEF4EAC49CB353425LL /* 380 */, 0xF450244EEF0129D8LL /* 381 */,
0x8ACC46E5CAF4DEB6LL /* 382 */, 0x2FFEAB63989263F7LL /* 383 */,
0x8F7CB9FE5D7A4578LL /* 384 */, 0x5BD8F7644E634635LL /* 385 */,
0x427A7315BF2DC900LL /* 386 */, 0x17D0C4AA2125261CLL /* 387 */,
0x3992486C93518E50LL /* 388 */, 0xB4CBFEE0A2D7D4C3LL /* 389 */,
0x7C75D6202C5DDD8DLL /* 390 */, 0xDBC295D8E35B6C61LL /* 391 */,
0x60B369D302032B19LL /* 392 */, 0xCE42685FDCE44132LL /* 393 */,
0x06F3DDB9DDF65610LL /* 394 */, 0x8EA4D21DB5E148F0LL /* 395 */,
0x20B0FCE62FCD496FLL /* 396 */, 0x2C1B912358B0EE31LL /* 397 */,
0xB28317B818F5A308LL /* 398 */, 0xA89C1E189CA6D2CFLL /* 399 */,
0x0C6B18576AAADBC8LL /* 400 */, 0xB65DEAA91299FAE3LL /* 401 */,
0xFB2B794B7F1027E7LL /* 402 */, 0x04E4317F443B5BEBLL /* 403 */,
0x4B852D325939D0A6LL /* 404 */, 0xD5AE6BEEFB207FFCLL /* 405 */,
0x309682B281C7D374LL /* 406 */, 0xBAE309A194C3B475LL /* 407 */,
0x8CC3F97B13B49F05LL /* 408 */, 0x98A9422FF8293967LL /* 409 */,
0x244B16B01076FF7CLL /* 410 */, 0xF8BF571C663D67EELL /* 411 */,
0x1F0D6758EEE30DA1LL /* 412 */, 0xC9B611D97ADEB9B7LL /* 413 */,
0xB7AFD5887B6C57A2LL /* 414 */, 0x6290AE846B984FE1LL /* 415 */,
0x94DF4CDEACC1A5FDLL /* 416 */, 0x058A5BD1C5483AFFLL /* 417 */,
0x63166CC142BA3C37LL /* 418 */, 0x8DB8526EB2F76F40LL /* 419 */,
0xE10880036F0D6D4ELL /* 420 */, 0x9E0523C9971D311DLL /* 421 */,
0x45EC2824CC7CD691LL /* 422 */, 0x575B8359E62382C9LL /* 423 */,
0xFA9E400DC4889995LL /* 424 */, 0xD1823ECB45721568LL /* 425 */,
0xDAFD983B8206082FLL /* 426 */, 0xAA7D29082386A8CBLL /* 427 */,
0x269FCD4403B87588LL /* 428 */, 0x1B91F5F728BDD1E0LL /* 429 */,
0xE4669F39040201F6LL /* 430 */, 0x7A1D7C218CF04ADELL /* 431 */,
0x65623C29D79CE5CELL /* 432 */, 0x2368449096C00BB1LL /* 433 */,
0xAB9BF1879DA503BALL /* 434 */, 0xBC23ECB1A458058ELL /* 435 */,
0x9A58DF01BB401ECCLL /* 436 */, 0xA070E868A85F143DLL /* 437 */,
0x4FF188307DF2239ELL /* 438 */, 0x14D565B41A641183LL /* 439 */,
0xEE13337452701602LL /* 440 */, 0x950E3DCF3F285E09LL /* 441 */,
0x59930254B9C80953LL /* 442 */, 0x3BF299408930DA6DLL /* 443 */,
0xA955943F53691387LL /* 444 */, 0xA15EDECAA9CB8784LL /* 445 */,
0x29142127352BE9A0LL /* 446 */, 0x76F0371FFF4E7AFBLL /* 447 */,
0x0239F450274F2228LL /* 448 */, 0xBB073AF01D5E868BLL /* 449 */,
0xBFC80571C10E96C1LL /* 450 */, 0xD267088568222E23LL /* 451 */,
0x9671A3D48E80B5B0LL /* 452 */, 0x55B5D38AE193BB81LL /* 453 */,
0x693AE2D0A18B04B8LL /* 454 */, 0x5C48B4ECADD5335FLL /* 455 */,
0xFD743B194916A1CALL /* 456 */, 0x2577018134BE98C4LL /* 457 */,
0xE77987E83C54A4ADLL /* 458 */, 0x28E11014DA33E1B9LL /* 459 */,
0x270CC59E226AA213LL /* 460 */, 0x71495F756D1A5F60LL /* 461 */,
0x9BE853FB60AFEF77LL /* 462 */, 0xADC786A7F7443DBFLL /* 463 */,
0x0904456173B29A82LL /* 464 */, 0x58BC7A66C232BD5ELL /* 465 */,
0xF306558C673AC8B2LL /* 466 */, 0x41F639C6B6C9772ALL /* 467 */,
0x216DEFE99FDA35DALL /* 468 */, 0x11640CC71C7BE615LL /* 469 */,
0x93C43694565C5527LL /* 470 */, 0xEA038E6246777839LL /* 471 */,
0xF9ABF3CE5A3E2469LL /* 472 */, 0x741E768D0FD312D2LL /* 473 */,
0x0144B883CED652C6LL /* 474 */, 0xC20B5A5BA33F8552LL /* 475 */,
0x1AE69633C3435A9DLL /* 476 */, 0x97A28CA4088CFDECLL /* 477 */,
0x8824A43C1E96F420LL /* 478 */, 0x37612FA66EEEA746LL /* 479 */,
0x6B4CB165F9CF0E5ALL /* 480 */, 0x43AA1C06A0ABFB4ALL /* 481 */,
0x7F4DC26FF162796BLL /* 482 */, 0x6CBACC8E54ED9B0FLL /* 483 */,
0xA6B7FFEFD2BB253ELL /* 484 */, 0x2E25BC95B0A29D4FLL /* 485 */,
0x86D6A58BDEF1388CLL /* 486 */, 0xDED74AC576B6F054LL /* 487 */,
0x8030BDBC2B45805DLL /* 488 */, 0x3C81AF70E94D9289LL /* 489 */,
0x3EFF6DDA9E3100DBLL /* 490 */, 0xB38DC39FDFCC8847LL /* 491 */,
0x123885528D17B87ELL /* 492 */, 0xF2DA0ED240B1B642LL /* 493 */,
0x44CEFADCD54BF9A9LL /* 494 */, 0x1312200E433C7EE6LL /* 495 */,
0x9FFCC84F3A78C748LL /* 496 */, 0xF0CD1F72248576BBLL /* 497 */,
0xEC6974053638CFE4LL /* 498 */, 0x2BA7B67C0CEC4E4CLL /* 499 */,
0xAC2F4DF3E5CE32EDLL /* 500 */, 0xCB33D14326EA4C11LL /* 501 */,
0xA4E9044CC77E58BCLL /* 502 */, 0x5F513293D934FCEFLL /* 503 */,
0x5DC9645506E55444LL /* 504 */, 0x50DE418F317DE40ALL /* 505 */,
0x388CB31A69DDE259LL /* 506 */, 0x2DB4A83455820A86LL /* 507 */,
0x9010A91E84711AE9LL /* 508 */, 0x4DF7F0B7B1498371LL /* 509 */,
0xD62A2EABC0977179LL /* 510 */, 0x22FAC097AA8D5C0ELL /* 511 */,
0xF49FCC2FF1DAF39BLL /* 512 */, 0x487FD5C66FF29281LL /* 513 */,
0xE8A30667FCDCA83FLL /* 514 */, 0x2C9B4BE3D2FCCE63LL /* 515 */,
0xDA3FF74B93FBBBC2LL /* 516 */, 0x2FA165D2FE70BA66LL /* 517 */,
0xA103E279970E93D4LL /* 518 */, 0xBECDEC77B0E45E71LL /* 519 */,
0xCFB41E723985E497LL /* 520 */, 0xB70AAA025EF75017LL /* 521 */,
0xD42309F03840B8E0LL /* 522 */, 0x8EFC1AD035898579LL /* 523 */,
0x96C6920BE2B2ABC5LL /* 524 */, 0x66AF4163375A9172LL /* 525 */,
0x2174ABDCCA7127FBLL /* 526 */, 0xB33CCEA64A72FF41LL /* 527 */,
0xF04A4933083066A5LL /* 528 */, 0x8D970ACDD7289AF5LL /* 529 */,
0x8F96E8E031C8C25ELL /* 530 */, 0xF3FEC02276875D47LL /* 531 */,
0xEC7BF310056190DDLL /* 532 */, 0xF5ADB0AEBB0F1491LL /* 533 */,
0x9B50F8850FD58892LL /* 534 */, 0x4975488358B74DE8LL /* 535 */,
0xA3354FF691531C61LL /* 536 */, 0x0702BBE481D2C6EELL /* 537 */,
0x89FB24057DEDED98LL /* 538 */, 0xAC3075138596E902LL /* 539 */,
0x1D2D3580172772EDLL /* 540 */, 0xEB738FC28E6BC30DLL /* 541 */,
0x5854EF8F63044326LL /* 542 */, 0x9E5C52325ADD3BBELL /* 543 */,
0x90AA53CF325C4623LL /* 544 */, 0xC1D24D51349DD067LL /* 545 */,
0x2051CFEEA69EA624LL /* 546 */, 0x13220F0A862E7E4FLL /* 547 */,
0xCE39399404E04864LL /* 548 */, 0xD9C42CA47086FCB7LL /* 549 */,
0x685AD2238A03E7CCLL /* 550 */, 0x066484B2AB2FF1DBLL /* 551 */,
0xFE9D5D70EFBF79ECLL /* 552 */, 0x5B13B9DD9C481854LL /* 553 */,
0x15F0D475ED1509ADLL /* 554 */, 0x0BEBCD060EC79851LL /* 555 */,
0xD58C6791183AB7F8LL /* 556 */, 0xD1187C5052F3EEE4LL /* 557 */,
0xC95D1192E54E82FFLL /* 558 */, 0x86EEA14CB9AC6CA2LL /* 559 */,
0x3485BEB153677D5DLL /* 560 */, 0xDD191D781F8C492ALL /* 561 */,
0xF60866BAA784EBF9LL /* 562 */, 0x518F643BA2D08C74LL /* 563 */,
0x8852E956E1087C22LL /* 564 */, 0xA768CB8DC410AE8DLL /* 565 */,
0x38047726BFEC8E1ALL /* 566 */, 0xA67738B4CD3B45AALL /* 567 */,
0xAD16691CEC0DDE19LL /* 568 */, 0xC6D4319380462E07LL /* 569 */,
0xC5A5876D0BA61938LL /* 570 */, 0x16B9FA1FA58FD840LL /* 571 */,
0x188AB1173CA74F18LL /* 572 */, 0xABDA2F98C99C021FLL /* 573 */,
0x3E0580AB134AE816LL /* 574 */, 0x5F3B05B773645ABBLL /* 575 */,
0x2501A2BE5575F2F6LL /* 576 */, 0x1B2F74004E7E8BA9LL /* 577 */,
0x1CD7580371E8D953LL /* 578 */, 0x7F6ED89562764E30LL /* 579 */,
0xB15926FF596F003DLL /* 580 */, 0x9F65293DA8C5D6B9LL /* 581 */,
0x6ECEF04DD690F84CLL /* 582 */, 0x4782275FFF33AF88LL /* 583 */,
0xE41433083F820801LL /* 584 */, 0xFD0DFE409A1AF9B5LL /* 585 */,
0x4325A3342CDB396BLL /* 586 */, 0x8AE77E62B301B252LL /* 587 */,
0xC36F9E9F6655615ALL /* 588 */, 0x85455A2D92D32C09LL /* 589 */,
0xF2C7DEA949477485LL /* 590 */, 0x63CFB4C133A39EBALL /* 591 */,
0x83B040CC6EBC5462LL /* 592 */, 0x3B9454C8FDB326B0LL /* 593 */,
0x56F56A9E87FFD78CLL /* 594 */, 0x2DC2940D99F42BC6LL /* 595 */,
0x98F7DF096B096E2DLL /* 596 */, 0x19A6E01E3AD852BFLL /* 597 */,
0x42A99CCBDBD4B40BLL /* 598 */, 0xA59998AF45E9C559LL /* 599 */,
0x366295E807D93186LL /* 600 */, 0x6B48181BFAA1F773LL /* 601 */,
0x1FEC57E2157A0A1DLL /* 602 */, 0x4667446AF6201AD5LL /* 603 */,
0xE615EBCACFB0F075LL /* 604 */, 0xB8F31F4F68290778LL /* 605 */,
0x22713ED6CE22D11ELL /* 606 */, 0x3057C1A72EC3C93BLL /* 607 */,
0xCB46ACC37C3F1F2FLL /* 608 */, 0xDBB893FD02AAF50ELL /* 609 */,
0x331FD92E600B9FCFLL /* 610 */, 0xA498F96148EA3AD6LL /* 611 */,
0xA8D8426E8B6A83EALL /* 612 */, 0xA089B274B7735CDCLL /* 613 */,
0x87F6B3731E524A11LL /* 614 */, 0x118808E5CBC96749LL /* 615 */,
0x9906E4C7B19BD394LL /* 616 */, 0xAFED7F7E9B24A20CLL /* 617 */,
0x6509EADEEB3644A7LL /* 618 */, 0x6C1EF1D3E8EF0EDELL /* 619 */,
0xB9C97D43E9798FB4LL /* 620 */, 0xA2F2D784740C28A3LL /* 621 */,
0x7B8496476197566FLL /* 622 */, 0x7A5BE3E6B65F069DLL /* 623 */,
0xF96330ED78BE6F10LL /* 624 */, 0xEEE60DE77A076A15LL /* 625 */,
0x2B4BEE4AA08B9BD0LL /* 626 */, 0x6A56A63EC7B8894ELL /* 627 */,
0x02121359BA34FEF4LL /* 628 */, 0x4CBF99F8283703FCLL /* 629 */,
0x398071350CAF30C8LL /* 630 */, 0xD0A77A89F017687ALL /* 631 */,
0xF1C1A9EB9E423569LL /* 632 */, 0x8C7976282DEE8199LL /* 633 */,
0x5D1737A5DD1F7ABDLL /* 634 */, 0x4F53433C09A9FA80LL /* 635 */,
0xFA8B0C53DF7CA1D9LL /* 636 */, 0x3FD9DCBC886CCB77LL /* 637 */,
0xC040917CA91B4720LL /* 638 */, 0x7DD00142F9D1DCDFLL /* 639 */,
0x8476FC1D4F387B58LL /* 640 */, 0x23F8E7C5F3316503LL /* 641 */,
0x032A2244E7E37339LL /* 642 */, 0x5C87A5D750F5A74BLL /* 643 */,
0x082B4CC43698992ELL /* 644 */, 0xDF917BECB858F63CLL /* 645 */,
0x3270B8FC5BF86DDALL /* 646 */, 0x10AE72BB29B5DD76LL /* 647 */,
0x576AC94E7700362BLL /* 648 */, 0x1AD112DAC61EFB8FLL /* 649 */,
0x691BC30EC5FAA427LL /* 650 */, 0xFF246311CC327143LL /* 651 */,
0x3142368E30E53206LL /* 652 */, 0x71380E31E02CA396LL /* 653 */,
0x958D5C960AAD76F1LL /* 654 */, 0xF8D6F430C16DA536LL /* 655 */,
0xC8FFD13F1BE7E1D2LL /* 656 */, 0x7578AE66004DDBE1LL /* 657 */,
0x05833F01067BE646LL /* 658 */, 0xBB34B5AD3BFE586DLL /* 659 */,
0x095F34C9A12B97F0LL /* 660 */, 0x247AB64525D60CA8LL /* 661 */,
0xDCDBC6F3017477D1LL /* 662 */, 0x4A2E14D4DECAD24DLL /* 663 */,
0xBDB5E6D9BE0A1EEBLL /* 664 */, 0x2A7E70F7794301ABLL /* 665 */,
0xDEF42D8A270540FDLL /* 666 */, 0x01078EC0A34C22C1LL /* 667 */,
0xE5DE511AF4C16387LL /* 668 */, 0x7EBB3A52BD9A330ALL /* 669 */,
0x77697857AA7D6435LL /* 670 */, 0x004E831603AE4C32LL /* 671 */,
0xE7A21020AD78E312LL /* 672 */, 0x9D41A70C6AB420F2LL /* 673 */,
0x28E06C18EA1141E6LL /* 674 */, 0xD2B28CBD984F6B28LL /* 675 */,
0x26B75F6C446E9D83LL /* 676 */, 0xBA47568C4D418D7FLL /* 677 */,
0xD80BADBFE6183D8ELL /* 678 */, 0x0E206D7F5F166044LL /* 679 */,
0xE258A43911CBCA3ELL /* 680 */, 0x723A1746B21DC0BCLL /* 681 */,
0xC7CAA854F5D7CDD3LL /* 682 */, 0x7CAC32883D261D9CLL /* 683 */,
0x7690C26423BA942CLL /* 684 */, 0x17E55524478042B8LL /* 685 */,
0xE0BE477656A2389FLL /* 686 */, 0x4D289B5E67AB2DA0LL /* 687 */,
0x44862B9C8FBBFD31LL /* 688 */, 0xB47CC8049D141365LL /* 689 */,
0x822C1B362B91C793LL /* 690 */, 0x4EB14655FB13DFD8LL /* 691 */,
0x1ECBBA0714E2A97BLL /* 692 */, 0x6143459D5CDE5F14LL /* 693 */,
0x53A8FBF1D5F0AC89LL /* 694 */, 0x97EA04D81C5E5B00LL /* 695 */,
0x622181A8D4FDB3F3LL /* 696 */, 0xE9BCD341572A1208LL /* 697 */,
0x1411258643CCE58ALL /* 698 */, 0x9144C5FEA4C6E0A4LL /* 699 */,
0x0D33D06565CF620FLL /* 700 */, 0x54A48D489F219CA1LL /* 701 */,
0xC43E5EAC6D63C821LL /* 702 */, 0xA9728B3A72770DAFLL /* 703 */,
0xD7934E7B20DF87EFLL /* 704 */, 0xE35503B61A3E86E5LL /* 705 */,
0xCAE321FBC819D504LL /* 706 */, 0x129A50B3AC60BFA6LL /* 707 */,
0xCD5E68EA7E9FB6C3LL /* 708 */, 0xB01C90199483B1C7LL /* 709 */,
0x3DE93CD5C295376CLL /* 710 */, 0xAED52EDF2AB9AD13LL /* 711 */,
0x2E60F512C0A07884LL /* 712 */, 0xBC3D86A3E36210C9LL /* 713 */,
0x35269D9B163951CELL /* 714 */, 0x0C7D6E2AD0CDB5FALL /* 715 */,
0x59E86297D87F5733LL /* 716 */, 0x298EF221898DB0E7LL /* 717 */,
0x55000029D1A5AA7ELL /* 718 */, 0x8BC08AE1B5061B45LL /* 719 */,
0xC2C31C2B6C92703ALL /* 720 */, 0x94CC596BAF25EF42LL /* 721 */,
0x0A1D73DB22540456LL /* 722 */, 0x04B6A0F9D9C4179ALL /* 723 */,
0xEFFDAFA2AE3D3C60LL /* 724 */, 0xF7C8075BB49496C4LL /* 725 */,
0x9CC5C7141D1CD4E3LL /* 726 */, 0x78BD1638218E5534LL /* 727 */,
0xB2F11568F850246ALL /* 728 */, 0xEDFABCFA9502BC29LL /* 729 */,
0x796CE5F2DA23051BLL /* 730 */, 0xAAE128B0DC93537CLL /* 731 */,
0x3A493DA0EE4B29AELL /* 732 */, 0xB5DF6B2C416895D7LL /* 733 */,
0xFCABBD25122D7F37LL /* 734 */, 0x70810B58105DC4B1LL /* 735 */,
0xE10FDD37F7882A90LL /* 736 */, 0x524DCAB5518A3F5CLL /* 737 */,
0x3C9E85878451255BLL /* 738 */, 0x4029828119BD34E2LL /* 739 */,
0x74A05B6F5D3CECCBLL /* 740 */, 0xB610021542E13ECALL /* 741 */,
0x0FF979D12F59E2ACLL /* 742 */, 0x6037DA27E4F9CC50LL /* 743 */,
0x5E92975A0DF1847DLL /* 744 */, 0xD66DE190D3E623FELL /* 745 */,
0x5032D6B87B568048LL /* 746 */, 0x9A36B7CE8235216ELL /* 747 */,
0x80272A7A24F64B4ALL /* 748 */, 0x93EFED8B8C6916F7LL /* 749 */,
0x37DDBFF44CCE1555LL /* 750 */, 0x4B95DB5D4B99BD25LL /* 751 */,
0x92D3FDA169812FC0LL /* 752 */, 0xFB1A4A9A90660BB6LL /* 753 */,
0x730C196946A4B9B2LL /* 754 */, 0x81E289AA7F49DA68LL /* 755 */,
0x64669A0F83B1A05FLL /* 756 */, 0x27B3FF7D9644F48BLL /* 757 */,
0xCC6B615C8DB675B3LL /* 758 */, 0x674F20B9BCEBBE95LL /* 759 */,
0x6F31238275655982LL /* 760 */, 0x5AE488713E45CF05LL /* 761 */,
0xBF619F9954C21157LL /* 762 */, 0xEABAC46040A8EAE9LL /* 763 */,
0x454C6FE9F2C0C1CDLL /* 764 */, 0x419CF6496412691CLL /* 765 */,
0xD3DC3BEF265B0F70LL /* 766 */, 0x6D0E60F5C3578A9ELL /* 767 */,
0x5B0E608526323C55LL /* 768 */, 0x1A46C1A9FA1B59F5LL /* 769 */,
0xA9E245A17C4C8FFALL /* 770 */, 0x65CA5159DB2955D7LL /* 771 */,
0x05DB0A76CE35AFC2LL /* 772 */, 0x81EAC77EA9113D45LL /* 773 */,
0x528EF88AB6AC0A0DLL /* 774 */, 0xA09EA253597BE3FFLL /* 775 */,
0x430DDFB3AC48CD56LL /* 776 */, 0xC4B3A67AF45CE46FLL /* 777 */,
0x4ECECFD8FBE2D05ELL /* 778 */, 0x3EF56F10B39935F0LL /* 779 */,
0x0B22D6829CD619C6LL /* 780 */, 0x17FD460A74DF2069LL /* 781 */,
0x6CF8CC8E8510ED40LL /* 782 */, 0xD6C824BF3A6ECAA7LL /* 783 */,
0x61243D581A817049LL /* 784 */, 0x048BACB6BBC163A2LL /* 785 */,
0xD9A38AC27D44CC32LL /* 786 */, 0x7FDDFF5BAAF410ABLL /* 787 */,
0xAD6D495AA804824BLL /* 788 */, 0xE1A6A74F2D8C9F94LL /* 789 */,
0xD4F7851235DEE8E3LL /* 790 */, 0xFD4B7F886540D893LL /* 791 */,
0x247C20042AA4BFDALL /* 792 */, 0x096EA1C517D1327CLL /* 793 */,
0xD56966B4361A6685LL /* 794 */, 0x277DA5C31221057DLL /* 795 */,
0x94D59893A43ACFF7LL /* 796 */, 0x64F0C51CCDC02281LL /* 797 */,
0x3D33BCC4FF6189DBLL /* 798 */, 0xE005CB184CE66AF1LL /* 799 */,
0xFF5CCD1D1DB99BEALL /* 800 */, 0xB0B854A7FE42980FLL /* 801 */,
0x7BD46A6A718D4B9FLL /* 802 */, 0xD10FA8CC22A5FD8CLL /* 803 */,
0xD31484952BE4BD31LL /* 804 */, 0xC7FA975FCB243847LL /* 805 */,
0x4886ED1E5846C407LL /* 806 */, 0x28CDDB791EB70B04LL /* 807 */,
0xC2B00BE2F573417FLL /* 808 */, 0x5C9590452180F877LL /* 809 */,
0x7A6BDDFFF370EB00LL /* 810 */, 0xCE509E38D6D9D6A4LL /* 811 */,
0xEBEB0F00647FA702LL /* 812 */, 0x1DCC06CF76606F06LL /* 813 */,
0xE4D9F28BA286FF0ALL /* 814 */, 0xD85A305DC918C262LL /* 815 */,
0x475B1D8732225F54LL /* 816 */, 0x2D4FB51668CCB5FELL /* 817 */,
0xA679B9D9D72BBA20LL /* 818 */, 0x53841C0D912D43A5LL /* 819 */,
0x3B7EAA48BF12A4E8LL /* 820 */, 0x781E0E47F22F1DDFLL /* 821 */,
0xEFF20CE60AB50973LL /* 822 */, 0x20D261D19DFFB742LL /* 823 */,
0x16A12B03062A2E39LL /* 824 */, 0x1960EB2239650495LL /* 825 */,
0x251C16FED50EB8B8LL /* 826 */, 0x9AC0C330F826016ELL /* 827 */,
0xED152665953E7671LL /* 828 */, 0x02D63194A6369570LL /* 829 */,
0x5074F08394B1C987LL /* 830 */, 0x70BA598C90B25CE1LL /* 831 */,
0x794A15810B9742F6LL /* 832 */, 0x0D5925E9FCAF8C6CLL /* 833 */,
0x3067716CD868744ELL /* 834 */, 0x910AB077E8D7731BLL /* 835 */,
0x6A61BBDB5AC42F61LL /* 836 */, 0x93513EFBF0851567LL /* 837 */,
0xF494724B9E83E9D5LL /* 838 */, 0xE887E1985C09648DLL /* 839 */,
0x34B1D3C675370CFDLL /* 840 */, 0xDC35E433BC0D255DLL /* 841 */,
0xD0AAB84234131BE0LL /* 842 */, 0x08042A50B48B7EAFLL /* 843 */,
0x9997C4EE44A3AB35LL /* 844 */, 0x829A7B49201799D0LL /* 845 */,
0x263B8307B7C54441LL /* 846 */, 0x752F95F4FD6A6CA6LL /* 847 */,
0x927217402C08C6E5LL /* 848 */, 0x2A8AB754A795D9EELL /* 849 */,
0xA442F7552F72943DLL /* 850 */, 0x2C31334E19781208LL /* 851 */,
0x4FA98D7CEAEE6291LL /* 852 */, 0x55C3862F665DB309LL /* 853 */,
0xBD0610175D53B1F3LL /* 854 */, 0x46FE6CB840413F27LL /* 855 */,
0x3FE03792DF0CFA59LL /* 856 */, 0xCFE700372EB85E8FLL /* 857 */,
0xA7BE29E7ADBCE118LL /* 858 */, 0xE544EE5CDE8431DDLL /* 859 */,
0x8A781B1B41F1873ELL /* 860 */, 0xA5C94C78A0D2F0E7LL /* 861 */,
0x39412E2877B60728LL /* 862 */, 0xA1265EF3AFC9A62CLL /* 863 */,
0xBCC2770C6A2506C5LL /* 864 */, 0x3AB66DD5DCE1CE12LL /* 865 */,
0xE65499D04A675B37LL /* 866 */, 0x7D8F523481BFD216LL /* 867 */,
0x0F6F64FCEC15F389LL /* 868 */, 0x74EFBE618B5B13C8LL /* 869 */,
0xACDC82B714273E1DLL /* 870 */, 0xDD40BFE003199D17LL /* 871 */,
0x37E99257E7E061F8LL /* 872 */, 0xFA52626904775AAALL /* 873 */,
0x8BBBF63A463D56F9LL /* 874 */, 0xF0013F1543A26E64LL /* 875 */,
0xA8307E9F879EC898LL /* 876 */, 0xCC4C27A4150177CCLL /* 877 */,
0x1B432F2CCA1D3348LL /* 878 */, 0xDE1D1F8F9F6FA013LL /* 879 */,
0x606602A047A7DDD6LL /* 880 */, 0xD237AB64CC1CB2C7LL /* 881 */,
0x9B938E7225FCD1D3LL /* 882 */, 0xEC4E03708E0FF476LL /* 883 */,
0xFEB2FBDA3D03C12DLL /* 884 */, 0xAE0BCED2EE43889ALL /* 885 */,
0x22CB8923EBFB4F43LL /* 886 */, 0x69360D013CF7396DLL /* 887 */,
0x855E3602D2D4E022LL /* 888 */, 0x073805BAD01F784CLL /* 889 */,
0x33E17A133852F546LL /* 890 */, 0xDF4874058AC7B638LL /* 891 */,
0xBA92B29C678AA14ALL /* 892 */, 0x0CE89FC76CFAADCDLL /* 893 */,
0x5F9D4E0908339E34LL /* 894 */, 0xF1AFE9291F5923B9LL /* 895 */,
0x6E3480F60F4A265FLL /* 896 */, 0xEEBF3A2AB29B841CLL /* 897 */,
0xE21938A88F91B4ADLL /* 898 */, 0x57DFEFF845C6D3C3LL /* 899 */,
0x2F006B0BF62CAAF2LL /* 900 */, 0x62F479EF6F75EE78LL /* 901 */,
0x11A55AD41C8916A9LL /* 902 */, 0xF229D29084FED453LL /* 903 */,
0x42F1C27B16B000E6LL /* 904 */, 0x2B1F76749823C074LL /* 905 */,
0x4B76ECA3C2745360LL /* 906 */, 0x8C98F463B91691BDLL /* 907 */,
0x14BCC93CF1ADE66ALL /* 908 */, 0x8885213E6D458397LL /* 909 */,
0x8E177DF0274D4711LL /* 910 */, 0xB49B73B5503F2951LL /* 911 */,
0x10168168C3F96B6BLL /* 912 */, 0x0E3D963B63CAB0AELL /* 913 */,
0x8DFC4B5655A1DB14LL /* 914 */, 0xF789F1356E14DE5CLL /* 915 */,
0x683E68AF4E51DAC1LL /* 916 */, 0xC9A84F9D8D4B0FD9LL /* 917 */,
0x3691E03F52A0F9D1LL /* 918 */, 0x5ED86E46E1878E80LL /* 919 */,
0x3C711A0E99D07150LL /* 920 */, 0x5A0865B20C4E9310LL /* 921 */,
0x56FBFC1FE4F0682ELL /* 922 */, 0xEA8D5DE3105EDF9BLL /* 923 */,
0x71ABFDB12379187ALL /* 924 */, 0x2EB99DE1BEE77B9CLL /* 925 */,
0x21ECC0EA33CF4523LL /* 926 */, 0x59A4D7521805C7A1LL /* 927 */,
0x3896F5EB56AE7C72LL /* 928 */, 0xAA638F3DB18F75DCLL /* 929 */,
0x9F39358DABE9808ELL /* 930 */, 0xB7DEFA91C00B72ACLL /* 931 */,
0x6B5541FD62492D92LL /* 932 */, 0x6DC6DEE8F92E4D5BLL /* 933 */,
0x353F57ABC4BEEA7ELL /* 934 */, 0x735769D6DA5690CELL /* 935 */,
0x0A234AA642391484LL /* 936 */, 0xF6F9508028F80D9DLL /* 937 */,
0xB8E319A27AB3F215LL /* 938 */, 0x31AD9C1151341A4DLL /* 939 */,
0x773C22A57BEF5805LL /* 940 */, 0x45C7561A07968633LL /* 941 */,
0xF913DA9E249DBE36LL /* 942 */, 0xDA652D9B78A64C68LL /* 943 */,
0x4C27A97F3BC334EFLL /* 944 */, 0x76621220E66B17F4LL /* 945 */,
0x967743899ACD7D0BLL /* 946 */, 0xF3EE5BCAE0ED6782LL /* 947 */,
0x409F753600C879FCLL /* 948 */, 0x06D09A39B5926DB6LL /* 949 */,
0x6F83AEB0317AC588LL /* 950 */, 0x01E6CA4A86381F21LL /* 951 */,
0x66FF3462D19F3025LL /* 952 */, 0x72207C24DDFD3BFBLL /* 953 */,
0x4AF6B6D3E2ECE2EBLL /* 954 */, 0x9C994DBEC7EA08DELL /* 955 */,
0x49ACE597B09A8BC4LL /* 956 */, 0xB38C4766CF0797BALL /* 957 */,
0x131B9373C57C2A75LL /* 958 */, 0xB1822CCE61931E58LL /* 959 */,
0x9D7555B909BA1C0CLL /* 960 */, 0x127FAFDD937D11D2LL /* 961 */,
0x29DA3BADC66D92E4LL /* 962 */, 0xA2C1D57154C2ECBCLL /* 963 */,
0x58C5134D82F6FE24LL /* 964 */, 0x1C3AE3515B62274FLL /* 965 */,
0xE907C82E01CB8126LL /* 966 */, 0xF8ED091913E37FCBLL /* 967 */,
0x3249D8F9C80046C9LL /* 968 */, 0x80CF9BEDE388FB63LL /* 969 */,
0x1881539A116CF19ELL /* 970 */, 0x5103F3F76BD52457LL /* 971 */,
0x15B7E6F5AE47F7A8LL /* 972 */, 0xDBD7C6DED47E9CCFLL /* 973 */,
0x44E55C410228BB1ALL /* 974 */, 0xB647D4255EDB4E99LL /* 975 */,
0x5D11882BB8AAFC30LL /* 976 */, 0xF5098BBB29D3212ALL /* 977 */,
0x8FB5EA14E90296B3LL /* 978 */, 0x677B942157DD025ALL /* 979 */,
0xFB58E7C0A390ACB5LL /* 980 */, 0x89D3674C83BD4A01LL /* 981 */,
0x9E2DA4DF4BF3B93BLL /* 982 */, 0xFCC41E328CAB4829LL /* 983 */,
0x03F38C96BA582C52LL /* 984 */, 0xCAD1BDBD7FD85DB2LL /* 985 */,
0xBBB442C16082AE83LL /* 986 */, 0xB95FE86BA5DA9AB0LL /* 987 */,
0xB22E04673771A93FLL /* 988 */, 0x845358C9493152D8LL /* 989 */,
0xBE2A488697B4541ELL /* 990 */, 0x95A2DC2DD38E6966LL /* 991 */,
0xC02C11AC923C852BLL /* 992 */, 0x2388B1990DF2A87BLL /* 993 */,
0x7C8008FA1B4F37BELL /* 994 */, 0x1F70D0C84D54E503LL /* 995 */,
0x5490ADEC7ECE57D4LL /* 996 */, 0x002B3C27D9063A3ALL /* 997 */,
0x7EAEA3848030A2BFLL /* 998 */, 0xC602326DED2003C0LL /* 999 */,
0x83A7287D69A94086LL /* 1000 */, 0xC57A5FCB30F57A8ALL /* 1001 */,
0xB56844E479EBE779LL /* 1002 */, 0xA373B40F05DCBCE9LL /* 1003 */,
0xD71A786E88570EE2LL /* 1004 */, 0x879CBACDBDE8F6A0LL /* 1005 */,
0x976AD1BCC164A32FLL /* 1006 */, 0xAB21E25E9666D78BLL /* 1007 */,
0x901063AAE5E5C33CLL /* 1008 */, 0x9818B34448698D90LL /* 1009 */,
0xE36487AE3E1E8ABBLL /* 1010 */, 0xAFBDF931893BDCB4LL /* 1011 */,
0x6345A0DC5FBBD519LL /* 1012 */, 0x8628FE269B9465CALL /* 1013 */,
0x1E5D01603F9C51ECLL /* 1014 */, 0x4DE44006A15049B7LL /* 1015 */,
0xBF6C70E5F776CBB1LL /* 1016 */, 0x411218F2EF552BEDLL /* 1017 */,
0xCB0C0708705A36A3LL /* 1018 */, 0xE74D14754F986044LL /* 1019 */,
0xCD56D9430EA8280ELL /* 1020 */, 0xC12591D7535F5065LL /* 1021 */,
0xC83223F1720AEF96LL /* 1022 */, 0xC3A0396F7363A51FLL /* 1023 */
};
/* The following macro denotes that an optimization */
/* for Alpha is required. It is used only for */
/* optimization of time. Otherwise it does nothing. */
#ifdef _LP64
#define OPTIMIZE_FOR_LP64
#endif
/* NOTE that this code is NOT FULLY OPTIMIZED for any */
/* machine. Assembly code might be much faster on some */
/* machines, especially if the code is compiled with */
/* gcc. */
/* The number of passes of the hash function. */
/* Three passes are recommended. */
/* Use four passes when you need extra security. */
/* Must be at least three. */
#define PASSES 3
#define T1 (table)
#define T2 (table+256)
#define T3 (table+(256*2))
#define T4 (table+(256*3))
#define SAVE_ABC do { \
aa = a; \
bb = b; \
cc = c; \
} while (/*CONSTCOND*/0)
#ifdef OPTIMIZE_FOR_LP64
/* This is the official definition of round */
#define ROUND(a,b,c,x,mul) do { \
c ^= x; \
a -= T1[((c)>>(0*8))&0xFF] ^ T2[((c)>>(2*8))&0xFF] ^ \
T3[((c)>>(4*8))&0xFF] ^ T4[((c)>>(6*8))&0xFF] ; \
b += T4[((c)>>(1*8))&0xFF] ^ T3[((c)>>(3*8))&0xFF] ^ \
T2[((c)>>(5*8))&0xFF] ^ T1[((c)>>(7*8))&0xFF] ; \
b *= mul; \
} while (/*CONSTCOND*/ 0)
#else
/* This code works faster when compiled on 32-bit machines */
/* (but works slower on Alpha) */
#define ROUND(a,b,c,x,mul) do { \
c ^= x; \
a -= T1[(uint8_t)(c)] ^ \
T2[(const uint8_t)(((uint32_t)(c))>>(2*8))] ^ \
T3[(const uint8_t)((c)>>(4*8))] ^ \
T4[(const uint8_t)(((uint32_t)((c)>>(4*8)))>>(2*8))] ; \
b += T4[(uint8_t)(((uint32_t)(c))>>(1*8))] ^ \
T3[(const uint8_t)(((uint32_t)(c))>>(3*8))] ^ \
T2[(const uint8_t)(((uint32_t)((c)>>(4*8)))>>(1*8))] ^ \
T1[(const uint8_t)(((uint32_t)((c)>>(4*8)))>>(3*8))]; \
b *= mul; \
} while (/*CONSTCOND*/0)
#endif
#define PASS(a,b,c,mul) do { \
ROUND(a,b,c,x0,mul); \
ROUND(b,c,a,x1,mul); \
ROUND(c,a,b,x2,mul); \
ROUND(a,b,c,x3,mul); \
ROUND(b,c,a,x4,mul); \
ROUND(c,a,b,x5,mul); \
ROUND(a,b,c,x6,mul); \
ROUND(b,c,a,x7,mul); \
} while (/*CONSTCOND*/ 0)
#define KEY_SCHEDULE do { \
x0 -= x7 ^ (uint64_t)0xA5A5A5A5A5A5A5A5LL; \
x1 ^= x0; \
x2 += x1; \
x3 -= x2 ^ ((~x1)<<19); \
x4 ^= x3; \
x5 += x4; \
x6 -= x5 ^ ((~x4)>>23); \
x7 ^= x6; \
x0 += x7; \
x1 -= x0 ^ ((~x7)<<19); \
x2 ^= x1; \
x3 += x2; \
x4 -= x3 ^ ((~x2)>>23); \
x5 ^= x4; \
x6 += x5; \
x7 -= x6 ^ (uint64_t)0x0123456789ABCDEFLL; \
} while (/*CONSTCOND*/ 0)
#define FEEDFORWARD do { \
a ^= aa; \
b -= bb; \
c += cc; \
} while (/*CONSTCOND*/ 0)
#ifdef OPTIMIZE_FOR_LP64
/* The loop is unrolled: works better on Alpha */
#define COMPRESS do { \
SAVE_ABC; \
PASS(a,b,c,5); \
KEY_SCHEDULE; \
PASS(c,a,b,7); \
KEY_SCHEDULE; \
PASS(b,c,a,9); \
for (pass_no = 3; pass_no < PASSES; pass_no++) { \
KEY_SCHEDULE; \
PASS(a,b,c,9); \
tmpa = a; a = c; c = b; b = tmpa; \
} \
FEEDFORWARD; \
} while (/*CONSTCOND*/ 0)
#else
/* loop: works better on PC and Sun (smaller cache?) */
#define COMPRESS do { \
SAVE_ABC; \
for (pass_no = 0; pass_no < PASSES; pass_no++) { \
if (pass_no != 0) { \
KEY_SCHEDULE; \
} \
PASS(a,b,c,(pass_no==0?5:pass_no==1?7:9)); \
tmpa = a; a = c; c = b; b = tmpa; \
} \
FEEDFORWARD; \
} while (/*CONSTCOND*/0)
#endif
#define TIGER_COMPRESS_MACRO(str, state) do { \
uint64_t a, b, c, tmpa; \
uint64_t aa, bb, cc; \
uint64_t x0, x1, x2, x3, x4, x5, x6, x7; \
int pass_no; \
\
a = state[0]; \
b = state[1]; \
c = state[2]; \
\
x0 = str[0]; x1 = str[1]; x2 = str[2]; x3 = str[3]; \
x4 = str[4]; x5 = str[5]; x6 = str[6]; x7 = str[7]; \
\
COMPRESS; \
\
state[0] = a; \
state[1] = b; \
state[2] = c; \
} while (/*CONSTCOND*/ 0)
#ifdef OPTIMIZE_FOR_LP64
/* The compress function is inlined: works better on Alpha. */
/* Still leaves the function above in the code, in case some other */
/* module calls it directly. */
#define tiger_compress(str, state) \
TIGER_COMPRESS_MACRO(((const uint64_t*)(const void *)str), ((uint64_t*)(void *)state))
#else
/* The compress function is a function. Requires smaller cache? */
static void
tiger_compress(const uint64_t *str, uint64_t state[3])
{
TIGER_COMPRESS_MACRO(((const uint64_t*)str), ((uint64_t*)state));
}
#endif
/* weird function to format 8 raw bytes to 16 formatted hex chars */
static void
sprint_uint64(char *buf, uint64_t val)
{
static const char hexdigits[] = "0123456789abcdef";
int indian = 1;
int i;
for (i = 0; i < 8; ++i) {
if (IS_LITTLE_ENDIAN(indian)) {
buf[2 * (7 - i)] = hexdigits[(val >> (56 - 8 * i + 4)) & 15];
buf[(2 * (7 - i)) + 1] = hexdigits[(val >> (56 - 8 * i)) & 15];
} else {
buf[2 * i] = hexdigits[(val >> (56 - 8 * i + 4)) & 15];
buf[(2 * i) + 1] = hexdigits[(val >> (56 - 8 * i)) & 15];
}
}
}
/* common function to initialise context */
static void
initcontext(TIGER_CTX *ctx, uint8_t pad)
{
(void) memset(ctx, 0x0, sizeof(*ctx));
ctx->ctx[0] = 0x0123456789ABCDEFLL;
ctx->ctx[1] = 0xFEDCBA9876543210LL;
ctx->ctx[2] = 0xF096A5B4C3B2E187LL;
ctx->init = 1;
ctx->pad = pad;
}
/* set the version number (0 is same as 1 for Tiger) */
static int
setversion(TIGER_CTX *ctx, int version)
{
switch(version) {
case 0:
case 1:
initcontext(ctx, 0x01);
break;
case 2:
initcontext(ctx, 0x80);
break;
default:
(void) fprintf(stderr, "unknown version %d\n", version);
return 0;
}
return 1;
}
/*****************************************************************************/
void
TIGER_Init(TIGER_CTX *ctx)
{
if (ctx) {
initcontext(ctx, 0x01);
}
}
void
TIGER2_Init(TIGER_CTX *ctx)
{
if (ctx) {
initcontext(ctx, 0x80);
}
}
void
TIGER_Update(TIGER_CTX *ctx, const void *data, size_t length)
{
const uint64_t *str = (const uint64_t *)data;
uint64_t i;
uint64_t j;
union {
uint8_t temp8[64];
uint64_t temp64[8];
} u;
int indian = 1;
if (ctx == NULL || data == NULL) {
return;
}
for(i = length; i >= 64; i -= 64) {
if (IS_BIG_ENDIAN(indian)) {
for (j = 0; j < 64; j++) {
u.temp8[j ^ 7] = ((const uint8_t *)(const void *)str)[j];
}
tiger_compress(u.temp64, ctx->ctx);
} else {
tiger_compress(str, ctx->ctx);
}
str += 8;
}
if (IS_BIG_ENDIAN(indian)) {
for (j = 0; j < i; j++) {
u.temp8[j ^ 7] = ((const uint8_t*)(const void *)str)[j];
}
u.temp8[j ^ 7] = ctx->pad;
for (j++; j&7; j++) {
u.temp8[j ^ 7] = 0;
}
} else {
for (j = 0; j < i; j++) {
u.temp8[j] = ((const uint8_t*)(const void *)str)[j];
}
u.temp8[j++] = ctx->pad;
for (; j&7; j++) {
u.temp8[j] = 0;
}
}
if (j > 56) {
for (; j < 64; j++) {
u.temp8[j] = 0;
}
tiger_compress(u.temp64, ctx->ctx);
j = 0;
}
for (; j < 56; j++) {
u.temp8[j] = 0;
}
u.temp64[7] = ((uint64_t)length) << 3;
tiger_compress(u.temp64, ctx->ctx);
}
void
TIGER_Final(uint8_t *digest, TIGER_CTX *ctx)
{
uint64_t le[3];
int indian = 1;
int i;
if (digest == NULL || ctx == NULL) {
return;
}
if (!ctx->init) {
TIGER_Init(ctx);
TIGER_Update(ctx, NULL, 0);
}
if (IS_LITTLE_ENDIAN(indian)) {
for (i = 0; i < 3; ++i) {
le[i] = (uint64_t)BSWAP64(ctx->ctx[i]);
}
(void) memcpy(digest, le, 3 * sizeof(le[0]));
} else {
(void) memcpy(digest, ctx->ctx, 3 * sizeof(ctx->ctx[0]));
}
}
char *
TIGER_End(TIGER_CTX *ctx, char *buf)
{
int i;
if (ctx == NULL) {
return NULL;
}
if (buf == NULL && (buf = calloc(1, 49)) == NULL) {
return NULL;
}
if (!ctx->init) {
TIGER_Init(ctx);
TIGER_Update(ctx, NULL, 0);
}
for (i = 0; i < 3; ++i) {
sprint_uint64(buf + i * 16, ctx->ctx[i]);
}
buf[16 * i] = 0x0;
return buf;
}
char *
TIGER_File(char *filename, char *buf, int version)
{
TIGER_CTX ctx;
uint8_t buffer[BUFSIZ];
ssize_t num;
int fd;
int oerrno;
if (filename == NULL || buf == NULL || !setversion(&ctx, version)) {
return NULL;
}
if ((fd = open(filename, O_RDONLY)) < 0) {
return NULL;
}
while ((num = read(fd, buffer, sizeof(buffer))) > 0) {
TIGER_Update(&ctx, buffer, (size_t)num);
}
oerrno = errno;
close(fd);
errno = oerrno;
return (num < 0) ? NULL : TIGER_End(&ctx, buf);
}
char *
TIGER_Data(const uint8_t *data, size_t len, char *buf, int version)
{
TIGER_CTX ctx;
if (data == NULL || buf == NULL || !setversion(&ctx, version)) {
return NULL;
}
TIGER_Update(&ctx, data, len);
return TIGER_End(&ctx, buf);
}

View File

@@ -0,0 +1,65 @@
/*-
* Copyright (c) 2005-2011 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TIGER_H_
#define TIGER_H_
#include <sys/types.h>
#include <inttypes.h>
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
#define TIGER_DIGEST_LENGTH 24
#define TIGER_DIGEST_STRING_LENGTH ((TIGER_DIGEST_LENGTH * 2) + 1)
typedef struct TIGER_CTX {
uint64_t ctx[3];
int init;
uint8_t pad;
} TIGER_CTX;
void TIGER_Init(TIGER_CTX *);
void TIGER2_Init(TIGER_CTX *);
void TIGER_Update(TIGER_CTX *, const void *, size_t);
void TIGER_Final(uint8_t *, TIGER_CTX *);
char *TIGER_End(TIGER_CTX *, char *);
char *TIGER_File(char *, char *, int);
char *TIGER_Data(const uint8_t *, size_t, char *, int);
__END_DECLS
#endif

View File

@@ -0,0 +1,11 @@
## $NetBSD: Makefile.am,v 1.4 2010/11/06 00:03:33 agc Exp $
AM_CFLAGS = $(WARNCFLAGS)
lib_LTLIBRARIES = libmj.la
libmj_la_CPPFLAGS = -I$(top_srcdir)/include
libmj_la_SOURCES = mj.c
dist_man_MANS = libmj.3

View File

@@ -0,0 +1,535 @@
# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/libmj
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/ax_check_openssl.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/src/lib/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libmj_la_LIBADD =
am_libmj_la_OBJECTS = libmj_la-mj.lo
libmj_la_OBJECTS = $(am_libmj_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/lib
depcomp = $(SHELL) $(top_srcdir)/buildaux/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libmj_la_SOURCES)
DIST_SOURCES = $(libmj_la_SOURCES)
man3dir = $(mandir)/man3
NROFF = nroff
MANS = $(dist_man_MANS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOM4TE = @AUTOM4TE@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CANONICAL_HOST = @CANONICAL_HOST@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
OPENSSL_LIBS = @OPENSSL_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WARNCFLAGS = @WARNCFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CFLAGS = $(WARNCFLAGS)
lib_LTLIBRARIES = libmj.la
libmj_la_CPPFLAGS = -I$(top_srcdir)/include
libmj_la_SOURCES = mj.c
dist_man_MANS = libmj.3
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/libmj/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign src/libmj/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libmj.la: $(libmj_la_OBJECTS) $(libmj_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libmj_la_OBJECTS) $(libmj_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmj_la-mj.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
libmj_la-mj.lo: mj.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmj_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmj_la-mj.lo -MD -MP -MF $(DEPDIR)/libmj_la-mj.Tpo -c -o libmj_la-mj.lo `test -f 'mj.c' || echo '$(srcdir)/'`mj.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libmj_la-mj.Tpo $(DEPDIR)/libmj_la-mj.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mj.c' object='libmj_la-mj.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmj_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmj_la-mj.lo `test -f 'mj.c' || echo '$(srcdir)/'`mj.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-man3: $(man3_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.3*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
*) ext='3' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \
done
uninstall-man3:
@$(NORMAL_UNINSTALL)
@list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.3*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
*) ext='3' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \
rm -f "$(DESTDIR)$(man3dir)/$$inst"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(MANS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-info: install-info-am
install-man: install-man3
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES uninstall-man
uninstall-man: uninstall-man3
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-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-libLTLIBRARIES install-man install-man3 install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-libLTLIBRARIES \
uninstall-man uninstall-man3
# 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:

View File

@@ -0,0 +1,95 @@
/* $NetBSD: defs.h,v 1.1 2010/08/07 04:13:57 agc Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Alistair Crooks (agc@NetBSD.org)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEFS_H_
#define DEFS_H_
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NEWARRAY(type,ptr,size,where,action) do { \
if ((ptr = calloc(sizeof(type), (unsigned)(size))) == NULL) { \
(void) fprintf(stderr, "%s: can't allocate %lu bytes\n", \
where, (unsigned long)(size * sizeof(type))); \
action; \
} \
} while( /* CONSTCOND */ 0)
#define RENEW(type, _ptr, _size, _newsize, where, action) do { \
type *_newptr; \
_newptr = realloc(_ptr, (size_t)(_newsize) * sizeof(type)); \
if (_newptr == NULL) { \
(void) fprintf(stderr, "%s: can't realloc %lu bytes\n", \
where, (unsigned long)((_newsize) * sizeof(type))); \
action; \
} else { \
(void) memset(&_newptr[_size], 0x0, \
(_newsize - _size) * sizeof(type)); \
_ptr = _newptr; \
_size = _newsize; \
} \
} while( /* CONSTCOND */ 0)
#define NEW(type, ptr, where, action) NEWARRAY(type, ptr, 1, where, action)
#define FREE(ptr) free(ptr)
#define ALLOC(type, v, size, c, init, incr, where, action) do { \
uint32_t _newsize = size; \
if (size == 0) { \
_newsize = init; \
NEWARRAY(type, v, _newsize, where ": new", action); \
} else if (c == size) { \
_newsize = size + incr; \
RENEW(type, v, size, _newsize, where ": renew", action); \
} \
size = _newsize; \
} while( /* CONSTCOND */ 0)
#define DEFINE_ARRAY(name, type) \
typedef struct name { \
uint32_t c; \
uint32_t size; \
type *v; \
} name
#endif /* !DEFS_H_ */

View File

@@ -0,0 +1,283 @@
.\" $NetBSD: libmj.3,v 1.6 2013/07/20 21:39:55 wiz Exp $
.\"
.\" Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd June 22, 2011
.Dt LIBMJ 3
.Os
.Sh NAME
.Nm libmj
.Nd minimalist JSON lightweight data interchange library
.Sh LIBRARY
.Lb libmj
.Sh SYNOPSIS
.In mj.h
.Ft int
.Fo mj_create
.Fa "mj_t *atom" "const char *text" "..."
.Fc
.Ft int
.Fo mj_parse
.Fa "mj_t *atom" "const char *text" "int *tokfrom" "int *tokto" "int *toktype"
.Fc
.Ft int
.Fo mj_append
.Fa "mj_t *atom" "const char *text" "..."
.Fc
.Ft int
.Fo mj_append_field
.Fa "mj_t *atom" "const char *fieldname" "const char *text" "..."
.Fc
.Ft int
.Fo mj_deepcopy
.Fa "mj_t *dest" "mj_t *src"
.Fc
.Ft void
.Fo mj_delete
.Fa "mj_t *atom"
.Fc
.Pp
Access to objects and array entries is made using the following functions:
.Ft int
.Fo mj_arraycount
.Fa "mj_t *atom"
.Fc
.Ft int
.Fo mj_object_find
.Fa "mj_t *atom" "const char *name" "const unsigned startpoint"
.Fa "const unsigned incr"
.Fc
.Ft mj_t *
.Fo mj_get_atom
.Fa "mj_t *atom" "..."
.Fc
.Pp
JSON object output functions:
.Ft int
.Fo mj_snprint
.Fa "char *buffer" "size_t size" "mj_t *atom"
.Fc
.Ft int
.Fo mj_asprint
.Fa "char **buffer" "mj_t *atom"
.Fc
.Ft int
.Fo mj_string_size
.Fa "mj_t *atom"
.Fc
.Ft int
.Fo mj_pretty
.Fa "mj_t *atom" "void *stream" "unsigned depth" "const char *trailer"
.Fc
.Ft const char *
.Fo mj_string_rep
.Fa "mj_t *atom"
.Fc
.Sh DESCRIPTION
.Nm
is a small library interface to allow JSON text to be created and parsed.
JSON is the Java Script Object Notation,
a lightweight data-interchange format, standardised in the ECMA standard.
The library name
.Nm
is derived from a further acronym of
.Dq minimalist JSON .
.\" Hey, Mary!
.Pp
The
.Nm
library can be used to create a string in memory which contains a textual
representation of a number of objects, arbitrarily structured.
The library can also be used to reconstruct the structure.
Data can thus be serialised easily and efficiently, and data structures
rebuilt to produce the original structure of the data.
.Pp
JSON contains basic units called atoms, the two
basic atoms being strings and numbers.
Three other useful atomic values are provided,
.Dq null ,
.Dq false ,
and
.Dq true .
Atoms can be grouped together as key/value pairs in an
.Dq object ,
and as individual, ordered atoms, in an
.Dq array .
.Pp
To create a new object, the
.Fn mj_create
is used.
It can be deleted using the
.Fn mj_delete
function.
.Pp
Atoms, objects and arrays can be appended
to arrays and objects using the
.Fn mj_append
function.
.Pp
Objects can be printed out
by using the
.Fn mj_snprint
function.
The size of a string of JSON text can be calculated
using the
.Fn mj_string_size
function.
A utility function
.Fn mj_asprint
is provided which will allocate space dynamically,
using
.Xr calloc 3 ,
and the JSON serialised text is copied into it.
This memory can later be de-allocated using
.Xr free 3 .
For formatted output to a
.Dv FILE *
stream, the
.Fn mj_pretty
function is used.
The calling interface gives the ability to indent the
output to a given
.Fa depth
and for the formatted output to be followed by a
.Fa trailer
string, which is usually
.Dv NULL
for external calls, but can be any valid string.
Output is sent to the
.Fa stream
file stream.
.Pp
The
.Fa type
argument given to the
.Fn mj_create ,
.Fn mj_append ,
and
.Fn mj_append_field
functions is taken from a list of
.Dq false
.Dq true
.Dq null
.Dq number
.Dq integer
.Dq string
.Dq array
and
.Dq object
types.
An integer differs from a number in that it cannot take on
any floating point values.
It is implemented internally using a signed 64-bit integer type.
This restriction of values for an integer type may be removed at a later date.
.Pp
Within a JSON object, the key values can be iterated over using an integer
index to access the individual JSON objects.
The index can also be found using the
.Fn mj_object_find
function.
.Pp
The way objects arrays are implemented in
.Nm
is by using varying-sized arrays internally.
Objects have the field name as the even entry in this internal array,
with the value being the odd entry.
Arrays are implemented as a simple array.
Thus, to find an object in an array using
.Fn mj_object_find ,
a value of 1 should be used as the increment value.
This means that every entry in the internal array will be examined,
and the first match after the starting point will be returned.
For objects, an incremental value of 2 should be used,
and an even start value should be specified.
.Pp
String values should be created and appended using two parameters in
the stdarg fields, that of the string itself, and its length in bytes
immediately after the string.
A value of
.Dv \-1
may be used if the string length is not known.
.Sh EXAMPLES
The follow code fragment will make a JSON object
out of the string
.Dq Hello <USERNAME>\en
in the
buffer called
.Dq buf
where
.Dq USERNAME
is the name of the user taken from the runtime environment.
The encoded text will be in an allocated buffer called
.Dq s
.Bd -literal -offset indent
mj_t atom;
char buf[BUFSIZ];
char *s;
int cc;
(void) memset(\*[Am]atom, 0x0, sizeof(atom));
cc = snprintf(buf, sizeof(buf), "Hello %s\en", getenv("USER"));
mj_create(\*[Am]atom, "string", buf, cc);
cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_JSON_ENCODE);
.Ed
.Pp
and the following example will take the (binary) text which has been encoded into
JSON and is in the buffer
.Dq buf ,
such as in the previous example, and re-create the original text:
.Bd -literal -offset indent
int from, to, tok, cc;
char *s;
mj_t atom;
(void) memset(\*[Am]atom, 0x0, sizeof(atom));
from = to = tok = 0;
mj_parse(\*[Am]atom, buf, \*[Am]from, \*[Am]to, \*[Am]tok);
cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_HUMAN);
printf("%.*s", cc, s);
.Ed
.Pp
The
.Dv s
pointer points to allocated storage with the original NUL-terminated string
in it.
.Sh SEE ALSO
.Xr calloc 3 ,
.Xr free 3
.Rs
.%Q Ecma International
.%D December 2009
.%T ECMA-262: ECMAScript Language Specification
.%U http://www.ecma-international.org/publications/files/ecma-st/ECMA-262.pdf
.%O 5th Edition
.Re
.Sh HISTORY
The
.Nm
library first appeared in
.Nx 6.0 .
.Sh AUTHORS
.An Alistair Crooks Aq Mt agc@NetBSD.org
wrote this implementation and manual page.

View File

@@ -0,0 +1,653 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <inttypes.h>
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "mj.h"
#include "defs.h"
/* save 'n' chars of 's' in malloc'd memory */
static char *
strnsave(const char *s, int n, unsigned encoded)
{
char *newc;
char *cp;
int i;
if (n < 0) {
n = (int)strlen(s);
}
NEWARRAY(char, cp, n + n + 1, "strnsave", return NULL);
if (encoded) {
newc = cp;
for (i = 0 ; i < n ; i++) {
if ((uint8_t)*s == 0xac) {
*newc++ = (char)0xac;
*newc++ = '1';
s += 1;
} else if (*s == '"') {
*newc++ = (char)0xac;
*newc++ = '2';
s += 1;
} else if (*s == 0x0) {
*newc++ = (char)0xac;
*newc++ = '0';
s += 1;
} else {
*newc++ = *s++;
}
}
*newc = 0x0;
} else {
(void) memcpy(cp, s, (unsigned)n);
cp[n] = 0x0;
}
return cp;
}
/* look in an object for the item */
static int
findentry(mj_t *atom, const char *name, const unsigned from, const unsigned incr)
{
unsigned i;
for (i = from ; i < atom->c ; i += incr) {
if (strcmp(name, atom->value.v[i].value.s) == 0) {
return i;
}
}
return -1;
}
/* create a real number */
static void
create_number(mj_t *atom, double d)
{
char number[128];
atom->type = MJ_NUMBER;
atom->c = snprintf(number, sizeof(number), "%g", d);
atom->value.s = strnsave(number, (int)atom->c, MJ_HUMAN);
}
/* create an integer */
static void
create_integer(mj_t *atom, int64_t i)
{
char number[128];
atom->type = MJ_NUMBER;
atom->c = snprintf(number, sizeof(number), "%" PRIi64, i);
atom->value.s = strnsave(number, (int)atom->c, MJ_HUMAN);
}
/* create a string */
static void
create_string(mj_t *atom, const char *s, ssize_t len)
{
atom->type = MJ_STRING;
atom->value.s = strnsave(s, (int)len, MJ_JSON_ENCODE);
atom->c = (unsigned)strlen(atom->value.s);
}
#define MJ_OPEN_BRACKET (MJ_OBJECT + 1) /* 8 */
#define MJ_CLOSE_BRACKET (MJ_OPEN_BRACKET + 1) /* 9 */
#define MJ_OPEN_BRACE (MJ_CLOSE_BRACKET + 1) /* 10 */
#define MJ_CLOSE_BRACE (MJ_OPEN_BRACE + 1) /* 11 */
#define MJ_COLON (MJ_CLOSE_BRACE + 1) /* 12 */
#define MJ_COMMA (MJ_COLON + 1) /* 13 */
/* return the token type, and start and finish locations in string */
static int
gettok(const char *s, int *from, int *to, int *tok)
{
static regex_t tokregex;
regmatch_t matches[15];
static int compiled;
if (!compiled) {
compiled = 1;
(void) regcomp(&tokregex,
"[ \t\r\n]*(([+-]?[0-9]{1,21}(\\.[0-9]*)?([eE][-+][0-9]+)?)|"
"(\"([^\"]|\\\\.)*\")|(null)|(false)|(true)|([][{}:,]))",
REG_EXTENDED);
}
if (regexec(&tokregex, &s[*from = *to], 15, matches, 0) != 0) {
return *tok = -1;
}
*to = *from + (int)(matches[1].rm_eo);
*tok = (matches[2].rm_so >= 0) ? MJ_NUMBER :
(matches[5].rm_so >= 0) ? MJ_STRING :
(matches[7].rm_so >= 0) ? MJ_NULL :
(matches[8].rm_so >= 0) ? MJ_FALSE :
(matches[9].rm_so >= 0) ? MJ_TRUE :
(matches[10].rm_so < 0) ? -1 :
(s[*from + (int)(matches[10].rm_so)] == '[') ? MJ_OPEN_BRACKET :
(s[*from + (int)(matches[10].rm_so)] == ']') ? MJ_CLOSE_BRACKET :
(s[*from + (int)(matches[10].rm_so)] == '{') ? MJ_OPEN_BRACE :
(s[*from + (int)(matches[10].rm_so)] == '}') ? MJ_CLOSE_BRACE :
(s[*from + (int)(matches[10].rm_so)] == ':') ? MJ_COLON :
MJ_COMMA;
*from += (int)(matches[1].rm_so);
return *tok;
}
/* minor function used to indent a JSON field */
static void
indent(FILE *fp, unsigned depth, const char *trailer)
{
unsigned i;
for (i = 0 ; i < depth ; i++) {
(void) fprintf(fp, " ");
}
if (trailer) {
(void) fprintf(fp, "%s", trailer);
}
}
/***************************************************************************/
/* return the number of entries in the array */
int
mj_arraycount(mj_t *atom)
{
return atom->c;
}
/* create a new JSON node */
int
mj_create(mj_t *atom, const char *type, ...)
{
va_list args;
ssize_t len;
char *s;
if (strcmp(type, "false") == 0) {
atom->type = MJ_FALSE;
atom->c = 0;
} else if (strcmp(type, "true") == 0) {
atom->type = MJ_TRUE;
atom->c = 1;
} else if (strcmp(type, "null") == 0) {
atom->type = MJ_NULL;
} else if (strcmp(type, "number") == 0) {
va_start(args, type);
create_number(atom, (double)va_arg(args, double));
va_end(args);
} else if (strcmp(type, "integer") == 0) {
va_start(args, type);
create_integer(atom, (int64_t)va_arg(args, int64_t));
va_end(args);
} else if (strcmp(type, "string") == 0) {
va_start(args, type);
s = (char *)va_arg(args, char *);
len = (size_t)va_arg(args, size_t);
va_end(args);
create_string(atom, s, len);
} else if (strcmp(type, "array") == 0) {
atom->type = MJ_ARRAY;
} else if (strcmp(type, "object") == 0) {
atom->type = MJ_OBJECT;
} else {
(void) fprintf(stderr, "weird type '%s'\n", type);
return 0;
}
return 1;
}
/* put a JSON tree into a text string */
int
mj_snprint(char *buf, size_t size, mj_t *atom, int encoded)
{
unsigned i;
char *s;
char *bp;
int cc;
switch(atom->type) {
case MJ_NULL:
return snprintf(buf, size, "null");
case MJ_FALSE:
return snprintf(buf, size, "false");
case MJ_TRUE:
return snprintf(buf, size, "true");
case MJ_NUMBER:
return snprintf(buf, size, "%s", atom->value.s);
case MJ_STRING:
if (encoded) {
return snprintf(buf, size, "\"%s\"", atom->value.s);
}
for (bp = buf, *bp++ = '"', s = atom->value.s ;
(size_t)(bp - buf) < size && (unsigned)(s - atom->value.s) < atom->c ; ) {
if ((uint8_t)*s == 0xac) {
switch(s[1]) {
case '0':
*bp++ = 0x0;
s += 2;
break;
case '1':
*bp++ = (char)0xac;
s += 2;
break;
case '2':
*bp++ = '"';
s += 2;
break;
default:
(void) fprintf(stderr, "unrecognised character '%02x'\n", (uint8_t)s[1]);
s += 1;
break;
}
} else {
*bp++ = *s++;
}
}
*bp++ = '"';
*bp = 0x0;
return (int)(bp - buf) - 1;
case MJ_ARRAY:
cc = snprintf(buf, size, "[ ");
for (i = 0 ; i < atom->c ; i++) {
cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i], encoded);
if (i < atom->c - 1) {
cc += snprintf(&buf[cc], size - cc, ", ");
}
}
return cc + snprintf(&buf[cc], size - cc, "]\n");
case MJ_OBJECT:
cc = snprintf(buf, size, "{ ");
for (i = 0 ; i < atom->c ; i += 2) {
cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i], encoded);
cc += snprintf(&buf[cc], size - cc, ":");
cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i + 1], encoded);
if (i + 1 < atom->c - 1) {
cc += snprintf(&buf[cc], size - cc, ", ");
}
}
return cc + snprintf(&buf[cc], size - cc, "}\n");
default:
(void) fprintf(stderr, "mj_snprint: weird type %d\n", atom->type);
return 0;
}
}
/* allocate and print the atom */
int
mj_asprint(char **buf, mj_t *atom, int encoded)
{
int size;
size = mj_string_size(atom);
if ((*buf = calloc(1, (unsigned)(size + 1))) == NULL) {
return -1;
}
return mj_snprint(*buf, (unsigned)(size + 1), atom, encoded) + 1;
}
/* read into a JSON tree from a string */
int
mj_parse(mj_t *atom, const char *s, int *from, int *to, int *tok)
{
int i;
switch(atom->type = *tok = gettok(s, from, to, tok)) {
case MJ_NUMBER:
atom->value.s = strnsave(&s[*from], *to - *from, MJ_JSON_ENCODE);
atom->c = atom->size = (unsigned)strlen(atom->value.s);
return gettok(s, from, to, tok);
case MJ_STRING:
atom->value.s = strnsave(&s[*from + 1], *to - *from - 2, MJ_HUMAN);
atom->c = atom->size = (unsigned)strlen(atom->value.s);
return gettok(s, from, to, tok);
case MJ_NULL:
case MJ_FALSE:
case MJ_TRUE:
atom->c = (unsigned)*to;
return gettok(s, from, to, tok);
case MJ_OPEN_BRACKET:
mj_create(atom, "array");
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
while (mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACKET) {
if (*tok != MJ_COMMA) {
(void) fprintf(stderr, "1. expected comma (got %d) at '%s'\n", *tok, &s[*from]);
break;
}
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
}
return gettok(s, from, to, tok);
case MJ_OPEN_BRACE:
mj_create(atom, "object");
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
for (i = 0 ; mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACE ; i++) {
if (((i % 2) == 0 && *tok != MJ_COLON) || ((i % 2) == 1 && *tok != MJ_COMMA)) {
(void) fprintf(stderr, "2. expected comma (got %d) at '%s'\n", *tok, &s[*from]);
break;
}
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0);
}
return gettok(s, from, to, tok);
default:
return *tok;
}
}
/* return the index of the item which corresponds to the name in the array */
int
mj_object_find(mj_t *atom, const char *name, const unsigned from, const unsigned incr)
{
return findentry(atom, name, from, incr);
}
/* find an atom in a composite mj JSON node */
mj_t *
mj_get_atom(mj_t *atom, ...)
{
unsigned i;
va_list args;
char *name;
int n;
switch(atom->type) {
case MJ_ARRAY:
va_start(args, atom);
i = va_arg(args, int);
va_end(args);
return (i < atom->c) ? &atom->value.v[i] : NULL;
case MJ_OBJECT:
va_start(args, atom);
name = va_arg(args, char *);
va_end(args);
return ((n = findentry(atom, name, 0, 2)) >= 0) ? &atom->value.v[n + 1] : NULL;
default:
return NULL;
}
}
/* perform a deep copy on an mj JSON atom */
int
mj_deepcopy(mj_t *dst, mj_t *src)
{
unsigned i;
switch(src->type) {
case MJ_FALSE:
case MJ_TRUE:
case MJ_NULL:
(void) memcpy(dst, src, sizeof(*dst));
return 1;
case MJ_STRING:
case MJ_NUMBER:
(void) memcpy(dst, src, sizeof(*dst));
dst->value.s = strnsave(src->value.s, -1, MJ_HUMAN);
dst->c = dst->size = (unsigned)strlen(dst->value.s);
return 1;
case MJ_ARRAY:
case MJ_OBJECT:
(void) memcpy(dst, src, sizeof(*dst));
NEWARRAY(mj_t, dst->value.v, dst->size, "mj_deepcopy()", return 0);
for (i = 0 ; i < src->c ; i++) {
if (!mj_deepcopy(&dst->value.v[i], &src->value.v[i])) {
return 0;
}
}
return 1;
default:
(void) fprintf(stderr, "weird type '%d'\n", src->type);
return 0;
}
}
/* do a deep delete on the object */
void
mj_delete(mj_t *atom)
{
unsigned i;
switch(atom->type) {
case MJ_STRING:
case MJ_NUMBER:
free(atom->value.s);
break;
case MJ_ARRAY:
case MJ_OBJECT:
for (i = 0 ; i < atom->c ; i++) {
mj_delete(&atom->value.v[i]);
}
/* XXX - agc - causing problems? free(atom->value.v); */
break;
default:
break;
}
}
/* return the string size needed for the textual output of the JSON node */
int
mj_string_size(mj_t *atom)
{
unsigned i;
int cc;
switch(atom->type) {
case MJ_NULL:
case MJ_TRUE:
return 4;
case MJ_FALSE:
return 5;
case MJ_NUMBER:
return atom->c;
case MJ_STRING:
return atom->c + 2;
case MJ_ARRAY:
for (cc = 2, i = 0 ; i < atom->c ; i++) {
cc += mj_string_size(&atom->value.v[i]);
if (i < atom->c - 1) {
cc += 2;
}
}
return cc + 1 + 1;
case MJ_OBJECT:
for (cc = 2, i = 0 ; i < atom->c ; i += 2) {
cc += mj_string_size(&atom->value.v[i]) + 1 + mj_string_size(&atom->value.v[i + 1]);
if (i + 1 < atom->c - 1) {
cc += 2;
}
}
return cc + 1 + 1;
default:
(void) fprintf(stderr, "mj_string_size: weird type %d\n", atom->type);
return 0;
}
}
/* create a new atom, and append it to the array or object */
int
mj_append(mj_t *atom, const char *type, ...)
{
va_list args;
ssize_t len;
char *s;
if (atom->type != MJ_ARRAY && atom->type != MJ_OBJECT) {
return 0;
}
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append()", return 0);
va_start(args, type);
if (strcmp(type, "string") == 0) {
s = (char *)va_arg(args, char *);
len = (ssize_t)va_arg(args, ssize_t);
create_string(&atom->value.v[atom->c++], s, len);
} else if (strcmp(type, "integer") == 0) {
create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t));
} else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) {
mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *));
} else {
(void) fprintf(stderr, "mj_append: weird type '%s'\n", type);
}
va_end(args);
return 1;
}
/* append a field to an object */
int
mj_append_field(mj_t *atom, const char *name, const char *type, ...)
{
va_list args;
ssize_t len;
char *s;
if (atom->type != MJ_OBJECT) {
return 0;
}
mj_append(atom, "string", name, -1);
ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append_field()", return 0);
va_start(args, type);
if (strcmp(type, "string") == 0) {
s = (char *)va_arg(args, char *);
len = (ssize_t)va_arg(args, ssize_t);
create_string(&atom->value.v[atom->c++], s, len);
} else if (strcmp(type, "integer") == 0) {
create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t));
} else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) {
mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *));
} else {
(void) fprintf(stderr, "mj_append_field: weird type '%s'\n", type);
}
va_end(args);
return 1;
}
/* make sure a JSON object is politically correct */
int
mj_lint(mj_t *obj)
{
unsigned i;
int ret;
switch(obj->type) {
case MJ_NULL:
case MJ_FALSE:
case MJ_TRUE:
if (obj->value.s != NULL) {
(void) fprintf(stderr, "null/false/true: non zero string\n");
return 0;
}
return 1;
case MJ_NUMBER:
case MJ_STRING:
if (obj->c > obj->size) {
(void) fprintf(stderr, "string/number lint c (%u) > size (%u)\n", obj->c, obj->size);
return 0;
}
return 1;
case MJ_ARRAY:
case MJ_OBJECT:
if (obj->c > obj->size) {
(void) fprintf(stderr, "array/object lint c (%u) > size (%u)\n", obj->c, obj->size);
return 0;
}
for (ret = 1, i = 0 ; i < obj->c ; i++) {
if (!mj_lint(&obj->value.v[i])) {
(void) fprintf(stderr, "array/object lint found at %d of %p\n", i, obj);
ret = 0;
}
}
return ret;
default:
(void) fprintf(stderr, "problem type %d in %p\n", obj->type, obj);
return 0;
}
}
/* pretty-print a JSON struct - can be called recursively */
int
mj_pretty(mj_t *mj, void *vp, unsigned depth, const char *trailer)
{
unsigned i;
FILE *fp;
char *s;
fp = (FILE *)vp;
switch(mj->type) {
case MJ_NUMBER:
case MJ_TRUE:
case MJ_FALSE:
case MJ_NULL:
indent(fp, depth, mj->value.s);
break;
case MJ_STRING:
indent(fp, depth, NULL);
mj_asprint(&s, mj, MJ_HUMAN);
(void) fprintf(fp, "\"%s\"", s);
free(s);
break;
case MJ_ARRAY:
indent(fp, depth, "[\n");
for (i = 0 ; i < mj->c ; i++) {
mj_pretty(&mj->value.v[i], fp, depth + 1, (i < mj->c - 1) ? ",\n" : "\n");
}
indent(fp, depth, "]");
break;
case MJ_OBJECT:
indent(fp, depth, "{\n");
for (i = 0 ; i < mj->c ; i += 2) {
mj_pretty(&mj->value.v[i], fp, depth + 1, " : ");
mj_pretty(&mj->value.v[i + 1], fp, 0, (i < mj->c - 2) ? ",\n" : "\n");
}
indent(fp, depth, "}");
break;
}
indent(fp, 0, trailer);
return 1;
}
/* show the contents of the simple atom as a string representation */
const char *
mj_string_rep(mj_t *atom)
{
if (atom == NULL) {
return 0;
}
switch(atom->type) {
case MJ_STRING:
case MJ_NUMBER:
return atom->value.s;
case MJ_NULL:
return "null";
case MJ_FALSE:
return "false";
case MJ_TRUE:
return "true";
default:
return NULL;
}
}

View File

@@ -0,0 +1,79 @@
/*-
* Copyright (c) 2010,2011 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MJ_H_
#define MJ_H_ 20110607
enum {
MJ_NULL = 1,
MJ_FALSE = 2,
MJ_TRUE = 3,
MJ_NUMBER = 4,
MJ_STRING = 5,
MJ_ARRAY = 6,
MJ_OBJECT = 7,
MJ_LAST = MJ_OBJECT,
MJ_HUMAN = 0, /* human readable, not encoded */
MJ_JSON_ENCODE = 1 /* encoded JSON */
};
/* a minimalist JSON node */
typedef struct mj_t {
unsigned type; /* type of JSON node */
unsigned c; /* # of chars */
unsigned size; /* size of array */
union {
struct mj_t *v; /* sub-objects */
char *s; /* string value */
} value;
} mj_t;
/* creation and deletion */
int mj_create(mj_t */*atom*/, const char */*type*/, .../*value*/);
int mj_parse(mj_t */*atom*/, const char */*s*/, int */*from*/,
int */*to*/, int */*token*/);
int mj_append(mj_t */*atom*/, const char */*type*/, .../*value*/);
int mj_append_field(mj_t */*atom*/, const char */*name*/, const char */*type*/,
.../*value*/);
int mj_deepcopy(mj_t */*dst*/, mj_t */*src*/);
void mj_delete(mj_t */*atom*/);
/* JSON object access */
int mj_arraycount(mj_t */*atom*/);
int mj_object_find(mj_t */*atom*/, const char */*name*/,
const unsigned /*from*/, const unsigned /*incr*/);
mj_t *mj_get_atom(mj_t */*atom*/, ...);
int mj_lint(mj_t */*atom*/);
/* textual output */
int mj_snprint(char */*buf*/, size_t /*size*/, mj_t */*atom*/, int /*encoded*/);
int mj_asprint(char **/*bufp*/, mj_t */*atom*/, int /*encoded*/);
int mj_string_size(mj_t */*atom*/);
int mj_pretty(mj_t */*atom*/, void */*fp*/, unsigned /*depth*/,
const char */*trailer*/);
const char *mj_string_rep(mj_t */*atom*/);
#endif

View File

@@ -0,0 +1,417 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
DRAFT VERSION 0.4.2
Oliver Vaughn Gould <ver@olix0r.net>
July 2010
PubKey Access Authentication Scheme, Version 1
----------------------------------------------
0 Introduction
--------------
0.1 Status of this Memo
------------------------
This document specifies a DRAFT protocol for the Internet community.
0.2 Copyright Notice
---------------------
Copyright (C) Yahoo!, Inc. (2010). All rights reseved.
0.3 Abstract
-------------
HTTP services are a core Internet technology, yet the Digest authentication
scheme provided by RFC 2617 only describes authentication by way of
shared-secrets (i.e. passwords).
The PubKey Access Authentication scheme aims to enhance security on the
World Wide Web by bringing an equivalent of SSH's "publickey" authentication
method to challenge-based HTTP client authentication.
0.4 Table of Contents
----------------------
1 PubKey Access Authentication Scheme, Version 1
1.1 Introduction
1.1.1 Purpose
1.1.2 Overall Operation
1.2 Specification of PubKey.v1 Headers
1.2.1 The WWW-Authenticate Response Header
1.2.2 The Authorize Request Header
1.3 Example
1.4 Proxy-Authentication and Proxy-Authorization
1.5 Operational Considerations
1.5.1 Replay Attacks
1.5.2 Man-in-the-Middle Attacks
1.5.3 Brute Force Attacks
1.5.4 Spoofing by Counterfeit Servers
2 References
A Appendices
A.1 Challenge Generation
1 PubKey Access Authentication Scheme, Version 1
-------------------------------------------------
1.1 Introduction
-----------------
1.1.1 Purpose
--------------
HTTP services are a core Internet technology, yet the Digest authentication
scheme provided by RFC 2617 only describes authentication by way of
shared-secrets (i.e. passwords). This model has operational drawbacks, as
authenticating services are required to have access to a user's secret (or
a hash thereof), or retrograde technologies, such as cookies, are employed.
Similarly to SSH's "publickey" authentication method [RFC 4252], the PubKey
Access Authentication scheme allows an HTTP server to authenticate clients using
public key credentials.
1.1.2 Overall Operation
------------------------
Like the Digest Access Authentication Scheme [RFC 2617], the PubKey.v1
scheme is based on a simple challenge-response paradigm. The PubKey scheme
responds to unauthorized clients with a challenge value; and a valid
response contains a cryptographic signature of client's id, the authentication
realm, and the server's challenge.
The client's secret never leaves the client. The server verifies the
client's signed authorization request with the client's published public
keys.
1.2 Specification of PubKey.v1 Headers
---------------------------------------
1.2.1 The WWW-Authenticate Response Header
-------------------------------------------
If a server receives a request for an access-protected object, and an
acceptable Authorization header is not sent, the server responds with a
"401 Unauthorized" status code, and a WWW-Authenticate header as per the
framework defined above, which for the digest scheme is utilized as
follows:
challenge = "PubKey.v1" pubkey-challenge
pubkey-challenge = 1#( realm | [domain] | challenge )
realm = "realm" "=" quoted-string
domain = "domain" "=" <"> URI ( 1*SP URI ) <">
URI = absoluteURI | abs_path
challenge = "challenge" "=" quoted-string
The meanings of the values of the directives used above are as follows:
realm
A string to be displayed to clients so they know which username and
public key to use. This string should contain at least the name of
the host performing the authentication and might additionally
indicate the collection of users who might have access. An example
might be "admin@svc.domain.tld".
domain
An optional quoted, space-separated list of URIs that define the
protection space. If a URI is an abs_path, it is relative to the
canonical root URL of the server being accessed. An absoluteURI in this
list may refer to a different server than the one being accessed. The
client can use this list to determine the set of URIs for which the same
authentication information may be sent: any URI that has a URI in this
list as a prefix (after both have been made absolute) may be assumed to be
in the same protection space. If this directive is omitted or its value
is empty, the client should assume that the protection space consists of
all URIs on the responding server.
This directive is not meaningful in Proxy-Authenticate headers, for
which the protection space is always the entire proxy; if present it
should be ignored.
challenge
A quoted string of data, specified by the server, which should be returned
by the client unchanged in the Authorization header of subsequent
requests with URIs in the same protection space. It is recommended
that this string be base 64 or hexadecimal data.
1.2.2 The Authorization Request Header
-------------------------------------
The client is expected to retry the request, passing an Authorization
header line, which is defined according to the framework above, utilized as
follows.
credentials = "PubKey.v1" privkey-credentials
privkey-credentials = 1#( identifier | realm | challenge | signature )
identifier = "id" "=" identifier-value
identifier-value = quoted-string
challenge = "challenge" "=" challenge-value
challenge-value = quoted-string
signature = "signature" "=" signature-value
signature-value = quoted-string
The values of the challenge and realm fields must be those supplied in the
WWW-Authenticate response header for the entity being requested.
identifier
The client identifier in the specified realm. I.e. the client's username.
signature
A quoted base 64 encoded string representation of a signature generated
with the client's private key as follows.
signature = BASE64( D^M( authorization ))
authorization = identifier-value ";" realm-value ";" challenge-value
If a directive or its value is improper, or required directives are
missing, the proper response is 400 Bad Request. If the signature is
invalid, then a login failure should be logged, since repeated login
failures from a single client may indicate malfeasance.
The client should be able to reuse this Authorization until a 401
Unauthorized is reached, or an Authentication-Info header provides a new
challenge.
1.2.3 Authentication-Info Header
---------------------------------
The optional Authentication-Info header may be used by the server to
communicate some information regarding the successful authentication in the
response. Specifically, this header can be used to send a new challenge to
an authorized client.
AuthenticationInfo = "Authentication-Info" ":" auth-info
auth-info = 1#( next-challenge )
next-challenge = "challenge" "=" challenge-value
The meanings of the values used above are as follows:
next-challenge
The following request on this domain should contain an authorization
on this challenge value. It should be expected that reissuing the
used Authorization header will result in a 401 Unauthorized response.
1.3 Example
------------
The following example assumes that an access-protected resource is being
requested from the server via a GET request. The URI of the document is
"http://svc.domain.tld/object". Both client and server know the public key
for the user identified as "McFly" in the realm "users@svc.domain.tld".
The first time the client requests the document, no Authorization header is
sent, so the server responds with:
401 Unauthorized
WWW-Authenticate: PubKey.v1
challenge="aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk=;dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09",
realm="users@svc.domain.tld"
The client's user agent determines the client's identifier and private key
to use for the realm. The user agent then uses this private key to sign
the server's challenge, prompting the user as neccessary. Finally, the
client sends a new request including the Authorization header:
Authorization: PubKey.v1
id="McFly",
challenge="aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk=;dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09",
realm="users@svc.domain.tld",
signature="AAAAB3NzaC1yc2EAAAEAWARe6cScN5t0aFy0lBA1EbC/JoyRxsEuPsWtFZ3qw12lXYcmTXuq1v/0lwqcgZQgutQdiavR6O6157uyk0dkfuDXiuOjsngkmgp0oN/kwYxKPVrXMze1tFr8tFBUQU+JeCbvVd+o6LeD7pO29onXqf776N21nX1sRaeT+wX6qNMNEgJ7S3TzwTgMJ4Ub5dMCxXYCX7AW15YzLie213fvU3YiBh1ZHy//ubDb29d/2t941/gAdipjRQiabWK5lpfkmLJWJddlZq3IyFqiXMM1vpaGmiiM5w2fMpuzO8enyRTDtQQwLAxrffxY/n6RbGvUiEU4YzSGLlPE6KUU36dKOw=="
The server verifies the client's signature on the following authorization
string:
McFly;users@svc.domain.tld;aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk=;dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09
Assuming that the challenge generation algorithm described in section A.1
is used, the server then verfies its own signature of the challenge by
decoding the challenge thusly:
b64-server-signature = "aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk="
b64-challenge = "dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09"
challenge = "users@svc.domain.tld;1278112799;127.0.0.1;m8o+rTkokEQO0QKEHv/o4w=="
After the server's signature is verified, it checks the realm, expiration, and
source IP encoded in the challenge to authorize the request.
1.4 Proxy-Authentication and Proxy-Authorization
-------------------------------------------------
The PubKey.v1 authentication scheme may also be used for authenticating
clients to proxies, proxies to proxies, or proxies to origin servers by use
of the Proxy-Authenticate and Proxy-Authorization headers. These headers
are instances of the Proxy-Authenticate and Proxy-Authorization headers
specified in sections 10.33 and 10.34 of the HTTP/1.1 specification [RFC
2616] and their behavior is subject to restrictions described there. The
transactions for proxy authentication are very similar to those already
described. Upon receiving a request which requires authentication, the
proxy/server must issue the "407 Proxy Authentication Required" response
with a "Proxy-Authenticate" header. The pubkey-challenge used in the
Proxy-Authenticate header is the same as that for the WWW-Authenticate
header as defined above in section 1.2.1.
The client/proxy must then re-issue the request with a Proxy-Authorization
header, with directives as specified for the Authorization header in
section 1.2.2 above.
Note that in principle a client could be asked to authenticate itself to
both a proxy and an end-server, but never in the same response.
1.5 Operational Considerations
-------------------------------
1.5.1 Replay Attacks
---------------------
The challenge generation scheme described in section A.1 includes a
server-signed time, client IP address, and random seed; after verifying its own
signature, the server verifies that the authorized request is from the expected
source and within the allowed session time.
The server may preempt the need for an expired transaction by sending a new
challenge in an AuthorizationInfo header.
1.5.2 Man-in-the-Middle Attacks
--------------------------------
In principal, it is not possible to distinguish untrusted intermediaries
from trustworthy (e.g. HTTP or SOCKS) proxy servers. Therefore, the
PubKey.v1 scheme does not attempt to implement any form of server
authentication or endpoint confidentiality. A client's Authorization token
may be stolen by intermediary servers.
Some form of socket-or-application-layer cryptography should be utilized to
establish confidentiality between endpoints.
1.5.3 Brute Force Attacks
--------------------------
Brute force attacks against strong cryptographic keys (currently, RSA 2048
or stronger) are particularly ineffective, which is a major advantage of this
authentication scheme over, for instance, the Digest scheme.
The challenge generation algorithm described in section A.1 uses a secret
value and digest algorithm to verify the returned, signed challenge. If an
authorized attacker gains access to this value and determine the digest
algorithm, it can override values encoded in the server's challenge. Note
that such an attack can only be exploited by sending a manipulated challenge
value with a valid signature from a client authorized to the given realm.
The randomized seed value in the challenge helps to mitigate cryptanalytic
attacks on the server's secret by introducing entropy into the signature.
1.5.4 Spoofing by Counterfeit Servers
--------------------------------------
The PubKey.v1 authentication scheme does not provide any means for a client
to validate a server.
Some form of socket-or-application-layer cryptography should be utilized to
establish confidentiality between endpoints.
2 References
------------
[RFC 2222] Simple Authentication and Security Layer (SASL)
[RFC 2616] Hypertext Transfer Protocol -- HTTP/1.1
[RFC 2617] HTTP Authentication: Basic and Digest Access Authentication
[RFC 2818] HTTP Over TLS
[RFC 2743] Generic Security Service Application Program Interface
Version 2, Update 1
[RFC 4251] The Secure Shell (SSH) Protocol Architecture
[RFC 4252] The Secure Shell (SSH) Authentication Protocol
Portions of this document were based directly on these references:
Copyright (C) The Internet Society (1999, 2006). All Rights Reserved.
A Appendices
-------------
A.1 Challenge Generation
-------------------------
- From a client's perspective, the challenge value is an opaque blob of data
to be signed. However, the server can encode data into its challenge value
in order to authenticate clients without maintaining state for all such
requests. One possible challenge generation scheme is discussed below, but
it can be replaced with no impact on the protocol.
challenge-value = server-signature ";" encoded-challenge
server-signature = BASE64( DIGEST( raw-server-signature ) )
raw-server-signature = raw-challenge ";" server-secret-value
encoded-challenge = BASE64( raw-challenge )
raw-challenge = realm-value ";" ip-address ";" epoch-time ";" seed-value
epoch-time = integer
ip-address = <IPv4 or IPv6 address>
seed-value = token [RFC 2616]
server-secret-value = token [RFC 2616]
The meanings of the values used above are as follows:
DIGEST
A digest algorithm such as SHA256.
epoch-time
The time at which the challenge was generated. The server may reference
this field to determine whether the authorization has expired.
ip-address
The IP address of the client-side of the connection on which the request
is being made.
realm-value
The realm-value specified in the WWW-Authenticate.
seed-value
A random value generated by the server to introduce entropy into the
server's signatures.
server-secret-value
A secret value that only the server may access. This is used to
'sign' a challenge. The client's Authorization is validated by
reconstructing the challenge with this secret.
It would also be possible for a server to use a private key instead
of a server-secret-value.
Depending on the server's resources, it may be desirable to use a cipher
algorithm instead of a digest algorithm.
DRAFT VERSION 0.4.2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
iEYEARECAAYFAkxJEZ0ACgkQkPEZLwKUCCVZeQCfb7zuztnPcEjCBF5CPtwaLJTd
xrgAoJ4etR3erN/PstMEOJc1mjRR7OXr
=R8Im
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,87 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <netdb.h>
#include <netpgp.h>
#include <regex.h>
#include <sha1.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "libpaa.h"
#define DEFAULT_HASH_ALG "SHA256"
int
main(int argc, char **argv)
{
paa_response_t response;
netpgp_t netpgp;
char challenge[2048];
char buf[2048];
int challengec;
int cc;
int i;
(void) memset(&response, 0x0, sizeof(response));
(void) memset(&netpgp, 0x0, sizeof(netpgp));
while ((i = getopt(argc, argv, "S:d:r:u:")) != -1) {
switch(i) {
case 'S':
netpgp_setvar(&netpgp, "ssh keys", "1");
netpgp_setvar(&netpgp, "sshkeyfile", optarg);
break;
case 'd':
//challenge.domain = optarg;
break;
case 'r':
//challenge.realm = optarg;
response.realm = optarg;
break;
case 'u':
netpgp_setvar(&netpgp, "userid", optarg);
break;
}
}
netpgp_setvar(&netpgp, "hash", DEFAULT_HASH_ALG);
netpgp_setvar(&netpgp, "need seckey", "1");
netpgp_setvar(&netpgp, "need userid", "1");
netpgp_set_homedir(&netpgp, getenv("HOME"),
netpgp_getvar(&netpgp, "ssh keys") ? "/.ssh" : "/.gnupg", 1);
if (!netpgp_init(&netpgp)) {
(void) fprintf(stderr, "can't initialise netpgp\n");
exit(EXIT_FAILURE);
}
/* read challenge into challenge */
challengec = read(0, challenge, sizeof(challenge));
cc = paa_format_response(&response, &netpgp, challenge, buf, sizeof(buf));
write(1, buf, cc);
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,117 @@
.\" $NetBSD: libpaa.3,v 1.3 2013/07/20 21:39:55 wiz Exp $
.\"
.\" Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This manual page is derived from software contributed to The
.\" NetBSD Foundation by Alistair Crooks (agc@NetBSD.org)
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd September 9, 2010
.Dt LIBPAA 3
.Os
.Sh NAME
.Nm libpaa
.Nd Public key Access Authentication Library
.Sh LIBRARY
.Lb libpaa
.Sh SYNOPSIS
.In libpaa.h
.Ft int
.Fo paa_server_init
.Fa "paa_server_info_t *server" "unsigned secretsize"
.Fc
.Ft int
.Fo paa_format_challenge
.Fa "paa_challenge_t *challenge" "paa_server_info_t *server"
.Fa "char *buf" "size_t size"
.Fc
.Ft int
.Fo paa_format_response
.Fa "paa_response_t *response" "netpgp_t *netpgp" "char *in"
.Fa "char *out" "size_t outsize"
.Fc
.Ft int
.Fo paa_check_response
.Fa "paa_challenge_t *challenge" "paa_identity_t *id"
.Fa "netpgp_t *netpgp" "char *response"
.Fc
.Ft int
.Fo paa_print_identity
.Fa "FILE *fp" "paa_identity_t *id"
.Fc
.Sh DESCRIPTION
.Nm
is a library interface which provides an authentication mechanism
layered on top of
.Xr libnetpgp 3 .
This is targeted at web services, and allows authentication by
means of digitally signing a generated challenge.
By verifying the signed response from the client, the server
can verify the identity of the user receiving the challenge,
and producing the signed response.
Random seeds and blinded secrets are used to protect against
spoofed signatures.
.Pp
The main reason for writing this authentication mechanism is
so that identities can be verified across a network without
transferring any secret information across the wire.
.Pp
Binary information is transferred using internal base64
functions.
.Pp
In the server
process, the server information is initialised using the
.Fn paa_server_init
function, which will set up the random data and secrets.
The challenge is generated using the
.Fn paa_format_challenge
function.
This will format the challenge into the buffer provided,
and can be transferred to the client using any means.
.Pp
The client reads the challenge, and produces a response
using the
.Fn paa_format_response
function to format the response in the buffer provided.
This response is given to the server.
.Pp
In the server, the response is verified using
the
.Fn paa_check_response
function.
If a positive verification has occurred, the identity of
various fields in the response can be displayed
using the
.Fn paa_print_identity
function.
.Sh SEE ALSO
.Xr libnetpgp 3 ,
.Xr sha1 3
.Sh HISTORY
The
.Nm
library first appeared in
.Nx 6.0 .
.Sh AUTHORS
.An Alistair Crooks Aq Mt agc@NetBSD.org

View File

@@ -0,0 +1,387 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet6/in6.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <netpgp.h>
#include <regex.h>
#include <sha1.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "libpaa.h"
#include "b64.h"
enum {
MAX_DIGEST_SIZE = 128
};
/* create an area of random memory */
static int
randomise(char *s, size_t size)
{
uint32_t r;
size_t i;
for (i = 0 ; i < size ; i += sizeof(r)) {
r = random();
(void) memcpy(&s[i], &r, sizeof(r));
}
return i;
}
/* generate a challenge */
static int
genchallenge(paa_challenge_t *challenge, paa_server_info_t *server)
{
time_t t;
char digest[MAX_DIGEST_SIZE];
char raw[PAA_CHALLENGE_SIZE * 2];
int cc;
t = time(NULL);
cc = snprintf(raw, sizeof(raw), "%s;%s;%lld;", challenge->realm, server->hostaddress, (int64_t)t);
cc += randomise(&raw[cc], 64); /* 64 is arbitrary */
/* raw now has the raw-challenge in it */
challenge->encc = b64encode(raw, (const unsigned)cc, challenge->encoded_challenge,
sizeof(challenge->encoded_challenge), 0);
cc += snprintf(&raw[cc], sizeof(raw) - cc, ";%.*s", server->secretc, server->secret);
(void) SHA1Data((uint8_t *)raw, (unsigned)cc, digest);
server->server_signaturec = b64encode(digest, (const unsigned)strlen(digest),
server->server_signature, sizeof(server->server_signature), (int)0);
/* raw has raw-challenge ; server-secret-value, i.e. raw-server-signature */
challenge->challengec = snprintf(challenge->challenge, sizeof(challenge->challenge),
"%.*s;%.*s", server->server_signaturec, server->server_signature,
challenge->encc, challenge->encoded_challenge);
return challenge->challengec;
}
/* fill in the identity information in the response */
static int
fill_identity(paa_identity_t *id, char *response, char *raw_challenge)
{
regmatch_t matches[10];
regex_t response_re;
regex_t id_re;
char t[32];
/* id="userid" */
(void) regcomp(&id_re, "id=\"([^\"]+)\"", REG_EXTENDED);
if (regexec(&id_re, response, 10, matches, 0) != 0) {
(void) fprintf(stderr, "No identity information found\n");
return 0;
}
(void) snprintf(id->userid, sizeof(id->userid), "%.*s",
(int)(matches[1].rm_eo - matches[1].rm_so),
&response[(int)matches[1].rm_so]);
/* realm;ip;timestamp;seed */
(void) regcomp(&response_re, "([^;]+);([^;]+);([^;]+);(.*)", REG_EXTENDED);
if (regexec(&response_re, raw_challenge, 10, matches, 0) != 0) {
(void) fprintf(stderr, "No identity information found\n");
return 0;
}
(void) snprintf(id->realm, sizeof(id->realm), "%.*s",
(int)(matches[1].rm_eo - matches[1].rm_so),
&raw_challenge[(int)matches[1].rm_so]);
(void) snprintf(id->client, sizeof(id->client), "%.*s",
(int)(matches[2].rm_eo - matches[2].rm_so),
&raw_challenge[(int)matches[2].rm_so]);
(void) snprintf(t, sizeof(t), "%.*s",
(int)(matches[3].rm_eo - matches[3].rm_so),
&raw_challenge[(int)matches[3].rm_so]);
id->timestamp = strtoll(t, NULL, 10);
return 1;
}
/***************************************************************************/
/* exported functions start here */
/***************************************************************************/
/* initialise the server info */
int
paa_server_init(paa_server_info_t *server, unsigned secretsize)
{
struct sockaddr_in6 *sin6;
struct sockaddr_in *sin;
struct ifaddrs *addrs;
char host[512];
if (getifaddrs(&addrs) < 0) {
(void) fprintf(stderr, "can't getifaddrs\n");
return 0;
}
for ( ; addrs ; addrs = addrs->ifa_next) {
if (addrs->ifa_addr->sa_family == AF_INET) {
sin = (struct sockaddr_in *)(void *)addrs->ifa_addr;
(void) snprintf(server->hostaddress, sizeof(server->hostaddress), "%s",
inet_ntoa(sin->sin_addr));
break;
}
if (addrs->ifa_addr->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)(void *)addrs->ifa_addr;
(void) getnameinfo((const struct sockaddr *)(void *)sin6,
(unsigned)sin6->sin6_len,
server->hostaddress, sizeof(server->hostaddress),
NULL, 0, NI_NUMERICHOST);
break;
}
}
if (addrs == NULL) {
if (gethostname(host, sizeof(host)) < 0) {
(void) fprintf(stderr, "can't get hostname\n");
return 0;
}
(void) snprintf(server->hostaddress, sizeof(server->hostaddress), "%s", host);
}
if ((server->secret = calloc(1, server->secretc = secretsize)) == NULL) {
(void) fprintf(stderr, "can't allocate server secret\n");
return 0;
}
server->secretc = randomise(server->secret, secretsize);
return 1;
}
/*
challenge = "PubKey.v1" pubkey-challenge
pubkey-challenge = 1#( realm | [domain] | challenge )
realm = "realm" "=" quoted-string
domain = "domain" "=" <"> URI ( 1*SP URI ) <">
URI = absoluteURI | abs_path
challenge = "challenge" "=" quoted-string
*/
/* called from server to send the challenge */
int
paa_format_challenge(paa_challenge_t *challenge, paa_server_info_t *server, char *buf, size_t size)
{
int cc;
if (challenge->realm == NULL) {
(void) fprintf(stderr, "paa_format_challenge: no realm information\n");
return 0;
}
cc = snprintf(buf, size, "401 Unauthorized\r\nWWW-Authenticate: PubKey.v1\r\n");
(void) genchallenge(challenge, server);
cc += snprintf(&buf[cc], size - cc, " challenge=\"%s\"", challenge->challenge);
if (challenge->realm) {
cc += snprintf(&buf[cc], size - cc, ",\r\n realm=\"%s\"", challenge->realm);
}
if (challenge->domain) {
cc += snprintf(&buf[cc], size - cc, ",\r\n domain=\"%s\"", challenge->domain);
}
cc += snprintf(&buf[cc], size - cc, "\r\n");
return cc;
}
/*
credentials = "PubKey.v1" privkey-credentials
privkey-credentials = 1#( identifier | realm | challenge | signature )
identifier = "id" "=" identifier-value
identifier-value = quoted-string
challenge = "challenge" "=" challenge-value
challenge-value = quoted-string
signature = "signature" "=" signature-value
signature-value = quoted-string
*/
/* called from client to respond to the challenge */
int
paa_format_response(paa_response_t *response, netpgp_t *netpgp, char *in, char *out, size_t outsize)
{
regmatch_t matches[10];
regex_t r;
char challenge[2048 * 2];
char base64_signature[2048 * 2];
char sig[2048];
int challengec;
int sig64c;
int sigc;
int outc;
if (response->realm == NULL) {
(void) fprintf(stderr, "paa_format_response: no realm information\n");
return 0;
}
(void) regcomp(&r, "challenge=\"([^\"]+)\"", REG_EXTENDED);
if (regexec(&r, in, 10, matches, 0) != 0) {
(void) fprintf(stderr, "no signature found\n");
return 0;
}
challengec = snprintf(challenge, sizeof(challenge), "%.*s",
(int)(matches[1].rm_eo - matches[1].rm_so), &in[(int)matches[1].rm_so]);
/* read challenge string */
outc = snprintf(out, outsize, "Authorization: PubKey.v1\r\n");
response->userid = netpgp_getvar(netpgp, "userid");
outc += snprintf(&out[outc], outsize - outc, " id=\"%s\"", response->userid);
outc += snprintf(&out[outc], outsize - outc, ",\r\n challenge=\"%s\"", challenge);
outc += snprintf(&out[outc], outsize - outc, ",\r\n realm=\"%s\"", response->realm);
/* set up response */
(void) memset(sig, 0x0, sizeof(sig));
(void) snprintf(sig, sizeof(sig), "%s;%s;%s;", response->userid, response->realm, challenge);
sigc = netpgp_sign_memory(netpgp, response->userid, challenge,
(unsigned)challengec, sig, sizeof(sig), 0, 0);
sig64c = b64encode(sig, (const unsigned)sigc, base64_signature,
sizeof(base64_signature), (int)0);
outc += snprintf(&out[outc], outsize - outc, ",\r\n signature=\"%.*s\"", sig64c, base64_signature);
return outc;
}
/* called from server to check the response to the challenge */
int
paa_check_response(paa_challenge_t *challenge, paa_identity_t *id, netpgp_t *netpgp, char *response)
{
regmatch_t matches[10];
regex_t challenge_regex;
regex_t signature_regex;
regex_t realm_regex;
time_t t;
char encoded_challenge[512];
char raw_challenge[512];
char verified[2048];
char realm[128];
char buf[2048];
int bufc;
/* grab the signed text from the response */
(void) regcomp(&signature_regex, "signature=\"([^\"]+)\"", REG_EXTENDED);
if (regexec(&signature_regex, response, 10, matches, 0) != 0) {
(void) fprintf(stderr, "paa_check: no signature found\n");
return 0;
}
/* atob the signature itself */
bufc = b64decode(&response[(int)matches[1].rm_so],
(size_t)(matches[1].rm_eo - matches[1].rm_so), buf, sizeof(buf));
/* verify the signature */
(void) memset(verified, 0x0, sizeof(verified));
if (netpgp_verify_memory(netpgp, buf, (const unsigned)bufc, verified, sizeof(verified), 0) <= 0) {
(void) fprintf(stderr, "paa_check: signature cannot be verified\n");
return 0;
}
/* we check the complete signed text against our challenge */
if (strcmp(challenge->challenge, verified) != 0) {
(void) fprintf(stderr, "paa_check: signature does not match\n");
return 0;
}
(void) regcomp(&challenge_regex, "^([^;]+);(.+)", REG_EXTENDED);
if (regexec(&challenge_regex, verified, 10, matches, 0) != 0) {
(void) fprintf(stderr, "paa_check: no 2 parts to challenge\n");
return 0;
}
/* we know server signature matches from comparison on whole challenge above */
(void) snprintf(encoded_challenge, sizeof(encoded_challenge), "%.*s",
(int)(matches[2].rm_eo - matches[2].rm_so), &verified[(int)matches[2].rm_so]);
(void) b64decode(&verified[(int)matches[2].rm_so],
(const unsigned)(matches[2].rm_eo - matches[2].rm_so),
raw_challenge, sizeof(raw_challenge));
if (!fill_identity(id, response, raw_challenge)) {
(void) fprintf(stderr, "paa_check: identity problems\n");
return 0;
}
/* check realm info in authentication header matches signed realm */
(void) regcomp(&realm_regex, "realm=\"([^\"]+)\"", REG_EXTENDED);
if (regexec(&realm_regex, response, 10, matches, 0) != 0) {
(void) fprintf(stderr, "paa_check: no realm found\n");
return 0;
}
(void) snprintf(realm, sizeof(realm), "%.*s",
(int)(matches[1].rm_eo - matches[1].rm_so),
&response[(int)matches[1].rm_so]);
if (strcmp(id->realm, realm) != 0) {
(void) fprintf(stderr, "paa_check: realm mismatch: signed realm '%s' vs '%s'\n",
id->realm, realm);
return 0;
}
/* check timestamp is within bounds */
t = time(NULL);
if (id->timestamp < t - (3 * 60)) {
(void) fprintf(stderr, "paa_check: timestamp check: %lld seconds ago\n",
t - id->timestamp);
return 0;
}
if (id->timestamp > t + (3 * 60)) {
(void) fprintf(stderr, "paa_check: timestamp check: %lld seconds in future\n",
id->timestamp - t);
return 0;
}
return 1;
}
/* print identity details on a stream */
int
paa_print_identity(FILE *fp, paa_identity_t *id)
{
(void) fprintf(fp, "\tuserid\t%s\n\tclient\t%s\n\trealm\t%s\n\ttime\t%.24s\n",
id->userid,
id->client,
id->realm,
ctime(&id->timestamp));
return 1;
}
/* utility function to write a string to a file */
int
paa_write_file(const char *f, char *s, unsigned cc)
{
FILE *fp;
if ((fp = fopen(f, "w")) == NULL) {
(void) fprintf(stderr, "can't write file '%s'\n", f);
return 0;
}
write(fileno(fp), s, cc);
(void) fclose(fp);
return 1;
}
/* utility function to read a string from a file */
int
paa_read_file(const char *f, char *s, size_t size)
{
FILE *fp;
int cc;
if ((fp = fopen(f, "r")) == NULL) {
(void) fprintf(stderr, "can't write '%s'\n", f);
return 0;
}
cc = read(fileno(fp), s, size);
(void) fclose(fp);
return cc;
}

View File

@@ -0,0 +1,93 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBPAA_H_
#define LIBPAA_H_ 20100908
#include <sys/types.h>
#include <inttypes.h>
#include <stdio.h>
#define DEFAULT_HASH_ALG "SHA256"
enum {
PAA_CHALLENGE_SIZE = 128
};
/* constant and secret info for server side */
typedef struct paa_server_info_t {
char hostaddress[128]; /* host ip address */
char *secret; /* raw secret of server */
unsigned secretc; /* # of characters used */
char server_signature[512]; /* this is the encoded signature */
int server_signaturec; /* # of chars in encoded sig */
} paa_server_info_t;
/* used in server to formulate challenge */
typedef struct paa_challenge_t {
const char *realm; /* this is realm of challenge */
const char *domain; /* domain of challenge */
char challenge[512]; /* the output challenge */
int challengec; /* # of chars in challenge */
/* sub-parts of challenge */
char encoded_challenge[512]; /* encoded challenge part */
int encc; /* # of chars in encoded challenge */
} paa_challenge_t;
/* used in client to formulate response */
typedef struct paa_response_t {
const char *userid; /* identity to be used for signature */
const char *realm; /* realm that client wants */
char challenge[PAA_CHALLENGE_SIZE]; /* input challenge */
int challengec; /* # if chars in input */
char response[PAA_CHALLENGE_SIZE * 2]; /* output response */
int respc; /* # of chars in output */
} paa_response_t;
/* this struct holds the identity information in the paa response */
typedef struct paa_identity_t {
char userid[32]; /* verified identity */
char client[128]; /* client address */
char realm[128]; /* client realm */
char domain[128]; /* client domain */
int64_t timestamp; /* time of response */
} paa_identity_t;
/* support functions */
int paa_write_file(const char *, char *, unsigned);
int paa_read_file(const char *, char *, size_t);
/* server initialisations - one time */
int paa_server_init(paa_server_info_t *, unsigned);
/* body of pubkey access authentication challenge/response/check functionality */
int paa_format_challenge(paa_challenge_t *, paa_server_info_t *, char *, size_t);
int paa_format_response(paa_response_t *, netpgp_t *, char *, char *, size_t);
int paa_check_response(paa_challenge_t *, paa_identity_t *, netpgp_t *, char *);
/* who are ya? */
int paa_print_identity(FILE *, paa_identity_t *);
#endif

View File

@@ -0,0 +1,114 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <netdb.h>
#include <netpgp.h>
#include <regex.h>
#include <sha1.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "libpaa.h"
#define DEFAULT_HASH_ALG "SHA256"
int
main(int argc, char **argv)
{
paa_server_info_t server;
paa_challenge_t challenge;
paa_identity_t id;
netpgp_t netpgp;
char buf[2048];
int secretc;
int cc;
int i;
(void) memset(&server, 0x0, sizeof(server));
(void) memset(&challenge, 0x0, sizeof(challenge));
(void) memset(&id, 0x0, sizeof(id));
(void) memset(&netpgp, 0x0, sizeof(netpgp));
secretc = 64;
while ((i = getopt(argc, argv, "S:c:d:r:u:")) != -1) {
switch(i) {
case 'S':
netpgp_setvar(&netpgp, "ssh keys", "1");
netpgp_setvar(&netpgp, "sshkeyfile", optarg);
break;
case 'c':
secretc = atoi(optarg);
break;
case 'd':
challenge.domain = optarg;
break;
case 'r':
challenge.realm = optarg;
break;
case 'u':
netpgp_setvar(&netpgp, "userid", optarg);
break;
}
}
netpgp_setvar(&netpgp, "hash", DEFAULT_HASH_ALG);
netpgp_setvar(&netpgp, "need seckey", "1");
netpgp_setvar(&netpgp, "need userid", "1");
netpgp_set_homedir(&netpgp, getenv("HOME"),
netpgp_getvar(&netpgp, "ssh keys") ? "/.ssh" : "/.gnupg", 1);
if (!netpgp_init(&netpgp)) {
(void) fprintf(stderr, "can't initialise netpgp\n");
exit(EXIT_FAILURE);
}
if (!paa_server_init(&server, secretc)) {
(void) fprintf(stderr, "can't initialise paa server\n");
exit(EXIT_FAILURE);
}
/* format the challenge */
cc = paa_format_challenge(&challenge, &server, buf, sizeof(buf));
/* write challenge to temp file */
paa_write_file("challenge", buf, cc);
/* get the client to authenticate via paa, writing to temp response file */
system("client/paaclient -r authentication@bigco.com < challenge > response");
/* read in response */
cc = paa_read_file("response", buf, sizeof(buf));
if (!paa_check_response(&challenge, &id, &netpgp, buf)) {
(void) fprintf(stderr, "server: paa_check failed\n");
exit(EXIT_FAILURE);
}
printf("paa_check_response verified challenge: signature authenticated:\n");
paa_print_identity(stdout, &id);
printf("Changing buf[%d] from '%c' to '%c'\n", cc / 2, buf[cc / 2], buf[cc / 2] - 1);
buf[cc / 2] = buf[cc / 2] - 1;
if (paa_check_response(&challenge, &id, &netpgp, buf)) {
(void) fprintf(stderr, "server: unexpected paa_check pass\n");
exit(EXIT_FAILURE);
}
printf("paa_check_response verified challenge: signature not authenticated:\n");
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,10 @@
LIB=netrsa
SRCS=rsa.c stubs.c
MKMAN=no
WARNS=4
CPPFLAGS+=-I${.CURDIR}/../bn
INCS=rsa.h
INCSDIR=/usr/include/netpgp
.include <bsd.lib.mk>

View File

@@ -0,0 +1,113 @@
.\" $NetBSD: libnetpgprsa.3,v 1.4 2013/07/20 21:39:56 wiz Exp $
.\"
.\" Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd April 13, 2012
.Dt LIBNETPGPRSA 3
.Os
.Sh NAME
.Nm libnetpgprsa
.Nd BIGNUM library of multi-precision integers
.Sh LIBRARY
.Lb libnetpgprsa
.Sh SYNOPSIS
.In netpgp/rsa.h
.Ft RSA *
.Fo RSA_new
.Fa "void"
.Fc
.Ft int
.Fo RSA_size
.Fa "const RSA *rsa"
.Fc
.Ft void
.Fo RSA_free
.Fa "RSA *rsa"
.Fc
.Ft int
.Fo RSA_check_key
.Fa "RSA *rsa"
.Fc
.Ft RSA *
.Fo RSA_generate_key
.Fa "int num" "unsigned long e" "void (*callback)(int, int, void *)" "void *callbackarg"
.Fc
.Ft int
.Fo RSA_public_encrypt
.Fa "int siglen" "const uint8_t *signature" "uint8_t *to" "RSA *rsa" "int padding"
.Fc
.Ft int
.Fo RSA_private_encrypt
.Fa "int siglen" "const uint8_t *signature" "uint8_t *to" "RSA *rsa" "int padding"
.Fc
.Ft int
.Fo RSA_private_decrypt
.Fa "int siglen" "const uint8_t *signature" "uint8_t *to" "RSA *rsa" "int padding"
.Fc
.Pp
.Ft DSA *
.Fo DSA_new
.Fa "void"
.Fc
.Ft int
.Fo DSA_size
.Fa "const DSA *dsa"
.Fc
.Ft void
.Fo DSA_free
.Fa "DSA *dsa"
.Fc
.Ft DSA_SIG *
.Fo DSA_SIG_new
.Fa "void"
.Fc
.Ft void
.Fo DSA_SIG_free
.Fa "DSA_SIG *sig"
.Fc
.Ft int
.Fo DSA_do_verify
.Fa "const unsigned char *digest" "int digestlen" "DSA_SIG *sig" "DSA *dsa"
.Fc
.Ft int
.Fo DSA_do_sign
.Fa "const unsigned char *digest" "int digestlen" "DSA *dsa"
.Fc
.Sh DESCRIPTION
.Nm
is a small library which provides RSA signing,
encryption and decryption, and DSA signing.
RSA and DSA verification are provided by the
.Xr libnetpgpverify 3
library.
.Sh SEE ALSO
.Xr libnetpgpbn 3 ,
.Xr libnetpgpverify 3
.Sh HISTORY
The
.Nm
library first appeared in
.Nx 7.0 .
.Sh AUTHORS
.An Alistair Crooks Aq Mt agc@NetBSD.org

View File

@@ -0,0 +1,696 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/syslog.h>
#ifdef _KERNEL
# include <sys/kmem.h>
# define logmessage log
#else
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
#endif
#include "misc.h"
#include "digest.h"
#include "rsa.h"
#ifndef USE_ARG
#define USE_ARG(x) /*LINTED*/(void)&(x)
#endif
#define RSA_MAX_MODULUS_BITS 16384
#define RSA_SMALL_MODULUS_BITS 3072
#define RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */
static int
rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num)
{
USE_ARG(num);
if (flen > tlen) {
printf("r too large\n");
return -1;
}
(void) memset(to, 0x0, tlen - flen);
(void) memcpy(to + tlen - flen, from, flen);
return tlen;
}
static int
lowlevel_rsa_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa)
{
BIGNUM *decbn;
BIGNUM *signedbn;
uint8_t *decbuf;
int nbytes;
int signc;
int signedbytes;
int r;
decbuf = NULL;
r = -1;
decbn = BN_new();
signedbn = BN_new();
nbytes = BN_num_bytes(rsa->n);
decbuf = netpgp_allocate(1, nbytes);
/* add no padding */
memcpy(decbuf, plain, plainc);
BN_bin2bn(decbuf, nbytes, decbn);
if (BN_cmp(decbn, rsa->n) >= 0) {
printf("decbn too big\n");
goto err;
}
if (!BN_mod_exp(signedbn, decbn, rsa->d, rsa->n, NULL)) {
printf("bad mod_exp\n");
goto err;
}
signedbytes = BN_num_bytes(signedbn);
signc = BN_bn2bin(signedbn, &encbuf[nbytes - signedbytes]);
memset(encbuf, 0x0, nbytes - signc);
r = nbytes;
err:
netpgp_deallocate(decbuf, nbytes);
BN_clear_free(decbn);
BN_clear_free(signedbn);
return r;
}
static int
lowlevel_rsa_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa)
{
BIGNUM *decbn;
BIGNUM *encbn;
uint8_t *decbuf;
int nbytes;
int encc;
int r;
int i;
r = -1;
decbn = BN_new();
encbn = BN_new();
nbytes = BN_num_bytes(rsa->n);
decbuf = netpgp_allocate(1, nbytes);
(void) memcpy(decbuf, plain, plainc);
if (BN_bin2bn(decbuf, nbytes, decbn) == NULL) {
printf("bin2bn failed\n");
goto err;
}
if (BN_cmp(decbn, rsa->n) >= 0) {
printf("BN_cmp failed\n");
goto err;
}
if (!BN_mod_exp(encbn, decbn, rsa->e, rsa->n, NULL)) {
printf("BN_mod_exp failed\n");
goto err;
}
encc = BN_num_bytes(encbn);
i = BN_bn2bin(encbn, &encbuf[nbytes - encc]);
(void) memset(encbuf, 0x0, nbytes - i);
r = nbytes;
err:
if (decbuf) {
memset(decbuf, 0x0, nbytes);
netpgp_deallocate(decbuf, nbytes);
}
BN_clear_free(decbn);
BN_clear_free(encbn);
return r;
}
static int
lowlevel_rsa_private_decrypt(int enclen, const unsigned char *encbuf, unsigned char *to, RSA *rsa)
{
BIGNUM *encbn;
BIGNUM *decbn;
uint8_t *buf;
int nbytes;
int j;
int r;
r = -1;
decbn = encbn = NULL;
buf = NULL;
if (BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) {
return -1;
}
if (BN_cmp(rsa->n, rsa->e) <= 0) {
return -1;
}
encbn = BN_new();
decbn = BN_new();
nbytes = BN_num_bytes(rsa->n);
buf = netpgp_allocate(1, nbytes);
if (enclen > nbytes) {
printf("bad enclen\n");
goto err;
}
BN_bin2bn(encbuf, enclen, encbn);
if (BN_cmp(encbn, rsa->n) >= 0) {
printf("bad encbn\n");
goto err;
}
BN_mod_exp(decbn, encbn, rsa->d, rsa->n, NULL);
j = BN_bn2bin(decbn, buf);
r = rsa_padding_check_none(to, nbytes, buf, j, nbytes);
err:
BN_clear_free(encbn);
BN_clear_free(decbn);
netpgp_deallocate(buf, nbytes);
return r;
}
static int
lowlevel_rsa_public_decrypt(const uint8_t *encbuf, int enclen, uint8_t *dec, const rsa_pubkey_t *rsa)
{
uint8_t *decbuf;
BIGNUM *decbn;
BIGNUM *encbn;
int decbytes;
int nbytes;
int r;
nbytes = 0;
r = -1;
decbuf = NULL;
decbn = encbn = NULL;
if (BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) {
printf("rsa r modulus too large\n");
goto err;
}
if (BN_cmp(rsa->n, rsa->e) <= 0) {
printf("rsa r bad n value\n");
goto err;
}
if (BN_num_bits(rsa->n) > RSA_SMALL_MODULUS_BITS &&
BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) {
printf("rsa r bad exponent limit\n");
goto err;
}
if ((encbn = BN_new()) == NULL ||
(decbn = BN_new()) == NULL ||
(decbuf = netpgp_allocate(1, nbytes = BN_num_bytes(rsa->n))) == NULL) {
printf("allocation failure\n");
goto err;
}
if (enclen > nbytes) {
printf("rsa r > mod len\n");
goto err;
}
if (BN_bin2bn(encbuf, enclen, encbn) == NULL) {
printf("null encrypted BN\n");
goto err;
}
if (BN_cmp(encbn, rsa->n) >= 0) {
printf("rsa r data too large for modulus\n");
goto err;
}
if (BN_mod_exp(decbn, encbn, rsa->e, rsa->n, NULL) < 0) {
printf("BN_mod_exp < 0\n");
goto err;
}
decbytes = BN_num_bytes(decbn);
(void) BN_bn2bin(decbn, decbuf);
if ((r = rsa_padding_check_none(dec, nbytes, decbuf, decbytes, 0)) < 0) {
printf("rsa r padding check failed\n");
}
err:
BN_free(encbn);
BN_free(decbn);
if (decbuf != NULL) {
(void) memset(decbuf, 0x0, nbytes);
netpgp_deallocate(decbuf, nbytes);
}
return r;
}
#if 0
/**
@file rsa_make_key.c
RSA key generation, Tom St Denis
*/
/**
Create an RSA key
@param prng An active PRNG state
@param wprng The index of the PRNG desired
@param size The size of the modulus (key size) desired (octets)
@param e The "e" value (public key). e==65537 is a good choice
@param key [out] Destination of a newly created private key pair
@return CRYPT_OK if successful, upon error all allocated ram is freed
*/
static int
rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
{
void *p, *q, *tmp1, *tmp2, *tmp3;
int err;
LTC_ARGCHK(ltc_mp.name != NULL);
LTC_ARGCHK(key != NULL);
if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
return CRYPT_INVALID_KEYSIZE;
}
if ((e < 3) || ((e & 1) == 0)) {
return CRYPT_INVALID_ARG;
}
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
}
if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) {
return err;
}
/* make primes p and q (optimization provided by Wayne Scott) */
/* tmp3 = e */
if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) {
goto errkey;
}
/* make prime "p" */
do {
if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) {
goto errkey;
}
/* tmp1 = p-1 */
if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) {
goto errkey;
}
/* tmp2 = gcd(p-1, e) */
if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) {
goto errkey;
}
} while (mp_cmp_d( tmp2, 1) != 0);
/* while e divides p-1 */
/* make prime "q" */
do {
if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) {
goto errkey;
}
/* tmp1 = q-1 */
if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) {
goto errkey;
}
/* tmp2 = gcd(q-1, e) */
if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) {
goto errkey;
}
} while (mp_cmp_d( tmp2, 1) != 0);
/* while e divides q-1 */
/* tmp1 = lcm(p-1, q-1) */
/* tmp2 = p-1 */
if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) {
goto errkey;
}
/* tmp1 = q-1 (previous do/while loop) */
/* tmp1 = lcm(p-1, q-1) */
if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) {
goto errkey;
}
/* make key */
if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
goto errkey;
}
/* key->e = e */
if ((err = mp_set_int( key->e, e)) != CRYPT_OK) {
goto errkey;
}
/* key->d = 1/e mod lcm(p-1,q-1) */
if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) {
goto errkey;
}
/* key->N = pq */
if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) {
goto errkey;
}
/* optimize for CRT now */
/* find d mod q-1 and d mod p-1 */
/* tmp1 = q-1 */
if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) {
goto errkey;
}
/* tmp2 = p-1 */
if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) {
goto errkey;
}
/* dP = d mod p-1 */
if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) {
goto errkey;
}
/* dQ = d mod q-1 */
if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) {
goto errkey;
}
/* qP = 1/q mod p */
if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) {
got oerrkey;
}
if ((err = mp_copy( p, key->p)) != CRYPT_OK) {
goto errkey;
}
if ((err = mp_copy( q, key->q)) != CRYPT_OK) {
goto errkey;
}
/* set key type (in this case it's CRT optimized) */
key->type = PK_PRIVATE;
/* return ok and free temps */
err = CRYPT_OK;
goto cleanup;
errkey:
mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
cleanup:
mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL);
return err;
}
#endif
#define HASHBUF_LEN 512
#define DSA_MAX_MODULUS_BITS 10000
static int
dsa_do_verify(const unsigned char *calculated, int dgst_len, const dsasig_t *sig, mpi_dsa_t *dsa)
{
BIGNUM *M;
BIGNUM *W;
BIGNUM *t1;
int ret = -1;
int qbits;
if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
return 0;
}
M = W = t1 = NULL;
qbits = BN_num_bits(dsa->q);
switch(qbits) {
case 160:
case 224:
case 256:
/* openssl sources say these are the valid values */
/* according to FIPS 186-3 */
break;
default:
printf("dsa: bad # of Q bits\n");
return 0;
}
if (BN_num_bits(dsa->p) > DSA_MAX_MODULUS_BITS) {
printf("dsa: p too large\n");
return 0;
}
/* no love for SHA512? */
if (dgst_len > SHA256_DIGEST_LENGTH) {
printf("dsa: digest too long\n");
return 0;
}
ret = 0;
if ((M = BN_new()) == NULL ||
(W = BN_new()) == NULL ||
(t1 = BN_new()) == NULL) {
goto err;
}
if (BN_is_zero(sig->r) ||
BN_is_negative(sig->r) ||
BN_cmp(sig->r, dsa->q) >= 0) {
goto err;
}
if (BN_is_zero(sig->s) ||
BN_is_negative(sig->s) ||
BN_cmp(sig->s, dsa->q) >= 0) {
goto err;
}
if (BN_mod_inverse(W, sig->s, dsa->q, NULL) != MP_OKAY) {
goto err;
}
if (dgst_len > qbits / 8) {
dgst_len = qbits / 8;
}
if (BN_bin2bn(calculated, dgst_len, M) == NULL) {
goto err;
}
if (!BN_mod_mul(M, M, W, dsa->q, NULL)) {
goto err;
}
if (!BN_mod_mul(W, sig->r, W, dsa->q, NULL)) {
goto err;
}
if (!BN_mod_exp(dsa->p, t1, dsa->g, M, NULL)) {
goto err;
}
if (!BN_div(NULL, M, t1, dsa->q, NULL)) {
goto err;
}
ret = (BN_cmp(M, sig->r) == 0);
err:
if (M) {
BN_free(M);
}
if (W) {
BN_free(W);
}
if (t1) {
BN_free(t1);
}
return ret;
}
/*************************************************************************/
int
RSA_size(const RSA *rsa)
{
return (rsa == NULL) ? 0 : BN_num_bits(rsa->n);
}
int
DSA_size(const DSA *dsa)
{
return (dsa == NULL) ? 0 : BN_num_bits(dsa->p);
}
unsigned
dsa_verify(const signature_t *signature, const dsa_pubkey_t *pubdsa, const uint8_t *calculated, size_t hash_length)
{
mpi_dsa_t odsa;
dsasig_t osig;
unsigned qlen;
int ret;
if (signature == NULL || pubdsa == NULL || calculated == NULL) {
return -1;
}
(void) memset(&osig, 0x0, sizeof(osig));
(void) memset(&odsa, 0x0, sizeof(odsa));
BN_copy(osig.r, signature->dsa.r);
BN_copy(osig.s, signature->dsa.s);
odsa.p = pubdsa->p;
odsa.q = pubdsa->q;
odsa.g = pubdsa->g;
odsa.pub_key = pubdsa->y;
if ((qlen = BN_num_bytes(odsa.q)) < hash_length) {
hash_length = qlen;
}
ret = dsa_do_verify(calculated, (int)hash_length, &signature->dsa, &odsa);
if (ret < 0) {
return 0;
}
BN_free(odsa.p);
BN_free(odsa.q);
BN_free(odsa.g);
BN_free(odsa.pub_key);
odsa.p = odsa.q = odsa.g = odsa.pub_key = NULL;
BN_free(osig.r);
BN_free(osig.s);
osig.r = osig.s = NULL;
return (unsigned)ret;
}
RSA *
RSA_new(void)
{
return netpgp_allocate(1, sizeof(RSA));
}
void
RSA_free(RSA *rsa)
{
if (rsa) {
netpgp_deallocate(rsa, sizeof(*rsa));
}
}
int
RSA_check_key(RSA *rsa)
{
BIGNUM *calcn;
int ret;
ret = 0;
if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->n == NULL) {
return -1;
}
/* check that p and q are coprime, and that n = p*q. */
if (!BN_is_prime(rsa->p, 1, NULL, NULL, NULL) ||
!BN_is_prime(rsa->q, 1, NULL, NULL, NULL)) {
return 0;
}
calcn = BN_new();
BN_mul(calcn, rsa->p, rsa->q, NULL);
if (BN_cmp(calcn, rsa->n) != 0) {
goto errout;
}
/* XXX - check that d*e = 1 mod (p-1*q-1) */
ret = 1;
errout:
BN_clear_free(calcn);
return ret;
}
RSA *
RSA_generate_key(int num, unsigned long e, void (*callback)(int,int,void *), void *cb_arg)
{
/* STUBBED */
USE_ARG(num);
USE_ARG(e);
USE_ARG(callback);
USE_ARG(cb_arg);
printf("RSA_generate_key stubbed\n");
return RSA_new();
}
/* encrypt */
int
RSA_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa, int padding)
{
USE_ARG(padding);
if (plain == NULL || encbuf == NULL || rsa == NULL) {
return -1;
}
return lowlevel_rsa_public_encrypt(plainc, plain, encbuf, rsa);
}
/* decrypt */
int
RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
USE_ARG(padding);
if (from == NULL || to == NULL || rsa == NULL) {
return -1;
}
return lowlevel_rsa_private_decrypt(flen, from, to, rsa);
}
/* sign */
int
RSA_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa, int padding)
{
USE_ARG(padding);
if (plain == NULL || encbuf == NULL || rsa == NULL) {
return -1;
}
return lowlevel_rsa_private_encrypt(plainc, plain, encbuf, rsa);
}
/* verify */
int
RSA_public_decrypt(int enclen, const unsigned char *enc, unsigned char *dec, RSA *rsa, int padding)
{
rsa_pubkey_t pub;
int ret;
if (enc == NULL || dec == NULL || rsa == NULL) {
return 0;
}
USE_ARG(padding);
(void) memset(&pub, 0x0, sizeof(pub));
pub.n = BN_dup(rsa->n);
pub.e = BN_dup(rsa->e);
ret = lowlevel_rsa_public_decrypt(enc, enclen, dec, &pub);
BN_free(pub.n);
BN_free(pub.e);
return ret;
}
/***********************************************************************/
DSA *
DSA_new(void)
{
return netpgp_allocate(1, sizeof(DSA));
}
void
DSA_free(DSA *dsa)
{
if (dsa) {
netpgp_deallocate(dsa, sizeof(*dsa));
}
}
DSA_SIG *
DSA_SIG_new(void)
{
return netpgp_allocate(1, sizeof(DSA_SIG));
}
void
DSA_SIG_free(DSA_SIG *sig)
{
if (sig) {
netpgp_deallocate(sig, sizeof(*sig));
}
}
DSA_SIG *
DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
/* STUBBED */
USE_ARG(dgst);
USE_ARG(dlen);
USE_ARG(dsa);
printf("DSA_do_sign stubbed\n");
return DSA_SIG_new();
}
int
DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa)
{
if (dgst == NULL || dgst_len == 0 || sig == NULL || dsa == NULL) {
return -1;
}
return dsa_do_verify(dgst, dgst_len, sig, dsa);
}

View File

@@ -0,0 +1,155 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RSA_H_
#define RSA_H_ 20120325
#include "bn.h"
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
typedef struct rsa_pubkey_t {
BIGNUM *n; /* RSA public modulus n */
BIGNUM *e; /* RSA public encryption exponent e */
} rsa_pubkey_t;
typedef struct mpi_rsa_t {
int f1; /* openssl pad */
long f2; /* openssl version */
const void *f3; /* openssl method */
void *f4; /* openssl engine */
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
} mpi_rsa_t;
#define RSA mpi_rsa_t
typedef struct dsa_pubkey_t {
BIGNUM *p; /* DSA public modulus n */
BIGNUM *q; /* DSA public encryption exponent e */
BIGNUM *g;
BIGNUM *y;
} dsa_pubkey_t;
typedef struct mpi_dsa_t {
BIGNUM *p;
BIGNUM *q;
BIGNUM *g;
BIGNUM *y;
BIGNUM *x;
BIGNUM *pub_key;
BIGNUM *priv_key;
} mpi_dsa_t;
#define DSA mpi_dsa_t
typedef struct rsasig_t {
BIGNUM *sig; /* mpi which is actual signature */
} rsasig_t;
typedef struct dsasig_t {
BIGNUM *r; /* mpi which is actual signature */
BIGNUM *s; /* mpi which is actual signature */
} dsasig_t;
#define DSA_SIG dsasig_t
/* misc defs */
#define RSA_NO_PADDING 3
#define SIGNETBSD_ID_SIZE 8
#define SIGNETBSD_NAME_SIZE 128
#define RSA_PUBKEY_ALG 1
#define DSA_PUBKEY_ALG 17
/* the public part of the key */
typedef struct pubkey_t {
uint32_t version; /* key version - usually 4 */
uint8_t id[SIGNETBSD_ID_SIZE]; /* binary id */
char name[SIGNETBSD_NAME_SIZE]; /* name of identity - not necessary, but looks better */
int64_t birthtime; /* time of creation of key */
int64_t expiry; /* expiration time of the key */
uint32_t validity; /* validity in days */
uint32_t alg; /* pubkey algorithm - rsa/dss etc */
rsa_pubkey_t rsa; /* specific RSA keys */
dsa_pubkey_t dsa; /* specific DSA keys */
} pubkey_t;
/* signature details (for a specific file) */
typedef struct signature_t {
uint32_t version; /* signature version number */
uint32_t type; /* signature type value */
int64_t birthtime; /* creation time of the signature */
int64_t expiry; /* expiration time of the signature */
uint8_t id[SIGNETBSD_ID_SIZE]; /* binary id */
uint32_t key_alg; /* public key algorithm number */
uint32_t hash_alg; /* hashing algorithm number */
rsasig_t rsa; /* RSA signature */
dsasig_t dsa; /* DSA signature */
size_t v4_hashlen; /* length of hashed info */
uint8_t *v4_hashed; /* hashed info */
uint8_t hash2[2]; /* high 2 bytes of hashed value - for quick test */
pubkey_t *signer; /* pubkey of signer */
} signature_t;
unsigned dsa_verify(const signature_t */*sig*/, const dsa_pubkey_t */*pubdsa*/, const uint8_t */*calc*/, size_t /*hashlen*/);
RSA *RSA_new(void);
int RSA_size(const RSA */*rsa*/);
void RSA_free(RSA */*rsa*/);
int RSA_check_key(RSA */*rsa*/);
RSA *RSA_generate_key(int /*num*/, unsigned long /*e*/, void (*callback)(int,int,void *), void */*cb_arg*/);
int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int RSA_public_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding);
DSA *DSA_new(void);
int DSA_size(const DSA */*rsa*/);
void DSA_free(DSA */*dsa*/);
DSA_SIG *DSA_SIG_new(void);
void DSA_SIG_free(DSA_SIG */*sig*/);
int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa);
DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
__END_DECLS
#endif

View File

@@ -0,0 +1,83 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include "rsa.h"
#include "rsastubs.h"
#ifndef USE_ARG
#define USE_ARG(x) /*LINTED*/(void)&(x)
#endif
static int
pass_cb(char *buf, int size, int rwflag, void *u)
{
char *passphrase;
char prompt[128];
USE_ARG(rwflag);
snprintf(prompt, sizeof(prompt), "\"%s\" passphrase: ", (char *)u);
if ((passphrase = getpass(prompt)) == NULL) {
return -1;
}
(void) memcpy(buf, passphrase, (size_t)size);
return (int)strlen(passphrase);
}
RSA *
PEM_read_RSAPrivateKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u)
{
char phrase[128 + 1];
RSA *rsa;
int cc;
fprintf(stderr, "Stubbed PEM_read_RSAPrivateKey\n");
USE_ARG(u);
if (cb == NULL) {
cb = pass_cb;
}
cc = (*cb)(phrase, sizeof(phrase), 0, u);
rsa = *x = RSA_new();
USE_ARG(fp);
return rsa;
}
DSA *
PEM_read_DSAPrivateKey(FILE *fp, DSA **x, pem_password_cb *cb, void *u)
{
DSA *dsa;
USE_ARG(u);
if (cb == NULL) {
cb = pass_cb;
}
dsa = *x = DSA_new();
USE_ARG(fp);
return dsa;
}

View File

@@ -0,0 +1,25 @@
#ifndef RSASTUBS_H_
#define RSASTUBS_H_ 20120412
#include "rsa.h"
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
typedef int pem_password_cb(char */*buf*/, int /*size*/, int /*rwflag*/, void */*userdata*/);
RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u);
DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **x, pem_password_cb *cb, void *u);
__END_DECLS
#endif

View File

@@ -0,0 +1,71 @@
# $NetBSD: Makefile,v 1.2 2012/11/20 05:26:25 agc Exp $
PROG=netpgpv
SRCS=libverify.c b64.c pgpsum.c
SRCS+=digest.c tiger.c
SRCS+=bignum.c misc.c
SRCS+=rsaglue.c rsa.c
SRCS+=main.c
WARNS=5
MKMAN=no
CPPFLAGS+=-I${.CURDIR}/../libbn
CPPFLAGS+=-I${.CURDIR}/../librsa
LDADD+=-lz
LDADD+=-lbz2
# XXX - debugging
#CPPFLAGS+=-g -O0
#LDFLAGS+=-g -O0
#CPPFLAGS+=-O3
#LDFLAGS+=-O3
.PATH: ${.CURDIR} ${.CURDIR}/../libdigest ${.CURDIR}/../libverify ${.CURDIR}/../libbn ${.CURDIR}/../librsa
.include <bsd.prog.mk>
t: ${PROG}
./${PROG} -c verify b.gpg > output16
diff expected16 output16
rm -f output16
./${PROG} -c verify a.gpg > output17
diff expected17 output17
rm -f output17
./${PROG} -c verify gpgsigned-a.gpg > output18
diff expected18 output18
rm -f output18
./${PROG} -c verify NetBSD-6.0_RC2_hashes.asc > output19
diff expected19 output19
rm -f output19
./${PROG} -c cat jj.asc > output20
diff expected20 output20
rm -f output20
./${PROG} < a.gpg > output21
diff expected21 output21
rm -f output21
./${PROG} < jj.asc > output22
diff expected22 output22
rm -f output22
./${PROG} < NetBSD-6.0_RC2_hashes.asc > output23
diff expected23 output23
rm -f output23
./${PROG} < b.gpg > output24
diff expected24 output24
rm -f output24
./${PROG} NetBSD-6.0_RC1_hashes.gpg > output25
diff expected25 output25
rm -f output25
./${PROG} < NetBSD-6.0_RC1_hashes.gpg > output26
diff expected26 output26
rm -f output26
./${PROG} < NetBSD-6.0_hashes.asc > output27
diff expected27 output27
rm -f output27
./${PROG} NetBSD-6.0_hashes.asc > output28
diff expected28 output28
rm -f output28
./${PROG} NetBSD-6.0_RC1_hashes_ascii.gpg > output29
diff expected29 output29
rm -f output29
./${PROG} < NetBSD-6.0_RC1_hashes_ascii.gpg > output30
diff expected30 output30
rm -f output30

View File

@@ -0,0 +1,82 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARRAY_H_
#define ARRAY_H_ 20120921
#ifndef PGPV_ARRAY
/* creates 2 unsigned vars called "name"c and "name"size in current scope */
/* also creates an array called "name"s in current scope */
#define PGPV_ARRAY(type, name) \
unsigned name##c; unsigned name##vsize; type *name##s
#endif
/* if this isn't part of a struct, need to specifically initialise things */
#define ARRAY_INIT(name) do { \
name##c = name##vsize = 0; \
name##s = NULL; \
} while(/*CONSTCOND*/0)
/* check the array is big enough - if not, expand it by explicit amount */
/* this is clunky, but there are bugs a-lurking */
#define ARRAY_EXPAND_SIZED(name, mult, add) do { \
if (name##c == name##vsize) { \
void *_v; \
char *_cv = NULL; \
unsigned _ents; \
_ents = (name##vsize * (mult)) + (add); \
_cv = _v = realloc(name##s, _ents * sizeof(*name##s)); \
if (_v == NULL) { \
fprintf(stderr, "ARRAY_EXPAND - bad realloc\n"); \
} else { \
memset(&_cv[name##vsize * sizeof(*name##s)], \
0x0, (_ents - name##vsize) * sizeof(*name##s)); \
name##s = _v; \
name##vsize = _ents; \
} \
} \
} while(/*CONSTCOND*/0)
/* check the array is big enough - if not, expand it (size * 2) + 10 */
#define ARRAY_EXPAND(name) ARRAY_EXPAND_SIZED(name, 2, 10)
#define ARRAY_ELEMENT(name, num) name##s[num]
#define ARRAY_LAST(name) name##s[name##c - 1]
#define ARRAY_COUNT(name) name##c
#define ARRAY_SIZE(name) name##vsize
#define ARRAY_ARRAY(name) name##s
#define ARRAY_APPEND(name, newel) do { \
ARRAY_EXPAND(name); \
ARRAY_COUNT(name) += 1; \
ARRAY_LAST(name) = newel; \
} while(/*CONSTCOND*/0)
#define ARRAY_DELETE(name, num) do { \
ARRAY_COUNT(name) -= 1; \
memmove(&ARRAY_ELEMENT(name, num), &ARRAY_ELEMENT(name, num + 1), \
(ARRAY_COUNT(name) - (num)) * sizeof(ARRAY_ELEMENT(name, 0))); \
} while(/*CONSTCOND*/0)
#endif

View File

@@ -0,0 +1,355 @@
/*********************************************************************\
MODULE NAME: b64.c
AUTHOR: Bob Trower 08/04/01
PROJECT: Crypt Data Packaging
COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001
NOTE: This source code may be used as you wish, subject to
the MIT license. See the LICENCE section below.
DESCRIPTION:
This little utility implements the Base64
Content-Transfer-Encoding standard described in
RFC1113 (http://www.faqs.org/rfcs/rfc1113.html).
This is the coding scheme used by MIME to allow
binary data to be transferred by SMTP mail.
Groups of 3 bytes from a binary stream are coded as
groups of 4 bytes in a text stream.
The input stream is 'padded' with zeros to create
an input that is an even multiple of 3.
A special character ('=') is used to denote padding so
that the stream can be decoded back to its exact size.
Encoded output is formatted in lines which should
be a maximum of 72 characters to conform to the
specification. This program defaults to 72 characters,
but will allow more or less through the use of a
switch. The program enforces a minimum line size
of 4 characters.
Example encoding:
The stream 'ABCD' is 32 bits long. It is mapped as
follows:
ABCD
A (65) B (66) C (67) D (68) (None) (None)
01000001 01000010 01000011 01000100
16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=)
010000 010100 001001 000011 010001 000000 000000 000000
QUJDRA==
Decoding is the process in reverse. A 'decode' lookup
table has been created to avoid string scans.
DESIGN GOALS: Specifically:
Code is a stand-alone utility to perform base64
encoding/decoding. It should be genuinely useful
when the need arises and it meets a need that is
likely to occur for some users.
Code acts as sample code to show the author's
design and coding style.
Generally:
This program is designed to survive:
Everything you need is in a single source file.
It compiles cleanly using a vanilla ANSI C compiler.
It does its job correctly with a minimum of fuss.
The code is not overly clever, not overly simplistic
and not overly verbose.
Access is 'cut and paste' from a web page.
Terms of use are reasonable.
VALIDATION: Non-trivial code is never without errors. This
file likely has some problems, since it has only
been tested by the author. It is expected with most
source code that there is a period of 'burn-in' when
problems are identified and corrected. That being
said, it is possible to have 'reasonably correct'
code by following a regime of unit test that covers
the most likely cases and regression testing prior
to release. This has been done with this code and
it has a good probability of performing as expected.
Unit Test Cases:
case 0:empty file:
CASE0.DAT -> ->
(Zero length target file created
on both encode and decode.)
case 1:One input character:
CASE1.DAT A -> QQ== -> A
case 2:Two input characters:
CASE2.DAT AB -> QUJD -> AB
case 3:Three input characters:
CASE3.DAT ABC -> QUJD -> ABC
case 4:Four input characters:
case4.dat ABCD -> QUJDRA== -> ABCD
case 5:All chars from 0 to ff, linesize set to 50:
AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj
JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH
SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr
bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P
kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz
tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX
2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7
/P3+/w==
case 6:Mime Block from e-mail:
(Data same as test case 5)
case 7: Large files:
Tested 28 MB file in/out.
case 8: Random Binary Integrity:
This binary program (b64.exe) was encoded to base64,
back to binary and then executed.
case 9 Stress:
All files in a working directory encoded/decoded
and compared with file comparison utility to
ensure that multiple runs do not cause problems
such as exhausting file handles, tmp storage, etc.
-------------
Syntax, operation and failure:
All options/switches tested. Performs as
expected.
case 10:
No Args -- Shows Usage Screen
Return Code 1 (Invalid Syntax)
case 11:
One Arg (invalid) -- Shows Usage Screen
Return Code 1 (Invalid Syntax)
case 12:
One Arg Help (-?) -- Shows detailed Usage Screen.
Return Code 0 (Success -- help request is valid).
case 13:
One Arg Help (-h) -- Shows detailed Usage Screen.
Return Code 0 (Success -- help request is valid).
case 14:
One Arg (valid) -- Uses stdin/stdout (filter)
Return Code 0 (Sucess)
case 15:
Two Args (invalid file) -- shows system error.
Return Code 2 (File Error)
case 16:
Encode non-existent file -- shows system error.
Return Code 2 (File Error)
case 17:
Out of disk space -- shows system error.
Return Code 3 (File I/O Error)
-------------
Compile/Regression test:
gcc compiled binary under Cygwin
Microsoft Visual Studio under Windows 2000
Microsoft Version 6.0 C under Windows 2000
DEPENDENCIES: None
LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall
be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
VERSION HISTORY:
Bob Trower 08/04/01 -- Create Version 0.00.00B
\******************************************************************* */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include "b64.h"
/*
** Translation Table as described in RFC1113
*/
static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
** Translation Table to decode (created by author)
*/
static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
/*
** encodeblock
**
** encode 3 8-bit binary bytes as 4 '6-bit' characters
*/
static void
encodeblock(uint8_t *wordin, uint8_t *wordout, int wordlen)
{
wordout[0] = cb64[(unsigned)wordin[0] >> 2];
wordout[1] = cb64[((unsigned)(wordin[0] & 0x03) << 4) | ((unsigned)(wordin[1] & 0xf0) >> 4)];
wordout[2] = (uint8_t)(wordlen > 1) ?
cb64[((unsigned)(wordin[1] & 0x0f) << 2) | ((unsigned)(wordin[2] & 0xc0) >> 6)] : '=';
wordout[3] = (uint8_t)(wordlen > 2) ? cb64[wordin[2] & 0x3f] : '=';
}
/*
** encode
**
** base64 encode a stream adding padding and line breaks as per spec.
*/
int
b64encode(const char *in, const size_t insize, void *vp, size_t outsize, int linesize)
{
const char *inp;
unsigned i;
uint8_t wordout[4];
uint8_t wordin[3];
char *out = vp;
char *outp;
int blocksout;
int wordlen;
if (in == NULL || vp == NULL) {
return 0;
}
wordlen = 0;
for (blocksout = 0, inp = in, outp = out; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize;) {
for (wordlen = 0, i = 0; i < sizeof(wordin); i++) {
wordin[i] = (uint8_t) *inp++;
if ((size_t)(inp - in) <= insize) {
wordlen++;
} else {
wordin[i] = 0x0;
}
}
if (wordlen > 0) {
encodeblock(wordin, wordout, wordlen);
for (i = 0; i < sizeof(wordout) ; i++) {
*outp++ = wordout[i];
}
blocksout++;
}
if (linesize > 0) {
if (blocksout >= (int)(linesize / sizeof(wordout)) ||
(size_t)(inp - in) >= insize) {
if (blocksout) {
*outp++ = '\r';
*outp++ = '\n';
}
blocksout = 0;
}
}
}
return (int)(outp - out);
}
/*
** decodeblock
**
** decode 4 '6-bit' characters into 3 8-bit binary bytes
*/
static void
decodeblock(uint8_t wordin[4], uint8_t wordout[3])
{
wordout[0] = (uint8_t) ((unsigned)wordin[0] << 2 | (unsigned)wordin[1] >> 4);
wordout[1] = (uint8_t) ((unsigned)wordin[1] << 4 | (unsigned)wordin[2] >> 2);
wordout[2] = (uint8_t) (((wordin[2] << 6) & 0xc0) | wordin[3]);
}
/*
** decode
**
** decode a base64 encoded stream discarding padding, line breaks and noise
*/
int
b64decode(const char *in, const size_t insize, void *vp, size_t outsize)
{
const char *inp;
unsigned wordlen;
unsigned i;
uint8_t wordout[3];
uint8_t wordin[4];
uint8_t v;
char *out = vp;
char *outp;
if (in == NULL || vp == NULL) {
return 0;
}
for (inp = in, outp = out ; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize ; ) {
for (wordlen = 0, i = 0 ; i < sizeof(wordin) && (size_t)(inp - in) < insize ; i++) {
/* get a single character */
for (v = 0; (size_t)(inp - in) <= insize && v == 0 ; ) {
if (*inp == '\r' && *(inp + 1) == '\n') {
inp += 2;
} else {
v = (uint8_t) *inp++;
v = (uint8_t) ((v < 43 || v > 122) ? 0 : cd64[v - 43]);
if (v) {
v = (uint8_t) ((v == '$') ? 0 : v - 61);
}
}
}
/* perhaps 0x0 pad */
if ((size_t)(inp - in) <= insize) {
wordlen += 1;
if (v) {
wordin[i] = (uint8_t) (v - 1);
}
} else {
wordin[i] = 0x0;
}
}
if (wordlen > 0) {
decodeblock(wordin, wordout);
for (i = 0; i < wordlen - 1 ; i++) {
*outp++ = wordout[i];
}
}
}
return (int)(outp - out);
}
/* return the encoded size for n bytes input */
int
b64_encsize(unsigned n)
{
return ((4 * n) / 3) + 4;
}

View File

@@ -0,0 +1,32 @@
/*-
* Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef B64_H_
#define B64_H_ 20091223
int b64encode(const char */*in*/, const size_t /*insize*/, void */*vp*/, size_t /*outsize*/, int /*linesize*/);
int b64decode(const char */*in*/, const size_t /*insize*/, void */*vp*/, size_t /*outsize*/);
int b64_encsize(unsigned /*n*/);
#endif

View File

@@ -0,0 +1,88 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef isprint
#define isprint(x) ((x) >= ' ' && (x) <= '~')
#endif
#define HEXDUMP_LINELEN 16
#ifndef PRIsize
#define PRIsize "z"
#endif
/* show hexadecimal/ascii dump */
static ssize_t
hexdump(const char *in, const size_t len, void *outvp, size_t size)
{
size_t i;
char line[HEXDUMP_LINELEN + 1];
char *out = (char *)outvp;
int o;
for (i = 0, o = 0 ; i < len ; i++) {
if (i % HEXDUMP_LINELEN == 0) {
o += snprintf(&out[o], size - o,
"%.5" PRIsize "u | ", i);
}
o += snprintf(&out[o], size - o, "%.02x ", (uint8_t)in[i]);
line[i % HEXDUMP_LINELEN] =
(isprint((uint8_t)in[i])) ? in[i] : '.';
if (i % HEXDUMP_LINELEN == HEXDUMP_LINELEN - 1) {
line[HEXDUMP_LINELEN] = 0x0;
o += snprintf(&out[o], size - o, " | %s\n", line);
}
}
if (i % HEXDUMP_LINELEN != 0) {
for ( ; i % HEXDUMP_LINELEN != 0 ; i++) {
o += snprintf(&out[o], size - o, " ");
line[i % HEXDUMP_LINELEN] = ' ';
}
line[HEXDUMP_LINELEN] = 0x0;
o += snprintf(&out[o], size - o, " | %s\n", line);
}
return (ssize_t)o;
}
void dumpmem(void */*p*/, size_t /*size*/);
/* just dump an area of memory to stdout */
void
dumpmem(void *vp, size_t size)
{
ssize_t cc;
uint8_t *p = (uint8_t *)vp;
char *buf;
buf = calloc(1, size * 5);
cc = hexdump((const char *)p, size, buf, size * 5);
fprintf(stdout, "%.*s\n", (int)cc, buf);
free(buf);
}

View File

@@ -0,0 +1,139 @@
.\" $NetBSD: libnetpgpverify.3,v 1.4 2013/07/20 21:39:56 wiz Exp $
.\"
.\" Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd October 21, 2012
.Dt LIBNETPGPVERIFY 3
.Os
.Sh NAME
.Nm libnetpgpverify
.Nd library to verify digital signatures
.Sh LIBRARY
.Lb libnetpgpverify
.Sh SYNOPSIS
.In netpgp/verify.h
.Ft int
.Fo pgpv_read_pubring
.Fa "pgpv_t *pgp" "const void *keyring" "ssize_t size"
.Fc
.Ft size_t
.Fo pgpv_verify
.Fa "pgpv_cursor_t *cursor" "pgpv_t *pgp" "const void *ptr" "ssize_t size"
.Fc
.Ft size_t
.Fo pgpv_get_verified
.Fa "pgpv_cursor_t *cursor" "size_t cookie " "char **ret"
.Fc
.Ft size_t
.Fo pgpv_get_entry
.Fa "pgpv_t *pgp" "unsigned ent" "char **ret"
.Fc
.Ft int
.Fo pgpv_close
.Fa "pgpv_t *pgp"
.Fc
.Sh DESCRIPTION
.Nm
is a small library which will verify a digital signature on a text or
binary document.
It has been kept deliberately small and only uses compression libraries
to function.
.Pp
PGP messages, including key rings, are made up of PGP packets, defined
in RFC 4880.
To match a digital signature, the public key of the signer must be
located in a public key ring.
This library has enough functionality to parse a pubkey keyring,
using
.Fn pgpv_read_pubring
to read the public keys of trusted identities,
and to read files or memory which has already been signed.
The
.Fn pgpv_verify
function is used to verify the signature, either on data, or on memory.
To signal to
.Fn pgpv_verify
to read a file and verify it, the
.Dv size
argument should be set to
.Dv -1
whilst a positive size signals that the pointer value should be that
of signed memory.
.Fn pgpv_verify
returns a cookie if the ignature was verified, or 0 if it did not.
This cookie can subsequently be used to retrieve the data which
was verified.
.Pp
If the signature does match, then the file or memory can be considered as being
verified as being unmodified and unchanged, integrally sound.
.Pp
Signatures have validity dates on them, and it is possible for a signature to
have expired when it is being checked.
If for any reason the signature does not match, then the reason for not
verifying the signature will be stored in the
.Dv why
buffer in the
.Dv pgpv_cursor_t
structure.
.Pp
Occasionally, the memory or contents of the file which matched the signature
will be needed, rather than a boolean value of whether it was verified.
To do this, the
.Fn pgpv_get_verified
function is used.
Arguments to
.Fn pgpv_get_verified
are the cookie returned from the verification, and a buffer
allocated for the returned data and its size.
If an error occurs, or the signature is not verified, a zero value is returned
for the size.
.Nm
stores the starts of the data of all verified matches, and so the entry
number argument is the index of the occurrence of verification.
The first match will have an entry number of 0, the second 1, and so on.
.Pp
The
.Fn pgpv_close
function is used to clean up after all matching and verification has taken place.
It frees and de-allocates all resources used in the verification of the signature.
.Pp
The program used for signing may encode into base64 encoding, and it may also
use embedded compression to make the output smaller than it would otherwise be.
This is handled automatically by
.Nm
.Sh SEE ALSO
.Xr bn 3 ,
.\" .Xr bzlib2 3 ,
.Xr zlib 3
.Sh STANDARDS
The
.Nm
utility is designed to conform to IETF RFC 4880.
.Sh HISTORY
The
.Nm
library first appeared in
.Nx 7.0 .
.Sh AUTHORS
.An Alistair Crooks Aq Mt agc@NetBSD.org

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,192 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <err.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "digest.h"
#include "pgpsum.h"
#ifndef USE_ARG
#define USE_ARG(x) /*LINTED*/(void)&(x)
#endif
/* add the ascii armor line endings (except for last line) */
static size_t
don_armor(digest_t *hash, uint8_t *in, size_t insize, int doarmor)
{
uint8_t *from;
uint8_t *newp;
uint8_t *p;
uint8_t dos_line_end[2];
dos_line_end[0] = '\r';
dos_line_end[1] = '\n';
for (from = in ; (p = memchr(from, '\n', insize - (size_t)(from - in))) != NULL ; from = p + 1) {
for (newp = p ; doarmor == 'w' && newp > from ; --newp) {
if (*(newp - 1) != ' ' && *(newp - 1) != '\t') {
break;
}
}
digest_update(hash, from, (size_t)(newp - from));
digest_update(hash, dos_line_end, sizeof(dos_line_end));
}
digest_update(hash, from, insize - (size_t)(from - in));
return 1;
}
#ifdef NETPGPV_DEBUG
/* just for giggles, write what we're about to checksum */
static int
writefile(uint8_t *mem, size_t insize)
{
size_t cc;
size_t wc;
char template[256];
int fd;
snprintf(template, sizeof(template), "netpgpvmd.XXXXXX");
if ((fd = mkstemp(template)) < 0) {
fprintf(stderr, "can't mkstemp %s\n", template);
return 0;
}
for (cc = 0 ; cc < insize ; cc += wc) {
if ((wc = write(fd, &mem[cc], insize - cc)) <= 0) {
fprintf(stderr, "short write\n");
break;
}
}
close(fd);
return 1;
}
#endif
/* return non-zero if this is actually an armored piece already */
static int
already_armored(uint8_t *in, size_t insize)
{
uint8_t *from;
uint8_t *p;
for (from = in ; (p = memchr(from, '\n', insize - (size_t)(from - in))) != NULL ; from = p + 1) {
if (*(p - 1) != '\r') {
return 0;
}
}
return 1;
}
/* calculate the checksum for the data we have */
static int
calcsum(uint8_t *out, size_t size, uint8_t *mem, size_t cc, const uint8_t *hashed, size_t hashsize, int doarmor)
{
digest_t hash;
uint32_t len32;
uint16_t len16;
uint8_t hashalg;
uint8_t trailer[6];
USE_ARG(size);
/* hashed data is non-null (previously checked) */
hashalg = hashed[3];
memcpy(&len16, &hashed[4], sizeof(len16));
len32 = ntohs(len16) + 6;
len32 = htonl(len32);
trailer[0] = 0x04;
trailer[1] = 0xff;
memcpy(&trailer[2], &len32, sizeof(len32));
#ifdef NETPGPV_DEBUG
writefile(mem, cc);
#endif
digest_init(&hash, (const unsigned)hashalg);
if (strchr("tw", doarmor) != NULL && !already_armored(mem, cc)) {
/* this took me ages to find - something causes gpg to truncate its input */
don_armor(&hash, mem, cc - 1, doarmor);
} else {
digest_update(&hash, mem, cc);
}
if (hashed) {
digest_update(&hash, hashed, hashsize);
}
digest_update(&hash, trailer, sizeof(trailer));
return digest_final(out, &hash);
}
/* open the file, mmap it, and then get the checksum on that */
int
pgpv_digest_file(uint8_t *data, size_t size, const char *name, const uint8_t *hashed, size_t hashsize, int doarmor)
{
struct stat st;
uint8_t *mem;
size_t cc;
FILE *fp;
int ret;
if (hashed == NULL || data == NULL || name == NULL) {
fprintf(stderr, "no hashed data provided\n");
return 0;
}
ret = 0;
mem = NULL;
cc = 0;
if ((fp = fopen(name, "r")) == NULL) {
warn("%s - not found", name);
return 0;
}
if (fstat(fileno(fp), &st) < 0) {
warn("%s - can't stat", name);
goto done;
}
cc = (size_t)(st.st_size);
if ((mem = mmap(NULL, cc, PROT_READ, MAP_SHARED, fileno(fp), 0)) == MAP_FAILED) {
warn("%s - can't mmap", name);
goto done;
}
ret = calcsum(data, size, mem, cc, hashed, hashsize, doarmor);
done:
if (data) {
munmap(mem, cc);
}
fclose(fp);
return ret;
}
/* calculate the digest over memory too */
int
pgpv_digest_memory(uint8_t *data, size_t size, void *mem, size_t cc, const uint8_t *hashed, size_t hashsize, int doarmor)
{
if (hashed == NULL || data == NULL || mem == NULL) {
fprintf(stderr, "no hashed data provided\n");
return 0;
}
return calcsum(data, size, mem, cc, hashed, hashsize, doarmor);
}

View File

@@ -0,0 +1,35 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PGPSUM_H_
#define PGPSUM_H_ 20121003
#include <sys/types.h>
#include <inttypes.h>
int pgpv_digest_file(uint8_t */*buf*/, size_t /*size*/, const char */*name*/, const uint8_t */*hashed*/, size_t /*hashsize*/, int /*doarmor*/);
int pgpv_digest_memory(uint8_t */*buf*/, size_t /*size*/, void */*memory*/, size_t /*cc*/, const uint8_t */*hashed*/, size_t /*hashsize*/, int /*doarmor*/);
#endif

View File

@@ -0,0 +1,292 @@
/*-
* Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NETPGP_VERIFY_H_
#define NETPGP_VERIFY_H_ 20120928
#include <sys/types.h>
#include <inttypes.h>
#ifndef PGPV_ARRAY
/* creates 2 unsigned vars called "name"c and "name"size in current scope */
/* also creates an array called "name"s in current scope */
#define PGPV_ARRAY(type, name) \
unsigned name##c; unsigned name##vsize; type *name##s
#endif
/* 64bit key ids */
#define PGPV_KEYID_LEN 8
#define PGPV_STR_KEYID_LEN (PGPV_KEYID_LEN + PGPV_KEYID_LEN + 1)
/* bignum structure */
typedef struct pgpv_bignum_t {
void *bn; /* hide the implementation details */
uint16_t bits; /* cached number of bits */
} pgpv_bignum_t;
/* right now, our max binary digest length is 20 bytes */
#define PGPV_MAX_HASH_LEN 20
/* fingerprint */
typedef struct pgpv_fingerprint_t {
uint8_t hashalg; /* algorithm for digest */
uint8_t v[PGPV_MAX_HASH_LEN]; /* the digest */
uint32_t len; /* its length */
} pgpv_fingerprint_t;
/* specify size for array of bignums */
#define PGPV_MAX_PUBKEY_BN 4
/* public key */
typedef struct pgpv_pubkey_t {
pgpv_fingerprint_t fingerprint; /* key fingerprint i.e. digest */
uint8_t keyid[PGPV_KEYID_LEN]; /* last 8 bytes of v4 keys */
int64_t birth; /* creation time */
int64_t expiry; /* expiry time */
pgpv_bignum_t bn[PGPV_MAX_PUBKEY_BN]; /* bignums */
uint8_t keyalg; /* key algorithm */
uint8_t hashalg; /* hash algorithm */
uint8_t version; /* key version */
} pgpv_pubkey_t;
#define PGPV_MAX_SESSKEY_BN 2
/* a (size, byte array) string */
typedef struct pgpv_string_t {
size_t size;
uint8_t *data;
} pgpv_string_t;
typedef struct pgpv_ref_t {
void *vp;
size_t offset;
unsigned mem;
} pgpv_ref_t;
#define PGPV_MAX_SECKEY_BN 4
typedef struct pgpv_compress_t {
pgpv_string_t s;
uint8_t compalg;
} pgpv_compress_t;
/* a packet dealing with trust */
typedef struct pgpv_trust_t {
uint8_t level;
uint8_t amount;
} pgpv_trust_t;
/* a signature sub packet */
typedef struct pgpv_sigsubpkt_t {
pgpv_string_t s;
uint8_t tag;
uint8_t critical;
} pgpv_sigsubpkt_t;
#define PGPV_MAX_SIG_BN 2
typedef struct pgpv_signature_t {
uint8_t *signer; /* key id of signer */
pgpv_ref_t hashstart;
uint8_t *hash2;
uint8_t *mpi;
int64_t birth;
int64_t keyexpiry;
int64_t expiry;
uint32_t hashlen;
uint8_t version;
uint8_t type;
uint8_t keyalg;
uint8_t hashalg;
uint8_t trustlevel;
uint8_t trustamount;
pgpv_bignum_t bn[PGPV_MAX_SIG_BN];
char *regexp;
char *pref_key_server;
char *policy;
char *features;
char *why_revoked;
uint8_t *revoke_fingerprint;
uint8_t revoke_alg;
uint8_t revoke_sensitive;
uint8_t trustsig;
uint8_t revocable;
uint8_t pref_symm_alg;
uint8_t pref_hash_alg;
uint8_t pref_compress_alg;
uint8_t key_server_modify;
uint8_t notation;
uint8_t type_key;
uint8_t primary_userid;
uint8_t revoked; /* subtract 1 to get real reason, 0 == not revoked */
} pgpv_signature_t;
/* a signature packet */
typedef struct pgpv_sigpkt_t {
pgpv_signature_t sig;
uint16_t subslen;
uint16_t unhashlen;
PGPV_ARRAY(pgpv_sigsubpkt_t, subpkts);
} pgpv_sigpkt_t;
/* a one-pass signature packet */
typedef struct pgpv_onepass_t {
uint8_t keyid[PGPV_KEYID_LEN];
uint8_t version;
uint8_t type;
uint8_t hashalg;
uint8_t keyalg;
uint8_t nested;
} pgpv_onepass_t;
/* a literal data packet */
typedef struct pgpv_litdata_t {
uint8_t *filename;
pgpv_string_t s;
uint32_t secs;
uint8_t namelen;
char format;
unsigned mem;
size_t offset;
size_t len;
} pgpv_litdata_t;
/* user attributes - images */
typedef struct pgpv_userattr_t {
size_t len;
PGPV_ARRAY(pgpv_string_t, subattrs);
} pgpv_userattr_t;
/* a general PGP packet */
typedef struct pgpv_pkt_t {
uint8_t tag;
uint8_t newfmt;
uint8_t allocated;
uint8_t mement;
size_t offset;
pgpv_string_t s;
union {
pgpv_sigpkt_t sigpkt;
pgpv_onepass_t onepass;
pgpv_litdata_t litdata;
pgpv_compress_t compressed;
pgpv_trust_t trust;
pgpv_pubkey_t pubkey;
pgpv_string_t userid;
pgpv_userattr_t userattr;
} u;
} pgpv_pkt_t;
/* a memory structure */
typedef struct pgpv_mem_t {
size_t size;
size_t cc;
uint8_t *mem;
FILE *fp;
uint8_t dealloc;
const char *allowed; /* the types of packet that are allowed */
} pgpv_mem_t;
/* packet parser */
typedef struct pgpv_signed_userid_t {
pgpv_string_t userid;
PGPV_ARRAY(pgpv_signature_t, sigs);
uint8_t primary_userid;
uint8_t revoked;
} pgpv_signed_userid_t;
typedef struct pgpv_signed_userattr_t {
pgpv_userattr_t userattr;
PGPV_ARRAY(pgpv_signature_t, sigs);
uint8_t revoked;
} pgpv_signed_userattr_t;
typedef struct pgpv_signed_subkey_t {
pgpv_pubkey_t subkey;
pgpv_signature_t revoc_self_sig;
PGPV_ARRAY(pgpv_signature_t, sigs);
} pgpv_signed_subkey_t;
typedef struct pgpv_primarykey_t {
pgpv_pubkey_t primary;
pgpv_signature_t revoc_self_sig;
PGPV_ARRAY(pgpv_signature_t, direct_sigs);
PGPV_ARRAY(pgpv_signed_userid_t, signed_userids);
PGPV_ARRAY(pgpv_signed_userattr_t, signed_userattrs);
PGPV_ARRAY(pgpv_signed_subkey_t, signed_subkeys);
size_t fmtsize;
uint8_t primary_userid;
} pgpv_primarykey_t;
/* everything stems from this structure */
typedef struct pgpv_t {
PGPV_ARRAY(pgpv_pkt_t, pkts); /* packet array */
PGPV_ARRAY(pgpv_primarykey_t, primaries); /* array of primary keys */
PGPV_ARRAY(pgpv_mem_t, areas); /* areas we read packets from */
PGPV_ARRAY(size_t, datastarts); /* starts of data packets */
size_t pkt; /* when parsing, current pkt number */
const char *op; /* the operation we're doing */
} pgpv_t;
#define PGPV_REASON_LEN 128
/* when searching, we define a cursor, and fill in an array of subscripts */
typedef struct pgpv_cursor_t {
pgpv_t *pgp; /* pointer to pgp tree */
char *field; /* field we're searching on */
char *op; /* operation we're doing */
char *value; /* value we're searching for */
void *ptr; /* for regexps etc */
PGPV_ARRAY(uint32_t, found); /* array of matched subscripts */
PGPV_ARRAY(size_t, datacookies); /* cookies to retrieve matched data */
int64_t sigtime; /* time of signature */
char why[PGPV_REASON_LEN]; /* reason for bad signature */
} pgpv_cursor_t;
#ifndef __BEGIN_DECLS
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
__BEGIN_DECLS
int pgpv_read_pubring(pgpv_t */*pgp*/, const void */*keyringfile/mem*/, ssize_t /*size*/);
size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/);
size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/);
size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/);
int pgpv_close(pgpv_t */*pgp*/);
__END_DECLS
#endif

Some files were not shown because too many files have changed in this diff Show More