mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
Merged with gpg 1.4.3 code.
The gpg part does not yet build.
This commit is contained in:
parent
751a3aeea7
commit
29b23dea97
@ -1,3 +1,12 @@
|
||||
2006-04-18 Werner Koch <wk@g10code.com>
|
||||
|
||||
* configure.ac (PK_UID_CACHE_SIZE): New.
|
||||
|
||||
2006-04-07 Werner Koch <wk@g10code.com>
|
||||
|
||||
* configure.ac: Use new method to include the SVN revison. Now it
|
||||
is the actual global revision number.
|
||||
|
||||
2005-12-20 Werner Koch <wk@g10code.com>
|
||||
|
||||
Released 1.9.20.
|
||||
|
6
NEWS
6
NEWS
@ -1,12 +1,14 @@
|
||||
Noteworthy changes in version 1.9.21
|
||||
-------------------------------------------------
|
||||
|
||||
* [scdaemon] New command APDU.
|
||||
|
||||
* [scdaemon] Support for keypads of some readers. Tested only with
|
||||
SPR532. New option --disable-keypad.
|
||||
|
||||
* Support for CardMan 4040 PCMCIA reader.
|
||||
* [scdaemon] Support for CardMan 4040 PCMCIA reader.
|
||||
|
||||
* Cards are not anymore reseted at the end of a connection.
|
||||
* [scdaemon] Cards are not anymore reseted at the end of a connection.
|
||||
|
||||
* [gpgsm] Kludge to allow use of Bundesnetzagentur issued
|
||||
certificates.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2006-04-18 Werner Koch <wk@g10code.com>
|
||||
|
||||
* homedir.c (w32_shgetfolderpath): New. Taken from gpg 1.4.3.
|
||||
(default_homedir): Use it.
|
||||
|
||||
2005-10-08 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* signal.c (get_signal_name): Check value of HAVE_DECL_SYS_SIGLIST
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* homedir.c - Setup the home directory.
|
||||
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2004, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -41,6 +41,47 @@
|
||||
#include "util.h"
|
||||
#include "sysutils.h"
|
||||
|
||||
|
||||
/* This is a helper function to load a Windows function from either of
|
||||
one DLLs. */
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
static HRESULT
|
||||
w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
|
||||
{
|
||||
static int initialized;
|
||||
static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
|
||||
void *handle;
|
||||
int i;
|
||||
|
||||
initialized = 1;
|
||||
|
||||
for (i=0, handle = NULL; !handle && dllnames[i]; i++)
|
||||
{
|
||||
handle = dlopen (dllnames[i], RTLD_LAZY);
|
||||
if (handle)
|
||||
{
|
||||
func = dlsym (handle, "SHGetFolderPathA");
|
||||
if (!func)
|
||||
{
|
||||
dlclose (handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (func)
|
||||
return func (a,b,c,d,e);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
|
||||
/* Set up the default home directory. The usual --homedir option
|
||||
should be parsed later. */
|
||||
const char *
|
||||
@ -56,15 +97,15 @@ default_homedir (void)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
|
||||
/* fixme: It might be better to use LOCAL_APPDATA because this
|
||||
is defined as "non roaming" and thus more likely to be kept
|
||||
/* It might be better to use LOCAL_APPDATA because this is
|
||||
defined as "non roaming" and thus more likely to be kept
|
||||
locally. For private keys this is desired. However, given
|
||||
that many users copy private keys anyway forth and back,
|
||||
using a system roaming serives might be better than to let
|
||||
using a system roaming services might be better than to let
|
||||
them do it manually. A security conscious user will anyway
|
||||
use the registry entry to have better control. */
|
||||
if (SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
|
||||
NULL, 0, path) >= 0)
|
||||
if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
|
||||
NULL, 0, path) >= 0)
|
||||
{
|
||||
char *tmp = xmalloc (strlen (path) + 6 +1);
|
||||
strcpy (stpcpy (tmp, path), "\\gnupg");
|
||||
|
@ -36,6 +36,7 @@
|
||||
#define IOBUFCTRL_USER 16
|
||||
|
||||
typedef struct iobuf_struct *iobuf_t;
|
||||
typedef struct iobuf_struct *IOBUF; /* Compatibility with gpg 1.4. */
|
||||
|
||||
/* fixme: we should hide most of this stuff */
|
||||
struct iobuf_struct
|
||||
|
@ -59,6 +59,10 @@
|
||||
#define xrealloc(a,b) gcry_xrealloc ((a),(b))
|
||||
#define xstrdup(a) gcry_xstrdup ((a))
|
||||
|
||||
/* For compatibility with gpg 1.4 we also define these: */
|
||||
#define xmalloc_clear(a) gcry_xcalloc (1, (a))
|
||||
#define xmalloc_secure_clear(a) gcry_xcalloc_secure (1, (a))
|
||||
|
||||
|
||||
/* A type to hold the ISO time. Note that this this is the same as
|
||||
the the KSBA type ksba_isotime_t. */
|
||||
@ -133,7 +137,7 @@ int cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b);
|
||||
unsigned char *make_simple_sexp_from_hexstr (const char *line,
|
||||
size_t *nscanned);
|
||||
|
||||
/*-- homedir. c --*/
|
||||
/*-- homedir.c --*/
|
||||
const char *default_homedir (void);
|
||||
|
||||
|
||||
|
43
configure.ac
43
configure.ac
@ -23,11 +23,16 @@ AC_PREREQ(2.52)
|
||||
min_automake_version="1.9.3"
|
||||
|
||||
# Remember to change the version number immediately *after* a release.
|
||||
# Uncomment the my_iscvs macro for non-released code.
|
||||
m4_define(my_version, [1.9.21])
|
||||
m4_define(my_iscvs, yes)
|
||||
AC_INIT([gnupg], my_version[]m4_ifdef([my_iscvs], [-cvs[]m4_translit(
|
||||
[$Revision$],[Ra-z $:])]), [gnupg-devel@gnupg.org])
|
||||
# Set my_issvn to "yes" for non-released code. Remember to run an
|
||||
# "svn up" and "autogen.sh" right before creating a distribution.
|
||||
m4_define([my_version], [1.9.21])
|
||||
m4_define([my_issvn], [yes])
|
||||
|
||||
|
||||
m4_define([svn_revision], m4_esyscmd([echo -n $((svn info 2>/dev/null \
|
||||
|| echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q}')]))
|
||||
AC_INIT([gnupg], my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision]),
|
||||
[gnupg-devel@gnupg.org])
|
||||
# Set development_version to yes if the minor number is odd or you
|
||||
# feel that the default check for a development version is not
|
||||
# sufficient.
|
||||
@ -219,6 +224,34 @@ if test "$use_exec" = yes ; then
|
||||
AC_MSG_RESULT($enableval)
|
||||
fi
|
||||
|
||||
|
||||
dnl
|
||||
dnl Check for the key/uid cache size. This can't be zero, but can be
|
||||
dnl pretty small on embedded systems.
|
||||
dnl
|
||||
AC_MSG_CHECKING([for the size of the key and uid cache])
|
||||
AC_ARG_ENABLE(key-cache,
|
||||
AC_HELP_STRING([--enable-key-cache=SIZE],[Set key cache to SIZE (default 4096)]),,enableval=4096)
|
||||
|
||||
if test "$enableval" = "no"; then
|
||||
enableval=5
|
||||
elif test "$enableval" = "yes" || test "$enableval" = ""; then
|
||||
enableval=4096
|
||||
fi
|
||||
|
||||
changequote(,)dnl
|
||||
key_cache_size=`echo "$enableval" | sed 's/[A-Za-z]//g'`
|
||||
changequote([,])dnl
|
||||
|
||||
if test "$enableval" != "$key_cache_size" || test "$key_cache_size" -lt 5; then
|
||||
AC_MSG_ERROR([invalid key-cache size])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT($key_cache_size)
|
||||
AC_DEFINE_UNQUOTED(PK_UID_CACHE_SIZE,$key_cache_size,[Size of the key and UID caches])
|
||||
|
||||
|
||||
|
||||
dnl
|
||||
dnl Check whether we want to use Linux capabilities
|
||||
dnl
|
||||
|
@ -1,3 +1,33 @@
|
||||
2006-04-18 Werner Koch <wk@g10code.com>
|
||||
|
||||
* tdbio.c (open_db, migrate_from_v2): Removed feature to migration
|
||||
from old trustdb version 2.
|
||||
|
||||
* gpg.c, mainproc.c: Removed pipemode feature.
|
||||
|
||||
* status.c: Removed shared memory coprocess stuff
|
||||
|
||||
Merged with current gpg 1.4.3 code.
|
||||
|
||||
* keygen.c, keyid.c, misc.c, openfile.c, verify.c, trustdb.c
|
||||
* textfilter.c, tdbio.c, tdbdump.c, status.c, skclist.c, signal.c
|
||||
* sign.c, sig-check.c, seskey.c, seckey-cert.c, revoke.c
|
||||
* pubkey-enc.c, progress.c, plaintext.c, pkclist.c, photoid.c
|
||||
* passphrase.c, parse-packet.c, mdfilter.c, mainproc.c
|
||||
* keyserver.c, keyring.c, keylist.c, keyedit.c, keydb.c, kbnode.c
|
||||
* import.c, getkey.c, gpgv.c, helptext.c, free-packet.c
|
||||
* build-packet.c, cipher.c, compress.c, dearmor.c, decrypt.c
|
||||
* delkey.c, encr-data.c, encode.c, exec.c, export.c
|
||||
* gpg.c, armor.c: Updated from gnupg-1.4.3 and merged back gcry and
|
||||
gnupg-1.9 related changes.
|
||||
* trustdb.h, tdbio.h, status.h, photoid.h, packet.h, options.h
|
||||
* main.h, keyserver-internal.h, keyring.h, keydb.h, filter.h
|
||||
* exec.h: Ditto.
|
||||
* global.h: Removed after merging constants with gpg.h.
|
||||
* comment.c, pipemode.c: Removed.
|
||||
* card-util.c: Updated from gnupg-1.4.3.
|
||||
* compress-bz2.c: New.
|
||||
|
||||
2005-06-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* g10.c (print_hashline, add_group): Fixes for signed/unsigned
|
||||
@ -9007,7 +9037,8 @@ Thu Feb 12 22:24:42 1998 Werner Koch (wk@frodo)
|
||||
* pubkey-enc.c (get_session_key): rewritten
|
||||
|
||||
|
||||
Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
|
||||
Copyright 1998,1999,2000,2001,2002,2003,2004,2005,
|
||||
2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003 Free Software Foundation, Inc.
|
||||
# 2003, 2006 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GnuPG.
|
||||
#
|
||||
@ -26,16 +26,17 @@ AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common \
|
||||
|
||||
include $(top_srcdir)/am/cmacros.am
|
||||
|
||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS)
|
||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) -Wno-pointer-sign
|
||||
|
||||
needed_libs = ../gl/libgnu.a ../common/libcommon.a ../jnlib/libjnlib.a
|
||||
|
||||
bin_PROGRAMS = gpg2 gpgv2
|
||||
|
||||
common_source = \
|
||||
global.h gpg.h \
|
||||
gpg.h \
|
||||
build-packet.c \
|
||||
compress.c \
|
||||
compress-bz2.c \
|
||||
filter.h \
|
||||
free-packet.c \
|
||||
getkey.c \
|
||||
@ -55,7 +56,6 @@ common_source = \
|
||||
keyid.c \
|
||||
packet.h \
|
||||
parse-packet.c \
|
||||
comment.c \
|
||||
status.c \
|
||||
status.h \
|
||||
plaintext.c \
|
||||
@ -63,7 +63,7 @@ common_source = \
|
||||
keylist.c \
|
||||
pkglue.c pkglue.h
|
||||
|
||||
gpg2_SOURCES = g10.c \
|
||||
gpg2_SOURCES = gpg.c \
|
||||
$(common_source) \
|
||||
pkclist.c \
|
||||
skclist.c \
|
||||
@ -88,7 +88,6 @@ gpg2_SOURCES = g10.c \
|
||||
tdbio.h \
|
||||
delkey.c \
|
||||
keygen.c \
|
||||
pipemode.c \
|
||||
helptext.c \
|
||||
keyserver.c \
|
||||
keyserver-internal.h \
|
||||
|
359
g10/armor.c
359
g10/armor.c
@ -1,6 +1,6 @@
|
||||
/* armor.c - Armor flter
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
|
||||
* Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -30,7 +31,6 @@
|
||||
#include "gpg.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
#include "packet.h"
|
||||
@ -39,12 +39,6 @@
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#define LF "\r\n"
|
||||
#else
|
||||
#define LF "\n"
|
||||
#endif
|
||||
|
||||
#define MAX_LINELEN 20000
|
||||
|
||||
#define CRCINIT 0xB704CE
|
||||
@ -120,7 +114,6 @@ static char *tail_strings[] = {
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void
|
||||
initialize(void)
|
||||
{
|
||||
@ -193,7 +186,7 @@ is_armored( const byte *buf )
|
||||
* filter to do further processing.
|
||||
*/
|
||||
int
|
||||
use_armor_filter( iobuf_t a )
|
||||
use_armor_filter( IOBUF a )
|
||||
{
|
||||
byte buf[1];
|
||||
int n;
|
||||
@ -292,17 +285,24 @@ is_armor_header( byte *line, unsigned len )
|
||||
save_p = p;
|
||||
p += 5;
|
||||
|
||||
/* Some mail programs on Windows seem to add spaces to the end of
|
||||
the line. This becomes strict if --openpgp is set. */
|
||||
/* Some Windows environments seem to add whitespace to the end of
|
||||
the line, so we strip it here. This becomes strict if
|
||||
--rfc2440 is set since 2440 reads "The header lines, therefore,
|
||||
MUST start at the beginning of a line, and MUST NOT have text
|
||||
following them on the same line." It is unclear whether "text"
|
||||
refers to all text or just non-whitespace text. */
|
||||
|
||||
if(!RFC2440)
|
||||
while(*p==' ')
|
||||
if(RFC2440)
|
||||
{
|
||||
if( *p == '\r' )
|
||||
p++;
|
||||
if( *p == '\n' )
|
||||
p++;
|
||||
}
|
||||
else
|
||||
while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
|
||||
p++;
|
||||
|
||||
if( *p == '\r' )
|
||||
p++;
|
||||
if( *p == '\n' )
|
||||
p++;
|
||||
if( *p )
|
||||
return -1; /* garbage after dashes */
|
||||
save_c = *save_p; *save_p = 0;
|
||||
@ -334,21 +334,35 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
|
||||
int hashes=0;
|
||||
unsigned int len2;
|
||||
|
||||
len2 = length_sans_trailing_ws( line, len );
|
||||
len2 = check_trailing_ws( line, len );
|
||||
if( !len2 ) {
|
||||
afx->buffer_pos = len2; /* (it is not the fine way to do it here) */
|
||||
return 0; /* WS only: same as empty line */
|
||||
}
|
||||
len = len2;
|
||||
line[len2] = 0;
|
||||
|
||||
/*
|
||||
This is fussy. The spec says that a header line is delimited
|
||||
with a colon-space pair. This means that a line such as
|
||||
"Comment: " (with nothing else) is actually legal as an empty
|
||||
string comment. However, email and cut-and-paste being what it
|
||||
is, that trailing space may go away. Therefore, we accept empty
|
||||
headers delimited with only a colon. --rfc2440, as always,
|
||||
makes this strict and enforces the colon-space pair. -dms
|
||||
*/
|
||||
|
||||
p = strchr( line, ':');
|
||||
if( !p || !p[1] ) {
|
||||
if( !p || (RFC2440 && p[1]!=' ')
|
||||
|| (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
|
||||
{
|
||||
log_error(_("invalid armor header: "));
|
||||
print_string( stderr, line, len, 0 );
|
||||
putc('\n', stderr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Chop off the whitespace we detected before */
|
||||
len=len2;
|
||||
line[len2]='\0';
|
||||
|
||||
if( opt.verbose ) {
|
||||
log_info(_("armor header: "));
|
||||
@ -373,7 +387,7 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
|
||||
|
||||
/* figure out whether the data is armored or not */
|
||||
static int
|
||||
check_input( armor_filter_context_t *afx, iobuf_t a )
|
||||
check_input( armor_filter_context_t *afx, IOBUF a )
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
@ -415,7 +429,7 @@ check_input( armor_filter_context_t *afx, iobuf_t a )
|
||||
if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
|
||||
if( afx->in_cleartext ) {
|
||||
log_error(_("nested clear text signatures\n"));
|
||||
rc = GPG_ERR_INV_ARMOR;
|
||||
rc = gpg_error (GPG_ERR_INV_ARMOR);
|
||||
}
|
||||
afx->in_cleartext = 1;
|
||||
}
|
||||
@ -431,9 +445,9 @@ check_input( armor_filter_context_t *afx, iobuf_t a )
|
||||
} while( !maxlen );
|
||||
}
|
||||
|
||||
/* parse the header lines */
|
||||
/* Parse the header lines. */
|
||||
while(len) {
|
||||
/* read the next line (skip all truncated lines) */
|
||||
/* Read the next line (skip all truncated lines). */
|
||||
do {
|
||||
maxlen = MAX_LINELEN;
|
||||
afx->buffer_len = iobuf_read_line( a, &afx->buffer,
|
||||
@ -444,8 +458,8 @@ check_input( armor_filter_context_t *afx, iobuf_t a )
|
||||
|
||||
i = parse_header_line( afx, line, len );
|
||||
if( i <= 0 ) {
|
||||
if( i )
|
||||
rc = GPG_ERR_INV_ARMOR;
|
||||
if (i && RFC2440)
|
||||
rc = G10ERR_INVALID_ARMOR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -465,7 +479,8 @@ check_input( armor_filter_context_t *afx, iobuf_t a )
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
#define PARTIAL_CHUNK 512
|
||||
#define PARTIAL_POW 9
|
||||
|
||||
/****************
|
||||
* Fake a literal data packet and wait for the next armor line
|
||||
@ -473,7 +488,7 @@ check_input( armor_filter_context_t *afx, iobuf_t a )
|
||||
* not implemented/checked.
|
||||
*/
|
||||
static int
|
||||
fake_packet( armor_filter_context_t *afx, iobuf_t a,
|
||||
fake_packet( armor_filter_context_t *afx, IOBUF a,
|
||||
size_t *retn, byte *buf, size_t size )
|
||||
{
|
||||
int rc = 0;
|
||||
@ -481,19 +496,31 @@ fake_packet( armor_filter_context_t *afx, iobuf_t a,
|
||||
int lastline = 0;
|
||||
unsigned maxlen, n;
|
||||
byte *p;
|
||||
byte tempbuf[PARTIAL_CHUNK];
|
||||
size_t tempbuf_len=0;
|
||||
|
||||
len = 2; /* reserve 2 bytes for the length header */
|
||||
size -= 2; /* and 2 for the terminating header */
|
||||
while( !rc && len < size ) {
|
||||
while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
|
||||
/* copy what we have in the line buffer */
|
||||
if( afx->faked == 1 )
|
||||
afx->faked++; /* skip the first (empty) line */
|
||||
else {
|
||||
while( len < size && afx->buffer_pos < afx->buffer_len )
|
||||
buf[len++] = afx->buffer[afx->buffer_pos++];
|
||||
if( len >= size )
|
||||
else
|
||||
{
|
||||
/* It's full, so write this partial chunk */
|
||||
if(tempbuf_len==PARTIAL_CHUNK)
|
||||
{
|
||||
buf[len++]=0xE0+PARTIAL_POW;
|
||||
memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
|
||||
len+=PARTIAL_CHUNK;
|
||||
tempbuf_len=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while( tempbuf_len < PARTIAL_CHUNK
|
||||
&& afx->buffer_pos < afx->buffer_len )
|
||||
tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
|
||||
if( tempbuf_len==PARTIAL_CHUNK )
|
||||
continue;
|
||||
}
|
||||
|
||||
/* read the next line */
|
||||
maxlen = MAX_LINELEN;
|
||||
@ -506,15 +533,64 @@ fake_packet( armor_filter_context_t *afx, iobuf_t a,
|
||||
}
|
||||
if( !maxlen )
|
||||
afx->truncated++;
|
||||
if( !afx->not_dash_escaped ) {
|
||||
int crlf;
|
||||
p = afx->buffer;
|
||||
n = afx->buffer_len;
|
||||
crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
|
||||
|
||||
p = afx->buffer;
|
||||
n = afx->buffer_len;
|
||||
|
||||
/* Armor header or dash-escaped line? */
|
||||
if(p[0]=='-')
|
||||
{
|
||||
/* 2440bis-10: When reversing dash-escaping, an
|
||||
implementation MUST strip the string "- " if it occurs
|
||||
at the beginning of a line, and SHOULD warn on "-" and
|
||||
any character other than a space at the beginning of a
|
||||
line. */
|
||||
|
||||
if(p[1]==' ' && !afx->not_dash_escaped)
|
||||
{
|
||||
/* It's a dash-escaped line, so skip over the
|
||||
escape. */
|
||||
afx->buffer_pos = 2;
|
||||
}
|
||||
else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
|
||||
{
|
||||
/* Five dashes in a row mean it's probably armor
|
||||
header. */
|
||||
int type = is_armor_header( p, n );
|
||||
if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
|
||||
; /* this is okay */
|
||||
else
|
||||
{
|
||||
if( type != BEGIN_SIGNATURE )
|
||||
{
|
||||
log_info(_("unexpected armor: "));
|
||||
print_string( stderr, p, n, 0 );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
lastline = 1;
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
else if(!afx->not_dash_escaped)
|
||||
{
|
||||
/* Bad dash-escaping. */
|
||||
log_info(_("invalid dash escaped line: "));
|
||||
print_string( stderr, p, n, 0 );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now handle the end-of-line canonicalization */
|
||||
if( !afx->not_dash_escaped )
|
||||
{
|
||||
int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
|
||||
|
||||
/* PGP2 does not treat a tab as white space character */
|
||||
afx->buffer_len = trim_trailing_chars( p, n,
|
||||
afx->pgp2mode ? " \r\n" : " \t\r\n");
|
||||
afx->buffer_len=
|
||||
trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
|
||||
afx->pgp2mode ? " \r\n" : " \t\r\n");
|
||||
afx->buffer_len+=afx->buffer_pos;
|
||||
/* the buffer is always allocated with enough space to append
|
||||
* the removed [CR], LF and a Nul
|
||||
* The reason for this complicated procedure is to keep at least
|
||||
@ -526,48 +602,23 @@ fake_packet( armor_filter_context_t *afx, iobuf_t a,
|
||||
* faked packet could do the job).
|
||||
*/
|
||||
if( crlf )
|
||||
afx->buffer[afx->buffer_len++] = '\r';
|
||||
afx->buffer[afx->buffer_len++] = '\r';
|
||||
afx->buffer[afx->buffer_len++] = '\n';
|
||||
afx->buffer[afx->buffer_len] = 0;
|
||||
}
|
||||
p = afx->buffer;
|
||||
n = afx->buffer_len;
|
||||
|
||||
if( n > 2 && *p == '-' ) {
|
||||
/* check for dash escaped or armor header */
|
||||
if( p[1] == ' ' && !afx->not_dash_escaped ) {
|
||||
/* issue a warning if it is not regular encoded */
|
||||
if( p[2] != '-' && !( n > 6 && !memcmp(p+2, "From ", 5))) {
|
||||
log_info(_("invalid dash escaped line: "));
|
||||
print_string( stderr, p, n, 0 );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
afx->buffer_pos = 2; /* skip */
|
||||
}
|
||||
else if( n >= 15 && p[1] == '-' && p[2] == '-' && p[3] == '-' ) {
|
||||
int type = is_armor_header( p, n );
|
||||
if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
|
||||
; /* this is okay */
|
||||
else {
|
||||
if( type != BEGIN_SIGNATURE ) {
|
||||
log_info(_("unexpected armor:"));
|
||||
print_string( stderr, p, n, 0 );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
lastline = 1;
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
afx->buffer[afx->buffer_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
buf[0] = (len-2) >> 8;
|
||||
buf[1] = (len-2);
|
||||
if( lastline ) { /* write last (ending) length header */
|
||||
if( buf[0] || buf[1] ) { /* only if we have some text */
|
||||
buf[len++] = 0;
|
||||
buf[len++] = 0;
|
||||
}
|
||||
if(tempbuf_len<192)
|
||||
buf[len++]=tempbuf_len;
|
||||
else
|
||||
{
|
||||
buf[len++]=((tempbuf_len-192)/256) + 192;
|
||||
buf[len++]=(tempbuf_len-192) % 256;
|
||||
}
|
||||
memcpy(&buf[len],tempbuf,tempbuf_len);
|
||||
len+=tempbuf_len;
|
||||
|
||||
rc = 0;
|
||||
afx->faked = 0;
|
||||
afx->in_cleartext = 0;
|
||||
@ -609,15 +660,15 @@ fake_packet( armor_filter_context_t *afx, iobuf_t a,
|
||||
static int
|
||||
invalid_crc(void)
|
||||
{
|
||||
if ( opt.ignore_crc_error )
|
||||
return 0;
|
||||
log_inc_errorcount();
|
||||
return GPG_ERR_INV_ARMOR;
|
||||
if ( opt.ignore_crc_error )
|
||||
return 0;
|
||||
log_inc_errorcount();
|
||||
return gpg_error (GPG_ERR_INV_ARMOR);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn,
|
||||
radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
|
||||
byte *buf, size_t size )
|
||||
{
|
||||
byte val;
|
||||
@ -676,7 +727,7 @@ radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn,
|
||||
break;
|
||||
}
|
||||
else if( (c = asctobin[(c2=c)]) == 255 ) {
|
||||
log_error(_("invalid radix64 character %02x skipped\n"), c2);
|
||||
log_error(_("invalid radix64 character %02X skipped\n"), c2);
|
||||
continue;
|
||||
}
|
||||
switch(idx) {
|
||||
@ -755,13 +806,17 @@ radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn,
|
||||
if( c == -1 ) {
|
||||
log_info(_("premature eof (in CRC)\n"));
|
||||
rc = invalid_crc();
|
||||
}
|
||||
}
|
||||
else if( idx == 0 ) {
|
||||
/* No CRC at all is legal ("MAY") */
|
||||
rc=0;
|
||||
}
|
||||
else if( idx != 4 ) {
|
||||
log_info(_("malformed CRC\n"));
|
||||
rc = invalid_crc();
|
||||
}
|
||||
else if( mycrc != afx->crc ) {
|
||||
log_info (_("CRC error; %06lx - %06lx\n"),
|
||||
log_info (_("CRC error; %06lX - %06lX\n"),
|
||||
(ulong)afx->crc, (ulong)mycrc);
|
||||
rc = invalid_crc();
|
||||
}
|
||||
@ -781,12 +836,12 @@ radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn,
|
||||
if( rc == -1 )
|
||||
rc = 0;
|
||||
else if( rc == 2 ) {
|
||||
log_error(_("premature eof (in Trailer)\n"));
|
||||
rc = GPG_ERR_INV_ARMOR;
|
||||
log_error(_("premature eof (in trailer)\n"));
|
||||
rc = G10ERR_INVALID_ARMOR;
|
||||
}
|
||||
else {
|
||||
log_error(_("error in trailer line\n"));
|
||||
rc = GPG_ERR_INV_ARMOR;
|
||||
rc = G10ERR_INVALID_ARMOR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -805,7 +860,7 @@ radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn,
|
||||
*/
|
||||
int
|
||||
armor_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
size_t size = *ret_len;
|
||||
armor_filter_context_t *afx = opaque;
|
||||
@ -843,9 +898,10 @@ armor_filter( void *opaque, int control,
|
||||
*ret_len = n;
|
||||
}
|
||||
else if( control == IOBUFCTRL_UNDERFLOW ) {
|
||||
/* We need some space for the faked packet. The minmum required
|
||||
* size is ~18 + length of the session marker */
|
||||
if( size < 50 )
|
||||
/* We need some space for the faked packet. The minmum
|
||||
* required size is the PARTIAL_CHUNK size plus a byte for the
|
||||
* length itself */
|
||||
if( size < PARTIAL_CHUNK+1 )
|
||||
BUG(); /* supplied buffer too short */
|
||||
|
||||
if( afx->faked )
|
||||
@ -882,7 +938,7 @@ armor_filter( void *opaque, int control,
|
||||
afx->pgp2mode = 1;
|
||||
}
|
||||
n=0;
|
||||
/* first a gpg control packet */
|
||||
/* First a gpg control packet... */
|
||||
buf[n++] = 0xff; /* new format, type 63, 1 length byte */
|
||||
n++; /* see below */
|
||||
memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
|
||||
@ -902,12 +958,16 @@ armor_filter( void *opaque, int control,
|
||||
buf[n++] = DIGEST_ALGO_SHA512;
|
||||
buf[1] = n - 2;
|
||||
|
||||
/* followed by a plaintext packet */
|
||||
buf[n++] = 0xaf; /* old packet format, type 11, var length */
|
||||
buf[n++] = 0; /* set the length header */
|
||||
buf[n++] = 6;
|
||||
/* ...followed by an invented plaintext packet.
|
||||
Amusingly enough, this packet is not compliant with
|
||||
2440 as the initial partial length is less than 512
|
||||
bytes. Of course, we'll accept it anyway ;) */
|
||||
|
||||
buf[n++] = 0xCB; /* new packet format, type 11 */
|
||||
buf[n++] = 0xE1; /* 2^1 == 2 bytes */
|
||||
buf[n++] = 't'; /* canonical text mode */
|
||||
buf[n++] = 0; /* namelength */
|
||||
buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
|
||||
memset(buf+n, 0, 4); /* timestamp */
|
||||
n += 4;
|
||||
}
|
||||
@ -926,35 +986,39 @@ armor_filter( void *opaque, int control,
|
||||
else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
|
||||
if( !afx->status ) { /* write the header line */
|
||||
const char *s;
|
||||
STRLIST comment = opt.comments;
|
||||
STRLIST comment=opt.comments;
|
||||
|
||||
if( afx->what >= DIM(head_strings) )
|
||||
log_bug("afx->what=%d", afx->what);
|
||||
iobuf_writestr(a, "-----");
|
||||
iobuf_writestr(a, head_strings[afx->what] );
|
||||
iobuf_writestr(a, "-----" LF );
|
||||
iobuf_writestr(a, "-----" );
|
||||
iobuf_writestr(a,afx->eol);
|
||||
if( !opt.no_version )
|
||||
{
|
||||
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")" LF );
|
||||
PRINTABLE_OS_NAME ")" );
|
||||
iobuf_writestr(a,afx->eol);
|
||||
}
|
||||
|
||||
/* Write the comment string. */
|
||||
for(s=comment? comment->d:NULL; comment;
|
||||
comment=comment->next,s=comment->d)
|
||||
/* write the comment strings */
|
||||
for(s=comment->d;comment;comment=comment->next,s=comment->d)
|
||||
{
|
||||
iobuf_writestr(a, "Comment: " );
|
||||
for ( ; *s; s++ )
|
||||
{
|
||||
for( ; *s; s++ )
|
||||
{
|
||||
if( *s == '\n' )
|
||||
iobuf_writestr(a, "\\n" );
|
||||
iobuf_writestr(a, "\\n" );
|
||||
else if( *s == '\r' )
|
||||
iobuf_writestr(a, "\\r" );
|
||||
iobuf_writestr(a, "\\r" );
|
||||
else if( *s == '\v' )
|
||||
iobuf_writestr(a, "\\v" );
|
||||
iobuf_writestr(a, "\\v" );
|
||||
else
|
||||
iobuf_put(a, *s );
|
||||
}
|
||||
iobuf_writestr(a, LF );
|
||||
}
|
||||
iobuf_put(a, *s );
|
||||
}
|
||||
|
||||
iobuf_writestr(a,afx->eol);
|
||||
}
|
||||
|
||||
if ( afx->hdrlines ) {
|
||||
for ( s = afx->hdrlines; *s; s++ ) {
|
||||
@ -965,7 +1029,8 @@ armor_filter( void *opaque, int control,
|
||||
iobuf_put(a, *s );
|
||||
}
|
||||
}
|
||||
iobuf_writestr(a, LF );
|
||||
|
||||
iobuf_writestr(a,afx->eol);
|
||||
afx->status++;
|
||||
afx->idx = 0;
|
||||
afx->idx2 = 0;
|
||||
@ -994,10 +1059,11 @@ armor_filter( void *opaque, int control,
|
||||
iobuf_put(a, c);
|
||||
c = bintoasc[radbuf[2]&077];
|
||||
iobuf_put(a, c);
|
||||
if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
|
||||
iobuf_writestr(a, LF );
|
||||
if( ++idx2 >= (64/4) )
|
||||
{ /* pgp doesn't like 72 here */
|
||||
iobuf_writestr(a,afx->eol);
|
||||
idx2=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0; i < idx; i++ )
|
||||
@ -1006,10 +1072,23 @@ armor_filter( void *opaque, int control,
|
||||
afx->idx2 = idx2;
|
||||
afx->crc = crc;
|
||||
}
|
||||
else if( control == IOBUFCTRL_INIT ) {
|
||||
else if( control == IOBUFCTRL_INIT )
|
||||
{
|
||||
if( !is_initialized )
|
||||
initialize();
|
||||
}
|
||||
initialize();
|
||||
|
||||
/* Figure out what we're using for line endings if the caller
|
||||
didn't specify. */
|
||||
if(afx->eol[0]==0)
|
||||
{
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
afx->eol[0]='\r';
|
||||
afx->eol[1]='\n';
|
||||
#else
|
||||
afx->eol[0]='\n';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if( control == IOBUFCTRL_CANCEL ) {
|
||||
afx->cancel = 1;
|
||||
}
|
||||
@ -1038,14 +1117,15 @@ armor_filter( void *opaque, int control,
|
||||
iobuf_put(a, c);
|
||||
iobuf_put(a, '=');
|
||||
}
|
||||
if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
|
||||
iobuf_writestr(a, LF );
|
||||
if( ++idx2 >= (64/4) )
|
||||
{ /* pgp doesn't like 72 here */
|
||||
iobuf_writestr(a,afx->eol);
|
||||
idx2=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* may need a linefeed */
|
||||
if( idx2 )
|
||||
iobuf_writestr(a, LF );
|
||||
iobuf_writestr(a,afx->eol);
|
||||
/* write the CRC */
|
||||
iobuf_put(a, '=');
|
||||
radbuf[0] = crc >>16;
|
||||
@ -1059,13 +1139,14 @@ armor_filter( void *opaque, int control,
|
||||
iobuf_put(a, c);
|
||||
c = bintoasc[radbuf[2]&077];
|
||||
iobuf_put(a, c);
|
||||
iobuf_writestr(a, LF );
|
||||
iobuf_writestr(a,afx->eol);
|
||||
/* and the the trailer */
|
||||
if( afx->what >= DIM(tail_strings) )
|
||||
log_bug("afx->what=%d", afx->what);
|
||||
iobuf_writestr(a, "-----");
|
||||
iobuf_writestr(a, tail_strings[afx->what] );
|
||||
iobuf_writestr(a, "-----" LF );
|
||||
iobuf_writestr(a, "-----" );
|
||||
iobuf_writestr(a,afx->eol);
|
||||
}
|
||||
else if( !afx->any_data && !afx->inp_bypass ) {
|
||||
log_error(_("no valid OpenPGP data found.\n"));
|
||||
@ -1079,7 +1160,7 @@ armor_filter( void *opaque, int control,
|
||||
if( afx->qp_detected )
|
||||
log_error(_("quoted printable character in armor - "
|
||||
"probably a buggy MTA has been used\n") );
|
||||
xfree ( afx->buffer );
|
||||
xfree( afx->buffer );
|
||||
afx->buffer = NULL;
|
||||
}
|
||||
else if( control == IOBUFCTRL_DESC )
|
||||
@ -1096,7 +1177,7 @@ make_radix64_string( const byte *data, size_t len )
|
||||
{
|
||||
char *buffer, *p;
|
||||
|
||||
buffer = p = xmalloc ( (len+2)/3*4 + 1 );
|
||||
buffer = p = xmalloc( (len+2)/3*4 + 1 );
|
||||
for( ; len >= 3 ; len -= 3, data += 3 ) {
|
||||
*p++ = bintoasc[(data[0] >> 2) & 077];
|
||||
*p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
|
||||
@ -1156,7 +1237,7 @@ unarmor_pump_new (void)
|
||||
|
||||
if( !is_initialized )
|
||||
initialize();
|
||||
x = xcalloc (1,sizeof *x);
|
||||
x = xmalloc_clear (sizeof *x);
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -1253,7 +1334,7 @@ unarmor_pump (UnarmorPump x, int c)
|
||||
{
|
||||
int c2;
|
||||
if( (c = asctobin[(c2=c)]) == 255 ) {
|
||||
log_error(_("invalid radix64 character %02x skipped\n"), c2);
|
||||
log_error(_("invalid radix64 character %02X skipped\n"), c2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1290,7 +1371,7 @@ unarmor_pump (UnarmorPump x, int c)
|
||||
if( (c = asctobin[c]) == 255 ) {
|
||||
rval = -1; /* ready */
|
||||
if( x->crc != x->mycrc ) {
|
||||
log_info (_("CRC error; %06lx - %06lx\n"),
|
||||
log_info (_("CRC error; %06lX - %06lX\n"),
|
||||
(ulong)x->crc, (ulong)x->mycrc);
|
||||
if ( invalid_crc() )
|
||||
rval = -3;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* build-packet.c - assemble packets and write them
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -24,40 +25,38 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "mpi.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "memory.h"
|
||||
#include "i18n.h"
|
||||
#include "options.h"
|
||||
|
||||
|
||||
static int do_comment( iobuf_t out, int ctb, PKT_comment *rem );
|
||||
static int do_user_id( iobuf_t out, int ctb, PKT_user_id *uid );
|
||||
static int do_public_key( iobuf_t out, int ctb, PKT_public_key *pk );
|
||||
static int do_secret_key( iobuf_t out, int ctb, PKT_secret_key *pk );
|
||||
static int do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc );
|
||||
static int do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc );
|
||||
static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
|
||||
static int do_public_key( IOBUF out, int ctb, PKT_public_key *pk );
|
||||
static int do_secret_key( IOBUF out, int ctb, PKT_secret_key *pk );
|
||||
static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
|
||||
static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
|
||||
static u32 calc_plaintext( PKT_plaintext *pt );
|
||||
static int do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt );
|
||||
static int do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed );
|
||||
static int do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed );
|
||||
static int do_compressed( iobuf_t out, int ctb, PKT_compressed *cd );
|
||||
static int do_signature( iobuf_t out, int ctb, PKT_signature *sig );
|
||||
static int do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops );
|
||||
static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
|
||||
static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed );
|
||||
static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed );
|
||||
static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
|
||||
static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
|
||||
static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops );
|
||||
|
||||
static int calc_header_length( u32 len, int new_ctb );
|
||||
static int write_16(iobuf_t inp, u16 a);
|
||||
static int write_32(iobuf_t inp, u32 a);
|
||||
static int write_header( iobuf_t out, int ctb, u32 len );
|
||||
static int write_sign_packet_header( iobuf_t out, int ctb, u32 len );
|
||||
static int write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode );
|
||||
static int write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen );
|
||||
static int write_version( iobuf_t out, int ctb );
|
||||
static int write_16(IOBUF inp, u16 a);
|
||||
static int write_32(IOBUF inp, u32 a);
|
||||
static int write_header( IOBUF out, int ctb, u32 len );
|
||||
static int write_sign_packet_header( IOBUF out, int ctb, u32 len );
|
||||
static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen );
|
||||
static int write_new_header( IOBUF out, int ctb, u32 len, int hdrlen );
|
||||
static int write_version( IOBUF out, int ctb );
|
||||
|
||||
/****************
|
||||
* Build a packet and write it to INP
|
||||
@ -66,7 +65,7 @@ static int write_version( iobuf_t out, int ctb );
|
||||
* Note: Caller must free the packet
|
||||
*/
|
||||
int
|
||||
build_packet( iobuf_t out, PACKET *pkt )
|
||||
build_packet( IOBUF out, PACKET *pkt )
|
||||
{
|
||||
int new_ctb=0, rc=0, ctb;
|
||||
int pkttype;
|
||||
@ -75,30 +74,38 @@ build_packet( iobuf_t out, PACKET *pkt )
|
||||
log_debug("build_packet() type=%d\n", pkt->pkttype );
|
||||
assert( pkt->pkt.generic );
|
||||
|
||||
switch( (pkttype = pkt->pkttype) ) {
|
||||
case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break;
|
||||
switch( (pkttype = pkt->pkttype) )
|
||||
{
|
||||
case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
|
||||
case PKT_ENCRYPTED:
|
||||
case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
|
||||
case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
|
||||
case PKT_USER_ID:
|
||||
if( pkt->pkt.user_id->attrib_data )
|
||||
pkttype = PKT_ATTRIBUTE;
|
||||
break;
|
||||
if( pkt->pkt.user_id->attrib_data )
|
||||
pkttype = PKT_ATTRIBUTE;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if( new_ctb || pkttype > 15 ) /* new format */
|
||||
ctb = 0xc0 | (pkttype & 0x3f);
|
||||
else
|
||||
ctb = 0x80 | ((pkttype & 15)<<2);
|
||||
switch( pkttype ) {
|
||||
switch( pkttype )
|
||||
{
|
||||
case PKT_ATTRIBUTE:
|
||||
case PKT_USER_ID:
|
||||
rc = do_user_id( out, ctb, pkt->pkt.user_id );
|
||||
break;
|
||||
case PKT_OLD_COMMENT:
|
||||
case PKT_COMMENT:
|
||||
rc = do_comment( out, ctb, pkt->pkt.comment );
|
||||
/*
|
||||
Ignore these. Theoretically, this will never be called as
|
||||
we have no way to output comment packets any longer, but
|
||||
just in case there is some code path that would end up
|
||||
outputting a comment that was written before comments were
|
||||
dropped (in the public key?) this is a no-op.
|
||||
*/
|
||||
break;
|
||||
case PKT_PUBLIC_SUBKEY:
|
||||
case PKT_PUBLIC_KEY:
|
||||
@ -138,11 +145,32 @@ build_packet( iobuf_t out, PACKET *pkt )
|
||||
default:
|
||||
log_bug("invalid packet type in build_packet()\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write the mpi A to OUT.
|
||||
*/
|
||||
static int
|
||||
mpi_write (iobuf_t out, gcry_mpi_t a)
|
||||
{
|
||||
char buffer[(MAX_EXTERN_MPI_BITS+7)/8];
|
||||
size_t nbytes;
|
||||
int rc;
|
||||
|
||||
nbytes = (MAX_EXTERN_MPI_BITS+7)/8;
|
||||
rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
|
||||
if( !rc )
|
||||
rc = iobuf_write( out, buffer, nbytes );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* calculate the length of a packet described by PKT
|
||||
*/
|
||||
@ -180,56 +208,42 @@ calc_packet_length( PACKET *pkt )
|
||||
}
|
||||
|
||||
static void
|
||||
write_fake_data( iobuf_t out, gcry_mpi_t a )
|
||||
write_fake_data (IOBUF out, gcry_mpi_t a)
|
||||
{
|
||||
if( a ) {
|
||||
unsigned int n;
|
||||
void *p;
|
||||
|
||||
assert( gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE));
|
||||
p = gcry_mpi_get_opaque (a, &n);
|
||||
iobuf_write (out, p, (n+7)/8);
|
||||
if (a)
|
||||
{
|
||||
unsigned int n;
|
||||
void *p;
|
||||
|
||||
p = gcry_mpi_get_opaque ( a, &n );
|
||||
iobuf_write (out, p, (n+7)/8 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_comment (iobuf_t out, int ctb, PKT_comment *rem)
|
||||
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
|
||||
{
|
||||
int rc = 0;
|
||||
int rc;
|
||||
|
||||
if (opt.sk_comments)
|
||||
{
|
||||
write_header(out, ctb, rem->len);
|
||||
rc = iobuf_write( out, rem->data, rem->len );
|
||||
}
|
||||
return rc;
|
||||
if( uid->attrib_data )
|
||||
{
|
||||
write_header(out, ctb, uid->attrib_len);
|
||||
rc = iobuf_write( out, uid->attrib_data, uid->attrib_len );
|
||||
}
|
||||
else
|
||||
{
|
||||
write_header2( out, ctb, uid->len, 2 );
|
||||
rc = iobuf_write( out, uid->name, uid->len );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_user_id( iobuf_t out, int ctb, PKT_user_id *uid )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (uid->attrib_data)
|
||||
{
|
||||
write_header (out, ctb, uid->attrib_len);
|
||||
rc = iobuf_write (out, uid->attrib_data, uid->attrib_len );
|
||||
}
|
||||
else
|
||||
{
|
||||
write_header (out, ctb, uid->len);
|
||||
rc = iobuf_write (out, uid->name, uid->len );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
do_public_key( iobuf_t out, int ctb, PKT_public_key *pk )
|
||||
do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
|
||||
{
|
||||
int rc = 0;
|
||||
int n, i;
|
||||
iobuf_t a = iobuf_temp();
|
||||
IOBUF a = iobuf_temp();
|
||||
|
||||
if( !pk->version )
|
||||
iobuf_put( a, 3 );
|
||||
@ -251,99 +265,20 @@ do_public_key( iobuf_t out, int ctb, PKT_public_key *pk )
|
||||
for(i=0; i < n; i++ )
|
||||
mpi_write(a, pk->pkey[i] );
|
||||
|
||||
write_header2(out, ctb, iobuf_get_temp_length(a), pk->hdrbytes, 1 );
|
||||
rc = iobuf_write_temp (out, a);
|
||||
write_header2(out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
|
||||
rc = iobuf_write_temp( out, a );
|
||||
|
||||
iobuf_close(a);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Make a hash value from the public key certificate
|
||||
*/
|
||||
void
|
||||
hash_public_key( MD_HANDLE md, PKT_public_key *pk )
|
||||
{
|
||||
PACKET pkt;
|
||||
int rc = 0;
|
||||
int ctb;
|
||||
ulong pktlen;
|
||||
int c;
|
||||
iobuf_t a = iobuf_temp();
|
||||
#if 0
|
||||
FILE *fp = fopen("dump.pk", "a");
|
||||
int i=0;
|
||||
|
||||
fprintf(fp, "\nHashing PK (v%d):\n", pk->version);
|
||||
#endif
|
||||
|
||||
/* build the packet */
|
||||
init_packet(&pkt);
|
||||
pkt.pkttype = PKT_PUBLIC_KEY;
|
||||
pkt.pkt.public_key = pk;
|
||||
if( (rc = build_packet( a, &pkt )) )
|
||||
log_fatal("build public_key for hashing failed: %s\n", gpg_strerror (rc));
|
||||
|
||||
if( !(pk->version == 3 && pk->pubkey_algo == 16) ) {
|
||||
/* skip the constructed header but don't do this for our very old
|
||||
* v3 ElG keys */
|
||||
ctb = iobuf_get_noeof(a);
|
||||
pktlen = 0;
|
||||
if( (ctb & 0x40) ) {
|
||||
c = iobuf_get_noeof(a);
|
||||
if( c < 192 )
|
||||
pktlen = c;
|
||||
else if( c < 224 ) {
|
||||
pktlen = (c - 192) * 256;
|
||||
c = iobuf_get_noeof(a);
|
||||
pktlen += c + 192;
|
||||
}
|
||||
else if( c == 255 ) {
|
||||
pktlen = iobuf_get_noeof(a) << 24;
|
||||
pktlen |= iobuf_get_noeof(a) << 16;
|
||||
pktlen |= iobuf_get_noeof(a) << 8;
|
||||
pktlen |= iobuf_get_noeof(a);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
|
||||
for( ; lenbytes; lenbytes-- ) {
|
||||
pktlen <<= 8;
|
||||
pktlen |= iobuf_get_noeof(a);
|
||||
}
|
||||
}
|
||||
/* hash a header */
|
||||
gcry_md_putc ( md, 0x99 );
|
||||
pktlen &= 0xffff; /* can't handle longer packets */
|
||||
gcry_md_putc ( md, pktlen >> 8 );
|
||||
gcry_md_putc ( md, pktlen & 0xff );
|
||||
}
|
||||
/* hash the packet body */
|
||||
while( (c=iobuf_get(a)) != -1 ) {
|
||||
#if 0
|
||||
fprintf( fp," %02x", c );
|
||||
if( (++i == 24) ) {
|
||||
putc('\n', fp);
|
||||
i=0;
|
||||
}
|
||||
#endif
|
||||
gcry_md_putc ( md, c );
|
||||
}
|
||||
#if 0
|
||||
putc('\n', fp);
|
||||
fclose(fp);
|
||||
#endif
|
||||
iobuf_cancel(a);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk )
|
||||
do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
|
||||
{
|
||||
int rc = 0;
|
||||
int i, nskey, npkey;
|
||||
iobuf_t a = iobuf_temp(); /* build in a self-enlarging buffer */
|
||||
IOBUF a = iobuf_temp(); /* build in a self-enlarging buffer */
|
||||
|
||||
/* Write the version number - if none is specified, use 3 */
|
||||
if( !sk->version )
|
||||
@ -371,7 +306,7 @@ do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk )
|
||||
|
||||
/* If we don't have any public parameters - which is the case if
|
||||
we don't know the algorithm used - the parameters are stored as
|
||||
one blob in a faked (opaque) gcry_mpi_t */
|
||||
one blob in a faked (opaque) MPI */
|
||||
if( !npkey ) {
|
||||
write_fake_data( a, sk->skey[0] );
|
||||
goto leave;
|
||||
@ -415,9 +350,9 @@ do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk )
|
||||
if( sk->protect.s2k.mode == 3 )
|
||||
iobuf_put(a, sk->protect.s2k.count );
|
||||
|
||||
/* For our special modes 1001 and 1002 we do not need an IV */
|
||||
if( sk->protect.s2k.mode != 1001
|
||||
&& sk->protect.s2k.mode != 1002 )
|
||||
/* For out special modes 1001, 1002 we do not need an IV */
|
||||
if( sk->protect.s2k.mode != 1001
|
||||
&& sk->protect.s2k.mode != 1002 )
|
||||
iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
|
||||
}
|
||||
}
|
||||
@ -437,19 +372,21 @@ do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk )
|
||||
else if( sk->is_protected && sk->version >= 4 ) {
|
||||
/* The secret key is protected - write it out as it is */
|
||||
byte *p;
|
||||
assert( gcry_mpi_get_flag( sk->skey[npkey], GCRYMPI_FLAG_OPAQUE ) );
|
||||
p = gcry_mpi_get_opaque( sk->skey[npkey], &i );
|
||||
iobuf_write(a, p, (i+7)/8 );
|
||||
unsigned int ndatabits;
|
||||
|
||||
assert (gcry_mpi_get_flag (sk->skey[npkey], GCRYMPI_FLAG_OPAQUE));
|
||||
p = gcry_mpi_get_opaque (sk->skey[npkey], &ndatabits );
|
||||
iobuf_write (a, p, (ndatabits+7)/8 );
|
||||
}
|
||||
else if( sk->is_protected ) {
|
||||
/* The secret key is protected the old v4 way. */
|
||||
/* The secret key is protected te old v4 way. */
|
||||
for( ; i < nskey; i++ ) {
|
||||
byte *p;
|
||||
size_t n;
|
||||
unsigned int ndatabits;
|
||||
|
||||
assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
|
||||
p = gcry_mpi_get_opaque( sk->skey[i], &n );
|
||||
iobuf_write (a, p, (n+7)/8);
|
||||
assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
|
||||
p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
|
||||
iobuf_write (a, p, (ndatabits+7)/8);
|
||||
}
|
||||
write_16(a, sk->csum );
|
||||
}
|
||||
@ -463,19 +400,19 @@ do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk )
|
||||
leave:
|
||||
/* Build the header of the packet - which we must do after writing all
|
||||
the other stuff, so that we know the length of the packet */
|
||||
write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 );
|
||||
write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes);
|
||||
/* And finally write it out the real stream */
|
||||
rc = iobuf_write_temp (out, a );
|
||||
rc = iobuf_write_temp( out, a );
|
||||
|
||||
iobuf_close(a); /* close the remporary buffer */
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc )
|
||||
do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
|
||||
{
|
||||
int rc = 0;
|
||||
iobuf_t a = iobuf_temp();
|
||||
IOBUF a = iobuf_temp();
|
||||
|
||||
assert( enc->version == 4 );
|
||||
switch( enc->s2k.mode ) {
|
||||
@ -495,21 +432,19 @@ do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc )
|
||||
iobuf_write(a, enc->seskey, enc->seskeylen );
|
||||
|
||||
write_header(out, ctb, iobuf_get_temp_length(a) );
|
||||
rc = iobuf_write_temp (out, a);
|
||||
rc = iobuf_write_temp( out, a );
|
||||
|
||||
iobuf_close(a);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc )
|
||||
do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
|
||||
{
|
||||
int rc = 0;
|
||||
int n, i;
|
||||
iobuf_t a = iobuf_temp();
|
||||
IOBUF a = iobuf_temp();
|
||||
|
||||
write_version( a, ctb );
|
||||
if( enc->throw_keyid ) {
|
||||
@ -528,55 +463,56 @@ do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc )
|
||||
mpi_write(a, enc->data[i] );
|
||||
|
||||
write_header(out, ctb, iobuf_get_temp_length(a) );
|
||||
rc = iobuf_write_temp (out, a);
|
||||
rc = iobuf_write_temp( out, a );
|
||||
|
||||
iobuf_close(a);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static u32
|
||||
calc_plaintext( PKT_plaintext *pt )
|
||||
{
|
||||
return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
|
||||
/* Truncate namelen to the maximum 255 characters. Note this means
|
||||
that a function that calls build_packet with an illegal literal
|
||||
packet will get it back legalized. */
|
||||
|
||||
if(pt->namelen>255)
|
||||
pt->namelen=255;
|
||||
|
||||
return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt )
|
||||
do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
|
||||
{
|
||||
int i, rc = 0;
|
||||
u32 n;
|
||||
byte buf[1000]; /* this buffer has the plaintext! */
|
||||
int nbytes;
|
||||
|
||||
/* Truncate namelen to the maximum 255 characters. This does mean
|
||||
that a function that calls build_packet with an illegal literal
|
||||
packet will get it back legalized. */
|
||||
if(pt->namelen>255)
|
||||
pt->namelen=255;
|
||||
|
||||
write_header(out, ctb, calc_plaintext( pt ) );
|
||||
iobuf_put(out, pt->mode );
|
||||
iobuf_put(out, pt->namelen );
|
||||
for(i=0; i < pt->namelen; i++ )
|
||||
iobuf_put(out, pt->name[i] );
|
||||
rc = write_32 (out, pt->timestamp);
|
||||
rc = write_32(out, pt->timestamp );
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
n = 0;
|
||||
while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) {
|
||||
rc = iobuf_write(out, buf, nbytes);
|
||||
if (rc)
|
||||
break;
|
||||
n += nbytes;
|
||||
rc = iobuf_write (out, buf, nbytes);
|
||||
if (rc)
|
||||
break;
|
||||
n += nbytes;
|
||||
}
|
||||
wipememory(buf,1000); /* burn the buffer */
|
||||
if( !pt->len )
|
||||
iobuf_set_block_mode(out, 0 ); /* write end marker */
|
||||
else if( n != pt->len )
|
||||
log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n",
|
||||
(ulong)n, (ulong)pt->len );
|
||||
if( (ctb&0x40) && !pt->len )
|
||||
iobuf_set_partial_block_mode(out, 0 ); /* turn off partial */
|
||||
if( pt->len && n != pt->len )
|
||||
log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n",
|
||||
(ulong)n, (ulong)pt->len );
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -584,7 +520,7 @@ do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt )
|
||||
|
||||
|
||||
static int
|
||||
do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed )
|
||||
do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed )
|
||||
{
|
||||
int rc = 0;
|
||||
u32 n;
|
||||
@ -598,7 +534,7 @@ do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed )
|
||||
}
|
||||
|
||||
static int
|
||||
do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed )
|
||||
do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
|
||||
{
|
||||
int rc = 0;
|
||||
u32 n;
|
||||
@ -617,7 +553,7 @@ do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed )
|
||||
|
||||
|
||||
static int
|
||||
do_compressed( iobuf_t out, int ctb, PKT_compressed *cd )
|
||||
do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@ -626,7 +562,7 @@ do_compressed( iobuf_t out, int ctb, PKT_compressed *cd )
|
||||
set, CTB is already formatted as new style and write_header2
|
||||
does create a partial length encoding using new the new
|
||||
style. */
|
||||
write_header2(out, ctb, 0, 0, 0 );
|
||||
write_header2(out, ctb, 0, 0);
|
||||
iobuf_put(out, cd->algorithm );
|
||||
|
||||
/* This is all. The caller has to write the real data */
|
||||
@ -734,6 +670,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
|
||||
case SIGSUBPKT_NOTATION:
|
||||
case SIGSUBPKT_POLICY:
|
||||
case SIGSUBPKT_REV_KEY:
|
||||
case SIGSUBPKT_SIGNATURE:
|
||||
/* we do allow multiple subpackets */
|
||||
break;
|
||||
|
||||
@ -803,18 +740,20 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
|
||||
else
|
||||
nlen = 1; /* just a 1 byte length header */
|
||||
|
||||
switch( type ) {
|
||||
switch( type )
|
||||
{
|
||||
/* The issuer being unhashed is a historical oddity. It
|
||||
should work equally as well hashed. Of course, if even an
|
||||
unhashed issuer is tampered with, it makes it awfully hard
|
||||
to verify the sig... */
|
||||
case SIGSUBPKT_ISSUER:
|
||||
case SIGSUBPKT_SIGNATURE:
|
||||
hashed = 0;
|
||||
break;
|
||||
default:
|
||||
hashed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( critical )
|
||||
type |= SIGSUBPKT_FLAG_CRITICAL;
|
||||
@ -966,12 +905,179 @@ build_attribute_subpkt(PKT_user_id *uid,byte type,
|
||||
uid->attrib_len+=idx+headerlen+buflen;
|
||||
}
|
||||
|
||||
struct notation *
|
||||
string_to_notation(const char *string,int is_utf8)
|
||||
{
|
||||
const char *s;
|
||||
int saw_at=0;
|
||||
struct notation *notation;
|
||||
|
||||
notation=xmalloc_clear(sizeof(*notation));
|
||||
|
||||
if(*string=='-')
|
||||
{
|
||||
notation->flags.ignore=1;
|
||||
string++;
|
||||
}
|
||||
|
||||
if(*string=='!')
|
||||
{
|
||||
notation->flags.critical=1;
|
||||
string++;
|
||||
}
|
||||
|
||||
/* If and when the IETF assigns some official name tags, we'll have
|
||||
to add them here. */
|
||||
|
||||
for( s=string ; *s != '='; s++ )
|
||||
{
|
||||
if( *s=='@')
|
||||
saw_at++;
|
||||
|
||||
/* -notationname is legal without an = sign */
|
||||
if(!*s && notation->flags.ignore)
|
||||
break;
|
||||
|
||||
if( !*s || !isascii (*s) || (!isgraph(*s) && !isspace(*s)) )
|
||||
{
|
||||
log_error(_("a notation name must have only printable characters"
|
||||
" or spaces, and end with an '='\n") );
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
notation->name=xmalloc((s-string)+1);
|
||||
strncpy(notation->name,string,s-string);
|
||||
notation->name[s-string]='\0';
|
||||
|
||||
if(!saw_at && !opt.expert)
|
||||
{
|
||||
log_error(_("a user notation name must contain the '@' character\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (saw_at > 1)
|
||||
{
|
||||
log_error(_("a notation name must not contain more than"
|
||||
" one '@' character\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(*s)
|
||||
{
|
||||
const char *i=s+1;
|
||||
int highbit=0;
|
||||
|
||||
/* we only support printable text - therefore we enforce the use
|
||||
of only printable characters (an empty value is valid) */
|
||||
for(s++; *s ; s++ )
|
||||
{
|
||||
if ( !isascii (*s) )
|
||||
highbit=1;
|
||||
else if (iscntrl(*s))
|
||||
{
|
||||
log_error(_("a notation value must not use any"
|
||||
" control characters\n"));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if(!highbit || is_utf8)
|
||||
notation->value=xstrdup(i);
|
||||
else
|
||||
notation->value=native_to_utf8(i);
|
||||
}
|
||||
|
||||
return notation;
|
||||
|
||||
fail:
|
||||
free_notation(notation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct notation *
|
||||
sig_to_notation(PKT_signature *sig)
|
||||
{
|
||||
const byte *p;
|
||||
size_t len;
|
||||
int seq=0,crit;
|
||||
struct notation *list=NULL;
|
||||
|
||||
while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
|
||||
{
|
||||
int n1,n2;
|
||||
struct notation *n=NULL;
|
||||
|
||||
if(len<8)
|
||||
{
|
||||
log_info(_("WARNING: invalid notation data found\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
n1=(p[4]<<8)|p[5];
|
||||
n2=(p[6]<<8)|p[7];
|
||||
|
||||
if(8+n1+n2!=len)
|
||||
{
|
||||
log_info(_("WARNING: invalid notation data found\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
n=xmalloc_clear(sizeof(*n));
|
||||
n->name=xmalloc(n1+1);
|
||||
|
||||
memcpy(n->name,&p[8],n1);
|
||||
n->name[n1]='\0';
|
||||
|
||||
if(p[0]&0x80)
|
||||
{
|
||||
n->value=xmalloc(n2+1);
|
||||
memcpy(n->value,&p[8+n1],n2);
|
||||
n->value[n2]='\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
n->bdat=xmalloc(n2);
|
||||
n->blen=n2;
|
||||
memcpy(n->bdat,&p[8+n1],n2);
|
||||
|
||||
n->value=xmalloc(2+strlen(_("not human readable"))+2+1);
|
||||
strcpy(n->value,"[ ");
|
||||
strcat(n->value,_("not human readable"));
|
||||
strcat(n->value," ]");
|
||||
}
|
||||
|
||||
n->flags.critical=crit;
|
||||
|
||||
n->next=list;
|
||||
list=n;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
free_notation(struct notation *notation)
|
||||
{
|
||||
while(notation)
|
||||
{
|
||||
struct notation *n=notation;
|
||||
|
||||
xfree(n->name);
|
||||
xfree(n->value);
|
||||
xfree(n->altvalue);
|
||||
xfree(n->bdat);
|
||||
notation=n->next;
|
||||
xfree(n);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
do_signature( iobuf_t out, int ctb, PKT_signature *sig )
|
||||
do_signature( IOBUF out, int ctb, PKT_signature *sig )
|
||||
{
|
||||
int rc = 0;
|
||||
int n, i;
|
||||
iobuf_t a = iobuf_temp();
|
||||
IOBUF a = iobuf_temp();
|
||||
|
||||
if( !sig->version )
|
||||
iobuf_put( a, 3 );
|
||||
@ -1013,7 +1119,7 @@ do_signature( iobuf_t out, int ctb, PKT_signature *sig )
|
||||
write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) );
|
||||
else
|
||||
write_header(out, ctb, iobuf_get_temp_length(a) );
|
||||
rc = iobuf_write_temp (out, a);
|
||||
rc = iobuf_write_temp( out, a );
|
||||
|
||||
iobuf_close(a);
|
||||
return rc;
|
||||
@ -1021,10 +1127,10 @@ do_signature( iobuf_t out, int ctb, PKT_signature *sig )
|
||||
|
||||
|
||||
static int
|
||||
do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops )
|
||||
do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
|
||||
{
|
||||
int rc = 0;
|
||||
iobuf_t a = iobuf_temp();
|
||||
IOBUF a = iobuf_temp();
|
||||
|
||||
write_version( a, ctb );
|
||||
iobuf_put(a, ops->sig_class );
|
||||
@ -1035,7 +1141,7 @@ do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops )
|
||||
iobuf_put(a, ops->last );
|
||||
|
||||
write_header(out, ctb, iobuf_get_temp_length(a) );
|
||||
rc = iobuf_write_temp (out, a);
|
||||
rc = iobuf_write_temp( out, a );
|
||||
|
||||
iobuf_close(a);
|
||||
return rc;
|
||||
@ -1043,19 +1149,21 @@ do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops )
|
||||
|
||||
|
||||
static int
|
||||
write_16(iobuf_t out, u16 a)
|
||||
write_16(IOBUF out, u16 a)
|
||||
{
|
||||
iobuf_put(out, a>>8);
|
||||
return iobuf_put(out,a);
|
||||
if( iobuf_put(out,a) )
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
write_32(iobuf_t out, u32 a)
|
||||
write_32(IOBUF out, u32 a)
|
||||
{
|
||||
iobuf_put(out, a>> 24);
|
||||
iobuf_put(out, a>> 16);
|
||||
iobuf_put(out, a>> 8);
|
||||
return iobuf_put (out, a);
|
||||
return iobuf_put(out, a);
|
||||
}
|
||||
|
||||
|
||||
@ -1088,14 +1196,14 @@ calc_header_length( u32 len, int new_ctb )
|
||||
* Write the CTB and the packet length
|
||||
*/
|
||||
static int
|
||||
write_header( iobuf_t out, int ctb, u32 len )
|
||||
write_header( IOBUF out, int ctb, u32 len )
|
||||
{
|
||||
return write_header2( out, ctb, len, 0, 1 );
|
||||
return write_header2( out, ctb, len, 0 );
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_sign_packet_header( iobuf_t out, int ctb, u32 len )
|
||||
write_sign_packet_header( IOBUF out, int ctb, u32 len )
|
||||
{
|
||||
/* work around a bug in the pgp read function for signature packets,
|
||||
* which are not correctly coded and silently assume at some
|
||||
@ -1106,57 +1214,66 @@ write_sign_packet_header( iobuf_t out, int ctb, u32 len )
|
||||
}
|
||||
|
||||
/****************
|
||||
* if HDRLEN is > 0, try to build a header of this length.
|
||||
* we need this, so that we can hash packets without reading them again.
|
||||
* If HDRLEN is > 0, try to build a header of this length. We need
|
||||
* this so that we can hash packets without reading them again. If
|
||||
* len is 0, write a partial or indeterminate length header, unless
|
||||
* hdrlen is specified in which case write an actual zero length
|
||||
* (using the specified hdrlen).
|
||||
*/
|
||||
static int
|
||||
write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode )
|
||||
write_header2( IOBUF out, int ctb, u32 len, int hdrlen )
|
||||
{
|
||||
if( ctb & 0x40 )
|
||||
return write_new_header( out, ctb, len, hdrlen );
|
||||
if( ctb & 0x40 )
|
||||
return write_new_header( out, ctb, len, hdrlen );
|
||||
|
||||
if( hdrlen ) {
|
||||
if( !len )
|
||||
ctb |= 3;
|
||||
else if( hdrlen == 2 && len < 256 )
|
||||
;
|
||||
else if( hdrlen == 3 && len < 65536 )
|
||||
ctb |= 1;
|
||||
else
|
||||
ctb |= 2;
|
||||
if( hdrlen )
|
||||
{
|
||||
if( hdrlen == 2 && len < 256 )
|
||||
;
|
||||
else if( hdrlen == 3 && len < 65536 )
|
||||
ctb |= 1;
|
||||
else
|
||||
ctb |= 2;
|
||||
}
|
||||
else {
|
||||
if( !len )
|
||||
ctb |= 3;
|
||||
else if( len < 256 )
|
||||
;
|
||||
else if( len < 65536 )
|
||||
ctb |= 1;
|
||||
else
|
||||
ctb |= 2;
|
||||
else
|
||||
{
|
||||
if( !len )
|
||||
ctb |= 3;
|
||||
else if( len < 256 )
|
||||
;
|
||||
else if( len < 65536 )
|
||||
ctb |= 1;
|
||||
else
|
||||
ctb |= 2;
|
||||
}
|
||||
if( iobuf_put(out, ctb ) )
|
||||
return -1;
|
||||
if( !len ) {
|
||||
if( blkmode )
|
||||
iobuf_set_block_mode(out, 8196 );
|
||||
}
|
||||
else {
|
||||
if( ctb & 2 ) {
|
||||
iobuf_put(out, len >> 24 );
|
||||
iobuf_put(out, len >> 16 );
|
||||
}
|
||||
if( ctb & 3 )
|
||||
iobuf_put(out, len >> 8 );
|
||||
if( iobuf_put(out, len ) )
|
||||
|
||||
if( iobuf_put(out, ctb ) )
|
||||
return -1;
|
||||
|
||||
if( len || hdrlen )
|
||||
{
|
||||
if( ctb & 2 )
|
||||
{
|
||||
if(iobuf_put(out, len >> 24 ))
|
||||
return -1;
|
||||
if(iobuf_put(out, len >> 16 ))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( ctb & 3 )
|
||||
if(iobuf_put(out, len >> 8 ))
|
||||
return -1;
|
||||
|
||||
if( iobuf_put(out, len ) )
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen )
|
||||
write_new_header( IOBUF out, int ctb, u32 len, int hdrlen )
|
||||
{
|
||||
if( hdrlen )
|
||||
log_bug("can't cope with hdrlen yet\n");
|
||||
@ -1195,7 +1312,7 @@ write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen )
|
||||
}
|
||||
|
||||
static int
|
||||
write_version( iobuf_t out, int ctb )
|
||||
write_version( IOBUF out, int ctb )
|
||||
{
|
||||
if( iobuf_put( out, 3 ) )
|
||||
return -1;
|
||||
|
@ -18,8 +18,8 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#if 0 /* lety Emacs display a red warning */
|
||||
#error fixme: this shares a lof of code with the file in ../sm
|
||||
#if 0 /* let Emacs display a red warning */
|
||||
#error fixme: this shares a lot of code with the file in ../sm
|
||||
#endif
|
||||
|
||||
#include <config.h>
|
||||
|
404
g10/card-util.c
404
g10/card-util.c
@ -1,5 +1,5 @@
|
||||
/* card-util.c - Utility functions for the OpenPGP card.
|
||||
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -27,7 +28,7 @@
|
||||
|
||||
#if GNUPG_MAJOR_VERSION != 1
|
||||
#include "gpg.h"
|
||||
#endif
|
||||
#endif /*GNUPG_MAJOR_VERSION != 1*/
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
#include "ttyio.h"
|
||||
@ -36,10 +37,14 @@
|
||||
#include "main.h"
|
||||
#include "keyserver-internal.h"
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
#include <stdio.h>
|
||||
#include <readline/readline.h>
|
||||
#endif /*HAVE_LIBREADLINE*/
|
||||
#include "cardglue.h"
|
||||
#else
|
||||
#else /*GNUPG_MAJOR_VERSION!=1*/
|
||||
#include "call-agent.h"
|
||||
#endif
|
||||
#endif /*GNUPG_MAJOR_VERSION!=1*/
|
||||
|
||||
#define CONTROL_D ('D' - 'A' + 1)
|
||||
|
||||
@ -63,21 +68,25 @@ change_pin (int chvno, int allow_admin)
|
||||
log_info (_("OpenPGP card no. %s detected\n"),
|
||||
info.serialno? info.serialno : "[none]");
|
||||
|
||||
agent_release_card_info (&info);
|
||||
agent_clear_pin_cache (info.serialno);
|
||||
|
||||
if (opt.batch)
|
||||
{
|
||||
log_error (_("sorry, can't do this in batch mode\n"));
|
||||
agent_release_card_info (&info);
|
||||
log_error (_("can't do this in batch mode\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!allow_admin)
|
||||
{
|
||||
rc = agent_scd_change_pin (1);
|
||||
rc = agent_scd_change_pin (1, info.serialno);
|
||||
if (rc)
|
||||
tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
|
||||
else
|
||||
tty_printf ("PIN changed.\n");
|
||||
{
|
||||
write_status (STATUS_SC_OP_SUCCESS);
|
||||
tty_printf ("PIN changed.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
for (;;)
|
||||
@ -99,33 +108,44 @@ change_pin (int chvno, int allow_admin)
|
||||
rc = 0;
|
||||
if (*answer == '1')
|
||||
{
|
||||
rc = agent_scd_change_pin (1);
|
||||
rc = agent_scd_change_pin (1, info.serialno);
|
||||
if (rc)
|
||||
tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
|
||||
else
|
||||
tty_printf ("PIN changed.\n");
|
||||
{
|
||||
write_status (STATUS_SC_OP_SUCCESS);
|
||||
tty_printf ("PIN changed.\n");
|
||||
}
|
||||
}
|
||||
else if (*answer == '2')
|
||||
{
|
||||
rc = agent_scd_change_pin (101);
|
||||
rc = agent_scd_change_pin (101, info.serialno);
|
||||
if (rc)
|
||||
tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
|
||||
else
|
||||
tty_printf ("PIN unblocked and new PIN set.\n");
|
||||
}
|
||||
{
|
||||
write_status (STATUS_SC_OP_SUCCESS);
|
||||
tty_printf ("PIN unblocked and new PIN set.\n");
|
||||
}
|
||||
}
|
||||
else if (*answer == '3')
|
||||
{
|
||||
rc = agent_scd_change_pin (3);
|
||||
rc = agent_scd_change_pin (3, info.serialno);
|
||||
if (rc)
|
||||
tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
|
||||
else
|
||||
tty_printf ("PIN changed.\n");
|
||||
{
|
||||
write_status (STATUS_SC_OP_SUCCESS);
|
||||
tty_printf ("PIN changed.\n");
|
||||
}
|
||||
}
|
||||
else if (*answer == 'q' || *answer == 'Q')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
agent_release_card_info (&info);
|
||||
}
|
||||
|
||||
static const char *
|
||||
@ -137,6 +157,8 @@ get_manufacturer (unsigned int no)
|
||||
case 0:
|
||||
case 0xffff: return "test card";
|
||||
case 0x0001: return "PPC Card Systems";
|
||||
case 0x0002: return "Prism";
|
||||
case 0x0003: return "OpenFortress";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
@ -270,6 +292,8 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
PKT_public_key *pk = xcalloc (1, sizeof *pk);
|
||||
int rc;
|
||||
unsigned int uval;
|
||||
const unsigned char *thefpr;
|
||||
int i;
|
||||
|
||||
if (serialno && serialnobuflen)
|
||||
*serialno = 0;
|
||||
@ -346,6 +370,17 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
info.chvretry[0], info.chvretry[1], info.chvretry[2]);
|
||||
fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
if (info.private_do[i])
|
||||
{
|
||||
fprintf (fp, "private_do:%d:", i+1);
|
||||
print_string (fp, info.private_do[i],
|
||||
strlen (info.private_do[i]), ':');
|
||||
fputs (":\n", fp);
|
||||
}
|
||||
}
|
||||
|
||||
fputs ("cafpr:", fp);
|
||||
print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
|
||||
print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
|
||||
@ -356,7 +391,9 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
|
||||
print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
|
||||
putc ('\n', fp);
|
||||
|
||||
fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
|
||||
(unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
|
||||
(unsigned long)info.fpr3time);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -377,6 +414,14 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
info.disp_sex == 2? _("female") : _("unspecified"));
|
||||
print_name (fp, "URL of public key : ", info.pubkey_url);
|
||||
print_name (fp, "Login data .......: ", info.login_data);
|
||||
if (info.private_do[0])
|
||||
print_name (fp, "Private DO 1 .....: ", info.private_do[0]);
|
||||
if (info.private_do[1])
|
||||
print_name (fp, "Private DO 2 .....: ", info.private_do[1]);
|
||||
if (info.private_do[2])
|
||||
print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
|
||||
if (info.private_do[3])
|
||||
print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
|
||||
if (info.cafpr1valid)
|
||||
{
|
||||
tty_fprintf (fp, "CA fingerprint %d .:", 1);
|
||||
@ -401,13 +446,48 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter);
|
||||
tty_fprintf (fp, "Signature key ....:");
|
||||
print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
|
||||
if (info.fpr1valid && info.fpr1time)
|
||||
tty_fprintf (fp, " created ....: %s\n",
|
||||
isotimestamp (info.fpr1time));
|
||||
tty_fprintf (fp, "Encryption key....:");
|
||||
print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
|
||||
if (info.fpr2valid && info.fpr2time)
|
||||
tty_fprintf (fp, " created ....: %s\n",
|
||||
isotimestamp (info.fpr2time));
|
||||
tty_fprintf (fp, "Authentication key:");
|
||||
print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
|
||||
if (info.fpr3valid && info.fpr3time)
|
||||
tty_fprintf (fp, " created ....: %s\n",
|
||||
isotimestamp (info.fpr3time));
|
||||
tty_fprintf (fp, "General key info..: ");
|
||||
if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20))
|
||||
print_pubkey_info (fp, pk);
|
||||
|
||||
thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 :
|
||||
info.fpr3valid? info.fpr3 : NULL);
|
||||
if ( thefpr && !get_pubkey_byfprint (pk, thefpr, 20))
|
||||
{
|
||||
KBNODE keyblock = NULL;
|
||||
|
||||
print_pubkey_info (fp, pk);
|
||||
|
||||
if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
|
||||
print_card_key_info (fp, keyblock);
|
||||
else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
|
||||
{
|
||||
release_kbnode (keyblock);
|
||||
keyblock = NULL;
|
||||
|
||||
if (!auto_create_card_key_stub (info.serialno,
|
||||
info.fpr1valid? info.fpr1:NULL,
|
||||
info.fpr2valid? info.fpr2:NULL,
|
||||
info.fpr3valid? info.fpr3:NULL))
|
||||
{
|
||||
if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
|
||||
print_card_key_info (fp, keyblock);
|
||||
}
|
||||
}
|
||||
|
||||
release_kbnode (keyblock);
|
||||
}
|
||||
else
|
||||
tty_fprintf (fp, "[none]\n");
|
||||
}
|
||||
@ -483,8 +563,7 @@ change_name (void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_debug ("setting Name to `%s'\n", isoname);
|
||||
rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) );
|
||||
rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
|
||||
if (rc)
|
||||
log_error ("error setting Name: %s\n", gpg_strerror (rc));
|
||||
|
||||
@ -513,13 +592,16 @@ change_url (void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) );
|
||||
rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
|
||||
if (rc)
|
||||
log_error ("error setting URL: %s\n", gpg_strerror (rc));
|
||||
xfree (url);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the key from the URL given on the card or try to get it from
|
||||
the default keyserver. */
|
||||
static int
|
||||
fetch_url(void)
|
||||
{
|
||||
@ -532,7 +614,7 @@ fetch_url(void)
|
||||
rc=agent_scd_getattr("PUBKEY-URL",&info);
|
||||
if(rc)
|
||||
log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
|
||||
else if(info.pubkey_url)
|
||||
else
|
||||
{
|
||||
struct keyserver_spec *spec=NULL;
|
||||
|
||||
@ -540,9 +622,9 @@ fetch_url(void)
|
||||
if(rc)
|
||||
log_error("error retrieving key fingerprint from card: %s\n",
|
||||
gpg_strerror(rc));
|
||||
else
|
||||
else if (info.pubkey_url && *info.pubkey_url)
|
||||
{
|
||||
spec=parse_keyserver_uri(info.pubkey_url,0,NULL,0);
|
||||
spec=parse_keyserver_uri(info.pubkey_url,1,NULL,0);
|
||||
if(spec && info.fpr1valid)
|
||||
{
|
||||
/* This is not perfectly right. Currently, all card
|
||||
@ -556,9 +638,11 @@ fetch_url(void)
|
||||
free_keyserver_spec(spec);
|
||||
}
|
||||
}
|
||||
else if (info.fpr1valid)
|
||||
{
|
||||
rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
|
||||
}
|
||||
}
|
||||
else
|
||||
log_error("no URL set on card\n");
|
||||
|
||||
return rc;
|
||||
#else
|
||||
@ -624,13 +708,82 @@ change_login (const char *args)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = agent_scd_setattr ("LOGIN-DATA", data, n );
|
||||
rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
|
||||
if (rc)
|
||||
log_error ("error setting login data: %s\n", gpg_strerror (rc));
|
||||
xfree (data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
change_private_do (const char *args, int nr)
|
||||
{
|
||||
char do_name[] = "PRIVATE-DO-X";
|
||||
char *data;
|
||||
int n;
|
||||
int rc;
|
||||
|
||||
assert (nr >= 1 && nr <= 4);
|
||||
do_name[11] = '0' + nr;
|
||||
|
||||
if (args && (args = strchr (args, '<'))) /* Read it from a file */
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
/* Fixme: Factor this duplicated code out. */
|
||||
for (args++; spacep (args); args++)
|
||||
;
|
||||
fp = fopen (args, "rb");
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
if (fp && is_secured_file (fileno (fp)))
|
||||
{
|
||||
fclose (fp);
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
#endif
|
||||
if (!fp)
|
||||
{
|
||||
tty_printf (_("can't open `%s': %s\n"), args, strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = xmalloc (254);
|
||||
n = fread (data, 1, 254, fp);
|
||||
fclose (fp);
|
||||
if (n < 0)
|
||||
{
|
||||
tty_printf (_("error reading `%s': %s\n"), args, strerror (errno));
|
||||
xfree (data);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = cpr_get ("cardedit.change_private_do",
|
||||
_("Private DO data: "));
|
||||
if (!data)
|
||||
return -1;
|
||||
trim_spaces (data);
|
||||
cpr_kill_prompt ();
|
||||
n = strlen (data);
|
||||
}
|
||||
|
||||
if (n > 254 )
|
||||
{
|
||||
tty_printf (_("Error: Private DO too long "
|
||||
"(limit is %d characters).\n"), 254);
|
||||
xfree (data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = agent_scd_setattr (do_name, data, n, NULL );
|
||||
if (rc)
|
||||
log_error ("error setting private DO: %s\n", gpg_strerror (rc));
|
||||
xfree (data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
change_lang (void)
|
||||
{
|
||||
@ -660,7 +813,7 @@ change_lang (void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) );
|
||||
rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
|
||||
if (rc)
|
||||
log_error ("error setting lang: %s\n", gpg_strerror (rc));
|
||||
xfree (data);
|
||||
@ -695,7 +848,7 @@ change_sex (void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = agent_scd_setattr ("DISP-SEX", str, 1 );
|
||||
rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
|
||||
if (rc)
|
||||
log_error ("error setting sex: %s\n", gpg_strerror (rc));
|
||||
xfree (data);
|
||||
@ -740,7 +893,7 @@ change_cafpr (int fprno)
|
||||
|
||||
rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
|
||||
fprno==2?"CA-FPR-2":
|
||||
fprno==3?"CA-FPR-3":"x", fpr, 20 );
|
||||
fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
|
||||
if (rc)
|
||||
log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
@ -765,7 +918,7 @@ toggle_forcesig (void)
|
||||
newstate = !info.chv1_cached;
|
||||
agent_release_card_info (&info);
|
||||
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1);
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
|
||||
if (rc)
|
||||
log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
|
||||
}
|
||||
@ -803,12 +956,14 @@ check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
agent_clear_pin_cache (info->serialno);
|
||||
|
||||
*forced_chv1 = !info->chv1_cached;
|
||||
if (*forced_chv1)
|
||||
{ /* Switch of the forced mode so that during key generation we
|
||||
don't get bothered with PIN queries for each
|
||||
self-signature. */
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error clearing forced signature PIN flag: %s\n",
|
||||
@ -836,7 +991,7 @@ restore_forced_chv1 (int *forced_chv1)
|
||||
|
||||
if (*forced_chv1)
|
||||
{ /* Switch back to forced state. */
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
|
||||
rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error setting forced signature PIN flag: %s\n",
|
||||
@ -900,7 +1055,7 @@ generate_card_keys (const char *serialno)
|
||||
|
||||
want_backup=answer_is_yes_no_default(answer,1);
|
||||
cpr_kill_prompt();
|
||||
m_free(answer);
|
||||
xfree(answer);
|
||||
}
|
||||
#else
|
||||
want_backup = cpr_get_answer_is_yes
|
||||
@ -949,7 +1104,7 @@ generate_card_keys (const char *serialno)
|
||||
}
|
||||
|
||||
|
||||
/* This fucntion is used by the key edit menu to generate an arbitrary
|
||||
/* This function is used by the key edit menu to generate an arbitrary
|
||||
subkey. */
|
||||
int
|
||||
card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
|
||||
@ -1007,9 +1162,10 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
|
||||
}
|
||||
|
||||
|
||||
/* Store the subkey at NODE into the smartcard and modify NODE to
|
||||
carry the serrialno stuff instead of the actual secret key
|
||||
parameters. */
|
||||
/* Store the key at NODE into the smartcard and modify NODE to
|
||||
carry the serialno stuff instead of the actual secret key
|
||||
parameters. USE is the usage for that key; 0 means any
|
||||
usage. */
|
||||
int
|
||||
card_store_subkey (KBNODE node, int use)
|
||||
{
|
||||
@ -1140,49 +1296,101 @@ card_store_subkey (KBNODE node, int use)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Data used by the command parser. This needs to be outside of the
|
||||
function scope to allow readline based command completion. */
|
||||
enum cmdids
|
||||
{
|
||||
cmdNOP = 0,
|
||||
cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
|
||||
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
|
||||
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO,
|
||||
cmdINVCMD
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
enum cmdids id;
|
||||
int admin_only;
|
||||
const char *desc;
|
||||
} cmds[] =
|
||||
{
|
||||
{ "quit" , cmdQUIT , 0, N_("quit this menu")},
|
||||
{ "q" , cmdQUIT , 0, NULL },
|
||||
{ "admin" , cmdADMIN , 0, N_("show admin commands")},
|
||||
{ "help" , cmdHELP , 0, N_("show this help")},
|
||||
{ "?" , cmdHELP , 0, NULL },
|
||||
{ "list" , cmdLIST , 0, N_("list all available data")},
|
||||
{ "l" , cmdLIST , 0, NULL },
|
||||
{ "debug" , cmdDEBUG , 0, NULL },
|
||||
{ "name" , cmdNAME , 1, N_("change card holder's name")},
|
||||
{ "url" , cmdURL , 1, N_("change URL to retrieve key")},
|
||||
{ "fetch" , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
|
||||
{ "login" , cmdLOGIN , 1, N_("change the login name")},
|
||||
{ "lang" , cmdLANG , 1, N_("change the language preferences")},
|
||||
{ "sex" , cmdSEX , 1, N_("change card holder's sex")},
|
||||
{ "cafpr" , cmdCAFPR , 1, N_("change a CA fingerprint")},
|
||||
{ "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
|
||||
{ "generate", cmdGENERATE, 1, N_("generate new keys")},
|
||||
{ "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
|
||||
{ "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
|
||||
/* Note, that we do not announce this command yet. */
|
||||
{ "privatedo", cmdPRIVATEDO, 0, NULL },
|
||||
{ NULL, cmdINVCMD, 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
#if GNUPG_MAJOR_VERSION == 1 && defined (HAVE_LIBREADLINE)
|
||||
|
||||
/* These two functions are used by readline for command completion. */
|
||||
|
||||
static char *
|
||||
command_generator(const char *text,int state)
|
||||
{
|
||||
static int list_index,len;
|
||||
const char *name;
|
||||
|
||||
/* If this is a new word to complete, initialize now. This includes
|
||||
saving the length of TEXT for efficiency, and initializing the
|
||||
index variable to 0. */
|
||||
if(!state)
|
||||
{
|
||||
list_index=0;
|
||||
len=strlen(text);
|
||||
}
|
||||
|
||||
/* Return the next partial match */
|
||||
while((name=cmds[list_index].name))
|
||||
{
|
||||
/* Only complete commands that have help text */
|
||||
if(cmds[list_index++].desc && strncmp(name,text,len)==0)
|
||||
return strdup(name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char **
|
||||
card_edit_completion(const char *text, int start, int end)
|
||||
{
|
||||
/* If we are at the start of a line, we try and command-complete.
|
||||
If not, just do nothing for now. */
|
||||
|
||||
if(start==0)
|
||||
return rl_completion_matches(text,command_generator);
|
||||
|
||||
rl_attempted_completion_over=1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* GNUPG_MAJOR_VERSION == 1 && HAVE_LIBREADLINE */
|
||||
|
||||
/* Menu to edit all user changeable values on an OpenPGP card. Only
|
||||
Key creation is not handled here. */
|
||||
void
|
||||
card_edit (STRLIST commands)
|
||||
{
|
||||
enum cmdids {
|
||||
cmdNOP = 0,
|
||||
cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG,
|
||||
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
|
||||
cmdFORCESIG, cmdGENERATE, cmdPASSWD,
|
||||
cmdINVCMD
|
||||
};
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
enum cmdids id;
|
||||
int admin_only;
|
||||
const char *desc;
|
||||
} cmds[] = {
|
||||
{ N_("quit") , cmdQUIT , 0, N_("quit this menu") },
|
||||
{ N_("q") , cmdQUIT , 0, NULL },
|
||||
{ N_("admin") , cmdADMIN , 0, N_("show admin commands") },
|
||||
{ N_("help") , cmdHELP , 0, N_("show this help") },
|
||||
{ "?" , cmdHELP , 0, NULL },
|
||||
{ N_("list") , cmdLIST , 0, N_("list all available data") },
|
||||
{ N_("l") , cmdLIST , 0, NULL },
|
||||
{ N_("debug") , cmdDEBUG , 0, NULL },
|
||||
{ N_("name") , cmdNAME , 1, N_("change card holder's name") },
|
||||
{ N_("url") , cmdURL , 1, N_("change URL to retrieve key") },
|
||||
{ N_("fetch") , cmdFETCH , 0,
|
||||
N_("fetch the key specified in the card URL") },
|
||||
{ N_("login") , cmdLOGIN , 1, N_("change the login name") },
|
||||
{ N_("lang") , cmdLANG , 1, N_("change the language preferences") },
|
||||
{ N_("sex") , cmdSEX , 1, N_("change card holder's sex") },
|
||||
{ N_("cafpr"), cmdCAFPR, 1, N_("change a CA fingerprint") },
|
||||
{ N_("forcesig"),
|
||||
cmdFORCESIG, 1, N_("toggle the signature force PIN flag") },
|
||||
{ N_("generate"),
|
||||
cmdGENERATE, 1, N_("generate new keys") },
|
||||
{ N_("passwd"), cmdPASSWD, 0, N_("menu to change or unblock the PIN") },
|
||||
{ NULL, cmdINVCMD, 0, NULL }
|
||||
};
|
||||
|
||||
enum cmdids cmd = cmdNOP;
|
||||
int have_commands = !!commands;
|
||||
int redisplay = 1;
|
||||
@ -1195,7 +1403,7 @@ card_edit (STRLIST commands)
|
||||
;
|
||||
else if (opt.batch && !have_commands)
|
||||
{
|
||||
log_error(_("can't do that in batchmode\n"));
|
||||
log_error(_("can't do this in batch mode\n"));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -1243,8 +1451,14 @@ card_edit (STRLIST commands)
|
||||
|
||||
if (!have_commands)
|
||||
{
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
tty_enable_completion (card_edit_completion);
|
||||
#endif
|
||||
answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
|
||||
cpr_kill_prompt();
|
||||
#if GNUPG_MAJOR_VERSION == 1
|
||||
tty_disable_completion ();
|
||||
#endif
|
||||
}
|
||||
trim_spaces(answer);
|
||||
}
|
||||
@ -1292,9 +1506,33 @@ card_edit (STRLIST commands)
|
||||
break;
|
||||
|
||||
case cmdADMIN:
|
||||
allow_admin=!allow_admin;
|
||||
if ( !strcmp (arg_string, "on") )
|
||||
allow_admin = 1;
|
||||
else if ( !strcmp (arg_string, "off") )
|
||||
allow_admin = 0;
|
||||
else if ( !strcmp (arg_string, "verify") )
|
||||
{
|
||||
/* Force verification of the Admin Command. However,
|
||||
this is only done if the retry counter is at initial
|
||||
state. */
|
||||
char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1);
|
||||
strcpy (stpcpy (tmp, serialnobuf), "[CHV3]");
|
||||
allow_admin = !agent_scd_checkpin (tmp);
|
||||
xfree (tmp);
|
||||
}
|
||||
else /* Toggle. */
|
||||
allow_admin=!allow_admin;
|
||||
if(allow_admin)
|
||||
tty_printf(_("Admin commands are allowed\n"));
|
||||
else
|
||||
tty_printf(_("Admin commands are not allowed\n"));
|
||||
break;
|
||||
|
||||
case cmdVERIFY:
|
||||
agent_scd_checkpin (serialnobuf);
|
||||
redisplay = 1;
|
||||
break;
|
||||
|
||||
case cmdLIST:
|
||||
redisplay = 1;
|
||||
break;
|
||||
@ -1331,6 +1569,14 @@ card_edit (STRLIST commands)
|
||||
change_cafpr (arg_number);
|
||||
break;
|
||||
|
||||
case cmdPRIVATEDO:
|
||||
if ( arg_number < 1 || arg_number > 4 )
|
||||
tty_printf ("usage: privatedo N\n"
|
||||
" 1 <= N <= 4\n");
|
||||
else
|
||||
change_private_do (arg_string, arg_number);
|
||||
break;
|
||||
|
||||
case cmdFORCESIG:
|
||||
toggle_forcesig ();
|
||||
break;
|
||||
|
76
g10/cipher.c
76
g10/cipher.c
@ -1,5 +1,6 @@
|
||||
/* cipher.c - En-/De-ciphering filter
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -28,7 +30,6 @@
|
||||
#include "gpg.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
#include "packet.h"
|
||||
@ -41,17 +42,17 @@
|
||||
|
||||
|
||||
static void
|
||||
write_header( cipher_filter_context_t *cfx, iobuf_t a )
|
||||
write_header( cipher_filter_context_t *cfx, IOBUF a )
|
||||
{
|
||||
gcry_error_t err;
|
||||
PACKET pkt;
|
||||
PKT_encrypted ed;
|
||||
byte temp[18];
|
||||
unsigned int blocksize;
|
||||
unsigned int nprefix;
|
||||
gpg_error_t rc;
|
||||
|
||||
blocksize = gcry_cipher_get_algo_blklen ( cfx->dek->algo );
|
||||
if( blocksize < 8 || blocksize > 16 )
|
||||
blocksize = gcry_cipher_algo_blklen (cfx->dek->algo);
|
||||
if ( blocksize < 8 || blocksize > 16 )
|
||||
log_fatal("unsupported blocksize %u\n", blocksize );
|
||||
|
||||
memset( &ed, 0, sizeof ed );
|
||||
@ -60,9 +61,9 @@ write_header( cipher_filter_context_t *cfx, iobuf_t a )
|
||||
ed.new_ctb = !ed.len && !RFC1991;
|
||||
if( cfx->dek->use_mdc ) {
|
||||
ed.mdc_method = DIGEST_ALGO_SHA1;
|
||||
gcry_md_open (&cfx->mdc_hash, GCRY_MD_SHA1, 0 );
|
||||
gcry_md_open (&cfx->mdc_hash, DIGEST_ALGO_SHA1, 0);
|
||||
if ( DBG_HASHING )
|
||||
gcry_md_start_debug ( cfx->mdc_hash, "creatmdc" );
|
||||
gcry_md_start_debug (cfx->mdc_hash, "creatmdc");
|
||||
}
|
||||
|
||||
{
|
||||
@ -78,28 +79,31 @@ write_header( cipher_filter_context_t *cfx, iobuf_t a )
|
||||
if( build_packet( a, &pkt ))
|
||||
log_bug("build_packet(ENCR_DATA) failed\n");
|
||||
nprefix = blocksize;
|
||||
gcry_randomize ( temp, nprefix, GCRY_STRONG_RANDOM);
|
||||
gcry_randomize (temp, nprefix, GCRY_STRONG_RANDOM );
|
||||
temp[nprefix] = temp[nprefix-2];
|
||||
temp[nprefix+1] = temp[nprefix-1];
|
||||
print_cipher_algo_note( cfx->dek->algo );
|
||||
rc = gcry_cipher_open (&cfx->cipher_hd, cfx->dek->algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
GCRY_CIPHER_SECURE
|
||||
| ((cfx->dek->use_mdc || cfx->dek->algo >= 100) ?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC));
|
||||
err = gcry_cipher_open (&cfx->cipher_hd,
|
||||
cfx->dek->algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
(GCRY_CIPHER_SECURE
|
||||
| ((cfx->dek->use_mdc || cfx->dek->algo >= 100)?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC));
|
||||
if (rc) {
|
||||
/* we should never get an error here cause we already checked, that
|
||||
* the algorithm is available. */
|
||||
/* We should never get an error here cause we already checked,
|
||||
* that the algorithm is available. */
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
/* log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/
|
||||
gcry_cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen );
|
||||
gcry_cipher_setiv( cfx->cipher_hd, NULL, 0 );
|
||||
/* log_hexdump( "prefix", temp, nprefix+2 ); */
|
||||
if( cfx->mdc_hash ) /* hash the "IV" */
|
||||
gcry_md_write( cfx->mdc_hash, temp, nprefix+2 );
|
||||
gcry_cipher_encrypt( cfx->cipher_hd, temp, nprefix+2, NULL, 0);
|
||||
gcry_cipher_sync( cfx->cipher_hd );
|
||||
if (cfx->mdc_hash) /* Hash the "IV". */
|
||||
gcry_md_write (cfx->mdc_hash, temp, nprefix+2 );
|
||||
gcry_cipher_encrypt (cfx->cipher_hd, temp, nprefix+2, NULL, 0);
|
||||
gcry_cipher_sync (cfx->cipher_hd);
|
||||
iobuf_write(a, temp, nprefix+2);
|
||||
cfx->header=1;
|
||||
}
|
||||
@ -111,7 +115,7 @@ write_header( cipher_filter_context_t *cfx, iobuf_t a )
|
||||
*/
|
||||
int
|
||||
cipher_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
size_t size = *ret_len;
|
||||
cipher_filter_context_t *cfx = opaque;
|
||||
@ -125,32 +129,31 @@ cipher_filter( void *opaque, int control,
|
||||
if( !cfx->header ) {
|
||||
write_header( cfx, a );
|
||||
}
|
||||
if( cfx->mdc_hash )
|
||||
gcry_md_write( cfx->mdc_hash, buf, size );
|
||||
gcry_cipher_encrypt( cfx->cipher_hd, buf, size, NULL, 0);
|
||||
if (cfx->mdc_hash)
|
||||
gcry_md_write (cfx->mdc_hash, buf, size);
|
||||
gcry_cipher_encrypt (cfx->cipher_hd, buf, size, NULL, 0);
|
||||
rc = iobuf_write( a, buf, size );
|
||||
}
|
||||
else if( control == IOBUFCTRL_FREE ) {
|
||||
if( cfx->mdc_hash ) {
|
||||
byte *hash;
|
||||
int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo (
|
||||
cfx->mdc_hash));
|
||||
int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo
|
||||
(cfx->mdc_hash));
|
||||
byte temp[22];
|
||||
|
||||
assert( hashlen == 20 );
|
||||
/* we must hash the prefix of the MDC packet here */
|
||||
temp[0] = 0xd3;
|
||||
temp[1] = 0x14;
|
||||
gcry_md_putc ( cfx->mdc_hash, temp[0] );
|
||||
gcry_md_putc ( cfx->mdc_hash, temp[1] );
|
||||
gcry_md_putc (cfx->mdc_hash, temp[0]);
|
||||
gcry_md_putc (cfx->mdc_hash, temp[1]);
|
||||
|
||||
gcry_md_final ( cfx->mdc_hash );
|
||||
hash = gcry_md_read ( cfx->mdc_hash, 0 );
|
||||
gcry_md_final (cfx->mdc_hash);
|
||||
hash = gcry_md_read (cfx->mdc_hash, 0);
|
||||
memcpy(temp+2, hash, 20);
|
||||
gcry_cipher_encrypt( cfx->cipher_hd, temp, 22, NULL, 0 );
|
||||
gcry_md_close ( cfx->mdc_hash ); cfx->mdc_hash = NULL;
|
||||
rc = iobuf_write( a, temp, 22 );
|
||||
if (rc)
|
||||
gcry_cipher_encrypt (cfx->cipher_hd, temp, 22, NULL, 0);
|
||||
gcry_md_close (cfx->mdc_hash); cfx->mdc_hash = NULL;
|
||||
if( iobuf_write( a, temp, 22 ) )
|
||||
log_error("writing MDC packet failed\n" );
|
||||
}
|
||||
gcry_cipher_close (cfx->cipher_hd);
|
||||
@ -160,6 +163,3 @@ cipher_filter( void *opaque, int control,
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
115
g10/compress.c
115
g10/compress.c
@ -1,6 +1,6 @@
|
||||
/* compress.c - compress filter
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* 2003, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,9 +16,16 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
/* Note that the code in compress-bz2.c is nearly identical to the
|
||||
code here, so if you fix a bug here, look there to see if a
|
||||
matching bug needs to be fixed. I tried to have one set of
|
||||
functions that could do ZIP, ZLIB, and BZIP2, but it became
|
||||
dangerously unreadable with #ifdefs and if(algo) -dshaw */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -27,43 +34,42 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <zlib.h>
|
||||
#ifdef __riscos__
|
||||
#if defined(__riscos__) && defined(USE_ZLIBRISCOS)
|
||||
# include "zlib-riscos.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "packet.h"
|
||||
#include "filter.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
|
||||
int compress_filter_bz2( void *opaque, int control,
|
||||
IOBUF a, byte *buf, size_t *ret_len);
|
||||
|
||||
static void
|
||||
init_compress( compress_filter_context_t *zfx, z_stream *zs )
|
||||
{
|
||||
int rc;
|
||||
int level;
|
||||
|
||||
#ifdef __riscos__
|
||||
#if defined(__riscos__) && defined(USE_ZLIBRISCOS)
|
||||
static int zlib_initialized = 0;
|
||||
|
||||
if (!zlib_initialized)
|
||||
zlib_initialized = riscos_load_module("ZLib", zlib_path, 1);
|
||||
#endif
|
||||
|
||||
if( opt.compress >= 0 && opt.compress <= 9 )
|
||||
level = opt.compress;
|
||||
else if( opt.compress == -1 )
|
||||
if( opt.compress_level >= 1 && opt.compress_level <= 9 )
|
||||
level = opt.compress_level;
|
||||
else if( opt.compress_level == -1 )
|
||||
level = Z_DEFAULT_COMPRESSION;
|
||||
else if( opt.compress == 10 ) /* remove this ! */
|
||||
level = 0;
|
||||
else {
|
||||
log_error("invalid compression level; using default level\n");
|
||||
level = Z_DEFAULT_COMPRESSION;
|
||||
}
|
||||
|
||||
|
||||
if( (rc = zfx->algo == 1? deflateInit2( zs, level, Z_DEFLATED,
|
||||
-13, 8, Z_DEFAULT_STRATEGY)
|
||||
: deflateInit( zs, level )
|
||||
@ -75,13 +81,13 @@ init_compress( compress_filter_context_t *zfx, z_stream *zs )
|
||||
}
|
||||
|
||||
zfx->outbufsize = 8192;
|
||||
zfx->outbuf = xmalloc ( zfx->outbufsize );
|
||||
zfx->outbuf = xmalloc( zfx->outbufsize );
|
||||
}
|
||||
|
||||
static int
|
||||
do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, iobuf_t a )
|
||||
do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, IOBUF a )
|
||||
{
|
||||
gpg_error_t rc;
|
||||
int rc;
|
||||
int zrc;
|
||||
unsigned n;
|
||||
|
||||
@ -111,12 +117,10 @@ do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, iobuf_t a
|
||||
(unsigned)zs->avail_in, (unsigned)zs->avail_out,
|
||||
(unsigned)n, zrc );
|
||||
|
||||
rc = iobuf_write (a, zfx->outbuf, n);
|
||||
if (rc)
|
||||
{
|
||||
if( (rc=iobuf_write( a, zfx->outbuf, n )) ) {
|
||||
log_debug("deflate: iobuf_write failed\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
} while( zs->avail_in || (flush == Z_FINISH && zrc != Z_STREAM_END) );
|
||||
return 0;
|
||||
}
|
||||
@ -145,13 +149,13 @@ init_uncompress( compress_filter_context_t *zfx, z_stream *zs )
|
||||
}
|
||||
|
||||
zfx->inbufsize = 2048;
|
||||
zfx->inbuf = xmalloc ( zfx->inbufsize );
|
||||
zfx->inbuf = xmalloc( zfx->inbufsize );
|
||||
zs->avail_in = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
||||
iobuf_t a, size_t *ret_len )
|
||||
IOBUF a, size_t *ret_len )
|
||||
{
|
||||
int zrc;
|
||||
int rc=0;
|
||||
@ -213,9 +217,9 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
compress_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
size_t size = *ret_len;
|
||||
compress_filter_context_t *zfx = opaque;
|
||||
@ -224,7 +228,7 @@ compress_filter( void *opaque, int control,
|
||||
|
||||
if( control == IOBUFCTRL_UNDERFLOW ) {
|
||||
if( !zfx->status ) {
|
||||
zs = zfx->opaque = xcalloc (1, sizeof *zs );
|
||||
zs = zfx->opaque = xmalloc_clear( sizeof *zs );
|
||||
init_uncompress( zfx, zs );
|
||||
zfx->status = 1;
|
||||
}
|
||||
@ -242,10 +246,8 @@ compress_filter( void *opaque, int control,
|
||||
if( !zfx->status ) {
|
||||
PACKET pkt;
|
||||
PKT_compressed cd;
|
||||
|
||||
if( !zfx->algo )
|
||||
zfx->algo = DEFAULT_COMPRESS_ALGO;
|
||||
if( zfx->algo != 1 && zfx->algo != 2 )
|
||||
if(zfx->algo != COMPRESS_ALGO_ZIP
|
||||
&& zfx->algo != COMPRESS_ALGO_ZLIB)
|
||||
BUG();
|
||||
memset( &cd, 0, sizeof cd );
|
||||
cd.len = 0;
|
||||
@ -255,7 +257,7 @@ compress_filter( void *opaque, int control,
|
||||
pkt.pkt.compressed = &cd;
|
||||
if( build_packet( a, &pkt ))
|
||||
log_bug("build_packet(PKT_COMPRESSED) failed\n");
|
||||
zs = zfx->opaque = xcalloc (1, sizeof *zs );
|
||||
zs = zfx->opaque = xmalloc_clear( sizeof *zs );
|
||||
init_compress( zfx, zs );
|
||||
zfx->status = 2;
|
||||
}
|
||||
@ -271,9 +273,9 @@ compress_filter( void *opaque, int control,
|
||||
else if( control == IOBUFCTRL_FREE ) {
|
||||
if( zfx->status == 1 ) {
|
||||
inflateEnd(zs);
|
||||
xfree (zs);
|
||||
xfree(zs);
|
||||
zfx->opaque = NULL;
|
||||
xfree (zfx->outbuf); zfx->outbuf = NULL;
|
||||
xfree(zfx->outbuf); zfx->outbuf = NULL;
|
||||
}
|
||||
else if( zfx->status == 2 ) {
|
||||
#ifndef __riscos__
|
||||
@ -284,9 +286,9 @@ compress_filter( void *opaque, int control,
|
||||
zs->avail_in = 0;
|
||||
do_compress( zfx, zs, Z_FINISH, a );
|
||||
deflateEnd(zs);
|
||||
xfree (zs);
|
||||
xfree(zs);
|
||||
zfx->opaque = NULL;
|
||||
xfree (zfx->outbuf); zfx->outbuf = NULL;
|
||||
xfree(zfx->outbuf); zfx->outbuf = NULL;
|
||||
}
|
||||
if (zfx->release)
|
||||
zfx->release (zfx);
|
||||
@ -308,17 +310,17 @@ release_context (compress_filter_context_t *ctx)
|
||||
*/
|
||||
int
|
||||
handle_compressed( void *procctx, PKT_compressed *cd,
|
||||
int (*callback)(iobuf_t, void *), void *passthru )
|
||||
int (*callback)(IOBUF, void *), void *passthru )
|
||||
{
|
||||
compress_filter_context_t *cfx;
|
||||
int rc;
|
||||
|
||||
if( cd->algorithm < 1 || cd->algorithm > 2 )
|
||||
return GPG_ERR_COMPR_ALGO;
|
||||
cfx = xcalloc (1,sizeof *cfx);
|
||||
cfx->algo = cd->algorithm;
|
||||
if(check_compress_algo(cd->algorithm))
|
||||
return G10ERR_COMPR_ALGO;
|
||||
cfx = xmalloc_clear (sizeof *cfx);
|
||||
cfx->release = release_context;
|
||||
iobuf_push_filter( cd->buf, compress_filter, cfx );
|
||||
cfx->algo = cd->algorithm;
|
||||
push_compress_filter(cd->buf,cfx,cd->algorithm);
|
||||
if( callback )
|
||||
rc = callback(cd->buf, passthru );
|
||||
else
|
||||
@ -327,3 +329,38 @@ handle_compressed( void *procctx, PKT_compressed *cd,
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
push_compress_filter(IOBUF out,compress_filter_context_t *zfx,int algo)
|
||||
{
|
||||
push_compress_filter2(out,zfx,algo,0);
|
||||
}
|
||||
|
||||
void
|
||||
push_compress_filter2(IOBUF out,compress_filter_context_t *zfx,
|
||||
int algo,int rel)
|
||||
{
|
||||
if(algo>=0)
|
||||
zfx->algo=algo;
|
||||
else
|
||||
zfx->algo=DEFAULT_COMPRESS_ALGO;
|
||||
|
||||
switch(zfx->algo)
|
||||
{
|
||||
case COMPRESS_ALGO_NONE:
|
||||
break;
|
||||
|
||||
case COMPRESS_ALGO_ZIP:
|
||||
case COMPRESS_ALGO_ZLIB:
|
||||
iobuf_push_filter2(out,compress_filter,zfx,rel);
|
||||
break;
|
||||
|
||||
#ifdef HAVE_BZIP2
|
||||
case COMPRESS_ALGO_BZIP2:
|
||||
iobuf_push_filter2(out,compress_filter_bz2,zfx,rel);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* dearmor.c - Armor utility
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -28,13 +29,12 @@
|
||||
#include "gpg.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
#include "packet.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
/****************
|
||||
* Take an armor file and write it out without armor
|
||||
@ -43,17 +43,24 @@ int
|
||||
dearmor_file( const char *fname )
|
||||
{
|
||||
armor_filter_context_t afx;
|
||||
iobuf_t inp = NULL, out = NULL;
|
||||
IOBUF inp = NULL, out = NULL;
|
||||
int rc = 0;
|
||||
int c;
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
|
||||
/* prepare iobufs */
|
||||
if( !(inp = iobuf_open(fname)) ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error("can't open %s: %s\n", fname? fname: "[stdin]",
|
||||
inp = iobuf_open(fname);
|
||||
if (inp && is_secured_file (iobuf_get_fd (inp)))
|
||||
{
|
||||
iobuf_close (inp);
|
||||
inp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if (!inp) {
|
||||
log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]",
|
||||
strerror(errno) );
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -85,17 +92,24 @@ int
|
||||
enarmor_file( const char *fname )
|
||||
{
|
||||
armor_filter_context_t afx;
|
||||
iobuf_t inp = NULL, out = NULL;
|
||||
IOBUF inp = NULL, out = NULL;
|
||||
int rc = 0;
|
||||
int c;
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
|
||||
/* prepare iobufs */
|
||||
if( !(inp = iobuf_open(fname)) ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error("can't open %s: %s\n", fname? fname: "[stdin]",
|
||||
strerror(errno) );
|
||||
inp = iobuf_open(fname);
|
||||
if (inp && is_secured_file (iobuf_get_fd (inp)))
|
||||
{
|
||||
iobuf_close (inp);
|
||||
inp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if (!inp) {
|
||||
log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]",
|
||||
strerror(errno) );
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* decrypt.c - verify signed data
|
||||
* Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
|
||||
* 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -25,12 +27,12 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "status.h"
|
||||
@ -49,17 +51,24 @@
|
||||
int
|
||||
decrypt_message( const char *filename )
|
||||
{
|
||||
iobuf_t fp;
|
||||
IOBUF fp;
|
||||
armor_filter_context_t afx;
|
||||
progress_filter_context_t pfx;
|
||||
int rc;
|
||||
int no_out=0;
|
||||
|
||||
/* open the message file */
|
||||
/* Open the message file. */
|
||||
fp = iobuf_open(filename);
|
||||
if (fp && is_secured_file (iobuf_get_fd (fp)))
|
||||
{
|
||||
iobuf_close (fp);
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !fp ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error(_("can't open `%s'\n"), print_fname_stdin(filename));
|
||||
log_error (_("can't open `%s': %s\n"), print_fname_stdin(filename),
|
||||
gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -84,13 +93,14 @@ decrypt_message( const char *filename )
|
||||
}
|
||||
|
||||
void
|
||||
decrypt_messages(int nfiles, char **files)
|
||||
decrypt_messages(int nfiles, char *files[])
|
||||
{
|
||||
iobuf_t fp;
|
||||
IOBUF fp;
|
||||
armor_filter_context_t afx;
|
||||
progress_filter_context_t pfx;
|
||||
char *p, *output = NULL;
|
||||
int rc = 0;
|
||||
int rc=0,use_stdin=0;
|
||||
unsigned int lno=0;
|
||||
|
||||
if (opt.outfile)
|
||||
{
|
||||
@ -99,20 +109,61 @@ decrypt_messages(int nfiles, char **files)
|
||||
|
||||
}
|
||||
|
||||
while (nfiles--)
|
||||
if(!nfiles)
|
||||
use_stdin=1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
print_file_status(STATUS_FILE_START, *files, 3);
|
||||
output = make_outfile_name(*files);
|
||||
char line[2048];
|
||||
char *filename=NULL;
|
||||
|
||||
if(use_stdin)
|
||||
{
|
||||
if(fgets(line, DIM(line), stdin))
|
||||
{
|
||||
lno++;
|
||||
if (!*line || line[strlen(line)-1] != '\n')
|
||||
log_error("input line %u too long or missing LF\n", lno);
|
||||
else
|
||||
{
|
||||
line[strlen(line)-1] = '\0';
|
||||
filename=line;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(nfiles)
|
||||
{
|
||||
filename=*files;
|
||||
nfiles--;
|
||||
files++;
|
||||
}
|
||||
}
|
||||
|
||||
if(filename==NULL)
|
||||
break;
|
||||
|
||||
print_file_status(STATUS_FILE_START, filename, 3);
|
||||
output = make_outfile_name(filename);
|
||||
if (!output)
|
||||
goto next_file;
|
||||
fp = iobuf_open(*files);
|
||||
fp = iobuf_open(filename);
|
||||
if (fp)
|
||||
iobuf_ioctl (fp,3,1,NULL); /* disable fd caching */
|
||||
if (fp && is_secured_file (iobuf_get_fd (fp)))
|
||||
{
|
||||
iobuf_close (fp);
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if (!fp)
|
||||
{
|
||||
log_error(_("can't open `%s'\n"), print_fname_stdin(*files));
|
||||
log_error(_("can't open `%s'\n"), print_fname_stdin(filename));
|
||||
goto next_file;
|
||||
}
|
||||
|
||||
handle_progress (&pfx, fp, *files);
|
||||
handle_progress (&pfx, fp, filename);
|
||||
|
||||
if (!opt.no_armor)
|
||||
{
|
||||
@ -125,8 +176,8 @@ decrypt_messages(int nfiles, char **files)
|
||||
rc = proc_packets(NULL, fp);
|
||||
iobuf_close(fp);
|
||||
if (rc)
|
||||
log_error("%s: decryption failed: %s\n", print_fname_stdin(*files),
|
||||
gpg_strerror (rc));
|
||||
log_error("%s: decryption failed: %s\n", print_fname_stdin(filename),
|
||||
g10_errstr(rc));
|
||||
p = get_last_passphrase();
|
||||
set_next_passphrase(p);
|
||||
xfree (p);
|
||||
@ -134,9 +185,8 @@ decrypt_messages(int nfiles, char **files)
|
||||
next_file:
|
||||
/* Note that we emit file_done even after an error. */
|
||||
write_status( STATUS_FILE_DONE );
|
||||
xfree (output);
|
||||
files++;
|
||||
xfree(output);
|
||||
}
|
||||
|
||||
set_next_passphrase(NULL);
|
||||
}
|
||||
|
||||
|
80
g10/delkey.c
80
g10/delkey.c
@ -1,5 +1,6 @@
|
||||
/* delkey.c - delete keys
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004,
|
||||
* 2005, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -26,12 +28,12 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "trustdb.h"
|
||||
@ -47,7 +49,7 @@
|
||||
* key can't be deleted for that reason.
|
||||
*/
|
||||
static int
|
||||
do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE keyblock = NULL;
|
||||
@ -68,9 +70,9 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20);
|
||||
rc = desc.mode? keydb_search (hd, &desc, 1):GPG_ERR_INV_USER_ID;
|
||||
rc = desc.mode? keydb_search (hd, &desc, 1):G10ERR_INV_USER_ID;
|
||||
if (rc) {
|
||||
log_error (_("key `%s' not found: %s\n"), username, gpg_strerror (rc));
|
||||
log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
|
||||
write_status_text( STATUS_DELETE_PROBLEM, "1" );
|
||||
goto leave;
|
||||
}
|
||||
@ -78,7 +80,7 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
/* read the keyblock */
|
||||
rc = keydb_get_keyblock (hd, &keyblock );
|
||||
if (rc) {
|
||||
log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
|
||||
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -86,29 +88,36 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY );
|
||||
if( !node ) {
|
||||
log_error("Oops; key not found anymore!\n");
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( secret ) {
|
||||
if( secret )
|
||||
{
|
||||
sk = node->pkt->pkt.secret_key;
|
||||
keyid_from_sk( sk, keyid );
|
||||
}
|
||||
else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* public */
|
||||
pk = node->pkt->pkt.public_key;
|
||||
keyid_from_pk( pk, keyid );
|
||||
rc = seckey_available( keyid );
|
||||
if( !rc ) {
|
||||
*r_sec_avail = 1;
|
||||
rc = -1;
|
||||
goto leave;
|
||||
}
|
||||
else if( rc != GPG_ERR_NO_SECKEY ) {
|
||||
log_error("%s: get secret key: %s\n", username, gpg_strerror (rc) );
|
||||
}
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if(!force)
|
||||
{
|
||||
rc = seckey_available( keyid );
|
||||
if( !rc )
|
||||
{
|
||||
*r_sec_avail = 1;
|
||||
rc = -1;
|
||||
goto leave;
|
||||
}
|
||||
else if( rc != G10ERR_NO_SECKEY )
|
||||
log_error("%s: get secret key: %s\n", username, g10_errstr(rc) );
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc )
|
||||
rc = 0;
|
||||
@ -116,26 +125,26 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
okay++;
|
||||
else if( opt.batch && secret )
|
||||
{
|
||||
log_error(_("can't do that in batchmode\n"));
|
||||
log_error(_("can't do this in batch mode\n"));
|
||||
log_info (_("(unless you specify the key by fingerprint)\n"));
|
||||
}
|
||||
else if( opt.batch && opt.answer_yes )
|
||||
okay++;
|
||||
else if( opt.batch )
|
||||
{
|
||||
log_error(_("can't do that in batchmode without \"--yes\"\n"));
|
||||
log_error(_("can't do this in batch mode without \"--yes\"\n"));
|
||||
log_info (_("(unless you specify the key by fingerprint)\n"));
|
||||
}
|
||||
else {
|
||||
if( secret )
|
||||
print_seckey_info( sk );
|
||||
else
|
||||
print_pubkey_info (NULL, pk );
|
||||
print_pubkey_info(NULL, pk );
|
||||
tty_printf( "\n" );
|
||||
|
||||
yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"
|
||||
: "delete_key.okay",
|
||||
_("Delete this key from the keyring? "));
|
||||
_("Delete this key from the keyring? (y/N) "));
|
||||
if( !cpr_enabled() && secret && yes ) {
|
||||
/* I think it is not required to check a passphrase; if
|
||||
* the user is so stupid as to let others access his secret keyring
|
||||
@ -143,7 +152,7 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
* basic texts about security.
|
||||
*/
|
||||
yes = cpr_get_answer_is_yes("delete_key.secret.okay",
|
||||
_("This is a secret key! - really delete? "));
|
||||
_("This is a secret key! - really delete? (y/N) "));
|
||||
}
|
||||
if( yes )
|
||||
okay++;
|
||||
@ -153,7 +162,7 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
if( okay ) {
|
||||
rc = keydb_delete_keyblock (hd);
|
||||
if (rc) {
|
||||
log_error (_("deleting keyblock failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error (_("deleting keyblock failed: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -179,15 +188,18 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
||||
int
|
||||
delete_keys( STRLIST names, int secret, int allow_both )
|
||||
{
|
||||
int rc, avail;
|
||||
int rc, avail, force=(!allow_both && !secret && opt.expert);
|
||||
|
||||
/* Force allows us to delete a public key even if a secret key
|
||||
exists. */
|
||||
|
||||
for(;names;names=names->next) {
|
||||
rc = do_delete_key (names->d, secret, &avail );
|
||||
rc = do_delete_key (names->d, secret, force, &avail );
|
||||
if ( rc && avail ) {
|
||||
if ( allow_both ) {
|
||||
rc = do_delete_key (names->d, 1, &avail );
|
||||
rc = do_delete_key (names->d, 1, 0, &avail );
|
||||
if ( !rc )
|
||||
rc = do_delete_key (names->d, 0, &avail );
|
||||
rc = do_delete_key (names->d, 0, 0, &avail );
|
||||
}
|
||||
else {
|
||||
log_error(_(
|
||||
@ -200,7 +212,7 @@ delete_keys( STRLIST names, int secret, int allow_both )
|
||||
}
|
||||
|
||||
if(rc) {
|
||||
log_error("%s: delete key failed: %s\n", names->d, gpg_strerror (rc) );
|
||||
log_error("%s: delete key failed: %s\n", names->d, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
462
g10/encode.c
462
g10/encode.c
@ -1,6 +1,6 @@
|
||||
/* encode.c - encode data
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -32,7 +33,6 @@
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "filter.h"
|
||||
@ -42,10 +42,8 @@
|
||||
#include "pkglue.h"
|
||||
|
||||
|
||||
static int encode_simple( const char *filename, int mode, int compat );
|
||||
static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
|
||||
|
||||
|
||||
static int encode_simple( const char *filename, int mode, int use_seskey );
|
||||
static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out );
|
||||
|
||||
/****************
|
||||
* Encode FILENAME with only the symmetric cipher. Take input from
|
||||
@ -54,17 +52,7 @@ static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
|
||||
int
|
||||
encode_symmetric( const char *filename )
|
||||
{
|
||||
int compat = 1;
|
||||
|
||||
#if 0
|
||||
/* We don't want to use it because older gnupg version can't
|
||||
handle it and we can presume that a lot of scripts are running
|
||||
with the expert mode set. Some time in the future we might
|
||||
want to allow for it. */
|
||||
if ( opt.expert )
|
||||
compat = 0; /* PGP knows how to handle this mode. */
|
||||
#endif
|
||||
return encode_simple( filename, 1, compat );
|
||||
return encode_simple( filename, 1, 0 );
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -74,69 +62,62 @@ encode_symmetric( const char *filename )
|
||||
int
|
||||
encode_store( const char *filename )
|
||||
{
|
||||
return encode_simple( filename, 0, 1 );
|
||||
return encode_simple( filename, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
encode_sesskey (DEK * dek, DEK ** ret_dek, byte * enckey)
|
||||
encode_seskey( DEK *dek, DEK **seskey, byte *enckey )
|
||||
{
|
||||
CIPHER_HANDLE hd;
|
||||
DEK * c;
|
||||
byte buf[33];
|
||||
gcry_cipher_hd_t hd;
|
||||
byte buf[33];
|
||||
|
||||
assert (dek->keylen < 32);
|
||||
assert ( dek->keylen <= 32 );
|
||||
if(!*seskey)
|
||||
{
|
||||
*seskey=xmalloc_clear(sizeof(DEK));
|
||||
(*seskey)->keylen=dek->keylen;
|
||||
(*seskey)->algo=dek->algo;
|
||||
make_session_key(*seskey);
|
||||
/*log_hexdump( "thekey", c->key, c->keylen );*/
|
||||
}
|
||||
|
||||
/* The encrypted session key is prefixed with a one-octet algorithm id. */
|
||||
buf[0] = (*seskey)->algo;
|
||||
memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
|
||||
|
||||
c = xcalloc (1, sizeof *c);
|
||||
c->keylen = dek->keylen;
|
||||
c->algo = dek->algo;
|
||||
make_session_key (c);
|
||||
/*log_hexdump ("thekey", c->key, c->keylen);*/
|
||||
/* We only pass already checked values to the following fucntion,
|
||||
thus we consider any failure as fatal. */
|
||||
if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
|
||||
BUG ();
|
||||
if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
|
||||
BUG ();
|
||||
gry_cipher_setiv (hd, NULL, 0);
|
||||
gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0);
|
||||
gcry_cipher_close (hd);
|
||||
|
||||
/* the encrypted session key is prefixed with a one-octet algorithm id */
|
||||
buf[0] = c->algo;
|
||||
memcpy (buf + 1, c->key, c->keylen);
|
||||
|
||||
/* due to the fact that we use only checked values, consider each
|
||||
failure as fatal. */
|
||||
if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
|
||||
BUG();
|
||||
if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
|
||||
BUG();
|
||||
gcry_cipher_setiv (hd, NULL, 0);
|
||||
gcry_cipher_encrypt (hd, buf, c->keylen + 1, NULL, 0);
|
||||
gcry_cipher_close (hd);
|
||||
|
||||
memcpy (enckey, buf, c->keylen + 1);
|
||||
wipememory (buf, sizeof buf); /* burn key */
|
||||
*ret_dek = c;
|
||||
memcpy( enckey, buf, (*seskey)->keylen + 1 );
|
||||
wipememory( buf, sizeof buf ); /* burn key */
|
||||
}
|
||||
|
||||
/* We try very hard to use a MDC */
|
||||
static int
|
||||
use_mdc (PK_LIST pk_list,int algo)
|
||||
use_mdc(PK_LIST pk_list,int algo)
|
||||
{
|
||||
byte cipher_algid[4] = {
|
||||
CIPHER_ALGO_AES,
|
||||
CIPHER_ALGO_AES192,
|
||||
CIPHER_ALGO_AES256,
|
||||
CIPHER_ALGO_TWOFISH
|
||||
};
|
||||
int i;
|
||||
|
||||
/* RFC-1991 and 2440 don't have MDC */
|
||||
if(RFC1991 || RFC2440)
|
||||
return 0;
|
||||
|
||||
|
||||
/* --force-mdc overrides --disable-mdc */
|
||||
if (opt.force_mdc)
|
||||
if(opt.force_mdc)
|
||||
return 1;
|
||||
|
||||
if (opt.disable_mdc)
|
||||
if(opt.disable_mdc)
|
||||
return 0;
|
||||
|
||||
/* Do the keys really support MDC? */
|
||||
|
||||
if (select_mdc_from_pklist (pk_list))
|
||||
if(select_mdc_from_pklist(pk_list))
|
||||
return 1;
|
||||
|
||||
/* The keys don't support MDC, so now we do a bit of a hack - if any
|
||||
@ -144,26 +125,40 @@ use_mdc (PK_LIST pk_list,int algo)
|
||||
can handle a MDC. This is valid for PGP 7, which can handle MDCs
|
||||
though it will not generate them. 2440bis allows this, by the
|
||||
way. */
|
||||
for (i=0; i < DIM (cipher_algid); i++)
|
||||
{
|
||||
if (select_algo_from_prefs (pk_list, PREFTYPE_SYM, cipher_algid[i],
|
||||
NULL) == cipher_algid[i])
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
|
||||
CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES)
|
||||
return 1;
|
||||
|
||||
if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
|
||||
CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192)
|
||||
return 1;
|
||||
|
||||
if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
|
||||
CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256)
|
||||
return 1;
|
||||
|
||||
if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
|
||||
CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH)
|
||||
return 1;
|
||||
|
||||
/* Last try. Use MDC for the modern ciphers. */
|
||||
|
||||
if (gcry_cipher_get_algo_blklen (algo) != 8)
|
||||
return 1;
|
||||
|
||||
return 0; /* No MDC */
|
||||
}
|
||||
|
||||
/* We don't want to use use_seskey yet because older gnupg versions
|
||||
can't handle it, and there isn't really any point unless we're
|
||||
making a message that can be decrypted by a public key or
|
||||
passphrase. */
|
||||
static int
|
||||
encode_simple( const char *filename, int mode, int compat )
|
||||
encode_simple( const char *filename, int mode, int use_seskey )
|
||||
{
|
||||
iobuf_t inp, out;
|
||||
IOBUF inp, out;
|
||||
PACKET pkt;
|
||||
DEK *dek = NULL;
|
||||
PKT_plaintext *pt = NULL;
|
||||
STRING2KEY *s2k = NULL;
|
||||
byte enckey[33];
|
||||
@ -175,7 +170,7 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
compress_filter_context_t zfx;
|
||||
text_filter_context_t tfx;
|
||||
progress_filter_context_t pfx;
|
||||
int do_compress = opt.compress && !RFC1991;
|
||||
int do_compress = !RFC1991 && default_compress_algo();
|
||||
|
||||
memset( &cfx, 0, sizeof cfx);
|
||||
memset( &afx, 0, sizeof afx);
|
||||
@ -184,10 +179,19 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
init_packet(&pkt);
|
||||
|
||||
/* prepare iobufs */
|
||||
if( !(inp = iobuf_open(filename)) ) {
|
||||
inp = iobuf_open(filename);
|
||||
if (inp)
|
||||
iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
|
||||
if (inp && is_secured_file (iobuf_get_fd (inp)))
|
||||
{
|
||||
iobuf_close (inp);
|
||||
inp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !inp ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
|
||||
strerror(errno) );
|
||||
log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]"
|
||||
strerror(errno) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -199,42 +203,49 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
/* Due the the fact that we use don't use an IV to encrypt the
|
||||
session key we can't use the new mode with RFC1991 because
|
||||
it has no S2K salt. RFC1991 always uses simple S2K. */
|
||||
if ( RFC1991 && !compat )
|
||||
compat = 1;
|
||||
if ( RFC1991 && use_seskey )
|
||||
use_seskey = 0;
|
||||
|
||||
cfx.dek = NULL;
|
||||
if( mode ) {
|
||||
s2k = xcalloc (1, sizeof *s2k );
|
||||
s2k = xmalloc_clear( sizeof *s2k );
|
||||
s2k->mode = RFC1991? 0:opt.s2k_mode;
|
||||
s2k->hash_algo = opt.s2k_digest_algo;
|
||||
s2k->hash_algo=S2K_DIGEST_ALGO;
|
||||
cfx.dek = passphrase_to_dek( NULL, 0,
|
||||
default_cipher_algo(), s2k, 2,
|
||||
NULL, NULL);
|
||||
if( !cfx.dek || !cfx.dek->keylen ) {
|
||||
rc = gpg_error (GPG_ERR_INV_PASSPHRASE);
|
||||
xfree (cfx.dek);
|
||||
xfree (s2k);
|
||||
rc = gpg_error (GPG_ERR_INV_PASSPHRASE);
|
||||
xfree(cfx.dek);
|
||||
xfree(s2k);
|
||||
iobuf_close(inp);
|
||||
log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
if (!compat && s2k->mode != 1 && s2k->mode != 3) {
|
||||
compat = 1;
|
||||
if (use_seskey && s2k->mode != 1 && s2k->mode != 3) {
|
||||
use_seskey = 0;
|
||||
log_info (_("can't use a symmetric ESK packet "
|
||||
"due to the S2K mode\n"));
|
||||
}
|
||||
|
||||
if ( !compat ) {
|
||||
seskeylen = gcry_cipher_get_algo_keylen (default_cipher_algo());
|
||||
encode_sesskey( cfx.dek, &dek, enckey );
|
||||
xfree (cfx.dek); cfx.dek = dek;
|
||||
}
|
||||
if ( use_seskey )
|
||||
{
|
||||
DEK *dek = NULL;
|
||||
|
||||
seskeylen = gcry_cipher_get_algo_keylen (default_cipher_algo ());
|
||||
encode_seskey( cfx.dek, &dek, enckey );
|
||||
xfree( cfx.dek ); cfx.dek = dek;
|
||||
}
|
||||
|
||||
if(opt.verbose)
|
||||
log_info(_("using cipher %s\n"),
|
||||
gcry_cipher_algo_name (cfx.dek->algo));
|
||||
|
||||
cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
|
||||
}
|
||||
|
||||
if (opt.compress == -1 && cfx.dek && cfx.dek->use_mdc &&
|
||||
is_file_compressed(filename, &rc))
|
||||
if (do_compress && cfx.dek && cfx.dek->use_mdc
|
||||
&& is_file_compressed(filename, &rc))
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info(_("`%s' already compressed\n"), filename);
|
||||
@ -243,52 +254,43 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
|
||||
if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
|
||||
iobuf_cancel(inp);
|
||||
xfree (cfx.dek);
|
||||
xfree (s2k);
|
||||
xfree(cfx.dek);
|
||||
xfree(s2k);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if( opt.armor )
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
#ifdef ENABLE_COMMENT_PACKETS
|
||||
else {
|
||||
write_comment( out, "#created by GNUPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")");
|
||||
if( opt.comment_string )
|
||||
write_comment( out, opt.comment_string );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( s2k && !RFC1991 ) {
|
||||
PKT_symkey_enc *enc = xcalloc (1, sizeof *enc + seskeylen + 1 );
|
||||
PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
|
||||
enc->version = 4;
|
||||
enc->cipher_algo = cfx.dek->algo;
|
||||
enc->s2k = *s2k;
|
||||
if ( !compat && seskeylen ) {
|
||||
if ( use_seskey && seskeylen ) {
|
||||
enc->seskeylen = seskeylen + 1; /* algo id */
|
||||
memcpy( enc->seskey, enckey, seskeylen + 1 );
|
||||
}
|
||||
pkt.pkttype = PKT_SYMKEY_ENC;
|
||||
pkt.pkt.symkey_enc = enc;
|
||||
if( (rc = build_packet( out, &pkt )) )
|
||||
log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
|
||||
xfree (enc);
|
||||
log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
|
||||
xfree(enc);
|
||||
}
|
||||
|
||||
if (!opt.no_literal) {
|
||||
/* setup the inner packet */
|
||||
if( filename || opt.set_filename ) {
|
||||
char *s = make_basename ( opt.set_filename ? opt.set_filename
|
||||
: filename
|
||||
/* for riscos?
|
||||
.iobuf_get_real_fname( inp ) */
|
||||
);
|
||||
pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
|
||||
char *s = make_basename( opt.set_filename ? opt.set_filename
|
||||
: filename,
|
||||
iobuf_get_real_fname( inp ) );
|
||||
pt = xmalloc( sizeof *pt + strlen(s) - 1 );
|
||||
pt->namelen = strlen(s);
|
||||
memcpy(pt->name, s, pt->namelen );
|
||||
xfree (s);
|
||||
xfree(s);
|
||||
}
|
||||
else { /* no filename */
|
||||
pt = xmalloc ( sizeof *pt - 1 );
|
||||
pt = xmalloc( sizeof *pt - 1 );
|
||||
pt->namelen = 0;
|
||||
}
|
||||
}
|
||||
@ -304,12 +306,14 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
either partial length or fixed length with the new style
|
||||
messages. */
|
||||
|
||||
if (filename && *filename && !(*filename == '-' && !filename[1])
|
||||
&& !opt.textmode ) {
|
||||
if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
|
||||
{
|
||||
off_t tmpsize;
|
||||
int overflow;
|
||||
|
||||
if ( !(tmpsize = iobuf_get_filelength(inp)) )
|
||||
log_info(_("%s: WARNING: empty file\n"), filename );
|
||||
if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
|
||||
&& !overflow )
|
||||
log_info(_("WARNING: `%s' is an empty file\n"), filename );
|
||||
/* We can't encode the length of very large files because
|
||||
OpenPGP uses only 32 bit for file sizes. So if the the
|
||||
size of a file is larger than 2^32 minus some bytes for
|
||||
@ -318,9 +322,9 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
filesize = tmpsize;
|
||||
else
|
||||
filesize = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
|
||||
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
|
||||
|
||||
if (!opt.no_literal) {
|
||||
pt->timestamp = make_timestamp();
|
||||
@ -347,14 +351,13 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
{
|
||||
if (cfx.dek && cfx.dek->use_mdc)
|
||||
zfx.new_ctb = 1;
|
||||
zfx.algo=default_compress_algo();
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
push_compress_filter(out,&zfx,default_compress_algo());
|
||||
}
|
||||
|
||||
/* do the work */
|
||||
if (!opt.no_literal) {
|
||||
if( (rc = build_packet( out, &pkt )) )
|
||||
log_error("build_packet failed: %s\n", gpg_strerror (rc) );
|
||||
log_error("build_packet failed: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
else {
|
||||
/* user requested not to create a literal packet,
|
||||
@ -362,8 +365,9 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
byte copy_buffer[4096];
|
||||
int bytes_copied;
|
||||
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
|
||||
if ( (rc=iobuf_write(out, copy_buffer, bytes_copied))) {
|
||||
log_error("copying input to output failed: %s\n", gpg_strerror (rc) );
|
||||
if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
log_error("copying input to output failed: %s\n", g10_errstr(rc) );
|
||||
break;
|
||||
}
|
||||
wipememory(copy_buffer, 4096); /* burn buffer */
|
||||
@ -381,21 +385,70 @@ encode_simple( const char *filename, int mode, int compat )
|
||||
if (pt)
|
||||
pt->buf = NULL;
|
||||
free_packet(&pkt);
|
||||
xfree (cfx.dek);
|
||||
xfree (s2k);
|
||||
xfree(cfx.dek);
|
||||
xfree(s2k);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek)
|
||||
{
|
||||
*symkey_s2k=xmalloc_clear(sizeof(STRING2KEY));
|
||||
(*symkey_s2k)->mode = opt.s2k_mode;
|
||||
(*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO;
|
||||
|
||||
*symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo,
|
||||
*symkey_s2k,2,NULL,NULL);
|
||||
if(!*symkey_dek || !(*symkey_dek)->keylen)
|
||||
{
|
||||
xfree(*symkey_dek);
|
||||
xfree(*symkey_s2k);
|
||||
return G10ERR_PASSPHRASE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
write_symkey_enc(STRING2KEY *symkey_s2k,DEK *symkey_dek,DEK *dek,IOBUF out)
|
||||
{
|
||||
int rc,seskeylen=cipher_get_keylen(dek->algo)/8;
|
||||
|
||||
PKT_symkey_enc *enc;
|
||||
byte enckey[33];
|
||||
PACKET pkt;
|
||||
|
||||
enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
|
||||
encode_seskey(symkey_dek,&dek,enckey);
|
||||
|
||||
enc->version = 4;
|
||||
enc->cipher_algo = opt.s2k_cipher_algo;
|
||||
enc->s2k = *symkey_s2k;
|
||||
enc->seskeylen = seskeylen + 1; /* algo id */
|
||||
memcpy( enc->seskey, enckey, seskeylen + 1 );
|
||||
|
||||
pkt.pkttype = PKT_SYMKEY_ENC;
|
||||
pkt.pkt.symkey_enc = enc;
|
||||
|
||||
if((rc=build_packet(out,&pkt)))
|
||||
log_error("build symkey_enc packet failed: %s\n",g10_errstr(rc));
|
||||
|
||||
xfree(enc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Encrypt the file with the given userids (or ask if none
|
||||
* is supplied).
|
||||
*/
|
||||
int
|
||||
encode_crypt( const char *filename, STRLIST remusr )
|
||||
encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
|
||||
{
|
||||
iobuf_t inp = NULL, out = NULL;
|
||||
IOBUF inp = NULL, out = NULL;
|
||||
PACKET pkt;
|
||||
PKT_plaintext *pt = NULL;
|
||||
DEK *symkey_dek = NULL;
|
||||
STRING2KEY *symkey_s2k = NULL;
|
||||
int rc = 0, rc2 = 0;
|
||||
u32 filesize;
|
||||
cipher_filter_context_t cfx;
|
||||
@ -404,8 +457,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
text_filter_context_t tfx;
|
||||
progress_filter_context_t pfx;
|
||||
PK_LIST pk_list,work_list;
|
||||
int do_compress = opt.compress && !RFC1991;
|
||||
|
||||
int do_compress = opt.compress_algo && !RFC1991;
|
||||
|
||||
memset( &cfx, 0, sizeof cfx);
|
||||
memset( &afx, 0, sizeof afx);
|
||||
@ -413,6 +465,10 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
memset( &tfx, 0, sizeof tfx);
|
||||
init_packet(&pkt);
|
||||
|
||||
if(use_symkey
|
||||
&& (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
|
||||
return rc;
|
||||
|
||||
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
|
||||
return rc;
|
||||
|
||||
@ -429,10 +485,20 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
}
|
||||
|
||||
/* prepare iobufs */
|
||||
if( !(inp = iobuf_open(filename)) ) {
|
||||
inp = iobuf_open(filename);
|
||||
if (inp)
|
||||
iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
|
||||
if (inp && is_secured_file (iobuf_get_fd (inp)))
|
||||
{
|
||||
iobuf_close (inp);
|
||||
inp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !inp ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
|
||||
strerror(errno) );
|
||||
log_error(_("can't open `%s': %s\n"),
|
||||
filename? filename: "[stdin]",
|
||||
gpg_strerror (rc) );
|
||||
goto leave;
|
||||
}
|
||||
else if( opt.verbose )
|
||||
@ -446,19 +512,11 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
|
||||
goto leave;
|
||||
|
||||
|
||||
if( opt.armor )
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
#ifdef ENABLE_COMMENT_PACKETS
|
||||
else {
|
||||
write_comment( out, "#created by GNUPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")");
|
||||
if( opt.comment_string )
|
||||
write_comment( out, opt.comment_string );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* create a session key */
|
||||
cfx.dek = xcalloc_secure (1, sizeof *cfx.dek);
|
||||
cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
|
||||
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
||||
cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
|
||||
/* The only way select_algo_from_prefs can fail here is when
|
||||
@ -482,8 +540,8 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
if(!opt.expert &&
|
||||
select_algo_from_prefs(pk_list,PREFTYPE_SYM,
|
||||
opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
|
||||
log_info(_("forcing symmetric cipher %s (%d) "
|
||||
"violates recipient preferences\n"),
|
||||
log_info(_("WARNING: forcing symmetric cipher %s (%d)"
|
||||
" violates recipient preferences\n"),
|
||||
gcry_cipher_algo_name (opt.def_cipher_algo),
|
||||
opt.def_cipher_algo);
|
||||
|
||||
@ -497,8 +555,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
not have a MDC to give some protection against chosen
|
||||
ciphertext attacks. */
|
||||
|
||||
if (opt.compress == -1 && cfx.dek->use_mdc &&
|
||||
is_file_compressed(filename, &rc2) )
|
||||
if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2) )
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info(_("`%s' already compressed\n"), filename);
|
||||
@ -518,40 +575,49 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
if( rc )
|
||||
goto leave;
|
||||
|
||||
/* We put the passphrase (if any) after any public keys as this
|
||||
seems to be the most useful on the recipient side - there is no
|
||||
point in prompting a user for a passphrase if they have the
|
||||
secret key needed to decrypt. */
|
||||
if(use_symkey && (rc=write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
|
||||
goto leave;
|
||||
|
||||
if (!opt.no_literal) {
|
||||
/* setup the inner packet */
|
||||
if( filename || opt.set_filename ) {
|
||||
char *s = make_basename( opt.set_filename ? opt.set_filename
|
||||
: filename
|
||||
/* ,iobuf_get_real_fname( inp )*/ );
|
||||
pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
|
||||
: filename,
|
||||
iobuf_get_real_fname( inp ) );
|
||||
pt = xmalloc( sizeof *pt + strlen(s) - 1 );
|
||||
pt->namelen = strlen(s);
|
||||
memcpy(pt->name, s, pt->namelen );
|
||||
xfree (s);
|
||||
xfree(s);
|
||||
}
|
||||
else { /* no filename */
|
||||
pt = xmalloc ( sizeof *pt - 1 );
|
||||
pt = xmalloc( sizeof *pt - 1 );
|
||||
pt->namelen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (filename && *filename && !(*filename == '-' && !filename[1])
|
||||
&& !opt.textmode ) {
|
||||
if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
|
||||
{
|
||||
off_t tmpsize;
|
||||
int overflow;
|
||||
|
||||
if ( !(tmpsize = iobuf_get_filelength(inp)) )
|
||||
log_info(_("%s: WARNING: empty file\n"), filename );
|
||||
if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
|
||||
&& !overflow )
|
||||
log_info(_("WARNING: `%s' is an empty file\n"), filename );
|
||||
/* We can't encode the length of very large files because
|
||||
OpenPGP uses only 32 bit for file sizes. So if the the
|
||||
size of a file is larger than 2^32 minus some bytes for
|
||||
packet headers, we switch to partial length encoding. */
|
||||
if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
|
||||
if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
|
||||
filesize = tmpsize;
|
||||
else
|
||||
filesize = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
|
||||
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
|
||||
|
||||
if (!opt.no_literal) {
|
||||
pt->timestamp = make_timestamp();
|
||||
@ -571,7 +637,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
|
||||
/* register the compress filter */
|
||||
if( do_compress ) {
|
||||
int compr_algo = opt.def_compress_algo;
|
||||
int compr_algo = opt.compress_algo;
|
||||
|
||||
if(compr_algo==-1)
|
||||
{
|
||||
@ -584,8 +650,8 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
else if(!opt.expert &&
|
||||
select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
|
||||
compr_algo,NULL)!=compr_algo)
|
||||
log_info(_("forcing compression algorithm %s (%d) "
|
||||
"violates recipient preferences\n"),
|
||||
log_info(_("WARNING: forcing compression algorithm %s (%d)"
|
||||
" violates recipient preferences\n"),
|
||||
compress_algo_to_string(compr_algo),compr_algo);
|
||||
|
||||
/* algo 0 means no compression */
|
||||
@ -593,15 +659,14 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
{
|
||||
if (cfx.dek && cfx.dek->use_mdc)
|
||||
zfx.new_ctb = 1;
|
||||
zfx.algo = compr_algo;
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
push_compress_filter(out,&zfx,compr_algo);
|
||||
}
|
||||
}
|
||||
|
||||
/* do the work */
|
||||
if (!opt.no_literal) {
|
||||
if( (rc = build_packet( out, &pkt )) )
|
||||
log_error("build_packet failed: %s\n", gpg_strerror (rc) );
|
||||
log_error("build_packet failed: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
else {
|
||||
/* user requested not to create a literal packet, so we copy
|
||||
@ -609,9 +674,10 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
byte copy_buffer[4096];
|
||||
int bytes_copied;
|
||||
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
|
||||
if ((rc=iobuf_write(out, copy_buffer, bytes_copied))) {
|
||||
if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
log_error("copying input to output failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
break;
|
||||
}
|
||||
wipememory(copy_buffer, 4096); /* burn buffer */
|
||||
@ -629,7 +695,9 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
if( pt )
|
||||
pt->buf = NULL;
|
||||
free_packet(&pkt);
|
||||
xfree (cfx.dek);
|
||||
xfree(cfx.dek);
|
||||
xfree(symkey_dek);
|
||||
xfree(symkey_s2k);
|
||||
release_pk_list( pk_list );
|
||||
return rc;
|
||||
}
|
||||
@ -642,7 +710,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
*/
|
||||
int
|
||||
encrypt_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
size_t size = *ret_len;
|
||||
encrypt_filter_context_t *efx = opaque;
|
||||
@ -653,7 +721,7 @@ encrypt_filter( void *opaque, int control,
|
||||
}
|
||||
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
||||
if( !efx->header_okay ) {
|
||||
efx->cfx.dek = xcalloc_secure (1, sizeof *efx->cfx.dek );
|
||||
efx->cfx.dek = xmalloc_secure_clear( sizeof *efx->cfx.dek );
|
||||
|
||||
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
||||
efx->cfx.dek->algo =
|
||||
@ -688,6 +756,14 @@ encrypt_filter( void *opaque, int control,
|
||||
if( rc )
|
||||
return rc;
|
||||
|
||||
if(efx->symkey_s2k && efx->symkey_dek)
|
||||
{
|
||||
rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek,
|
||||
efx->cfx.dek,a);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
iobuf_push_filter( a, cipher_filter, &efx->cfx );
|
||||
|
||||
efx->header_okay = 1;
|
||||
@ -695,8 +771,11 @@ encrypt_filter( void *opaque, int control,
|
||||
rc = iobuf_write( a, buf, size );
|
||||
|
||||
}
|
||||
else if( control == IOBUFCTRL_FREE ) {
|
||||
}
|
||||
else if( control == IOBUFCTRL_FREE )
|
||||
{
|
||||
xfree(efx->symkey_dek);
|
||||
xfree(efx->symkey_s2k);
|
||||
}
|
||||
else if( control == IOBUFCTRL_DESC ) {
|
||||
*(char**)buf = "encrypt_filter";
|
||||
}
|
||||
@ -708,7 +787,7 @@ encrypt_filter( void *opaque, int control,
|
||||
* Write pubkey-enc packets from the list of PKs to OUT.
|
||||
*/
|
||||
static int
|
||||
write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out )
|
||||
write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
|
||||
{
|
||||
PACKET pkt;
|
||||
PKT_public_key *pk;
|
||||
@ -716,12 +795,12 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out )
|
||||
int rc;
|
||||
|
||||
for( ; pk_list; pk_list = pk_list->next ) {
|
||||
gcry_mpi_t frame;
|
||||
MPI frame;
|
||||
|
||||
pk = pk_list->pk;
|
||||
|
||||
print_pubkey_algo_note( pk->pubkey_algo );
|
||||
enc = xcalloc (1, sizeof *enc );
|
||||
enc = xmalloc_clear( sizeof *enc );
|
||||
enc->pubkey_algo = pk->pubkey_algo;
|
||||
keyid_from_pk( pk, enc->keyid );
|
||||
enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1));
|
||||
@ -742,23 +821,24 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out )
|
||||
* algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
|
||||
* which returns the encrypted value in the array ENC->DATA.
|
||||
* This array has a size which depends on the used algorithm
|
||||
* (e.g. 2 for ElGamal). We don't need frame anymore because we
|
||||
* (e.g. 2 for Elgamal). We don't need frame anymore because we
|
||||
* have everything now in enc->data which is the passed to
|
||||
* build_packet()
|
||||
*/
|
||||
frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
|
||||
pk->pkey ) );
|
||||
rc = pk_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
|
||||
gcry_mpi_release ( frame );
|
||||
frame = encode_session_key (dek, pubkey_nbits (pk->pubkey_algo,
|
||||
pk->pkey) );
|
||||
rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk->pkey);
|
||||
gcry_mpi_release (frame);
|
||||
if( rc )
|
||||
log_error("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
|
||||
log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
|
||||
else {
|
||||
if( opt.verbose ) {
|
||||
char *ustr = get_user_id_string_printable (enc->keyid);
|
||||
char *ustr = get_user_id_string_native (enc->keyid);
|
||||
log_info(_("%s/%s encrypted for: \"%s\"\n"),
|
||||
gcry_pk_algo_name (enc->pubkey_algo),
|
||||
gcry_cipher_algo_name (dek->algo), ustr );
|
||||
xfree (ustr);
|
||||
gcry_pk_algo_name (enc->pubkey_algo),
|
||||
gcry_cipher_algo_name (dek->algo),
|
||||
ustr );
|
||||
xfree(ustr);
|
||||
}
|
||||
/* and write it */
|
||||
init_packet(&pkt);
|
||||
@ -766,7 +846,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out )
|
||||
pkt.pkt.pubkey_enc = enc;
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc )
|
||||
log_error("build_packet(pubkey_enc) failed: %s\n", gpg_strerror (rc));
|
||||
log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
|
||||
}
|
||||
free_pubkey_enc(enc);
|
||||
if( rc )
|
||||
@ -800,9 +880,9 @@ encode_crypt_files(int nfiles, char **files, STRLIST remusr)
|
||||
}
|
||||
line[strlen(line)-1] = '\0';
|
||||
print_file_status(STATUS_FILE_START, line, 2);
|
||||
if ( (rc = encode_crypt(line, remusr)) )
|
||||
log_error("%s: encryption failed: %s\n",
|
||||
print_fname_stdin(line), gpg_strerror (rc) );
|
||||
if ( (rc = encode_crypt(line, remusr, 0)) )
|
||||
log_error("encryption of `%s' failed: %s\n",
|
||||
print_fname_stdin(line), g10_errstr(rc) );
|
||||
write_status( STATUS_FILE_DONE );
|
||||
}
|
||||
}
|
||||
@ -811,9 +891,9 @@ encode_crypt_files(int nfiles, char **files, STRLIST remusr)
|
||||
while (nfiles--)
|
||||
{
|
||||
print_file_status(STATUS_FILE_START, *files, 2);
|
||||
if ( (rc = encode_crypt(*files, remusr)) )
|
||||
log_error("%s: encryption failed: %s\n",
|
||||
print_fname_stdin(*files), gpg_strerror (rc) );
|
||||
if ( (rc = encode_crypt(*files, remusr, 0)) )
|
||||
log_error("encryption of `%s' failed: %s\n",
|
||||
print_fname_stdin(*files), g10_errstr(rc) );
|
||||
write_status( STATUS_FILE_DONE );
|
||||
files++;
|
||||
}
|
||||
|
109
g10/encr-data.c
109
g10/encr-data.c
@ -1,5 +1,6 @@
|
||||
/* encr-data.c - process an encrypted data packet
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -26,25 +28,24 @@
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "packet.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
#include "options.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
static int mdc_decode_filter( void *opaque, int control, iobuf_t a,
|
||||
static int mdc_decode_filter( void *opaque, int control, IOBUF a,
|
||||
byte *buf, size_t *ret_len);
|
||||
static int decode_filter( void *opaque, int control, iobuf_t a,
|
||||
static int decode_filter( void *opaque, int control, IOBUF a,
|
||||
byte *buf, size_t *ret_len);
|
||||
|
||||
typedef struct {
|
||||
CIPHER_HANDLE cipher_hd;
|
||||
MD_HANDLE mdc_hash;
|
||||
char defer[20];
|
||||
int defer_filled;
|
||||
int eof_seen;
|
||||
typedef struct
|
||||
{
|
||||
gcry_cipher_hd_t cipher_hd;
|
||||
gcry_md_hd_t mdc_hash;
|
||||
char defer[20];
|
||||
int defer_filled;
|
||||
int eof_seen;
|
||||
} decode_filter_ctx_t;
|
||||
|
||||
|
||||
@ -70,7 +71,8 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
log_info(_("encrypted with unknown algorithm %d\n"), dek->algo );
|
||||
dek->algo_info_printed = 1;
|
||||
}
|
||||
if( (rc=openpgp_cipher_test_algo(dek->algo)) )
|
||||
rc = openpgp_cipher_test_algo (dek->algo);
|
||||
if (rc)
|
||||
goto leave;
|
||||
blocksize = gcry_cipher_get_algo_blklen (dek->algo);
|
||||
if( !blocksize || blocksize > 16 )
|
||||
@ -80,31 +82,39 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
BUG();
|
||||
|
||||
if( ed->mdc_method ) {
|
||||
gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 );
|
||||
if (gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 ))
|
||||
BUG ();
|
||||
if ( DBG_HASHING )
|
||||
gcry_md_start_debug (dfx.mdc_hash, "checkmdc");
|
||||
}
|
||||
|
||||
rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
GCRY_CIPHER_SECURE
|
||||
| ((ed->mdc_method || dek->algo >= 100)?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC) );
|
||||
if (rc)
|
||||
{
|
||||
/* we should never get an error here cause we already
|
||||
* checked, that the algorithm is available. What about a
|
||||
* flag to let the function die in this case? */
|
||||
BUG();
|
||||
}
|
||||
(GCRY_CIPHER_SECURE
|
||||
| ((ed->mdc_method || dek->algo >= 100)?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC)));
|
||||
if (rc)
|
||||
{
|
||||
/* We should never get an error here cause we already checked
|
||||
* that the algorithm is available. */
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
/* log_hexdump( "thekey", dek->key, dek->keylen );*/
|
||||
rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen);
|
||||
if( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
|
||||
log_info(_("WARNING: message was encrypted with "
|
||||
"a weak key in the symmetric cipher.\n"));
|
||||
else if( rc ) {
|
||||
log_error("key setup failed: %s\n", gpg_strerror (rc) );
|
||||
if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
|
||||
{
|
||||
log_info(_("WARNING: message was encrypted with"
|
||||
" a weak key in the symmetric cipher.\n"));
|
||||
rc=0;
|
||||
}
|
||||
else if( rc )
|
||||
{
|
||||
log_error("key setup failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
}
|
||||
if (!ed->buf) {
|
||||
log_error(_("problem handling encrypted packet\n"));
|
||||
goto leave;
|
||||
@ -112,7 +122,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
|
||||
gcry_cipher_setiv (dfx.cipher_hd, NULL, 0);
|
||||
|
||||
if (ed->len) {
|
||||
if( ed->len ) {
|
||||
for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) {
|
||||
if( (c=iobuf_get(ed->buf)) == -1 )
|
||||
break;
|
||||
@ -127,17 +137,20 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
else
|
||||
temp[i] = c;
|
||||
}
|
||||
gcry_cipher_decrypt( dfx.cipher_hd, temp, nprefix+2, NULL, 0);
|
||||
gcry_cipher_sync( dfx.cipher_hd );
|
||||
|
||||
gcry_cipher_decrypt (dfx.cipher_hd, temp, nprefix+2, NULL, 0);
|
||||
gcry_cipher_sync (dfx.cipher_hd);
|
||||
p = temp;
|
||||
/* log_hexdump( "prefix", temp, nprefix+2 ); */
|
||||
if( p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1] ) {
|
||||
if(dek->symmetric
|
||||
&& (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
|
||||
{
|
||||
rc = GPG_ERR_BAD_KEY;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if( dfx.mdc_hash )
|
||||
gcry_md_write( dfx.mdc_hash, temp, nprefix+2 );
|
||||
gcry_md_write (dfx.mdc_hash, temp, nprefix+2);
|
||||
|
||||
if( ed->mdc_method )
|
||||
iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
|
||||
@ -152,18 +165,18 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
|
||||
|
||||
gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 20, NULL, 0);
|
||||
gcry_md_final ( dfx.mdc_hash );
|
||||
if( datalen != 20
|
||||
|| memcmp(gcry_md_read ( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
|
||||
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
||||
/*log_hexdump("MDC calculated:", gcry_md_read ( dfx.mdc_hash, 0), datalen);*/
|
||||
gcry_md_final (dfx.mdc_hash);
|
||||
if (datalen != 20
|
||||
|| memcmp (gcry_md_read( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
|
||||
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
||||
/*log_hexdump("MDC calculated:", md_read( dfx.mdc_hash, 0), datalen);*/
|
||||
/*log_hexdump("MDC message :", dfx.defer, 20);*/
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
gcry_cipher_close(dfx.cipher_hd);
|
||||
gcry_md_close ( dfx.mdc_hash );
|
||||
gcry_cipher_close (dfx.cipher_hd);
|
||||
gcry_md_close (dfx.mdc_hash);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -171,7 +184,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
|
||||
/* I think we should merge this with cipher_filter */
|
||||
static int
|
||||
mdc_decode_filter( void *opaque, int control, iobuf_t a,
|
||||
mdc_decode_filter( void *opaque, int control, IOBUF a,
|
||||
byte *buf, size_t *ret_len)
|
||||
{
|
||||
decode_filter_ctx_t *dfx = opaque;
|
||||
@ -229,8 +242,8 @@ mdc_decode_filter( void *opaque, int control, iobuf_t a,
|
||||
}
|
||||
|
||||
if( n ) {
|
||||
gcry_cipher_decrypt( dfx->cipher_hd, buf, n, NULL, 0);
|
||||
gcry_md_write( dfx->mdc_hash, buf, n );
|
||||
gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
|
||||
gcry_md_write (dfx->mdc_hash, buf, n);
|
||||
}
|
||||
else {
|
||||
assert( dfx->eof_seen );
|
||||
@ -245,7 +258,7 @@ mdc_decode_filter( void *opaque, int control, iobuf_t a,
|
||||
}
|
||||
|
||||
static int
|
||||
decode_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len)
|
||||
decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
decode_filter_ctx_t *fc = opaque;
|
||||
size_t n, size = *ret_len;
|
||||
@ -256,7 +269,7 @@ decode_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len)
|
||||
n = iobuf_read( a, buf, size );
|
||||
if( n == -1 ) n = 0;
|
||||
if( n )
|
||||
gcry_cipher_decrypt( fc->cipher_hd, buf, n, NULL, 0);
|
||||
gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
|
||||
else
|
||||
rc = -1; /* eof */
|
||||
*ret_len = n;
|
||||
|
169
g10/exec.c
169
g10/exec.c
@ -1,5 +1,5 @@
|
||||
/* exec.c - generic call-a-program code
|
||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -34,12 +35,13 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "memory.h"
|
||||
#include "i18n.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include "mkdtemp.h"
|
||||
#include "mkdtemp.h" /* From gnulib. */
|
||||
#include "exec.h"
|
||||
|
||||
#ifdef NO_EXEC
|
||||
@ -47,12 +49,12 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
const char *args_in,const char *name,int writeonly,int binary)
|
||||
{
|
||||
log_error(_("no remote program execution supported\n"));
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
int exec_read(struct exec_info *info) { return GPG_ERR_GENERAL; }
|
||||
int exec_finish(struct exec_info *info) { return GPG_ERR_GENERAL; }
|
||||
int set_exec_path(const char *path,int method) { return GPG_ERR_GENERAL; }
|
||||
int exec_read(struct exec_info *info) { return G10ERR_GENERAL; }
|
||||
int exec_finish(struct exec_info *info) { return G10ERR_GENERAL; }
|
||||
int set_exec_path(const char *path) { return G10ERR_GENERAL; }
|
||||
|
||||
#else /* ! NO_EXEC */
|
||||
|
||||
@ -60,7 +62,7 @@ int set_exec_path(const char *path,int method) { return GPG_ERR_GENERAL; }
|
||||
/* This is a nicer system() for windows that waits for programs to
|
||||
return before returning control to the caller. I hate helpful
|
||||
computers. */
|
||||
static int win_system(const char *command)
|
||||
static int w32_system(const char *command)
|
||||
{
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
@ -68,7 +70,7 @@ static int win_system(const char *command)
|
||||
|
||||
/* We must use a copy of the command as CreateProcess modifies this
|
||||
argument. */
|
||||
string=xstrdup (command);
|
||||
string=xstrdup(command);
|
||||
|
||||
memset(&pi,0,sizeof(pi));
|
||||
memset(&si,0,sizeof(si));
|
||||
@ -82,42 +84,30 @@ static int win_system(const char *command)
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
xfree (string);
|
||||
xfree(string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* method==0 to replace current $PATH, and 1 to append to current
|
||||
$PATH. */
|
||||
int set_exec_path(const char *path,int method)
|
||||
/* Replaces current $PATH */
|
||||
int set_exec_path(const char *path)
|
||||
{
|
||||
char *p,*curpath=NULL;
|
||||
size_t curlen=0;
|
||||
char *p;
|
||||
|
||||
if(method==1 && (curpath=getenv("PATH")))
|
||||
curlen=strlen(curpath)+1;
|
||||
|
||||
p=xmalloc (5+curlen+strlen(path)+1);
|
||||
p=xmalloc(5+strlen(path)+1);
|
||||
strcpy(p,"PATH=");
|
||||
|
||||
if(curpath)
|
||||
{
|
||||
strcat(p,curpath);
|
||||
strcat(p,":");
|
||||
}
|
||||
|
||||
strcat(p,path);
|
||||
|
||||
if(DBG_EXTPROG)
|
||||
log_debug("set_exec_path method %d: %s\n",method,p);
|
||||
log_debug("set_exec_path: %s\n",p);
|
||||
|
||||
/* Notice that path is never freed. That is intentional due to the
|
||||
way putenv() works. This leaks a few bytes if we call
|
||||
set_exec_path multiple times. */
|
||||
|
||||
if(putenv(p)!=0)
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -128,16 +118,16 @@ static int make_tempdir(struct exec_info *info)
|
||||
char *tmp=opt.temp_dir,*namein=info->name,*nameout;
|
||||
|
||||
if(!namein)
|
||||
namein=info->binary?"tempin" EXTSEP_S "bin":"tempin" EXTSEP_S "txt";
|
||||
namein=info->flags.binary?"tempin" EXTSEP_S "bin":"tempin" EXTSEP_S "txt";
|
||||
|
||||
nameout=info->binary?"tempout" EXTSEP_S "bin":"tempout" EXTSEP_S "txt";
|
||||
nameout=info->flags.binary?"tempout" EXTSEP_S "bin":"tempout" EXTSEP_S "txt";
|
||||
|
||||
/* Make up the temp dir and files in case we need them */
|
||||
|
||||
if(tmp==NULL)
|
||||
{
|
||||
#if defined (_WIN32)
|
||||
tmp=xmalloc (256);
|
||||
tmp=xmalloc(256);
|
||||
if(GetTempPath(256,tmp)==0)
|
||||
strcpy(tmp,"c:\\windows\\temp");
|
||||
else
|
||||
@ -169,12 +159,12 @@ static int make_tempdir(struct exec_info *info)
|
||||
#endif
|
||||
}
|
||||
|
||||
info->tempdir=xmalloc (strlen(tmp)+strlen(DIRSEP_S)+10+1);
|
||||
info->tempdir=xmalloc(strlen(tmp)+strlen(DIRSEP_S)+10+1);
|
||||
|
||||
sprintf(info->tempdir,"%s" DIRSEP_S "gpg-XXXXXX",tmp);
|
||||
|
||||
#if defined (_WIN32)
|
||||
xfree (tmp);
|
||||
xfree(tmp);
|
||||
#endif
|
||||
|
||||
if(mkdtemp(info->tempdir)==NULL)
|
||||
@ -182,21 +172,21 @@ static int make_tempdir(struct exec_info *info)
|
||||
info->tempdir,strerror(errno));
|
||||
else
|
||||
{
|
||||
info->madedir=1;
|
||||
info->flags.madedir=1;
|
||||
|
||||
info->tempfile_in=xmalloc (strlen(info->tempdir)+
|
||||
info->tempfile_in=xmalloc(strlen(info->tempdir)+
|
||||
strlen(DIRSEP_S)+strlen(namein)+1);
|
||||
sprintf(info->tempfile_in,"%s" DIRSEP_S "%s",info->tempdir,namein);
|
||||
|
||||
if(!info->writeonly)
|
||||
if(!info->flags.writeonly)
|
||||
{
|
||||
info->tempfile_out=xmalloc (strlen(info->tempdir)+
|
||||
info->tempfile_out=xmalloc(strlen(info->tempdir)+
|
||||
strlen(DIRSEP_S)+strlen(nameout)+1);
|
||||
sprintf(info->tempfile_out,"%s" DIRSEP_S "%s",info->tempdir,nameout);
|
||||
}
|
||||
}
|
||||
|
||||
return info->madedir?0:GPG_ERR_GENERAL;
|
||||
return info->flags.madedir?0:G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
/* Expands %i and %o in the args to the full temp files within the
|
||||
@ -206,14 +196,14 @@ static int expand_args(struct exec_info *info,const char *args_in)
|
||||
const char *ch=args_in;
|
||||
unsigned int size,len;
|
||||
|
||||
info->use_temp_files=0;
|
||||
info->keep_temp_files=0;
|
||||
info->flags.use_temp_files=0;
|
||||
info->flags.keep_temp_files=0;
|
||||
|
||||
if(DBG_EXTPROG)
|
||||
log_debug("expanding string \"%s\"\n",args_in);
|
||||
|
||||
size=100;
|
||||
info->command=xmalloc (size);
|
||||
info->command=xmalloc(size);
|
||||
len=0;
|
||||
info->command[0]='\0';
|
||||
|
||||
@ -228,31 +218,31 @@ static int expand_args(struct exec_info *info,const char *args_in)
|
||||
switch(*ch)
|
||||
{
|
||||
case 'O':
|
||||
info->keep_temp_files=1;
|
||||
info->flags.keep_temp_files=1;
|
||||
/* fall through */
|
||||
|
||||
case 'o': /* out */
|
||||
if(!info->madedir)
|
||||
if(!info->flags.madedir)
|
||||
{
|
||||
if(make_tempdir(info))
|
||||
goto fail;
|
||||
}
|
||||
append=info->tempfile_out;
|
||||
info->use_temp_files=1;
|
||||
info->flags.use_temp_files=1;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
info->keep_temp_files=1;
|
||||
info->flags.keep_temp_files=1;
|
||||
/* fall through */
|
||||
|
||||
case 'i': /* in */
|
||||
if(!info->madedir)
|
||||
if(!info->flags.madedir)
|
||||
{
|
||||
if(make_tempdir(info))
|
||||
goto fail;
|
||||
}
|
||||
append=info->tempfile_in;
|
||||
info->use_temp_files=1;
|
||||
info->flags.use_temp_files=1;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
@ -293,17 +283,17 @@ static int expand_args(struct exec_info *info,const char *args_in)
|
||||
}
|
||||
|
||||
if(DBG_EXTPROG)
|
||||
log_debug("args expanded to \"%s\", use %d, keep %d\n",
|
||||
info->command,info->use_temp_files,info->keep_temp_files);
|
||||
log_debug("args expanded to \"%s\", use %u, keep %u\n",info->command,
|
||||
info->flags.use_temp_files,info->flags.keep_temp_files);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
||||
xfree (info->command);
|
||||
xfree(info->command);
|
||||
info->command=NULL;
|
||||
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
/* Either handles the tempfile creation, or the fork/exec. If it
|
||||
@ -315,7 +305,7 @@ static int expand_args(struct exec_info *info,const char *args_in)
|
||||
int exec_write(struct exec_info **info,const char *program,
|
||||
const char *args_in,const char *name,int writeonly,int binary)
|
||||
{
|
||||
int ret=GPG_ERR_GENERAL;
|
||||
int ret=G10ERR_GENERAL;
|
||||
|
||||
if(opt.exec_disable && !opt.no_perm_warn)
|
||||
{
|
||||
@ -335,22 +325,22 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
if(program==NULL && args_in==NULL)
|
||||
BUG();
|
||||
|
||||
*info=xcalloc (1,sizeof(struct exec_info));
|
||||
*info=xmalloc_clear(sizeof(struct exec_info));
|
||||
|
||||
if(name)
|
||||
(*info)->name=xstrdup (name);
|
||||
(*info)->binary=binary;
|
||||
(*info)->writeonly=writeonly;
|
||||
(*info)->name=xstrdup(name);
|
||||
(*info)->flags.binary=binary;
|
||||
(*info)->flags.writeonly=writeonly;
|
||||
|
||||
/* Expand the args, if any */
|
||||
if(args_in && expand_args(*info,args_in))
|
||||
goto fail;
|
||||
|
||||
#ifdef EXEC_TEMPFILE_ONLY
|
||||
if(!(*info)->use_temp_files)
|
||||
if(!(*info)->flags.use_temp_files)
|
||||
{
|
||||
log_error(_("this platform requires temp files when calling external "
|
||||
"programs\n"));
|
||||
log_error(_("this platform requires temporary files when calling"
|
||||
" external programs\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -358,7 +348,7 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
|
||||
/* If there are no args, or there are args, but no temp files, we
|
||||
can use fork/exec/pipe */
|
||||
if(args_in==NULL || (*info)->use_temp_files==0)
|
||||
if(args_in==NULL || (*info)->flags.use_temp_files==0)
|
||||
{
|
||||
int to[2],from[2];
|
||||
|
||||
@ -392,7 +382,7 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
|
||||
/* If the program isn't going to respond back, they get to
|
||||
keep their stdout/stderr */
|
||||
if(!(*info)->writeonly)
|
||||
if(!(*info)->flags.writeonly)
|
||||
{
|
||||
/* implied close of STDERR */
|
||||
if(dup2(STDOUT_FILENO,STDERR_FILENO)==-1)
|
||||
@ -426,10 +416,12 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
|
||||
/* If we get this far the exec failed. Clean up and return. */
|
||||
|
||||
log_error(_("unable to execute %s \"%s\": %s\n"),
|
||||
args_in==NULL?"program":"shell",
|
||||
args_in==NULL?program:shell,
|
||||
strerror(errno));
|
||||
if(args_in==NULL)
|
||||
log_error(_("unable to execute program `%s': %s\n"),
|
||||
program,strerror(errno));
|
||||
else
|
||||
log_error(_("unable to execute shell `%s': %s\n"),
|
||||
shell,strerror(errno));
|
||||
|
||||
/* This mimics the POSIX sh behavior - 127 means "not found"
|
||||
from the shell. */
|
||||
@ -446,8 +438,8 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
(*info)->tochild=fdopen(to[1],binary?"wb":"w");
|
||||
if((*info)->tochild==NULL)
|
||||
{
|
||||
ret = gpg_error_from_errno (errno);
|
||||
close(to[1]);
|
||||
ret=G10ERR_WRITE_FILE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -456,8 +448,8 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
(*info)->fromchild=iobuf_fdopen(from[0],"r");
|
||||
if((*info)->fromchild==NULL)
|
||||
{
|
||||
ret = gpg_error_from_errno (errno);
|
||||
close(from[0]);
|
||||
ret=G10ERR_READ_FILE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -472,12 +464,18 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
log_debug("using temp file `%s'\n",(*info)->tempfile_in);
|
||||
|
||||
/* It's not fork/exec/pipe, so create a temp file */
|
||||
(*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w");
|
||||
if( is_secured_filename ((*info)->tempfile_in) )
|
||||
{
|
||||
(*info)->tochild = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
else
|
||||
(*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w");
|
||||
if((*info)->tochild==NULL)
|
||||
{
|
||||
ret = gpg_error_from_errno (errno);
|
||||
log_error(_("can't create `%s': %s\n"),
|
||||
(*info)->tempfile_in,strerror(errno));
|
||||
ret=G10ERR_WRITE_FILE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -489,18 +487,18 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
|
||||
int exec_read(struct exec_info *info)
|
||||
{
|
||||
int ret=GPG_ERR_GENERAL;
|
||||
int ret=G10ERR_GENERAL;
|
||||
|
||||
fclose(info->tochild);
|
||||
info->tochild=NULL;
|
||||
|
||||
if(info->use_temp_files)
|
||||
if(info->flags.use_temp_files)
|
||||
{
|
||||
if(DBG_EXTPROG)
|
||||
log_debug("system() command is %s\n",info->command);
|
||||
|
||||
#if defined (_WIN32)
|
||||
info->progreturn=win_system(info->command);
|
||||
info->progreturn=w32_system(info->command);
|
||||
#else
|
||||
info->progreturn=system(info->command);
|
||||
#endif
|
||||
@ -537,14 +535,21 @@ int exec_read(struct exec_info *info)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(!info->writeonly)
|
||||
if(!info->flags.writeonly)
|
||||
{
|
||||
info->fromchild=iobuf_open(info->tempfile_out);
|
||||
if (info->fromchild
|
||||
&& is_secured_file (iobuf_get_fd (info->fromchild)))
|
||||
{
|
||||
iobuf_close (info->fromchild);
|
||||
info->fromchild = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if(info->fromchild==NULL)
|
||||
{
|
||||
ret = gpg_error_from_errno (errno);
|
||||
log_error(_("unable to read external program response: %s\n"),
|
||||
strerror(errno));
|
||||
ret=G10ERR_READ_FILE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -583,7 +588,7 @@ int exec_finish(struct exec_info *info)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(info->madedir && !info->keep_temp_files)
|
||||
if(info->flags.madedir && !info->flags.keep_temp_files)
|
||||
{
|
||||
if(info->tempfile_in)
|
||||
{
|
||||
@ -604,12 +609,12 @@ int exec_finish(struct exec_info *info)
|
||||
info->tempdir,strerror(errno));
|
||||
}
|
||||
|
||||
xfree (info->command);
|
||||
xfree (info->name);
|
||||
xfree (info->tempdir);
|
||||
xfree (info->tempfile_in);
|
||||
xfree (info->tempfile_out);
|
||||
xfree (info);
|
||||
xfree(info->command);
|
||||
xfree(info->name);
|
||||
xfree(info->tempdir);
|
||||
xfree(info->tempfile_in);
|
||||
xfree(info->tempfile_out);
|
||||
xfree(info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
18
g10/exec.h
18
g10/exec.h
@ -1,5 +1,5 @@
|
||||
/* exec.h
|
||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef _EXEC_H_
|
||||
@ -23,11 +24,20 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../common/iobuf.h"
|
||||
|
||||
struct exec_info
|
||||
{
|
||||
int progreturn,binary,writeonly,madedir,use_temp_files,keep_temp_files;
|
||||
int progreturn;
|
||||
struct
|
||||
{
|
||||
unsigned int binary:1;
|
||||
unsigned int writeonly:1;
|
||||
unsigned int madedir:1;
|
||||
unsigned int use_temp_files:1;
|
||||
unsigned int keep_temp_files:1;
|
||||
} flags;
|
||||
pid_t child;
|
||||
FILE *tochild;
|
||||
iobuf_t fromchild;
|
||||
@ -38,6 +48,6 @@ int exec_write(struct exec_info **info,const char *program,
|
||||
const char *args_in,const char *name,int writeonly,int binary);
|
||||
int exec_read(struct exec_info *info);
|
||||
int exec_finish(struct exec_info *info);
|
||||
int set_exec_path(const char *path,int method);
|
||||
int set_exec_path(const char *path);
|
||||
|
||||
#endif /* !_EXEC_H_ */
|
||||
|
513
g10/export.c
513
g10/export.c
@ -1,6 +1,6 @@
|
||||
/* export.c
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -26,38 +27,68 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
#include "trustdb.h"
|
||||
|
||||
|
||||
/* An object to keep track of subkeys. */
|
||||
struct subkey_list_s
|
||||
{
|
||||
struct subkey_list_s *next;
|
||||
u32 kid[2];
|
||||
};
|
||||
typedef struct subkey_list_s *subkey_list_t;
|
||||
|
||||
|
||||
static int do_export( STRLIST users, int secret, unsigned int options );
|
||||
static int do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
static int do_export_stream( IOBUF out, STRLIST users, int secret,
|
||||
KBNODE *keyblock_out, unsigned int options,
|
||||
int *any );
|
||||
static int build_sexp (iobuf_t out, PACKET *pkt, int *indent);
|
||||
|
||||
|
||||
int
|
||||
parse_export_options(char *str,unsigned int *options)
|
||||
parse_export_options(char *str,unsigned int *options,int noisy)
|
||||
{
|
||||
struct parse_options export_opts[]=
|
||||
{
|
||||
{"include-non-rfc",EXPORT_INCLUDE_NON_RFC},
|
||||
{"include-local-sigs",EXPORT_INCLUDE_LOCAL_SIGS},
|
||||
{"include-attributes",EXPORT_INCLUDE_ATTRIBUTES},
|
||||
{"include-sensitive-revkeys",EXPORT_INCLUDE_SENSITIVE_REVKEYS},
|
||||
{"sexp-format",EXPORT_SEXP_FORMAT},
|
||||
{NULL,0}
|
||||
{"export-local-sigs",EXPORT_LOCAL_SIGS,NULL,
|
||||
N_("export signatures that are marked as local-only")},
|
||||
{"export-attributes",EXPORT_ATTRIBUTES,NULL,
|
||||
N_("export attribute user IDs (generally photo IDs)")},
|
||||
{"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,
|
||||
N_("export revocation keys marked as \"sensitive\"")},
|
||||
{"export-reset-subkey-passwd",EXPORT_RESET_SUBKEY_PASSWD,NULL,
|
||||
N_("remove the passphrase from exported subkeys")},
|
||||
{"export-clean",EXPORT_CLEAN,NULL,
|
||||
N_("remove unusable parts from key during export")},
|
||||
{"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
|
||||
N_("remove as much as possible from key during export")},
|
||||
{"export-sexp-format",EXPORT_SEXP_FORMAT, NULL,
|
||||
N_("export keys in an S-expression based format")},
|
||||
/* Aliases for backward compatibility */
|
||||
{"include-local-sigs",EXPORT_LOCAL_SIGS,NULL,NULL},
|
||||
{"include-attributes",EXPORT_ATTRIBUTES,NULL,NULL},
|
||||
{"include-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL,NULL},
|
||||
/* dummy */
|
||||
{"export-unusable-sigs",0,NULL,NULL},
|
||||
{"export-clean-sigs",0,NULL,NULL},
|
||||
{"export-clean-uids",0,NULL,NULL},
|
||||
{NULL,0,NULL,NULL}
|
||||
/* add tags for include revoked and disabled? */
|
||||
};
|
||||
|
||||
return parse_options(str,options,export_opts);
|
||||
return parse_options(str,options,export_opts,noisy);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Export the public keys (to standard out or --output).
|
||||
* Depending on opt.armor the output is armored.
|
||||
@ -74,7 +105,7 @@ export_pubkeys( STRLIST users, unsigned int options )
|
||||
* been exported
|
||||
*/
|
||||
int
|
||||
export_pubkeys_stream( iobuf_t out, STRLIST users,
|
||||
export_pubkeys_stream( IOBUF out, STRLIST users,
|
||||
KBNODE *keyblock_out, unsigned int options )
|
||||
{
|
||||
int any, rc;
|
||||
@ -90,7 +121,7 @@ export_seckeys( STRLIST users )
|
||||
{
|
||||
/* Use only relevant options for the secret key. */
|
||||
unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
|
||||
return do_export (users, 1, options);
|
||||
return do_export( users, 1, options );
|
||||
}
|
||||
|
||||
int
|
||||
@ -98,37 +129,38 @@ export_secsubkeys( STRLIST users )
|
||||
{
|
||||
/* Use only relevant options for the secret key. */
|
||||
unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
|
||||
return do_export( users, 2, options);
|
||||
return do_export( users, 2, options );
|
||||
}
|
||||
|
||||
static int
|
||||
do_export (STRLIST users, int secret, unsigned int options)
|
||||
do_export( STRLIST users, int secret, unsigned int options )
|
||||
{
|
||||
iobuf_t out = NULL;
|
||||
IOBUF out = NULL;
|
||||
int any, rc;
|
||||
armor_filter_context_t afx;
|
||||
compress_filter_context_t zfx;
|
||||
|
||||
memset (&afx, 0, sizeof afx);
|
||||
memset (&zfx, 0, sizeof zfx);
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
|
||||
rc = open_outfile (NULL, 0, &out);
|
||||
rc = open_outfile( NULL, 0, &out );
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!(options & EXPORT_SEXP_FORMAT))
|
||||
{
|
||||
if (opt.armor)
|
||||
if ( opt.armor )
|
||||
{
|
||||
afx.what = secret?5:1;
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
iobuf_push_filter ( out, armor_filter, &afx );
|
||||
}
|
||||
if (opt.compress_keys && opt.compress)
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
if ( opt.compress_keys )
|
||||
push_compress_filter (out,&zfx,default_compress_algo());
|
||||
}
|
||||
rc = do_export_stream (out, users, secret, NULL, options, &any );
|
||||
|
||||
if (rc || !any)
|
||||
rc = do_export_stream ( out, users, secret, NULL, options, &any );
|
||||
|
||||
if ( rc || !any )
|
||||
iobuf_cancel (out);
|
||||
else
|
||||
iobuf_close (out);
|
||||
@ -136,11 +168,129 @@ do_export (STRLIST users, int secret, unsigned int options)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Release an entire subkey list. */
|
||||
static void
|
||||
release_subkey_list (subkey_list_t list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
subkey_list_t tmp = list->next;;
|
||||
xfree (list);
|
||||
list = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns true if NODE is a subkey and contained in LIST. */
|
||||
static int
|
||||
subkey_in_list_p (subkey_list_t list, KBNODE node)
|
||||
{
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
|| node->pkt->pkttype == PKT_SECRET_SUBKEY )
|
||||
{
|
||||
u32 kid[2];
|
||||
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
keyid_from_pk (node->pkt->pkt.public_key, kid);
|
||||
else
|
||||
keyid_from_sk (node->pkt->pkt.secret_key, kid);
|
||||
|
||||
for (; list; list = list->next)
|
||||
if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate a new subkey list item from NODE. */
|
||||
static subkey_list_t
|
||||
new_subkey_list_item (KBNODE node)
|
||||
{
|
||||
subkey_list_t list = xcalloc (1, sizeof *list);
|
||||
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
keyid_from_pk (node->pkt->pkt.public_key, list->kid);
|
||||
else if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
keyid_from_sk (node->pkt->pkt.secret_key, list->kid);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/* Helper function to check whether the subkey at NODE actually
|
||||
matches the description at DESC. The function returns true if the
|
||||
key under question has been specified by an exact specification
|
||||
(keyID or fingerprint) and does match the one at NODE. It is
|
||||
assumed that the packet at NODE is either a public or secret
|
||||
subkey. */
|
||||
static int
|
||||
exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
|
||||
{
|
||||
u32 kid[2];
|
||||
byte fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
int result = 0;
|
||||
|
||||
switch(desc->mode)
|
||||
{
|
||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
keyid_from_pk (node->pkt->pkt.public_key, kid);
|
||||
else
|
||||
keyid_from_sk (node->pkt->pkt.secret_key, kid);
|
||||
break;
|
||||
|
||||
case KEYDB_SEARCH_MODE_FPR16:
|
||||
case KEYDB_SEARCH_MODE_FPR20:
|
||||
case KEYDB_SEARCH_MODE_FPR:
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
|
||||
else
|
||||
fingerprint_from_sk (node->pkt->pkt.secret_key, fpr,&fprlen);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(desc->mode)
|
||||
{
|
||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||
if (desc->u.kid[1] == kid[1])
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||
if (desc->u.kid[0] == kid[0] && desc->u.kid[1] == kid[1])
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case KEYDB_SEARCH_MODE_FPR16:
|
||||
if (!memcmp (desc->u.fpr, fpr, 16))
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case KEYDB_SEARCH_MODE_FPR20:
|
||||
case KEYDB_SEARCH_MODE_FPR:
|
||||
if (!memcmp (desc->u.fpr, fpr, 20))
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* If keyblock_out is non-NULL, AND the exit code is zero, then it
|
||||
contains a pointer to the first keyblock found and exported. No
|
||||
other keyblocks are exported. The caller must free it. */
|
||||
static int
|
||||
do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
do_export_stream( IOBUF out, STRLIST users, int secret,
|
||||
KBNODE *keyblock_out, unsigned int options, int *any )
|
||||
{
|
||||
int rc = 0;
|
||||
@ -149,6 +299,7 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
KBNODE kbctx, node;
|
||||
size_t ndesc, descindex;
|
||||
KEYDB_SEARCH_DESC *desc = NULL;
|
||||
subkey_list_t subkey_list = NULL; /* Track alreay processed subkeys. */
|
||||
KEYDB_HANDLE kdbhd;
|
||||
STRLIST sl;
|
||||
int indent = 0;
|
||||
@ -159,7 +310,7 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
|
||||
if (!users) {
|
||||
ndesc = 1;
|
||||
desc = xcalloc (1, ndesc * sizeof *desc);
|
||||
desc = xcalloc ( ndesc, sizeof *desc );
|
||||
desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
|
||||
}
|
||||
else {
|
||||
@ -171,11 +322,11 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
if (classify_user_id (sl->d, desc+ndesc))
|
||||
ndesc++;
|
||||
else
|
||||
log_error (_("key `%s' not found: %s\n"),
|
||||
sl->d, gpg_strerror (GPG_ERR_INV_USER_ID));
|
||||
log_error (_("key \"%s\" not found: %s\n"),
|
||||
sl->d, g10_errstr (G10ERR_INV_USER_ID));
|
||||
}
|
||||
|
||||
/* it would be nice to see which of the given users did
|
||||
/* It would be nice to see which of the given users did
|
||||
actually match one in the keyring. To implement this we
|
||||
need to have a found flag for each entry in desc and to set
|
||||
this we must check all those entries after a match to mark
|
||||
@ -183,6 +334,14 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
do this we need an extra flag to enable this feature so */
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SELINUX_HACKS
|
||||
if (secret) {
|
||||
log_error (_("exporting secret keys not allowed\n"));
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) {
|
||||
int sha1_warned=0,skip_until_subkey=0;
|
||||
u32 sk_keyid[2];
|
||||
@ -190,49 +349,59 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
if (!users)
|
||||
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
|
||||
|
||||
/* read the keyblock */
|
||||
/* Read the keyblock. */
|
||||
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||
if( rc ) {
|
||||
log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
|
||||
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* do not export keys which are incompatible with rfc2440 */
|
||||
if( !(options&EXPORT_INCLUDE_NON_RFC) &&
|
||||
(node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
|
||||
PKT_public_key *pk = node->pkt->pkt.public_key;
|
||||
if( pk->version == 3 && pk->pubkey_algo > 3 ) {
|
||||
log_info(_("key %08lX: not a rfc2440 key - skipped\n"),
|
||||
(ulong)keyid_from_pk( pk, NULL) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
node=find_kbnode( keyblock, PKT_SECRET_KEY );
|
||||
if(node)
|
||||
if((node=find_kbnode(keyblock,PKT_SECRET_KEY)))
|
||||
{
|
||||
PKT_secret_key *sk=node->pkt->pkt.secret_key;
|
||||
|
||||
keyid_from_sk(sk,sk_keyid);
|
||||
|
||||
/* we can't apply GNU mode 1001 on an unprotected key */
|
||||
/* We can't apply GNU mode 1001 on an unprotected key. */
|
||||
if( secret == 2 && !sk->is_protected )
|
||||
{
|
||||
log_info(_("key %08lX: not protected - skipped\n"),
|
||||
(ulong)sk_keyid[1]);
|
||||
log_info(_("key %s: not protected - skipped\n"),
|
||||
keystr(sk_keyid));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* no v3 keys with GNU mode 1001 */
|
||||
/* No v3 keys with GNU mode 1001. */
|
||||
if( secret == 2 && sk->version == 3 )
|
||||
{
|
||||
log_info(_("key %08lX: PGP 2.x style key - skipped\n"),
|
||||
(ulong)sk_keyid[1]);
|
||||
log_info(_("key %s: PGP 2.x style key - skipped\n"),
|
||||
keystr(sk_keyid));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* It does not make sense to export a key with a primary
|
||||
key on card using a non-key stub. We simply skip those
|
||||
keys when used with --export-secret-subkeys. */
|
||||
if (secret == 2 && sk->is_protected
|
||||
&& sk->protect.s2k.mode == 1002 )
|
||||
{
|
||||
log_info(_("key %s: key material on-card - skipped\n"),
|
||||
keystr(sk_keyid));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's a public key export, so do the cleaning if
|
||||
requested. Note that both export-clean and
|
||||
export-minimal only apply to UID sigs (0x10, 0x11,
|
||||
0x12, and 0x13). A designated revocation is never
|
||||
stripped, even with export-minimal set. */
|
||||
|
||||
if(options&EXPORT_CLEAN)
|
||||
clean_key(keyblock,opt.verbose,options&EXPORT_MINIMAL,NULL,NULL);
|
||||
}
|
||||
|
||||
/* and write it */
|
||||
/* And write it. */
|
||||
for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
|
||||
if( skip_until_subkey )
|
||||
{
|
||||
@ -243,104 +412,92 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* don't export any comment packets but those in the
|
||||
* secret keyring */
|
||||
if( !secret && node->pkt->pkttype == PKT_COMMENT )
|
||||
continue;
|
||||
/* We used to use comment packets, but not any longer. In
|
||||
case we still have comments on a key, strip them here
|
||||
before we call build_packet(). */
|
||||
if( node->pkt->pkttype == PKT_COMMENT )
|
||||
continue;
|
||||
|
||||
/* make sure that ring_trust packets never get exported */
|
||||
/* Make sure that ring_trust packets never get exported. */
|
||||
if (node->pkt->pkttype == PKT_RING_TRUST)
|
||||
continue;
|
||||
|
||||
/* If exact is set, then we only export what was requested
|
||||
(plus the primary key, if the user didn't specifically
|
||||
request it) */
|
||||
request it). */
|
||||
if(desc[descindex].exact
|
||||
&& (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
|
||||
|| node->pkt->pkttype==PKT_SECRET_SUBKEY))
|
||||
{
|
||||
u32 kid[2];
|
||||
byte fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
if (!exact_subkey_match_p (desc+descindex, node))
|
||||
{
|
||||
/* Before skipping this subkey, check whether any
|
||||
other description wants an exact match on a
|
||||
subkey and include that subkey into the output
|
||||
too. Need to add this subkey to a list so that
|
||||
it won't get processed a second time.
|
||||
|
||||
So the first step here is to check that list and
|
||||
skip in any case if the key is in that list.
|
||||
|
||||
switch(desc[descindex].mode)
|
||||
{
|
||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||
if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
|
||||
keyid_from_pk(node->pkt->pkt.public_key,kid);
|
||||
else
|
||||
keyid_from_sk(node->pkt->pkt.secret_key,kid);
|
||||
break;
|
||||
We need this whole mess because the import
|
||||
function is not able to merge secret keys and
|
||||
thus it is useless to output them as two
|
||||
separate keys and have import merge them. */
|
||||
if (subkey_in_list_p (subkey_list, node))
|
||||
skip_until_subkey = 1; /* Already processed this one. */
|
||||
else
|
||||
{
|
||||
size_t j;
|
||||
|
||||
case KEYDB_SEARCH_MODE_FPR16:
|
||||
case KEYDB_SEARCH_MODE_FPR20:
|
||||
case KEYDB_SEARCH_MODE_FPR:
|
||||
if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
|
||||
fingerprint_from_pk(node->pkt->pkt.public_key,
|
||||
fpr,&fprlen);
|
||||
else
|
||||
fingerprint_from_sk(node->pkt->pkt.secret_key,
|
||||
fpr,&fprlen);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(desc[descindex].mode)
|
||||
{
|
||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||
if (desc[descindex].u.kid[1] != kid[1])
|
||||
skip_until_subkey=1;
|
||||
break;
|
||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||
if (desc[descindex].u.kid[0] != kid[0]
|
||||
|| desc[descindex].u.kid[1] != kid[1])
|
||||
skip_until_subkey=1;
|
||||
break;
|
||||
case KEYDB_SEARCH_MODE_FPR16:
|
||||
if (memcmp (desc[descindex].u.fpr, fpr, 16))
|
||||
skip_until_subkey=1;
|
||||
break;
|
||||
case KEYDB_SEARCH_MODE_FPR20:
|
||||
case KEYDB_SEARCH_MODE_FPR:
|
||||
if (memcmp (desc[descindex].u.fpr, fpr, 20))
|
||||
skip_until_subkey=1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (j=0; j < ndesc; j++)
|
||||
if (j != descindex && desc[j].exact
|
||||
&& exact_subkey_match_p (desc+j, node))
|
||||
break;
|
||||
if (!(j < ndesc))
|
||||
skip_until_subkey = 1; /* No other one matching. */
|
||||
}
|
||||
}
|
||||
|
||||
if(skip_until_subkey)
|
||||
continue;
|
||||
|
||||
/* Mark this one as processed. */
|
||||
{
|
||||
subkey_list_t tmp = new_subkey_list_item (node);
|
||||
tmp->next = subkey_list;
|
||||
subkey_list = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if( node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
/* do not export packets which are marked as not exportable */
|
||||
if( !(options&EXPORT_INCLUDE_LOCAL_SIGS) &&
|
||||
!node->pkt->pkt.signature->flags.exportable )
|
||||
continue; /* not exportable */
|
||||
if(node->pkt->pkttype==PKT_SIGNATURE)
|
||||
{
|
||||
/* do not export packets which are marked as not
|
||||
exportable */
|
||||
if(!(options&EXPORT_LOCAL_SIGS)
|
||||
&& !node->pkt->pkt.signature->flags.exportable)
|
||||
continue; /* not exportable */
|
||||
|
||||
/* Do not export packets with a "sensitive" revocation
|
||||
key unless the user wants us to. Note that we do
|
||||
export these when issuing the actual revocation (see
|
||||
revoke.c). */
|
||||
if( !(options&EXPORT_INCLUDE_SENSITIVE_REVKEYS) &&
|
||||
node->pkt->pkt.signature->revkey ) {
|
||||
int i;
|
||||
/* Do not export packets with a "sensitive" revocation
|
||||
key unless the user wants us to. Note that we do
|
||||
export these when issuing the actual revocation
|
||||
(see revoke.c). */
|
||||
if(!(options&EXPORT_SENSITIVE_REVKEYS)
|
||||
&& node->pkt->pkt.signature->revkey)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
|
||||
if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
|
||||
break;
|
||||
for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
|
||||
if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
|
||||
break;
|
||||
|
||||
if(i<node->pkt->pkt.signature->numrevkeys)
|
||||
continue;
|
||||
if(i<node->pkt->pkt.signature->numrevkeys)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't export attribs? */
|
||||
if( !(options&EXPORT_INCLUDE_ATTRIBUTES) &&
|
||||
if( !(options&EXPORT_ATTRIBUTES) &&
|
||||
node->pkt->pkttype == PKT_USER_ID &&
|
||||
node->pkt->pkt.user_id->attrib_data ) {
|
||||
/* Skip until we get to something that is not an attrib
|
||||
@ -352,8 +509,9 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
continue;
|
||||
}
|
||||
|
||||
if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) {
|
||||
/* we don't want to export the secret parts of the
|
||||
if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY )
|
||||
{
|
||||
/* We don't want to export the secret parts of the
|
||||
* primary key, this is done by using GNU protection mode 1001
|
||||
*/
|
||||
int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
|
||||
@ -363,42 +521,91 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
else
|
||||
rc = build_packet (out, node->pkt);
|
||||
node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
|
||||
}
|
||||
else {
|
||||
/* Warn the user if the secret key or any of the secret
|
||||
subkeys are protected with SHA1 and we have
|
||||
simple_sk_checksum set. */
|
||||
if(!sha1_warned && opt.simple_sk_checksum &&
|
||||
(node->pkt->pkttype==PKT_SECRET_KEY ||
|
||||
node->pkt->pkttype==PKT_SECRET_SUBKEY) &&
|
||||
node->pkt->pkt.secret_key->protect.sha1chk)
|
||||
{
|
||||
/* I hope this warning doesn't confuse people. */
|
||||
log_info(_("WARNING: secret key %08lX does not have a "
|
||||
"simple SK checksum\n"),(ulong)sk_keyid[1]);
|
||||
}
|
||||
else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY
|
||||
&& (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD))
|
||||
{
|
||||
/* If the subkey is protected reset the passphrase to
|
||||
export an unprotected subkey. This feature is
|
||||
useful in cases of a subkey copied to an unattended
|
||||
machine where a passphrase is not required. */
|
||||
PKT_secret_key *sk_save, *sk;
|
||||
|
||||
sha1_warned=1;
|
||||
}
|
||||
sk_save = node->pkt->pkt.secret_key;
|
||||
sk = copy_secret_key (NULL, sk_save);
|
||||
node->pkt->pkt.secret_key = sk;
|
||||
|
||||
log_info (_("about to export an unprotected subkey\n"));
|
||||
switch (is_secret_key_protected (sk))
|
||||
{
|
||||
case -1:
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
if (sk->protect.s2k.mode == 1001)
|
||||
; /* No secret parts. */
|
||||
else if( sk->protect.s2k.mode == 1002 )
|
||||
; /* Card key stub. */
|
||||
else
|
||||
{
|
||||
rc = check_secret_key( sk, 0 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
node->pkt->pkt.secret_key = sk_save;
|
||||
free_secret_key (sk);
|
||||
log_error (_("failed to unprotect the subkey: %s\n"),
|
||||
g10_errstr (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = build_packet (out, node->pkt);
|
||||
|
||||
node->pkt->pkt.secret_key = sk_save;
|
||||
free_secret_key (sk);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Warn the user if the secret key or any of the secret
|
||||
subkeys are protected with SHA1 and we have
|
||||
simple_sk_checksum set. */
|
||||
if(!sha1_warned && opt.simple_sk_checksum &&
|
||||
(node->pkt->pkttype==PKT_SECRET_KEY ||
|
||||
node->pkt->pkttype==PKT_SECRET_SUBKEY) &&
|
||||
node->pkt->pkt.secret_key->protect.sha1chk)
|
||||
{
|
||||
/* I hope this warning doesn't confuse people. */
|
||||
log_info(_("WARNING: secret key %s does not have a "
|
||||
"simple SK checksum\n"),keystr(sk_keyid));
|
||||
|
||||
sha1_warned=1;
|
||||
}
|
||||
|
||||
if ((options&EXPORT_SEXP_FORMAT))
|
||||
rc = build_sexp (out, node->pkt, &indent);
|
||||
else
|
||||
rc = build_packet (out, node->pkt);
|
||||
}
|
||||
}
|
||||
|
||||
if( rc ) {
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, gpg_strerror (rc) );
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if ((options&EXPORT_SEXP_FORMAT) && indent)
|
||||
{
|
||||
for (; indent; indent--)
|
||||
iobuf_put (out, ')');
|
||||
iobuf_put (out, '\n');
|
||||
}
|
||||
|
||||
|
||||
++*any;
|
||||
if(keyblock_out)
|
||||
{
|
||||
@ -416,7 +623,8 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
rc = 0;
|
||||
|
||||
leave:
|
||||
xfree (desc);
|
||||
release_subkey_list (subkey_list);
|
||||
xfree(desc);
|
||||
keydb_release (kdbhd);
|
||||
if(rc || keyblock_out==NULL)
|
||||
release_kbnode( keyblock );
|
||||
@ -426,6 +634,7 @@ do_export_stream( iobuf_t out, STRLIST users, int secret,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
write_sexp_line (iobuf_t out, int *indent, const char *text)
|
||||
{
|
||||
@ -524,8 +733,8 @@ build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
|
||||
}
|
||||
|
||||
|
||||
/* For some packet types we write them in a S-Exp like format. This is
|
||||
still EXPERIMENTAL and subject to change. */
|
||||
/* For some packet types we write them in a S-expression format. This
|
||||
is still EXPERIMENTAL and subject to change. */
|
||||
static int
|
||||
build_sexp (iobuf_t out, PACKET *pkt, int *indent)
|
||||
{
|
||||
|
44
g10/filter.h
44
g10/filter.h
@ -1,5 +1,6 @@
|
||||
/* filter.h
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,18 +16,18 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef G10_FILTER_H
|
||||
#define G10_FILTER_H
|
||||
|
||||
#include "types.h"
|
||||
#include "cipher.h"
|
||||
#include "iobuf.h"
|
||||
|
||||
typedef struct {
|
||||
MD_HANDLE md; /* catch all */
|
||||
MD_HANDLE md2; /* if we want to calculate an alternate hash */
|
||||
gcry_md_hd_t md; /* catch all */
|
||||
gcry_md_hd_t md2; /* if we want to calculate an alternate hash */
|
||||
size_t maxbuf_size;
|
||||
} md_filter_context_t;
|
||||
|
||||
@ -49,6 +50,10 @@ typedef struct {
|
||||
int truncated; /* number of truncated lines */
|
||||
int qp_detected;
|
||||
int pgp2mode;
|
||||
byte eol[3]; /* The end of line characters as a
|
||||
zero-terminated string. Defaults
|
||||
(eol[0]=='\0') to whatever the local
|
||||
platform uses. */
|
||||
|
||||
byte *buffer; /* malloced buffer */
|
||||
unsigned buffer_size; /* and size of this buffer */
|
||||
@ -87,9 +92,9 @@ typedef struct compress_filter_context_s compress_filter_context_t;
|
||||
typedef struct {
|
||||
DEK *dek;
|
||||
u32 datalen;
|
||||
CIPHER_HANDLE cipher_hd;
|
||||
gcry_cipher_hd_t cipher_hd;
|
||||
int header;
|
||||
MD_HANDLE mdc_hash;
|
||||
gcry_md_hd_t mdc_hash;
|
||||
byte enchash[20];
|
||||
int create_mdc; /* flag will be set by the cipher filter */
|
||||
} cipher_filter_context_t;
|
||||
@ -104,7 +109,7 @@ typedef struct {
|
||||
int truncated; /* number of truncated lines */
|
||||
int not_dash_escaped;
|
||||
int escape_from;
|
||||
MD_HANDLE md;
|
||||
gcry_md_hd_t md;
|
||||
int pending_lf;
|
||||
int pending_esc;
|
||||
} text_filter_context_t;
|
||||
@ -121,35 +126,36 @@ typedef struct {
|
||||
/* encrypt_filter_context_t defined in main.h */
|
||||
|
||||
/*-- mdfilter.c --*/
|
||||
int md_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len);
|
||||
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
|
||||
void free_md_filter_context( md_filter_context_t *mfx );
|
||||
|
||||
/*-- armor.c --*/
|
||||
int use_armor_filter( iobuf_t a );
|
||||
int use_armor_filter( IOBUF a );
|
||||
int armor_filter( void *opaque, int control,
|
||||
iobuf_t chain, byte *buf, size_t *ret_len);
|
||||
IOBUF chain, byte *buf, size_t *ret_len);
|
||||
UnarmorPump unarmor_pump_new (void);
|
||||
void unarmor_pump_release (UnarmorPump x);
|
||||
int unarmor_pump (UnarmorPump x, int c);
|
||||
|
||||
/*-- compress.c --*/
|
||||
int compress_filter( void *opaque, int control,
|
||||
iobuf_t chain, byte *buf, size_t *ret_len);
|
||||
void push_compress_filter(IOBUF out,compress_filter_context_t *zfx,int algo);
|
||||
void push_compress_filter2(IOBUF out,compress_filter_context_t *zfx,
|
||||
int algo,int rel);
|
||||
|
||||
/*-- cipher.c --*/
|
||||
int cipher_filter( void *opaque, int control,
|
||||
iobuf_t chain, byte *buf, size_t *ret_len);
|
||||
IOBUF chain, byte *buf, size_t *ret_len);
|
||||
|
||||
/*-- textfilter.c --*/
|
||||
int text_filter( void *opaque, int control,
|
||||
iobuf_t chain, byte *buf, size_t *ret_len);
|
||||
int copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md,
|
||||
int escape_dash, int escape_from, int pgp2mode );
|
||||
IOBUF chain, byte *buf, size_t *ret_len);
|
||||
int copy_clearsig_text (IOBUF out, IOBUF inp, gcry_md_hd_t md,
|
||||
int escape_dash, int escape_from, int pgp2mode);
|
||||
|
||||
/*-- progress.c --*/
|
||||
int progress_filter (void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len);
|
||||
IOBUF a, byte *buf, size_t *ret_len);
|
||||
void handle_progress (progress_filter_context_t *pfx,
|
||||
iobuf_t inp, const char *name);
|
||||
IOBUF inp, const char *name);
|
||||
|
||||
#endif /*G10_FILTER_H*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* free-packet.c - cleanup stuff for packets
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
|
||||
* Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -25,18 +26,18 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "mpi.h"
|
||||
#include "../common/iobuf.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "memory.h"
|
||||
#include "options.h"
|
||||
#include "options.h"
|
||||
|
||||
|
||||
void
|
||||
free_symkey_enc( PKT_symkey_enc *enc )
|
||||
{
|
||||
xfree (enc);
|
||||
xfree(enc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -45,10 +46,10 @@ free_pubkey_enc( PKT_pubkey_enc *enc )
|
||||
int n, i;
|
||||
n = pubkey_get_nenc( enc->pubkey_algo );
|
||||
if( !n )
|
||||
mpi_release (enc->data[0]);
|
||||
mpi_release(enc->data[0]);
|
||||
for(i=0; i < n; i++ )
|
||||
mpi_release ( enc->data[i] );
|
||||
xfree (enc);
|
||||
mpi_release( enc->data[i] );
|
||||
xfree(enc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -58,14 +59,21 @@ free_seckey_enc( PKT_signature *sig )
|
||||
|
||||
n = pubkey_get_nsig( sig->pubkey_algo );
|
||||
if( !n )
|
||||
mpi_release (sig->data[0]);
|
||||
mpi_release(sig->data[0]);
|
||||
for(i=0; i < n; i++ )
|
||||
mpi_release ( sig->data[i] );
|
||||
|
||||
xfree (sig->revkey);
|
||||
xfree (sig->hashed);
|
||||
xfree (sig->unhashed);
|
||||
xfree (sig);
|
||||
mpi_release( sig->data[i] );
|
||||
|
||||
xfree(sig->revkey);
|
||||
xfree(sig->hashed);
|
||||
xfree(sig->unhashed);
|
||||
|
||||
if (sig->pka_info)
|
||||
{
|
||||
xfree (sig->pka_info->uri);
|
||||
xfree (sig->pka_info);
|
||||
}
|
||||
|
||||
xfree(sig);
|
||||
}
|
||||
|
||||
|
||||
@ -75,9 +83,9 @@ release_public_key_parts( PKT_public_key *pk )
|
||||
int n, i;
|
||||
n = pubkey_get_npkey( pk->pubkey_algo );
|
||||
if( !n )
|
||||
mpi_release (pk->pkey[0]);
|
||||
mpi_release(pk->pkey[0]);
|
||||
for(i=0; i < n; i++ ) {
|
||||
mpi_release ( pk->pkey[i] );
|
||||
mpi_release( pk->pkey[i] );
|
||||
pk->pkey[i] = NULL;
|
||||
}
|
||||
if (pk->prefs) {
|
||||
@ -89,7 +97,7 @@ release_public_key_parts( PKT_public_key *pk )
|
||||
pk->user_id = NULL;
|
||||
}
|
||||
if (pk->revkey) {
|
||||
xfree (pk->revkey);
|
||||
xfree(pk->revkey);
|
||||
pk->revkey=NULL;
|
||||
pk->numrevkeys=0;
|
||||
}
|
||||
@ -100,7 +108,7 @@ void
|
||||
free_public_key( PKT_public_key *pk )
|
||||
{
|
||||
release_public_key_parts( pk );
|
||||
xfree (pk);
|
||||
xfree(pk);
|
||||
}
|
||||
|
||||
|
||||
@ -150,7 +158,7 @@ copy_public_key ( PKT_public_key *d, PKT_public_key *s)
|
||||
int n, i;
|
||||
|
||||
if( !d )
|
||||
d = xmalloc (sizeof *d);
|
||||
d = xmalloc(sizeof *d);
|
||||
memcpy( d, s, sizeof *d );
|
||||
d->user_id = scopy_user_id (s->user_id);
|
||||
d->prefs = copy_prefs (s->prefs);
|
||||
@ -164,7 +172,7 @@ copy_public_key ( PKT_public_key *d, PKT_public_key *s)
|
||||
if( !s->revkey && s->numrevkeys )
|
||||
BUG();
|
||||
if( s->numrevkeys ) {
|
||||
d->revkey = xmalloc (sizeof(struct revocation_key)*s->numrevkeys);
|
||||
d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
|
||||
memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
|
||||
}
|
||||
else
|
||||
@ -194,13 +202,28 @@ copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
|
||||
sk->keyid[1] = pk->keyid[1];
|
||||
}
|
||||
|
||||
|
||||
static pka_info_t *
|
||||
cp_pka_info (const pka_info_t *s)
|
||||
{
|
||||
pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
|
||||
|
||||
d->valid = s->valid;
|
||||
d->checked = s->checked;
|
||||
d->uri = s->uri? xstrdup (s->uri):NULL;
|
||||
memcpy (d->fpr, s->fpr, sizeof s->fpr);
|
||||
strcpy (d->email, s->email);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
PKT_signature *
|
||||
copy_signature( PKT_signature *d, PKT_signature *s )
|
||||
{
|
||||
int n, i;
|
||||
|
||||
if( !d )
|
||||
d = xmalloc (sizeof *d);
|
||||
d = xmalloc(sizeof *d);
|
||||
memcpy( d, s, sizeof *d );
|
||||
n = pubkey_get_nsig( s->pubkey_algo );
|
||||
if( !n )
|
||||
@ -209,6 +232,7 @@ copy_signature( PKT_signature *d, PKT_signature *s )
|
||||
for(i=0; i < n; i++ )
|
||||
d->data[i] = mpi_copy( s->data[i] );
|
||||
}
|
||||
d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
|
||||
d->hashed = cp_subpktarea (s->hashed);
|
||||
d->unhashed = cp_subpktarea (s->unhashed);
|
||||
if(s->numrevkeys)
|
||||
@ -241,9 +265,9 @@ release_secret_key_parts( PKT_secret_key *sk )
|
||||
|
||||
n = pubkey_get_nskey( sk->pubkey_algo );
|
||||
if( !n )
|
||||
mpi_release (sk->skey[0]);
|
||||
mpi_release(sk->skey[0]);
|
||||
for(i=0; i < n; i++ ) {
|
||||
mpi_release ( sk->skey[i] );
|
||||
mpi_release( sk->skey[i] );
|
||||
sk->skey[i] = NULL;
|
||||
}
|
||||
}
|
||||
@ -252,7 +276,7 @@ void
|
||||
free_secret_key( PKT_secret_key *sk )
|
||||
{
|
||||
release_secret_key_parts( sk );
|
||||
xfree (sk);
|
||||
xfree(sk);
|
||||
}
|
||||
|
||||
PKT_secret_key *
|
||||
@ -261,29 +285,32 @@ copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
|
||||
int n, i;
|
||||
|
||||
if( !d )
|
||||
d = xmalloc (sizeof *d);
|
||||
d = xmalloc_secure(sizeof *d);
|
||||
else
|
||||
release_secret_key_parts (d);
|
||||
memcpy( d, s, sizeof *d );
|
||||
n = pubkey_get_nskey( s->pubkey_algo );
|
||||
if( !n )
|
||||
d->skey[0] = mpi_copy(s->skey[0]);
|
||||
d->skey[0] = mpi_copy(s->skey[0]);
|
||||
else {
|
||||
for(i=0; i < n; i++ )
|
||||
d->skey[i] = mpi_copy( s->skey[i] );
|
||||
d->skey[i] = mpi_copy( s->skey[i] );
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
free_comment( PKT_comment *rem )
|
||||
{
|
||||
xfree (rem);
|
||||
xfree(rem);
|
||||
}
|
||||
|
||||
void
|
||||
free_attributes(PKT_user_id *uid)
|
||||
{
|
||||
xfree (uid->attribs);
|
||||
xfree (uid->attrib_data);
|
||||
xfree(uid->attribs);
|
||||
xfree(uid->attrib_data);
|
||||
|
||||
uid->attribs=NULL;
|
||||
uid->attrib_data=NULL;
|
||||
@ -312,14 +339,14 @@ free_compressed( PKT_compressed *zd )
|
||||
while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
|
||||
;
|
||||
}
|
||||
xfree (zd);
|
||||
xfree(zd);
|
||||
}
|
||||
|
||||
void
|
||||
free_encrypted( PKT_encrypted *ed )
|
||||
{
|
||||
if( ed->buf ) { /* have to skip some bytes */
|
||||
if( iobuf_in_block_mode(ed->buf) ) {
|
||||
if( ed->is_partial ) {
|
||||
while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
|
||||
;
|
||||
}
|
||||
@ -333,7 +360,7 @@ free_encrypted( PKT_encrypted *ed )
|
||||
}
|
||||
}
|
||||
}
|
||||
xfree (ed);
|
||||
xfree(ed);
|
||||
}
|
||||
|
||||
|
||||
@ -341,7 +368,7 @@ void
|
||||
free_plaintext( PKT_plaintext *pt )
|
||||
{
|
||||
if( pt->buf ) { /* have to skip some bytes */
|
||||
if( iobuf_in_block_mode(pt->buf) ) {
|
||||
if( pt->is_partial ) {
|
||||
while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
|
||||
;
|
||||
}
|
||||
@ -355,7 +382,7 @@ free_plaintext( PKT_plaintext *pt )
|
||||
}
|
||||
}
|
||||
}
|
||||
xfree (pt);
|
||||
xfree(pt);
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -405,7 +432,7 @@ free_packet( PACKET *pkt )
|
||||
free_plaintext( pkt->pkt.plaintext );
|
||||
break;
|
||||
default:
|
||||
xfree ( pkt->pkt.generic );
|
||||
xfree( pkt->pkt.generic );
|
||||
break;
|
||||
}
|
||||
pkt->pkt.generic = NULL;
|
||||
|
966
g10/getkey.c
966
g10/getkey.c
File diff suppressed because it is too large
Load Diff
31
g10/global.h
31
g10/global.h
@ -1,31 +0,0 @@
|
||||
/* global.h - Local typedefs and constants
|
||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef GPG_GLOBAL_H
|
||||
#define GPG_GLOBAL_H
|
||||
|
||||
#define MAX_FINGERPRINT_LEN 20
|
||||
|
||||
typedef struct kbnode_struct *KBNODE;
|
||||
typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
|
||||
|
||||
#include "gpg.h"
|
||||
|
||||
#endif /*GPG_GLOBAL_H*/
|
65
g10/gpg.h
65
g10/gpg.h
@ -1,5 +1,5 @@
|
||||
/* gpg.h - top level include file for gpg etc.
|
||||
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2003, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -32,9 +32,70 @@
|
||||
#define map_assuan_err(a) \
|
||||
map_assuan_err_with_source (GPG_ERR_SOURCE_DEFAULT, (a))
|
||||
#include <gpg-error.h>
|
||||
#include <gcrypt.h>
|
||||
|
||||
|
||||
/* FIXME: merge this with global.h */
|
||||
/* Number of bits we accept when reading or writing MPIs. */
|
||||
#define MAX_EXTERN_MPI_BITS 16384
|
||||
|
||||
/* The maximum length of a binary fingerprints. */
|
||||
#define MAX_FINGERPRINT_LEN 20
|
||||
|
||||
|
||||
/* Forward declarations. */
|
||||
typedef struct kbnode_struct *KBNODE;
|
||||
typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
|
||||
|
||||
|
||||
|
||||
/* Simple wrappers. */
|
||||
#define g10_errstr(a) gpg_strerror ((a))
|
||||
|
||||
|
||||
/* Mapping of the old erro codes to the gpg-error ones. Fixme: This
|
||||
is just a temporary solution: We need to do all these gpg_error()
|
||||
calls in the code. */
|
||||
#define G10ERR_BAD_KEY GPG_ERR_BAD_KEY
|
||||
#define G10ERR_BAD_PASS GPG_ERR_BAD_PASS
|
||||
#define G10ERR_BAD_PUBKEY GPG_ERR_BAD_PUBKEY
|
||||
#define G10ERR_BAD_SIGN GPG_ERR_BAD_SIGNATURE
|
||||
#define G10ERR_BAD_URI GPG_ERR_BAD_URI
|
||||
#define G10ERR_CHECKSUM GPG_ERR_CHECKSUM
|
||||
#define G10ERR_CIPHER_ALGO GPG_ERR_CIPHER_ALGO
|
||||
#define G10ERR_CLOSE_FILE GPG_ERR_CLOSE_FILE
|
||||
#define G10ERR_COMPR_ALGO GPG_ERR_COMPR_ALGO
|
||||
#define G10ERR_CREATE_FILE GPG_ERR_CREATE_FILE
|
||||
#define G10ERR_DIGEST_ALGO GPG_ERR_DIGEST_ALGO
|
||||
#define G10ERR_FILE_EXISTS GPG_ERR_EEXIST
|
||||
#define G10ERR_GENERAL GPG_ERR_GENERAL
|
||||
#define G10ERR_INV_ARG GPG_ERR_INV_ARG
|
||||
#define G10ERR_INV_KEYRING GPG_ERR_INV_KEYRING
|
||||
#define G10ERR_INV_USER_ID GPG_ERR_INV_USER_ID
|
||||
#define G10ERR_INVALID_ARMOR GPG_ERR_INV_ARMOR
|
||||
#define G10ERR_INVALID_PACKET GPG_ERR_INV_PACKET
|
||||
#define G10ERR_KEYRING_OPEN GPG_ERR_KEYRING_OPEN
|
||||
#define G10ERR_KEYSERVER GPG_ERR_KEYSERVER
|
||||
#define G10ERR_NO_DATA GPG_ERR_NO_DATA
|
||||
#define G10ERR_NO_PUBKEY GPG_ERR_NO_PUBKEY
|
||||
#define G10ERR_NO_SECKEY GPG_ERR_NO_SECKEY
|
||||
#define G10ERR_NO_USER_ID GPG_ERR_NO_USER_ID
|
||||
#define G10ERR_NOT_PROCESSED GPG_ERR_NOT_PROCESSED
|
||||
#define G10ERR_OPEN_FILE GPG_ERR_OPEN_FILE
|
||||
#define G10ERR_PASSPHRASE GPG_ERR_PASSPHRASE
|
||||
#define G10ERR_PUBKEY_ALGO GPG_ERR_PUBKEY_ALGO
|
||||
#define G10ERR_READ_FILE GPG_ERR_READ_FILE
|
||||
#define G10ERR_RENAME_FILE GPG_ERR_RENAME_FILE
|
||||
#define G10ERR_RESOURCE_LIMIT GPG_ERR_RESOURCE_LIMIT
|
||||
#define G10ERR_SIG_CLASS GPG_ERR_SIG_CLASS
|
||||
#define G10ERR_TIME_CONFLICT GPG_ERR_TIME_CONFLICT
|
||||
#define G10ERR_TRUSTDB GPG_ERR_TRUSTDB
|
||||
#define G10ERR_UNEXPECTED GPG_ERR_UNEXPECTED
|
||||
#define G10ERR_UNKNOWN_PACKET GPG_ERR_UNKNOWN_PACKET
|
||||
#define G10ERR_UNSUPPORTED GPG_ERR_UNSUPPORTED
|
||||
#define G10ERR_UNU_PUBKEY GPG_ERR_UNUSABLE_PUBKEY
|
||||
#define G10ERR_UNU_SECKEY GPG_ERR_UNUSABLE_SECKEY
|
||||
#define G10ERR_WRONG_SECKEY GPG_ERR_WRONG_SECKEY
|
||||
|
||||
|
||||
|
||||
#endif /*GNUPG_G10_GPG_H*/
|
||||
|
143
g10/gpgv.c
143
g10/gpgv.c
@ -1,6 +1,6 @@
|
||||
/* gpgv.c - The GnuPG signature verify utility
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -29,23 +30,27 @@
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#include <fcntl.h> /* for setmode() */
|
||||
#endif
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
#include <stdio.h>
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
|
||||
#define INCLUDED_BY_MAIN_MODULE 1
|
||||
#include "gpg.h"
|
||||
#include "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "keydb.h"
|
||||
#include "trustdb.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
#include "filter.h"
|
||||
#include "ttyio.h"
|
||||
#include "i18n.h"
|
||||
#include "status.h"
|
||||
#include "g10defs.h"
|
||||
#include "cardglue.h"
|
||||
|
||||
|
||||
enum cmd_and_opt_values { aNull = 0,
|
||||
@ -79,10 +84,6 @@ static ARGPARSE_OPTS opts[] = {
|
||||
|
||||
int g10_errors_seen = 0;
|
||||
|
||||
#ifdef __riscos__
|
||||
RISCOS_GLOBAL_STATICS("GnuPG (gpgv) Heap")
|
||||
#endif /* __riscos__ */
|
||||
|
||||
static const char *
|
||||
my_strusage( int level )
|
||||
{
|
||||
@ -110,23 +111,22 @@ my_strusage( int level )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
i18n_init(void)
|
||||
{
|
||||
#ifdef USE_SIMPLE_GETTEXT
|
||||
set_gettext_file( PACKAGE_GT );
|
||||
set_gettext_file (PACKAGE_GT, "Software\\GNU\\GnuPG");
|
||||
#else
|
||||
#ifdef ENABLE_NLS
|
||||
setlocale( LC_ALL, "" );
|
||||
bindtextdomain( PACKAGE_GT, LOCALEDIR );
|
||||
textdomain( PACKAGE_GT );
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE_GT, LOCALEDIR);
|
||||
textdomain (PACKAGE_GT);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
@ -136,17 +136,13 @@ main( int argc, char **argv )
|
||||
STRLIST nrings=NULL;
|
||||
unsigned configlineno;
|
||||
|
||||
#ifdef __riscos__
|
||||
riscos_global_defaults();
|
||||
#endif /* __riscos__ */
|
||||
|
||||
set_strusage (my_strusage);
|
||||
log_set_prefix ("gpgv", 1);
|
||||
gnupg_init_signals(0, NULL);
|
||||
gnupg_init_signals (0, NULL);
|
||||
i18n_init();
|
||||
opt.command_fd = -1; /* no command fd */
|
||||
opt.pgp2_workarounds = 1;
|
||||
opt.keyserver_options.auto_key_retrieve = 1;
|
||||
opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
|
||||
opt.trust_model = TM_ALWAYS;
|
||||
opt.batch = 1;
|
||||
|
||||
@ -164,8 +160,11 @@ main( int argc, char **argv )
|
||||
while( optfile_parse( NULL, NULL, &configlineno, &pargs, opts) ) {
|
||||
switch( pargs.r_opt ) {
|
||||
case oQuiet: opt.quiet = 1; break;
|
||||
case oVerbose: g10_opt_verbose++;
|
||||
opt.verbose++; opt.list_sigs=1; break;
|
||||
case oVerbose:
|
||||
opt.verbose++;
|
||||
opt.list_sigs=1;
|
||||
gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
|
||||
break;
|
||||
case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
|
||||
case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
|
||||
case oLoggerFD:
|
||||
@ -180,9 +179,7 @@ main( int argc, char **argv )
|
||||
if( log_get_errorcount(0) )
|
||||
g10_exit(2);
|
||||
|
||||
g10_opt_homedir = opt.homedir;
|
||||
|
||||
if( opt.verbose > 1 )
|
||||
if( opt.verbose > 1 )
|
||||
set_packet_list_mode(1);
|
||||
|
||||
if( !nrings ) /* no keyring given: use default one */
|
||||
@ -193,7 +190,7 @@ main( int argc, char **argv )
|
||||
FREE_STRLIST(nrings);
|
||||
|
||||
if( (rc = verify_signatures( argc, argv ) ))
|
||||
log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
|
||||
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
||||
|
||||
/* cleanup */
|
||||
g10_exit(0);
|
||||
@ -210,14 +207,6 @@ g10_exit( int rc )
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
read_trust_options (byte *trust_model,ulong *created,ulong *nextcheck,
|
||||
byte *marginals,byte *completes,byte *cert_depth)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* Stub:
|
||||
* We have to override the trustcheck from pkclist.c becuase
|
||||
* this utility assumes that all keys in the keyring are trustworthy
|
||||
@ -228,6 +217,9 @@ check_signatures_trust( PKT_signature *sig )
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
|
||||
byte *marginals,byte *completes,byte *cert_depth) {}
|
||||
|
||||
/* Stub:
|
||||
* We don't have the trustdb , so we have to provide some stub functions
|
||||
@ -240,6 +232,9 @@ cache_disabled_value(PKT_public_key *pk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
check_trustdb_stale(void) {}
|
||||
|
||||
int
|
||||
get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
|
||||
{
|
||||
@ -258,7 +253,12 @@ trust_value_to_string (unsigned int value)
|
||||
return "err";
|
||||
}
|
||||
|
||||
/* Stub: */
|
||||
const char *
|
||||
uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid)
|
||||
{
|
||||
return "err";
|
||||
}
|
||||
|
||||
int
|
||||
get_ownertrust_info (PKT_public_key *pk)
|
||||
{
|
||||
@ -272,35 +272,54 @@ get_ownertrust (PKT_public_key *pk)
|
||||
}
|
||||
|
||||
|
||||
/* Stub:
|
||||
/* Stubs:
|
||||
* Because we only work with trusted keys, it does not make sense to
|
||||
* get them from a keyserver
|
||||
*/
|
||||
|
||||
struct keyserver_spec *
|
||||
keyserver_match(struct keyserver_spec *spec) { return NULL; }
|
||||
|
||||
int
|
||||
keyserver_import_keyid( u32 *keyid, void *dummy )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_import_cert(const char *name) { return -1; }
|
||||
|
||||
int
|
||||
keyserver_import_pka(const char *name,unsigned char *fpr) { return -1; }
|
||||
|
||||
int
|
||||
keyserver_import_name(const char *name,struct keyserver_spec *spec)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
keyserver_import_ldap(const char *name) { return -1; }
|
||||
|
||||
/* Stub:
|
||||
* No encryption here but mainproc links to these functions.
|
||||
*/
|
||||
int
|
||||
get_session_key( PKT_pubkey_enc *k, DEK *dek )
|
||||
{
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
/* Stub: */
|
||||
int
|
||||
get_override_session_key( DEK *dek, const char *string )
|
||||
{
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
/* Stub: */
|
||||
int
|
||||
decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
|
||||
{
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
|
||||
@ -318,7 +337,7 @@ display_online_help( const char *keyword )
|
||||
int
|
||||
check_secret_key( PKT_secret_key *sk, int n )
|
||||
{
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
/* Stub:
|
||||
@ -334,11 +353,25 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig) {return NULL;}
|
||||
struct keyserver_spec *parse_keyserver_uri(const char *uri,int require_scheme,
|
||||
const char *configname,
|
||||
unsigned int configlineno)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_keyserver_spec(struct keyserver_spec *keyserver) {}
|
||||
|
||||
/* Stubs to avoid linking to photoid.c */
|
||||
void show_photos(const struct user_attribute *attrs,int count,PKT_public_key *pk) {}
|
||||
int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len) {return 0;}
|
||||
char *image_type_to_string(byte type,int string) {return NULL;}
|
||||
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
int agent_scd_getattr (const char *name, struct agent_card_info_s *info) {return 0;}
|
||||
#endif /* ENABLE_CARD_SUPPORT */
|
||||
|
||||
/* Stubs to void linking to ../cipher/cipher.c */
|
||||
int string_to_cipher_algo( const char *string ) { return 0; }
|
||||
const char *cipher_algo_to_string( int algo ) { return "?";}
|
||||
@ -356,10 +389,31 @@ void cipher_decrypt( CIPHER_HANDLE c, byte *outbuf,
|
||||
byte *inbuf, unsigned nbytes ) {}
|
||||
void cipher_sync( CIPHER_HANDLE c ) {}
|
||||
|
||||
/* Stubs to avoid linking to ../cipher/random.c */
|
||||
void random_dump_stats(void) {}
|
||||
int quick_random_gen( int onoff ) { return -1;}
|
||||
void randomize_buffer( byte *buffer, size_t length, int level ) {}
|
||||
int random_is_faked() { return -1;}
|
||||
byte *get_random_bits( size_t nbits, int level, int secure ) { return NULL;}
|
||||
void set_random_seed_file( const char *name ) {}
|
||||
void update_random_seed_file() {}
|
||||
void fast_random_poll() {}
|
||||
|
||||
/* Stubs to avoid linking of ../cipher/primegen.c */
|
||||
void register_primegen_progress ( void (*cb)( void *, int), void *cb_data ) {}
|
||||
MPI generate_secret_prime( unsigned nbits ) { return NULL;}
|
||||
MPI generate_public_prime( unsigned nbits ) { return NULL;}
|
||||
MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
|
||||
MPI g, MPI **ret_factors ) { return NULL;}
|
||||
|
||||
/* Do not link to ../cipher/rndlinux.c */
|
||||
void rndlinux_constructor(void) {}
|
||||
|
||||
|
||||
/* Stubs to avoid linking to ../util/ttyio.c */
|
||||
int tty_batchmode( int onoff ) { return 0; }
|
||||
void tty_printf( const char *fmt, ... ) { }
|
||||
void tty_fprintf (FILE *fp, const char *fmt, ... ) { }
|
||||
void tty_print_string( const byte *p, size_t n ) { }
|
||||
void tty_print_utf8_string( const byte *p, size_t n ) {}
|
||||
void tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) {}
|
||||
@ -368,10 +422,15 @@ char *tty_get_hidden( const char *prompt ) {return NULL; }
|
||||
void tty_kill_prompt(void) {}
|
||||
int tty_get_answer_is_yes( const char *prompt ) {return 0;}
|
||||
int tty_no_terminal(int onoff) {return 0;}
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
void tty_enable_completion(rl_completion_func_t *completer) {}
|
||||
void tty_disable_completion(void) {}
|
||||
#endif
|
||||
|
||||
/* We do not do any locking, so use these stubs here */
|
||||
void disable_dotlock(void) {}
|
||||
DOTLOCK create_dotlock( const char *file_to_lock ) { return NULL; }
|
||||
void destroy_dotlock (DOTLOCK h) {}
|
||||
int make_dotlock( DOTLOCK h, long timeout ) { return 0;}
|
||||
int release_dotlock( DOTLOCK h ) {return 0;}
|
||||
void dotlock_remove_lockfiles(void) {}
|
||||
void remove_lockfiles(void) {}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* helptext.c - English help texts
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -58,10 +60,6 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
|
||||
"ultimately trusted\n"
|
||||
)},
|
||||
|
||||
{ "revoked_key.override", N_(
|
||||
"If you want to use this revoked key anyway, answer \"yes\"."
|
||||
)},
|
||||
|
||||
{ "untrusted_key.override", N_(
|
||||
"If you want to use this untrusted key anyway, answer \"yes\"."
|
||||
)},
|
||||
@ -73,29 +71,17 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
|
||||
{ "keygen.algo", N_(
|
||||
"Select the algorithm to use.\n"
|
||||
"\n"
|
||||
"DSA (aka DSS) is the digital signature algorithm which can only be used\n"
|
||||
"for signatures. This is the suggested algorithm because verification of\n"
|
||||
"DSA signatures are much faster than those of ElGamal.\n"
|
||||
"DSA (aka DSS) is the Digital Signature Algorithm and can only be used\n"
|
||||
"for signatures.\n"
|
||||
"\n"
|
||||
"ElGamal is an algorithm which can be used for signatures and encryption.\n"
|
||||
"OpenPGP distinguishs between two flavors of this algorithms: an encrypt only\n"
|
||||
"and a sign+encrypt; actually it is the same, but some parameters must be\n"
|
||||
"selected in a special way to create a safe key for signatures: this program\n"
|
||||
"does this but other OpenPGP implementations are not required to understand\n"
|
||||
"the signature+encryption flavor.\n"
|
||||
"Elgamal is an encrypt-only algorithm.\n"
|
||||
"\n"
|
||||
"The first (primary) key must always be a key which is capable of signing;\n"
|
||||
"this is the reason why the encryption only ElGamal key is not available in\n"
|
||||
"this menu."
|
||||
"RSA may be used for signatures or encryption.\n"
|
||||
"\n"
|
||||
"The first (primary) key must always be a key which is capable of signing."
|
||||
)},
|
||||
|
||||
|
||||
{ "keygen.algo.elg_se", N_(
|
||||
"Although these keys are defined in RFC2440 they are not suggested\n"
|
||||
"because they are not supported by all programs and signatures created\n"
|
||||
"with them are quite large and very slow to verify."
|
||||
)},
|
||||
|
||||
{ "keygen.algo.rsa_se", N_(
|
||||
"In general it is not a good idea to use the same key for signing and\n"
|
||||
"encryption. This algorithm should only be used in certain domains.\n"
|
||||
@ -199,7 +185,7 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
|
||||
)},
|
||||
|
||||
{ "keyedit.sign_all.okay", N_(
|
||||
"Answer \"yes\" is you want to sign ALL the user IDs"
|
||||
"Answer \"yes\" if you want to sign ALL the user IDs"
|
||||
)},
|
||||
|
||||
{ "keyedit.remove.uid.okay", N_(
|
||||
|
1300
g10/import.c
1300
g10/import.c
File diff suppressed because it is too large
Load Diff
19
g10/kbnode.c
19
g10/kbnode.c
@ -1,5 +1,6 @@
|
||||
/* kbnode.c - keyblock node utility functions
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -26,7 +28,6 @@
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "packet.h"
|
||||
#include "keydb.h"
|
||||
|
||||
@ -43,7 +44,7 @@ alloc_node(void)
|
||||
if( n )
|
||||
unused_nodes = n->next;
|
||||
else
|
||||
n = xmalloc ( sizeof *n );
|
||||
n = xmalloc( sizeof *n );
|
||||
n->next = NULL;
|
||||
n->pkt = NULL;
|
||||
n->flag = 0;
|
||||
@ -60,7 +61,7 @@ free_node( KBNODE n )
|
||||
n->next = unused_nodes;
|
||||
unused_nodes = n;
|
||||
#else
|
||||
xfree ( n );
|
||||
xfree( n );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -96,7 +97,7 @@ release_kbnode( KBNODE n )
|
||||
n2 = n->next;
|
||||
if( !is_cloned_kbnode(n) ) {
|
||||
free_packet( n->pkt );
|
||||
xfree ( n->pkt );
|
||||
xfree( n->pkt );
|
||||
}
|
||||
free_node( n );
|
||||
n = n2;
|
||||
@ -114,8 +115,6 @@ delete_kbnode( KBNODE node )
|
||||
node->private_flag |= 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Append NODE to ROOT. ROOT must exist!
|
||||
*/
|
||||
@ -269,7 +268,7 @@ commit_kbnode( KBNODE *root )
|
||||
nl->next = n->next;
|
||||
if( !is_cloned_kbnode(n) ) {
|
||||
free_packet( n->pkt );
|
||||
xfree ( n->pkt );
|
||||
xfree( n->pkt );
|
||||
}
|
||||
free_node( n );
|
||||
changed = 1;
|
||||
@ -293,7 +292,7 @@ remove_kbnode( KBNODE *root, KBNODE node )
|
||||
nl->next = n->next;
|
||||
if( !is_cloned_kbnode(n) ) {
|
||||
free_packet( n->pkt );
|
||||
xfree ( n->pkt );
|
||||
xfree( n->pkt );
|
||||
}
|
||||
free_node( n );
|
||||
}
|
||||
|
233
g10/keydb.c
233
g10/keydb.c
@ -1,5 +1,5 @@
|
||||
/* keydb.c - key database dispatcher
|
||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -71,6 +72,124 @@ static int lock_all (KEYDB_HANDLE hd);
|
||||
static void unlock_all (KEYDB_HANDLE hd);
|
||||
|
||||
|
||||
/* Handle the creation of a keyring if it does not yet exist. Take
|
||||
into acount that other processes might have the keyring already
|
||||
locked. This lock check does not work if the directory itself is
|
||||
not yet available. */
|
||||
static int
|
||||
maybe_create_keyring (char *filename, int force)
|
||||
{
|
||||
DOTLOCK lockhd = NULL;
|
||||
IOBUF iobuf;
|
||||
int rc;
|
||||
mode_t oldmask;
|
||||
char *last_slash_in_filename;
|
||||
|
||||
/* A quick test whether the filename already exists. */
|
||||
if (!access (filename, F_OK))
|
||||
return 0;
|
||||
|
||||
/* If we don't want to create a new file at all, there is no need to
|
||||
go any further - bail out right here. */
|
||||
if (!force)
|
||||
return gpg_error (GPG_ERR_ENOENT);
|
||||
|
||||
/* First of all we try to create the home directory. Note, that we
|
||||
don't do any locking here because any sane application of gpg
|
||||
would create the home directory by itself and not rely on gpg's
|
||||
tricky auto-creation which is anyway only done for some home
|
||||
directory name patterns. */
|
||||
last_slash_in_filename = strrchr (filename, DIRSEP_C);
|
||||
*last_slash_in_filename = 0;
|
||||
if (access(filename, F_OK))
|
||||
{
|
||||
static int tried;
|
||||
|
||||
if (!tried)
|
||||
{
|
||||
tried = 1;
|
||||
try_make_homedir (filename);
|
||||
}
|
||||
if (access (filename, F_OK))
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
*last_slash_in_filename = DIRSEP_C;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
*last_slash_in_filename = DIRSEP_C;
|
||||
|
||||
|
||||
/* To avoid races with other instances of gpg trying to create or
|
||||
update the keyring (it is removed during an update for a short
|
||||
time), we do the next stuff in a locked state. */
|
||||
lockhd = create_dotlock (filename);
|
||||
if (!lockhd)
|
||||
{
|
||||
/* A reason for this to fail is that the directory is not
|
||||
writable. However, this whole locking stuff does not make
|
||||
sense if this is the case. An empty non-writable directory
|
||||
with no keyring is not really useful at all. */
|
||||
if (opt.verbose)
|
||||
log_info ("can't allocate lock for `%s'\n", filename );
|
||||
|
||||
if (!force)
|
||||
return G10ERR_OPEN_FILE;
|
||||
else
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
if ( make_dotlock (lockhd, -1) )
|
||||
{
|
||||
/* This is something bad. Probably a stale lockfile. */
|
||||
log_info ("can't lock `%s'\n", filename );
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Now the real test while we are locked. */
|
||||
if (!access(filename, F_OK))
|
||||
{
|
||||
rc = 0; /* Okay, we may access the file now. */
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* The file does not yet exist, create it now. */
|
||||
oldmask = umask (077);
|
||||
if (is_secured_filename (filename))
|
||||
{
|
||||
iobuf = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
else
|
||||
iobuf = iobuf_create (filename);
|
||||
umask (oldmask);
|
||||
if (!iobuf)
|
||||
{
|
||||
log_error ( _("error creating keyring `%s': %s\n"),
|
||||
filename, strerror(errno));
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!opt.quiet)
|
||||
log_info (_("keyring `%s' created\n"), filename);
|
||||
|
||||
iobuf_close (iobuf);
|
||||
/* Must invalidate that ugly cache */
|
||||
iobuf_ioctl (NULL, 2, 0, filename);
|
||||
rc = 0;
|
||||
|
||||
leave:
|
||||
if (lockhd)
|
||||
{
|
||||
release_dotlock (lockhd);
|
||||
destroy_dotlock (lockhd);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Register a resource (which currently may only be a keyring file).
|
||||
* The first keyring which is added by this function is
|
||||
@ -78,14 +197,14 @@ static void unlock_all (KEYDB_HANDLE hd);
|
||||
* Note: this function may be called before secure memory is
|
||||
* available.
|
||||
* Flag 1 == force
|
||||
* Flag 2 == default
|
||||
* Flag 2 == mark resource as primary
|
||||
* Flag 4 == This is a default resources
|
||||
*/
|
||||
int
|
||||
keydb_add_resource (const char *url, int flags, int secret)
|
||||
{
|
||||
static int any_secret, any_public;
|
||||
const char *resname = url;
|
||||
iobuf_t iobuf = NULL;
|
||||
char *filename = NULL;
|
||||
int force=(flags&1);
|
||||
int rc = 0;
|
||||
@ -104,7 +223,7 @@ keydb_add_resource (const char *url, int flags, int secret)
|
||||
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
|
||||
else if (strchr (resname, ':')) {
|
||||
log_error ("invalid key resource URL `%s'\n", url );
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
|
||||
@ -146,65 +265,18 @@ keydb_add_resource (const char *url, int flags, int secret)
|
||||
switch (rt) {
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
log_error ("unknown type of key resource `%s'\n", url );
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
if (access(filename, F_OK))
|
||||
{ /* file does not exist */
|
||||
mode_t oldmask;
|
||||
char *last_slash_in_filename;
|
||||
|
||||
if (!force)
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
last_slash_in_filename = strrchr (filename, DIRSEP_C);
|
||||
*last_slash_in_filename = 0;
|
||||
if (access(filename, F_OK))
|
||||
{ /* On the first time we try to create the default
|
||||
homedir and check again. */
|
||||
static int tried;
|
||||
|
||||
if (!tried)
|
||||
{
|
||||
tried = 1;
|
||||
try_make_homedir (filename);
|
||||
}
|
||||
if (access (filename, F_OK))
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
*last_slash_in_filename = DIRSEP_C;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
*last_slash_in_filename = DIRSEP_C;
|
||||
|
||||
oldmask=umask(077);
|
||||
iobuf = iobuf_create (filename);
|
||||
umask(oldmask);
|
||||
if (!iobuf)
|
||||
{
|
||||
log_error ( _("error creating keyring `%s': %s\n"),
|
||||
filename, strerror(errno));
|
||||
rc = gpg_error_from_errno (errno);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!opt.quiet)
|
||||
log_info (_("keyring `%s' created\n"), filename);
|
||||
iobuf_close (iobuf);
|
||||
iobuf = NULL;
|
||||
/* must invalidate that ugly cache */
|
||||
iobuf_ioctl (NULL, 2, 0, (char*)filename);
|
||||
} /* end file creation */
|
||||
rc = maybe_create_keyring (filename, force);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
if(keyring_register_filename (filename, secret, &token))
|
||||
{
|
||||
if (used_resources >= MAX_KEYDB_RESOURCES)
|
||||
rc = GPG_ERR_RESOURCE_LIMIT;
|
||||
rc = G10ERR_RESOURCE_LIMIT;
|
||||
else
|
||||
{
|
||||
if(flags&2)
|
||||
@ -228,7 +300,7 @@ keydb_add_resource (const char *url, int flags, int secret)
|
||||
|
||||
default:
|
||||
log_error ("resource type of `%s' not supported\n", url);
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -236,7 +308,18 @@ keydb_add_resource (const char *url, int flags, int secret)
|
||||
|
||||
leave:
|
||||
if (rc)
|
||||
log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror (rc));
|
||||
{
|
||||
/* Secret keyrings are not required in all cases. To avoid
|
||||
having gpg return failure we use log_info here if the
|
||||
rewsource is a secret one and marked as default
|
||||
resource. */
|
||||
if ((flags&4) && secret)
|
||||
log_info (_("keyblock resource `%s': %s\n"),
|
||||
filename, g10_errstr(rc));
|
||||
else
|
||||
log_error (_("keyblock resource `%s': %s\n"),
|
||||
filename, g10_errstr(rc));
|
||||
}
|
||||
else if (secret)
|
||||
any_secret = 1;
|
||||
else
|
||||
@ -254,7 +337,7 @@ keydb_new (int secret)
|
||||
KEYDB_HANDLE hd;
|
||||
int i, j;
|
||||
|
||||
hd = xcalloc (1,sizeof *hd);
|
||||
hd = xmalloc_clear (sizeof *hd);
|
||||
hd->found = -1;
|
||||
|
||||
assert (used_resources <= MAX_KEYDB_RESOURCES);
|
||||
@ -414,14 +497,14 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
|
||||
int rc = 0;
|
||||
|
||||
if (!hd)
|
||||
return GPG_ERR_INV_ARG;
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
if ( hd->found < 0 || hd->found >= hd->used)
|
||||
return -1; /* nothing found */
|
||||
|
||||
switch (hd->active[hd->found].type) {
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
rc = GPG_ERR_GENERAL; /* oops */
|
||||
rc = G10ERR_GENERAL; /* oops */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
|
||||
@ -440,7 +523,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
||||
int rc = 0;
|
||||
|
||||
if (!hd)
|
||||
return GPG_ERR_INV_ARG;
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
if ( hd->found < 0 || hd->found >= hd->used)
|
||||
return -1; /* nothing found */
|
||||
@ -454,7 +537,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
||||
|
||||
switch (hd->active[hd->found].type) {
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
rc = GPG_ERR_GENERAL; /* oops */
|
||||
rc = G10ERR_GENERAL; /* oops */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
|
||||
@ -476,7 +559,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
||||
int idx;
|
||||
|
||||
if (!hd)
|
||||
return GPG_ERR_INV_ARG;
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
if( opt.dry_run )
|
||||
return 0;
|
||||
@ -486,7 +569,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
||||
else if ( hd->current >= 0 && hd->current < hd->used)
|
||||
idx = hd->current;
|
||||
else
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
rc = lock_all (hd);
|
||||
if (rc)
|
||||
@ -494,7 +577,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
||||
|
||||
switch (hd->active[idx].type) {
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
rc = GPG_ERR_GENERAL; /* oops */
|
||||
rc = G10ERR_GENERAL; /* oops */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
|
||||
@ -515,7 +598,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
|
||||
int rc = -1;
|
||||
|
||||
if (!hd)
|
||||
return GPG_ERR_INV_ARG;
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
if ( hd->found < 0 || hd->found >= hd->used)
|
||||
return -1; /* nothing found */
|
||||
@ -529,7 +612,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
|
||||
|
||||
switch (hd->active[hd->found].type) {
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
rc = GPG_ERR_GENERAL; /* oops */
|
||||
rc = G10ERR_GENERAL; /* oops */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
|
||||
@ -552,7 +635,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
|
||||
int rc;
|
||||
|
||||
if (!hd)
|
||||
return GPG_ERR_INV_ARG;
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
rc = keydb_search_reset (hd); /* this does reset hd->current */
|
||||
if (rc)
|
||||
@ -598,7 +681,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
|
||||
* Rebuild the caches of all key resources.
|
||||
*/
|
||||
void
|
||||
keydb_rebuild_caches (void)
|
||||
keydb_rebuild_caches (int noisy)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
@ -611,10 +694,10 @@ keydb_rebuild_caches (void)
|
||||
case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||
rc = keyring_rebuild_cache (all_resources[i].token);
|
||||
rc = keyring_rebuild_cache (all_resources[i].token,noisy);
|
||||
if (rc)
|
||||
log_error (_("failed to rebuild keyring cache: %s\n"),
|
||||
gpg_strerror (rc));
|
||||
g10_errstr (rc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -631,7 +714,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
|
||||
int i, rc = 0;
|
||||
|
||||
if (!hd)
|
||||
return GPG_ERR_INV_ARG;
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
hd->current = 0;
|
||||
hd->found = -1;
|
||||
@ -660,7 +743,7 @@ keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
int rc = -1;
|
||||
|
||||
if (!hd)
|
||||
return GPG_ERR_INV_ARG;
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
while (rc == -1 && hd->current >= 0 && hd->current < hd->used) {
|
||||
switch (hd->active[hd->current].type) {
|
||||
|
62
g10/keydb.h
62
g10/keydb.h
@ -1,5 +1,6 @@
|
||||
/* keydb.h - Key database
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,14 +16,16 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_KEYDB_H
|
||||
#define G10_KEYDB_H
|
||||
|
||||
#include <assuan.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "global.h"
|
||||
#include "packet.h"
|
||||
#include "cipher.h"
|
||||
|
||||
@ -75,7 +78,7 @@ struct keyblock_pos_struct {
|
||||
enum resource_type rt;
|
||||
off_t offset; /* position information */
|
||||
unsigned count; /* length of the keyblock in packets */
|
||||
iobuf_t fp; /* used by enum_keyblocks */
|
||||
iobuf_t fp; /* Used by enum_keyblocks. */
|
||||
int secret; /* working on a secret keyring */
|
||||
PACKET *pkt; /* ditto */
|
||||
int valid;
|
||||
@ -131,11 +134,11 @@ typedef enum {
|
||||
|
||||
struct keydb_search_desc {
|
||||
KeydbSearchMode mode;
|
||||
int (*skipfnc)(void *,u32*);
|
||||
int (*skipfnc)(void *,u32*,PKT_user_id*);
|
||||
void *skipfncvalue;
|
||||
union {
|
||||
const char *name;
|
||||
char fpr[MAX_FINGERPRINT_LEN];
|
||||
byte fpr[MAX_FINGERPRINT_LEN];
|
||||
u32 kid[2];
|
||||
} u;
|
||||
int exact;
|
||||
@ -156,7 +159,7 @@ int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb);
|
||||
int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
|
||||
int keydb_delete_keyblock (KEYDB_HANDLE hd);
|
||||
int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
|
||||
void keydb_rebuild_caches (void);
|
||||
void keydb_rebuild_caches (int noisy);
|
||||
int keydb_search_reset (KEYDB_HANDLE hd);
|
||||
#define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL)
|
||||
int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
@ -183,14 +186,23 @@ int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
|
||||
int unlock, unsigned use );
|
||||
|
||||
/*-- passphrase.h --*/
|
||||
assuan_context_t agent_open (int try, const char *orig_codeset);
|
||||
void agent_close (assuan_context_t ctx);
|
||||
int have_static_passphrase(void);
|
||||
void set_passphrase_from_string(const char *pass);
|
||||
void read_passphrase_from_fd( int fd );
|
||||
void passphrase_clear_cache ( u32 *keyid, int algo );
|
||||
void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo );
|
||||
char *ask_passphrase (const char *description,
|
||||
const char *tryagain_text,
|
||||
const char *promptid,
|
||||
const char *prompt,
|
||||
const char *cacheid, int *canceled);
|
||||
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
|
||||
int cipher_algo, STRING2KEY *s2k, int mode,
|
||||
const char *tryagain_text, int *canceled);
|
||||
void set_next_passphrase( const char *s );
|
||||
char *get_last_passphrase(void);
|
||||
void next_to_last_passphrase(void);
|
||||
|
||||
/*-- getkey.c --*/
|
||||
int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc);
|
||||
@ -201,7 +213,7 @@ int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
|
||||
KBNODE get_pubkeyblock( u32 *keyid );
|
||||
int get_pubkey_byname( PKT_public_key *pk, const char *name,
|
||||
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
|
||||
int include_disabled );
|
||||
int include_unusable );
|
||||
int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
|
||||
STRLIST names, KBNODE *ret_keyblock );
|
||||
int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );
|
||||
@ -219,27 +231,39 @@ int seckey_available( u32 *keyid );
|
||||
int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
|
||||
int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
|
||||
STRLIST names, KBNODE *ret_keyblock );
|
||||
int get_seckey_next (GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock);
|
||||
void get_seckey_end( GETKEY_CTX ctx );
|
||||
|
||||
int get_seckey_byfprint( PKT_secret_key *sk,
|
||||
const byte *fprint, size_t fprint_len);
|
||||
int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
|
||||
void get_seckey_end( GETKEY_CTX ctx );
|
||||
int get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint,
|
||||
size_t fprint_len );
|
||||
|
||||
|
||||
int enum_secret_keys( void **context, PKT_secret_key *sk,
|
||||
int with_subkeys, int with_spm );
|
||||
void merge_keys_and_selfsig( KBNODE keyblock );
|
||||
char*get_user_id_string( u32 *keyid );
|
||||
char*get_user_id_string_printable( u32 *keyid );
|
||||
char*get_user_id_string_native( u32 *keyid );
|
||||
char*get_long_user_id_string( u32 *keyid );
|
||||
char*get_user_id( u32 *keyid, size_t *rn );
|
||||
char*get_user_id_printable( u32 *keyid );
|
||||
char*get_user_id_native( u32 *keyid );
|
||||
KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
|
||||
void release_akl(void);
|
||||
int parse_auto_key_locate(char *options);
|
||||
|
||||
/*-- keyid.c --*/
|
||||
int pubkey_letter( int algo );
|
||||
u32 v3_keyid (gcry_mpi_t a, u32 *ki);
|
||||
void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk );
|
||||
size_t keystrlen(void);
|
||||
const char *keystr(u32 *keyid);
|
||||
const char *keystr_from_pk(PKT_public_key *pk);
|
||||
const char *keystr_from_sk(PKT_secret_key *sk);
|
||||
const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc);
|
||||
u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
|
||||
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
|
||||
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
|
||||
u32 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid );
|
||||
u32 keyid_from_fingerprint(const byte *fprint, size_t fprint_len, u32 *keyid);
|
||||
byte *namehash_from_uid(PKT_user_id *uid);
|
||||
unsigned nbits_from_pk( PKT_public_key *pk );
|
||||
unsigned nbits_from_sk( PKT_secret_key *sk );
|
||||
@ -249,20 +273,16 @@ const char *datestr_from_sig( PKT_signature *sig );
|
||||
const char *expirestr_from_pk( PKT_public_key *pk );
|
||||
const char *expirestr_from_sk( PKT_secret_key *sk );
|
||||
const char *expirestr_from_sig( PKT_signature *sig );
|
||||
|
||||
const char *revokestr_from_pk( PKT_public_key *pk );
|
||||
const char *usagestr_from_pk( PKT_public_key *pk );
|
||||
const char *colon_strtime (u32 t);
|
||||
const char *colon_datestr_from_pk (PKT_public_key *pk);
|
||||
const char *colon_datestr_from_sk (PKT_secret_key *sk);
|
||||
const char *colon_datestr_from_sig (PKT_signature *sig);
|
||||
const char *colon_expirestr_from_sig (PKT_signature *sig);
|
||||
|
||||
byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
|
||||
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
|
||||
|
||||
char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
|
||||
PKT_secret_key *sk);
|
||||
|
||||
|
||||
/*-- kbnode.c --*/
|
||||
KBNODE new_kbnode( PACKET *pkt );
|
||||
KBNODE clone_kbnode( KBNODE node );
|
||||
|
2688
g10/keyedit.c
2688
g10/keyedit.c
File diff suppressed because it is too large
Load Diff
3049
g10/keygen.c
3049
g10/keygen.c
File diff suppressed because it is too large
Load Diff
691
g10/keyid.c
691
g10/keyid.c
@ -1,5 +1,6 @@
|
||||
/* keyid.c - key ID and fingerprint handling
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
|
||||
* 2004, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -31,11 +33,9 @@
|
||||
#include "main.h"
|
||||
#include "packet.h"
|
||||
#include "options.h"
|
||||
#include "mpi.h"
|
||||
#include "keydb.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
int
|
||||
pubkey_letter( int algo )
|
||||
{
|
||||
@ -50,66 +50,93 @@ pubkey_letter( int algo )
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is useful for v4 fingerprints and v3 or v4 key
|
||||
signing. */
|
||||
void
|
||||
hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
|
||||
{
|
||||
unsigned int n = 6;
|
||||
unsigned int nb[PUBKEY_MAX_NPKEY];
|
||||
unsigned int nn[PUBKEY_MAX_NPKEY];
|
||||
byte *pp[PUBKEY_MAX_NPKEY];
|
||||
int i;
|
||||
size_t nbits, nbytes;
|
||||
int npkey = pubkey_get_npkey (pk->pubkey_algo);
|
||||
|
||||
/* Two extra bytes for the expiration date in v3 */
|
||||
if(pk->version<4)
|
||||
n+=2;
|
||||
|
||||
if (npkey==0 && pk->pkey[0]
|
||||
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
|
||||
{
|
||||
pp[0] = gcry_mpi_get_opaque (pk->pkey[0], &nbits);
|
||||
nn[0] = (nbits+7)/8;
|
||||
n+=nn[0];
|
||||
}
|
||||
else
|
||||
for(i=0; i < npkey; i++ )
|
||||
{
|
||||
nb[i] = gcry_mpi_get_nbits (pk->pkey[i]);
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i]))
|
||||
BUG ();
|
||||
pp[i] = xmalloc (nbytes);
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
|
||||
&nbytes, pk->pkey[i]))
|
||||
BUG ();
|
||||
nn[i] = nbytes;
|
||||
n += 2 + nn[i];
|
||||
}
|
||||
|
||||
gcry_md_putc ( md, 0x99 ); /* ctb */
|
||||
/* What does it mean if n is greater than than 0xFFFF ? */
|
||||
gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
|
||||
gcry_md_putc ( md, n );
|
||||
gcry_md_putc ( md, pk->version );
|
||||
|
||||
gcry_md_putc ( md, pk->timestamp >> 24 );
|
||||
gcry_md_putc ( md, pk->timestamp >> 16 );
|
||||
gcry_md_putc ( md, pk->timestamp >> 8 );
|
||||
gcry_md_putc ( md, pk->timestamp );
|
||||
|
||||
if(pk->version<4)
|
||||
{
|
||||
u16 days=0;
|
||||
if(pk->expiredate)
|
||||
days=(u16)((pk->expiredate - pk->timestamp) / 86400L);
|
||||
|
||||
gcry_md_putc ( md, days >> 8 );
|
||||
gcry_md_putc ( md, days );
|
||||
}
|
||||
|
||||
gcry_md_putc ( md, pk->pubkey_algo );
|
||||
|
||||
if(npkey==0 && pk->pkey[0]
|
||||
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
|
||||
{
|
||||
gcry_md_write (md, pp[0], nn[0]);
|
||||
}
|
||||
else
|
||||
for(i=0; i < npkey; i++ )
|
||||
{
|
||||
gcry_md_putc ( md, nb[i]>>8);
|
||||
gcry_md_putc ( md, nb[i] );
|
||||
gcry_md_write ( md, pp[i], nn[i] );
|
||||
xfree(pp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static gcry_md_hd_t
|
||||
do_fingerprint_md( PKT_public_key *pk )
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
unsigned int n;
|
||||
unsigned int nn[PUBKEY_MAX_NPKEY];
|
||||
byte *pp[PUBKEY_MAX_NPKEY];
|
||||
int i;
|
||||
int npkey = pubkey_get_npkey( pk->pubkey_algo );
|
||||
gcry_md_hd_t md;
|
||||
|
||||
gcry_md_open (&md, pk->version < 4 ? DIGEST_ALGO_RMD160
|
||||
: DIGEST_ALGO_SHA1, 0);
|
||||
if (gcry_md_open (&md, DIGEST_ALGO_SHA1, 0))
|
||||
BUG ();
|
||||
hash_public_key(md,pk);
|
||||
gcry_md_final( md );
|
||||
|
||||
n = pk->version < 4 ? 8 : 6;
|
||||
for(i=0; i < npkey; i++ ) {
|
||||
size_t nbytes;
|
||||
|
||||
if (gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i] ))
|
||||
BUG ();
|
||||
/* fixme: we should try to allocate a buffer on the stack */
|
||||
pp[i] = xmalloc(nbytes);
|
||||
if (gcry_mpi_print ( GCRYMPI_FMT_PGP, pp[i], nbytes, &nbytes,
|
||||
pk->pkey[i] ))
|
||||
BUG ();
|
||||
nn[i] = nbytes;
|
||||
n += nn[i];
|
||||
}
|
||||
|
||||
gcry_md_putc ( md, 0x99 ); /* ctb */
|
||||
gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
|
||||
gcry_md_putc ( md, n );
|
||||
if( pk->version < 4 )
|
||||
gcry_md_putc ( md, 3 );
|
||||
else
|
||||
gcry_md_putc ( md, 4 );
|
||||
|
||||
{ u32 a = pk->timestamp;
|
||||
gcry_md_putc ( md, a >> 24 );
|
||||
gcry_md_putc ( md, a >> 16 );
|
||||
gcry_md_putc ( md, a >> 8 );
|
||||
gcry_md_putc ( md, a );
|
||||
}
|
||||
if( pk->version < 4 ) {
|
||||
u16 a;
|
||||
|
||||
if( pk->expiredate )
|
||||
a = (u16)((pk->expiredate - pk->timestamp) / 86400L);
|
||||
else
|
||||
a = 0;
|
||||
gcry_md_putc ( md, a >> 8 );
|
||||
gcry_md_putc ( md, a );
|
||||
}
|
||||
gcry_md_putc ( md, pk->pubkey_algo );
|
||||
for(i=0; i < npkey; i++ ) {
|
||||
gcry_md_write( md, pp[i], nn[i] );
|
||||
xfree (pp[i]);
|
||||
}
|
||||
gcry_md_final ( md );
|
||||
|
||||
return md;
|
||||
return md;
|
||||
}
|
||||
|
||||
static gcry_md_hd_t
|
||||
@ -119,13 +146,16 @@ do_fingerprint_md_sk( PKT_secret_key *sk )
|
||||
int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */
|
||||
int i;
|
||||
|
||||
if(npkey==0)
|
||||
return NULL;
|
||||
|
||||
pk.pubkey_algo = sk->pubkey_algo;
|
||||
pk.version = sk->version;
|
||||
pk.timestamp = sk->timestamp;
|
||||
pk.expiredate = sk->expiredate;
|
||||
pk.pubkey_algo = sk->pubkey_algo;
|
||||
for( i=0; i < npkey; i++ )
|
||||
pk.pkey[i] = sk->skey[i];
|
||||
pk.pkey[i] = sk->skey[i];
|
||||
return do_fingerprint_md( &pk );
|
||||
}
|
||||
|
||||
@ -154,6 +184,112 @@ v3_keyid (gcry_mpi_t a, u32 *ki)
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
keystrlen(void)
|
||||
{
|
||||
switch(opt.keyid_format)
|
||||
{
|
||||
case KF_SHORT:
|
||||
return 8;
|
||||
|
||||
case KF_LONG:
|
||||
return 16;
|
||||
|
||||
case KF_0xSHORT:
|
||||
return 10;
|
||||
|
||||
case KF_0xLONG:
|
||||
return 18;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
keystr(u32 *keyid)
|
||||
{
|
||||
static char keyid_str[19];
|
||||
|
||||
switch(opt.keyid_format)
|
||||
{
|
||||
case KF_SHORT:
|
||||
sprintf(keyid_str,"%08lX",(ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
case KF_LONG:
|
||||
if(keyid[0])
|
||||
sprintf(keyid_str,"%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
|
||||
else
|
||||
sprintf(keyid_str,"%08lX",(ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
case KF_0xSHORT:
|
||||
sprintf(keyid_str,"0x%08lX",(ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
case KF_0xLONG:
|
||||
if(keyid[0])
|
||||
sprintf(keyid_str,"0x%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
|
||||
else
|
||||
sprintf(keyid_str,"0x%08lX",(ulong)keyid[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
return keyid_str;
|
||||
}
|
||||
|
||||
const char *
|
||||
keystr_from_pk(PKT_public_key *pk)
|
||||
{
|
||||
keyid_from_pk(pk,NULL);
|
||||
|
||||
return keystr(pk->keyid);
|
||||
}
|
||||
|
||||
const char *
|
||||
keystr_from_sk(PKT_secret_key *sk)
|
||||
{
|
||||
keyid_from_sk(sk,NULL);
|
||||
|
||||
return keystr(sk->keyid);
|
||||
}
|
||||
|
||||
const char *
|
||||
keystr_from_desc(KEYDB_SEARCH_DESC *desc)
|
||||
{
|
||||
switch(desc->mode)
|
||||
{
|
||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||
return keystr(desc->u.kid);
|
||||
|
||||
case KEYDB_SEARCH_MODE_FPR20:
|
||||
{
|
||||
u32 keyid[2];
|
||||
|
||||
keyid[0] = ((unsigned char)desc->u.fpr[12] << 24
|
||||
| (unsigned char)desc->u.fpr[13] << 16
|
||||
| (unsigned char)desc->u.fpr[14] << 8
|
||||
| (unsigned char)desc->u.fpr[15]);
|
||||
keyid[1] = ((unsigned char)desc->u.fpr[16] << 24
|
||||
| (unsigned char)desc->u.fpr[17] << 16
|
||||
| (unsigned char)desc->u.fpr[18] << 8
|
||||
| (unsigned char)desc->u.fpr[19]);
|
||||
|
||||
return keystr(keyid);
|
||||
}
|
||||
|
||||
case KEYDB_SEARCH_MODE_FPR16:
|
||||
return "?v3 fpr?";
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* Get the keyid from the secret key and put it into keyid
|
||||
@ -162,29 +298,51 @@ v3_keyid (gcry_mpi_t a, u32 *ki)
|
||||
u32
|
||||
keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
|
||||
{
|
||||
u32 lowbits;
|
||||
u32 dummy_keyid[2];
|
||||
u32 lowbits;
|
||||
u32 dummy_keyid[2];
|
||||
|
||||
if( !keyid )
|
||||
keyid = dummy_keyid;
|
||||
if( !keyid )
|
||||
keyid = dummy_keyid;
|
||||
|
||||
if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
|
||||
keyid[0] = keyid[1] = 0;
|
||||
lowbits = pubkey_get_npkey(sk->pubkey_algo) ?
|
||||
v3_keyid (sk->skey[0], keyid) : 0;
|
||||
if( sk->keyid[0] || sk->keyid[1] )
|
||||
{
|
||||
keyid[0] = sk->keyid[0];
|
||||
keyid[1] = sk->keyid[1];
|
||||
lowbits = keyid[1];
|
||||
}
|
||||
else {
|
||||
const byte *dp;
|
||||
gcry_md_hd_t md;
|
||||
md = do_fingerprint_md_sk(sk);
|
||||
dp = gcry_md_read ( md, 0 );
|
||||
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
lowbits = keyid[1];
|
||||
gcry_md_close (md);
|
||||
else if( sk->version < 4 )
|
||||
{
|
||||
if( is_RSA(sk->pubkey_algo) )
|
||||
{
|
||||
lowbits = (pubkey_get_npkey (sk->pubkey_algo) ?
|
||||
v3_keyid( sk->skey[0], keyid ) : 0); /* Take n. */
|
||||
sk->keyid[0]=keyid[0];
|
||||
sk->keyid[1]=keyid[1];
|
||||
}
|
||||
else
|
||||
sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
const byte *dp;
|
||||
gcry_md_hd_t md;
|
||||
|
||||
md = do_fingerprint_md_sk(sk);
|
||||
if(md)
|
||||
{
|
||||
dp = gcry_md_read (md, 0);
|
||||
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
lowbits = keyid[1];
|
||||
gcry_md_close (md);
|
||||
sk->keyid[0] = keyid[0];
|
||||
sk->keyid[1] = keyid[1];
|
||||
}
|
||||
else
|
||||
sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return lowbits;
|
||||
return lowbits;
|
||||
}
|
||||
|
||||
|
||||
@ -195,38 +353,51 @@ keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
|
||||
u32
|
||||
keyid_from_pk( PKT_public_key *pk, u32 *keyid )
|
||||
{
|
||||
u32 lowbits;
|
||||
u32 dummy_keyid[2];
|
||||
u32 lowbits;
|
||||
u32 dummy_keyid[2];
|
||||
|
||||
if( !keyid )
|
||||
keyid = dummy_keyid;
|
||||
if( !keyid )
|
||||
keyid = dummy_keyid;
|
||||
|
||||
if( pk->keyid[0] || pk->keyid[1] ) {
|
||||
keyid[0] = pk->keyid[0];
|
||||
keyid[1] = pk->keyid[1];
|
||||
lowbits = keyid[1];
|
||||
if( pk->keyid[0] || pk->keyid[1] )
|
||||
{
|
||||
keyid[0] = pk->keyid[0];
|
||||
keyid[1] = pk->keyid[1];
|
||||
lowbits = keyid[1];
|
||||
}
|
||||
else if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
|
||||
keyid[0] = keyid[1] = 0;
|
||||
lowbits = pubkey_get_npkey(pk->pubkey_algo) ?
|
||||
v3_keyid (pk->pkey[0], keyid) : 0 ;
|
||||
pk->keyid[0] = keyid[0];
|
||||
pk->keyid[1] = keyid[1];
|
||||
else if( pk->version < 4 )
|
||||
{
|
||||
if( is_RSA(pk->pubkey_algo) )
|
||||
{
|
||||
lowbits = (pubkey_get_npkey (pk->pubkey_algo) ?
|
||||
v3_keyid ( pk->pkey[0], keyid ) : 0); /* From n. */
|
||||
pk->keyid[0] = keyid[0];
|
||||
pk->keyid[1] = keyid[1];
|
||||
}
|
||||
else
|
||||
pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
|
||||
}
|
||||
else {
|
||||
const byte *dp;
|
||||
gcry_md_hd_t md;
|
||||
md = do_fingerprint_md(pk);
|
||||
dp = gcry_md_read ( md, 0 );
|
||||
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
lowbits = keyid[1];
|
||||
gcry_md_close (md);
|
||||
pk->keyid[0] = keyid[0];
|
||||
pk->keyid[1] = keyid[1];
|
||||
else
|
||||
{
|
||||
const byte *dp;
|
||||
gcry_md_hd_t md;
|
||||
|
||||
md = do_fingerprint_md(pk);
|
||||
if(md)
|
||||
{
|
||||
dp = gcry_md_read ( md, 0 );
|
||||
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
lowbits = keyid[1];
|
||||
gcry_md_close (md);
|
||||
pk->keyid[0] = keyid[0];
|
||||
pk->keyid[1] = keyid[1];
|
||||
}
|
||||
else
|
||||
pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return lowbits;
|
||||
return lowbits;
|
||||
}
|
||||
|
||||
|
||||
@ -282,16 +453,16 @@ namehash_from_uid(PKT_user_id *uid)
|
||||
{
|
||||
if(uid->namehash==NULL)
|
||||
{
|
||||
uid->namehash=xmalloc (20);
|
||||
uid->namehash = xmalloc(20);
|
||||
|
||||
if(uid->attrib_data)
|
||||
gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash,
|
||||
uid->attrib_data,uid->attrib_len);
|
||||
gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash,
|
||||
uid->attrib_data, uid->attrib_len);
|
||||
else
|
||||
gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash,
|
||||
uid->name,uid->len);
|
||||
uid->name, uid->len);
|
||||
}
|
||||
|
||||
|
||||
return uid->namehash;
|
||||
}
|
||||
|
||||
@ -396,6 +567,46 @@ expirestr_from_sig( PKT_signature *sig )
|
||||
return mk_datestr (buffer, atime);
|
||||
}
|
||||
|
||||
const char *
|
||||
revokestr_from_pk( PKT_public_key *pk )
|
||||
{
|
||||
static char buffer[11+5];
|
||||
time_t atime;
|
||||
|
||||
if(!pk->revoked.date)
|
||||
return _("never ");
|
||||
atime=pk->revoked.date;
|
||||
return mk_datestr (buffer, atime);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
usagestr_from_pk( PKT_public_key *pk )
|
||||
{
|
||||
static char buffer[10];
|
||||
int i = 0;
|
||||
unsigned int use = pk->pubkey_usage;
|
||||
|
||||
if ( use & PUBKEY_USAGE_SIG )
|
||||
buffer[i++] = 'S';
|
||||
|
||||
if ( use & PUBKEY_USAGE_CERT )
|
||||
buffer[i++] = 'C';
|
||||
|
||||
if ( use & PUBKEY_USAGE_ENC )
|
||||
buffer[i++] = 'E';
|
||||
|
||||
if ( (use & PUBKEY_USAGE_AUTH) )
|
||||
buffer[i++] = 'A';
|
||||
|
||||
while (i < 4)
|
||||
buffer[i++] = ' ';
|
||||
|
||||
buffer[i] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
colon_strtime (u32 t)
|
||||
{
|
||||
@ -465,145 +676,143 @@ colon_expirestr_from_sig (PKT_signature *sig)
|
||||
byte *
|
||||
fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
|
||||
{
|
||||
byte *buf;
|
||||
const byte *dp;
|
||||
size_t len;
|
||||
|
||||
if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
|
||||
/* RSA in version 3 packets is special */
|
||||
gcry_md_hd_t md;
|
||||
|
||||
gcry_md_open (&md, DIGEST_ALGO_MD5, 0);
|
||||
if( pubkey_get_npkey( pk->pubkey_algo ) > 1 ) {
|
||||
size_t nbytes;
|
||||
|
||||
if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes,
|
||||
pk->pkey[0]))
|
||||
BUG ();
|
||||
/* fixme: allocate it on the stack */
|
||||
buf = xmalloc(nbytes);
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[0]))
|
||||
BUG ();
|
||||
gcry_md_write (md, buf, nbytes);
|
||||
xfree (buf);
|
||||
if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, pk->pkey[1]))
|
||||
BUG ();
|
||||
/* fixme: allocate it on the stack */
|
||||
buf = xmalloc(nbytes);
|
||||
if (gcry_mpi_print( GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[1]))
|
||||
BUG ();
|
||||
gcry_md_write( md, buf, nbytes );
|
||||
xfree(buf);
|
||||
}
|
||||
gcry_md_final (md);
|
||||
if( !array )
|
||||
array = xmalloc ( 16 );
|
||||
len = 16;
|
||||
memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 );
|
||||
gcry_md_close (md);
|
||||
byte *buf;
|
||||
const byte *dp;
|
||||
size_t len, nbytes;
|
||||
int i;
|
||||
|
||||
if ( pk->version < 4 )
|
||||
{
|
||||
if ( is_RSA(pk->pubkey_algo) )
|
||||
{
|
||||
/* RSA in version 3 packets is special. */
|
||||
gcry_md_hd_t md;
|
||||
|
||||
if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
|
||||
BUG ();
|
||||
if ( pubkey_get_npkey (pk->pubkey_algo) > 1 )
|
||||
{
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
|
||||
&nbytes, pk->pkey[i]))
|
||||
BUG ();
|
||||
/* fixme: Better allocate BUF on the stack */
|
||||
buf = xmalloc (nbytes);
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes,
|
||||
NULL, pk->pkey[i]))
|
||||
BUG ();
|
||||
gcry_md_write (md, buf, nbytes);
|
||||
xfree (buf);
|
||||
}
|
||||
}
|
||||
gcry_md_final (md);
|
||||
if (!array)
|
||||
array = xmalloc (16);
|
||||
len = 16;
|
||||
memcpy (array, gcry_md_read (md, DIGEST_ALGO_MD5), 16);
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!array)
|
||||
array = xmalloc(16);
|
||||
len = 16;
|
||||
memset (array,0,16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
gcry_md_hd_t md;
|
||||
md = do_fingerprint_md(pk);
|
||||
dp = gcry_md_read ( md, 0 );
|
||||
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
|
||||
assert( len <= MAX_FINGERPRINT_LEN );
|
||||
if( !array )
|
||||
array = xmalloc ( len );
|
||||
memcpy(array, dp, len );
|
||||
pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
gcry_md_close (md);
|
||||
else
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
|
||||
md = do_fingerprint_md(pk);
|
||||
dp = gcry_md_read( md, 0 );
|
||||
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
|
||||
assert( len <= MAX_FINGERPRINT_LEN );
|
||||
if (!array)
|
||||
array = xmalloc ( len );
|
||||
memcpy (array, dp, len );
|
||||
pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
gcry_md_close( md);
|
||||
}
|
||||
|
||||
*ret_len = len;
|
||||
return array;
|
||||
|
||||
*ret_len = len;
|
||||
return array;
|
||||
}
|
||||
|
||||
byte *
|
||||
fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
|
||||
{
|
||||
byte *buf;
|
||||
const char *dp;
|
||||
size_t len;
|
||||
|
||||
if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
|
||||
/* RSA in version 3 packets is special */
|
||||
gcry_md_hd_t md;
|
||||
|
||||
gcry_md_open (&md, DIGEST_ALGO_MD5, 0);
|
||||
if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) {
|
||||
size_t nbytes;
|
||||
|
||||
if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[0]))
|
||||
BUG ();
|
||||
/* fixme: allocate it on the stack */
|
||||
buf = xmalloc(nbytes);
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,sk->skey[0]))
|
||||
BUG ();
|
||||
gcry_md_write (md, buf, nbytes);
|
||||
xfree (buf);
|
||||
if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[1]))
|
||||
BUG ();
|
||||
/* fixme: allocate it on the stack */
|
||||
buf = xmalloc(nbytes);
|
||||
if (gcry_mpi_print( GCRYMPI_FMT_USG, buf,nbytes, NULL, sk->skey[1]))
|
||||
BUG ();
|
||||
gcry_md_write( md, buf, nbytes );
|
||||
xfree(buf);
|
||||
}
|
||||
gcry_md_final (md);
|
||||
if( !array )
|
||||
array = xmalloc ( 16 );
|
||||
len = 16;
|
||||
memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 );
|
||||
gcry_md_close (md);
|
||||
}
|
||||
else {
|
||||
gcry_md_hd_t md;
|
||||
|
||||
md = do_fingerprint_md_sk(sk);
|
||||
dp = gcry_md_read ( md, 0 );
|
||||
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
|
||||
assert( len <= MAX_FINGERPRINT_LEN );
|
||||
if( !array )
|
||||
array = xmalloc ( len );
|
||||
memcpy(array, dp, len );
|
||||
gcry_md_close (md);
|
||||
}
|
||||
|
||||
*ret_len = len;
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/* Create a serialno/fpr string from the serial number and the secret
|
||||
* key. caller must free the returned string. There is no error
|
||||
* return. */
|
||||
char *
|
||||
serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
|
||||
PKT_secret_key *sk)
|
||||
{
|
||||
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
char *buffer, *p;
|
||||
byte *buf;
|
||||
const char *dp;
|
||||
size_t len, nbytes;
|
||||
int i;
|
||||
|
||||
fingerprint_from_sk (sk, fpr, &fprlen);
|
||||
buffer = p= xmalloc (snlen*2 + 1 + fprlen*2 + 1);
|
||||
for (i=0; i < snlen; i++, p+=2)
|
||||
sprintf (p, "%02X", sn[i]);
|
||||
*p++ = '/';
|
||||
for (i=0; i < fprlen; i++, p+=2)
|
||||
sprintf (p, "%02X", fpr[i]);
|
||||
*p = 0;
|
||||
return buffer;
|
||||
if (sk->version < 4)
|
||||
{
|
||||
if ( is_RSA(sk->pubkey_algo) )
|
||||
{
|
||||
/* RSA in version 3 packets is special. */
|
||||
gcry_md_hd_t md;
|
||||
|
||||
if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
|
||||
BUG ();
|
||||
if (pubkey_get_npkey( sk->pubkey_algo ) > 1)
|
||||
{
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
|
||||
&nbytes, sk->skey[i]))
|
||||
BUG ();
|
||||
/* fixme: Better allocate BUF on the stack */
|
||||
buf = xmalloc (nbytes);
|
||||
if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes,
|
||||
NULL, sk->skey[i]))
|
||||
BUG ();
|
||||
gcry_md_write (md, buf, nbytes);
|
||||
xfree (buf);
|
||||
}
|
||||
}
|
||||
gcry_md_final(md);
|
||||
if (!array)
|
||||
array = xmalloc (16);
|
||||
len = 16;
|
||||
memcpy (array, gcry_md_read (md, DIGEST_ALGO_MD5), 16);
|
||||
gcry_md_close (md);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!array)
|
||||
array = xmalloc (16);
|
||||
len=16;
|
||||
memset (array,0,16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
|
||||
md = do_fingerprint_md_sk(sk);
|
||||
if (md)
|
||||
{
|
||||
dp = gcry_md_read ( md, 0 );
|
||||
len = gcry_md_get_algo_dlen ( gcry_md_get_algo (md) );
|
||||
assert ( len <= MAX_FINGERPRINT_LEN );
|
||||
if (!array)
|
||||
array = xmalloc( len );
|
||||
memcpy (array, dp, len);
|
||||
gcry_md_close (md);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = MAX_FINGERPRINT_LEN;
|
||||
if (!array)
|
||||
array = xmalloc (len);
|
||||
memset (array, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
*ret_len = len;
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
774
g10/keylist.c
774
g10/keylist.c
File diff suppressed because it is too large
Load Diff
216
g10/keyring.c
216
g10/keyring.c
@ -1,5 +1,5 @@
|
||||
/* keyring.c - keyring file handling
|
||||
* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -73,7 +74,7 @@ struct keyring_handle {
|
||||
int secret; /* this is for a secret keyring */
|
||||
struct {
|
||||
CONST_KR_NAME kr;
|
||||
iobuf_t iobuf;
|
||||
IOBUF iobuf;
|
||||
int eof;
|
||||
int error;
|
||||
} current;
|
||||
@ -102,7 +103,7 @@ new_offset_item (void)
|
||||
{
|
||||
struct off_item *k;
|
||||
|
||||
k = xcalloc (1,sizeof *k);
|
||||
k = xmalloc_clear (sizeof *k);
|
||||
return k;
|
||||
}
|
||||
|
||||
@ -125,7 +126,7 @@ new_offset_hash_table (void)
|
||||
{
|
||||
struct off_item **tbl;
|
||||
|
||||
tbl = xcalloc (2048, sizeof *tbl);
|
||||
tbl = xmalloc_clear (2048 * sizeof *tbl);
|
||||
return tbl;
|
||||
}
|
||||
|
||||
@ -214,6 +215,9 @@ keyring_register_filename (const char *fname, int secret, void **ptr)
|
||||
}
|
||||
}
|
||||
|
||||
if (secret)
|
||||
register_secured_file (fname);
|
||||
|
||||
kr = xmalloc (sizeof *kr + strlen (fname));
|
||||
strcpy (kr->fname, fname);
|
||||
kr->secret = !!secret;
|
||||
@ -255,7 +259,7 @@ keyring_new (void *token, int secret)
|
||||
|
||||
assert (resource && !resource->secret == !secret);
|
||||
|
||||
hd = xcalloc (1,sizeof *hd);
|
||||
hd = xmalloc_clear (sizeof *hd);
|
||||
hd->resource = resource;
|
||||
hd->secret = !!secret;
|
||||
active_handles++;
|
||||
@ -304,7 +308,7 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
|
||||
kr->lockhd = create_dotlock( kr->fname );
|
||||
if (!kr->lockhd) {
|
||||
log_info ("can't allocate lock for `%s'\n", kr->fname );
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -319,7 +323,7 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
|
||||
;
|
||||
else if (make_dotlock (kr->lockhd, -1) ) {
|
||||
log_info ("can't lock `%s'\n", kr->fname );
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
}
|
||||
else
|
||||
kr->is_locked = 1;
|
||||
@ -356,7 +360,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
|
||||
PACKET *pkt;
|
||||
int rc;
|
||||
KBNODE keyblock = NULL, node, lastnode;
|
||||
iobuf_t a;
|
||||
IOBUF a;
|
||||
int in_cert = 0;
|
||||
int pk_no = 0;
|
||||
int uid_no = 0;
|
||||
@ -369,15 +373,16 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
|
||||
return -1; /* no successful search */
|
||||
|
||||
a = iobuf_open (hd->found.kr->fname);
|
||||
if (!a) {
|
||||
log_error ("can't open `%s'\n", hd->found.kr->fname);
|
||||
return GPG_ERR_KEYRING_OPEN;
|
||||
}
|
||||
if (!a)
|
||||
{
|
||||
log_error(_("can't open `%s'\n"), hd->found.kr->fname);
|
||||
return G10ERR_KEYRING_OPEN;
|
||||
}
|
||||
|
||||
if (iobuf_seek (a, hd->found.offset) ) {
|
||||
log_error ("can't seek `%s'\n", hd->found.kr->fname);
|
||||
iobuf_close(a);
|
||||
return GPG_ERR_KEYRING_OPEN;
|
||||
return G10ERR_KEYRING_OPEN;
|
||||
}
|
||||
|
||||
pkt = xmalloc (sizeof *pkt);
|
||||
@ -387,15 +392,15 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
|
||||
save_mode = set_packet_list_mode(0);
|
||||
while ((rc=parse_packet (a, pkt)) != -1) {
|
||||
hd->found.n_packets++;
|
||||
if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) {
|
||||
if (rc == G10ERR_UNKNOWN_PACKET) {
|
||||
free_packet (pkt);
|
||||
init_packet (pkt);
|
||||
continue;
|
||||
}
|
||||
if (rc) {
|
||||
log_error ("keyring_get_keyblock: read error: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
rc = GPG_ERR_INV_KEYRING;
|
||||
g10_errstr(rc) );
|
||||
rc = G10ERR_INV_KEYRING;
|
||||
break;
|
||||
}
|
||||
if (pkt->pkttype == PKT_COMPRESSED) {
|
||||
@ -478,7 +483,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
|
||||
/* Make sure that future search operations fail immediately when
|
||||
* we know that we are working on a invalid keyring
|
||||
*/
|
||||
if (gpg_err_code (rc) == GPG_ERR_INV_KEYRING)
|
||||
if (rc == G10ERR_INV_KEYRING)
|
||||
hd->current.error = rc;
|
||||
|
||||
return rc;
|
||||
@ -496,7 +501,7 @@ keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb)
|
||||
/* need to know the number of packets - do a dummy get_keyblock*/
|
||||
rc = keyring_get_keyblock (hd, NULL);
|
||||
if (rc) {
|
||||
log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc));
|
||||
log_error ("re-reading keyblock failed: %s\n", g10_errstr (rc));
|
||||
return rc;
|
||||
}
|
||||
if (!hd->found.n_packets)
|
||||
@ -540,7 +545,7 @@ keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
|
||||
fname = hd->resource? hd->resource->fname:NULL;
|
||||
|
||||
if (!fname)
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
/* close this one otherwise we will lose the position for
|
||||
* a next search. Fixme: it would be better to adjust the position
|
||||
@ -572,7 +577,7 @@ keyring_delete_keyblock (KEYRING_HANDLE hd)
|
||||
/* need to know the number of packets - do a dummy get_keyblock*/
|
||||
rc = keyring_get_keyblock (hd, NULL);
|
||||
if (rc) {
|
||||
log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc));
|
||||
log_error ("re-reading keyblock failed: %s\n", g10_errstr (rc));
|
||||
return rc;
|
||||
}
|
||||
if (!hd->found.n_packets)
|
||||
@ -629,7 +634,7 @@ prepare_search (KEYRING_HANDLE hd)
|
||||
|
||||
if (hd->current.kr && !hd->current.eof) {
|
||||
if ( !hd->current.iobuf )
|
||||
return GPG_ERR_GENERAL; /* position invalid after a modify */
|
||||
return G10ERR_GENERAL; /* position invalid after a modify */
|
||||
return 0; /* okay */
|
||||
}
|
||||
|
||||
@ -654,11 +659,12 @@ prepare_search (KEYRING_HANDLE hd)
|
||||
|
||||
hd->current.eof = 0;
|
||||
hd->current.iobuf = iobuf_open (hd->current.kr->fname);
|
||||
if (!hd->current.iobuf) {
|
||||
if (!hd->current.iobuf)
|
||||
{
|
||||
hd->current.error = gpg_error_from_errno (errno);
|
||||
log_error ("can't open `%s'\n", hd->current.kr->fname );
|
||||
log_error(_("can't open `%s'\n"), hd->current.kr->fname );
|
||||
return hd->current.error;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -776,7 +782,7 @@ prepare_word_match (const byte *name)
|
||||
int c;
|
||||
|
||||
/* the original length is always enough for the pattern */
|
||||
p = pattern = xmalloc (strlen(name)+1);
|
||||
p = pattern = xmalloc(strlen(name)+1);
|
||||
do {
|
||||
/* skip leading delimiters */
|
||||
while( *name && !word_match_chars[*name] )
|
||||
@ -1071,7 +1077,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
goto found;
|
||||
break;
|
||||
default:
|
||||
rc = GPG_ERR_INV_ARG;
|
||||
rc = G10ERR_INV_ARG;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
@ -1085,7 +1091,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
for (n=any_skip?0:ndesc; n < ndesc; n++)
|
||||
{
|
||||
if (desc[n].skipfnc
|
||||
&& desc[n].skipfnc (desc[n].skipfncvalue, aki))
|
||||
&& desc[n].skipfnc (desc[n].skipfncvalue, aki, uid))
|
||||
break;
|
||||
}
|
||||
if (n == ndesc)
|
||||
@ -1141,7 +1147,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
|
||||
static int
|
||||
create_tmp_file (const char *template,
|
||||
char **r_bakfname, char **r_tmpfname, iobuf_t *r_fp)
|
||||
char **r_bakfname, char **r_tmpfname, IOBUF *r_fp)
|
||||
{
|
||||
char *bakfname, *tmpfname;
|
||||
mode_t oldmask;
|
||||
@ -1184,15 +1190,22 @@ create_tmp_file (const char *template,
|
||||
|
||||
/* Create the temp file with limited access */
|
||||
oldmask=umask(077);
|
||||
*r_fp = iobuf_create (tmpfname);
|
||||
if (is_secured_filename (tmpfname))
|
||||
{
|
||||
*r_fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
else
|
||||
*r_fp = iobuf_create (tmpfname);
|
||||
umask(oldmask);
|
||||
if (!*r_fp) {
|
||||
int tmperr = gpg_error_from_errno (errno);
|
||||
log_error ("can't create `%s': %s\n", tmpfname, strerror(errno) );
|
||||
if (!*r_fp)
|
||||
{
|
||||
int rc = gpg_error_from_errno (errno);
|
||||
log_error(_("can't create `%s': %s\n"), tmpfname, strerror(errno) );
|
||||
xfree (tmpfname);
|
||||
xfree (bakfname);
|
||||
return tmperr;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
*r_bakfname = bakfname;
|
||||
*r_tmpfname = tmpfname;
|
||||
@ -1219,10 +1232,10 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
|
||||
#endif
|
||||
if (rename (fname, bakfname) )
|
||||
{
|
||||
int tmperr = gpg_error_from_errno (errno);
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("renaming `%s' to `%s' failed: %s\n",
|
||||
fname, bakfname, strerror(errno) );
|
||||
return tmperr;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1230,11 +1243,14 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
|
||||
#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
|
||||
remove( fname );
|
||||
#endif
|
||||
if (secret)
|
||||
unregister_secured_file (fname);
|
||||
if (rename (tmpfname, fname) )
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("renaming `%s' to `%s' failed: %s\n",
|
||||
log_error (_("renaming `%s' to `%s' failed: %s\n"),
|
||||
tmpfname, fname, strerror(errno) );
|
||||
register_secured_file (fname);
|
||||
if (secret)
|
||||
{
|
||||
log_info(_("WARNING: 2 files with confidential"
|
||||
@ -1269,7 +1285,7 @@ rename_tmp_file (const char *bakfname, const char *tmpfname,
|
||||
|
||||
|
||||
static int
|
||||
write_keyblock (iobuf_t fp, KBNODE keyblock)
|
||||
write_keyblock (IOBUF fp, KBNODE keyblock)
|
||||
{
|
||||
KBNODE kbctx = NULL, node;
|
||||
int rc;
|
||||
@ -1282,7 +1298,7 @@ write_keyblock (iobuf_t fp, KBNODE keyblock)
|
||||
if ( (rc = build_packet (fp, node->pkt) ))
|
||||
{
|
||||
log_error ("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, gpg_strerror (rc) );
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
if (node->pkt->pkttype == PKT_SIGNATURE)
|
||||
@ -1299,11 +1315,12 @@ write_keyblock (iobuf_t fp, KBNODE keyblock)
|
||||
iobuf_put (fp, 0xb0); /* old style packet 12, 1 byte len*/
|
||||
iobuf_put (fp, 2); /* 2 bytes */
|
||||
iobuf_put (fp, 0); /* unused */
|
||||
if (iobuf_put (fp, cacheval)) {
|
||||
int tmperr = gpg_error_from_errno (errno);
|
||||
log_error ("writing sigcache packet failed\n");
|
||||
return tmperr;
|
||||
}
|
||||
if (iobuf_put (fp, cacheval))
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("writing sigcache packet failed\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -1315,13 +1332,13 @@ write_keyblock (iobuf_t fp, KBNODE keyblock)
|
||||
* This is only done for the public keyrings.
|
||||
*/
|
||||
int
|
||||
keyring_rebuild_cache (void *token)
|
||||
keyring_rebuild_cache (void *token,int noisy)
|
||||
{
|
||||
KEYRING_HANDLE hd;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
KBNODE keyblock = NULL, node;
|
||||
const char *lastresname = NULL, *resname;
|
||||
iobuf_t tmpfp = NULL;
|
||||
IOBUF tmpfp = NULL;
|
||||
char *tmpfilename = NULL;
|
||||
char *bakfilename = NULL;
|
||||
int rc;
|
||||
@ -1361,8 +1378,8 @@ keyring_rebuild_cache (void *token)
|
||||
if (rc)
|
||||
goto leave;
|
||||
lastresname = resname;
|
||||
if (!opt.quiet)
|
||||
log_info (_("checking keyring `%s'\n"), resname);
|
||||
if (noisy && !opt.quiet)
|
||||
log_info (_("caching keyring `%s'\n"), resname);
|
||||
rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp);
|
||||
if (rc)
|
||||
goto leave;
|
||||
@ -1372,7 +1389,7 @@ keyring_rebuild_cache (void *token)
|
||||
rc = keyring_get_keyblock (hd, &keyblock);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("keyring_get_keyblock failed: %s\n", gpg_strerror (rc));
|
||||
log_error ("keyring_get_keyblock failed: %s\n", g10_errstr(rc));
|
||||
goto leave;
|
||||
}
|
||||
assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
||||
@ -1380,16 +1397,24 @@ keyring_rebuild_cache (void *token)
|
||||
/* check all signature to set the signature's cache flags */
|
||||
for (node=keyblock; node; node=node->next)
|
||||
{
|
||||
/* Note that this doesn't cache the result of a revocation
|
||||
issued by a designated revoker. This is because the pk
|
||||
in question does not carry the revkeys as we haven't
|
||||
merged the key and selfsigs. It is questionable whether
|
||||
this matters very much since there are very very few
|
||||
designated revoker revocation packets out there. */
|
||||
|
||||
if (node->pkt->pkttype == PKT_SIGNATURE)
|
||||
{
|
||||
/* Note that this doesn't cache the result of a
|
||||
revocation issued by a designated revoker. This is
|
||||
because the pk in question does not carry the revkeys
|
||||
as we haven't merged the key and selfsigs. It is
|
||||
questionable whether this matters very much since
|
||||
there are very very few designated revoker revocation
|
||||
packets out there. */
|
||||
check_key_signature (keyblock, node, NULL);
|
||||
PKT_signature *sig=node->pkt->pkt.signature;
|
||||
|
||||
if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
|
||||
&& (openpgp_md_test_algo(sig->digest_algo)
|
||||
|| openpgp_pk_test_algo(sig->pubkey_algo)))
|
||||
sig->flags.checked=sig->flags.valid=0;
|
||||
else
|
||||
check_key_signature (keyblock, node, NULL);
|
||||
|
||||
sigcount++;
|
||||
}
|
||||
}
|
||||
@ -1399,8 +1424,8 @@ keyring_rebuild_cache (void *token)
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
if ( !(++count % 50) && !opt.quiet)
|
||||
log_info(_("%lu keys checked so far (%lu signatures)\n"),
|
||||
if ( !(++count % 50) && noisy && !opt.quiet)
|
||||
log_info(_("%lu keys cached so far (%lu signatures)\n"),
|
||||
count, sigcount );
|
||||
|
||||
} /* end main loop */
|
||||
@ -1408,10 +1433,11 @@ keyring_rebuild_cache (void *token)
|
||||
rc = 0;
|
||||
if (rc)
|
||||
{
|
||||
log_error ("keyring_search failed: %s\n", gpg_strerror (rc));
|
||||
log_error ("keyring_search failed: %s\n", g10_errstr(rc));
|
||||
goto leave;
|
||||
}
|
||||
log_info(_("%lu keys checked (%lu signatures)\n"), count, sigcount );
|
||||
if(noisy || opt.verbose)
|
||||
log_info(_("%lu keys cached (%lu signatures)\n"), count, sigcount );
|
||||
if (tmpfp)
|
||||
{
|
||||
if (iobuf_close (tmpfp))
|
||||
@ -1452,17 +1478,16 @@ static int
|
||||
do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
off_t start_offset, unsigned int n_packets )
|
||||
{
|
||||
iobuf_t fp, newfp;
|
||||
IOBUF fp, newfp;
|
||||
int rc=0;
|
||||
char *bakfname = NULL;
|
||||
char *tmpfname = NULL;
|
||||
|
||||
/* Open the source file. Because we do a rname, we have to check the
|
||||
/* Open the source file. Because we do a rename, we have to check the
|
||||
permissions of the file */
|
||||
if (access (fname, W_OK))
|
||||
return gpg_error_from_errno (errno);
|
||||
|
||||
|
||||
fp = iobuf_open (fname);
|
||||
if (mode == 1 && !fp && errno == ENOENT) {
|
||||
/* insert mode but file does not exist: create a new file */
|
||||
@ -1470,14 +1495,19 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
mode_t oldmask;
|
||||
|
||||
oldmask=umask(077);
|
||||
newfp = iobuf_create (fname);
|
||||
if (!secret && is_secured_filename (fname)) {
|
||||
newfp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
else
|
||||
newfp = iobuf_create (fname);
|
||||
umask(oldmask);
|
||||
if( !newfp ) {
|
||||
int tmperr = gpg_error_from_errno (errno);
|
||||
log_error (_("%s: can't create: %s\n"),
|
||||
fname, strerror(errno));
|
||||
return tmperr;
|
||||
}
|
||||
if( !newfp )
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error (_("can't create `%s': %s\n"), fname, strerror(errno));
|
||||
return rc;
|
||||
}
|
||||
if( !opt.quiet )
|
||||
log_info(_("%s: keyring created\n"), fname );
|
||||
|
||||
@ -1485,38 +1515,44 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
while ( (node = walk_kbnode( root, &kbctx, 0 )) ) {
|
||||
if( (rc = build_packet( newfp, node->pkt )) ) {
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, gpg_strerror (rc) );
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
iobuf_cancel(newfp);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if (iobuf_close(newfp)) {
|
||||
int tmperr = gpg_error_from_errno (errno);
|
||||
if( iobuf_close(newfp) ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("%s: close failed: %s\n", fname, strerror(errno));
|
||||
return tmperr;
|
||||
return rc;
|
||||
}
|
||||
return 0; /* ready */
|
||||
}
|
||||
|
||||
if( !fp ) {
|
||||
if( !fp )
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("%s: can't open: %s\n", fname, strerror(errno) );
|
||||
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
/* create the new file */
|
||||
/* Create the new file. */
|
||||
rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
|
||||
if (rc) {
|
||||
iobuf_close(fp);
|
||||
goto leave;
|
||||
}
|
||||
if (secret)
|
||||
register_secured_file (tmpfname);
|
||||
|
||||
if( mode == 1 ) { /* insert */
|
||||
/* copy everything to the new file */
|
||||
rc = copy_all_packets (fp, newfp);
|
||||
if( rc != -1 ) {
|
||||
log_error("%s: copy to `%s' failed: %s\n",
|
||||
fname, tmpfname, gpg_strerror (rc) );
|
||||
fname, tmpfname, g10_errstr(rc) );
|
||||
iobuf_close(fp);
|
||||
if (secret)
|
||||
unregister_secured_file (tmpfname);
|
||||
iobuf_cancel(newfp);
|
||||
goto leave;
|
||||
}
|
||||
@ -1528,8 +1564,10 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
rc = copy_some_packets( fp, newfp, start_offset );
|
||||
if( rc ) { /* should never get EOF here */
|
||||
log_error ("%s: copy to `%s' failed: %s\n",
|
||||
fname, tmpfname, gpg_strerror (rc) );
|
||||
fname, tmpfname, g10_errstr(rc) );
|
||||
iobuf_close(fp);
|
||||
if (secret)
|
||||
unregister_secured_file (tmpfname);
|
||||
iobuf_cancel(newfp);
|
||||
goto leave;
|
||||
}
|
||||
@ -1538,8 +1576,10 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
rc = skip_some_packets( fp, n_packets );
|
||||
if( rc ) {
|
||||
log_error("%s: skipping %u packets failed: %s\n",
|
||||
fname, n_packets, gpg_strerror (rc));
|
||||
fname, n_packets, g10_errstr(rc));
|
||||
iobuf_close(fp);
|
||||
if (secret)
|
||||
unregister_secured_file (tmpfname);
|
||||
iobuf_cancel(newfp);
|
||||
goto leave;
|
||||
}
|
||||
@ -1549,6 +1589,8 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
rc = write_keyblock (newfp, root);
|
||||
if (rc) {
|
||||
iobuf_close(fp);
|
||||
if (secret)
|
||||
unregister_secured_file (tmpfname);
|
||||
iobuf_cancel(newfp);
|
||||
goto leave;
|
||||
}
|
||||
@ -1559,8 +1601,10 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
rc = copy_all_packets( fp, newfp );
|
||||
if( rc != -1 ) {
|
||||
log_error("%s: copy to `%s' failed: %s\n",
|
||||
fname, tmpfname, gpg_strerror (rc) );
|
||||
fname, tmpfname, g10_errstr(rc) );
|
||||
iobuf_close(fp);
|
||||
if (secret)
|
||||
unregister_secured_file (tmpfname);
|
||||
iobuf_cancel(newfp);
|
||||
goto leave;
|
||||
}
|
||||
@ -1582,7 +1626,7 @@ do_copy (int mode, const char *fname, KBNODE root, int secret,
|
||||
rc = rename_tmp_file (bakfname, tmpfname, fname, secret);
|
||||
|
||||
leave:
|
||||
xfree (bakfname);
|
||||
xfree (tmpfname);
|
||||
xfree(bakfname);
|
||||
xfree(tmpfname);
|
||||
return rc;
|
||||
}
|
||||
|
@ -15,14 +15,13 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef GPG_KEYRING_H
|
||||
#define GPG_KEYRING_H 1
|
||||
|
||||
#include "global.h"
|
||||
|
||||
|
||||
typedef struct keyring_handle *KEYRING_HANDLE;
|
||||
|
||||
@ -41,6 +40,6 @@ int keyring_delete_keyblock (KEYRING_HANDLE hd);
|
||||
int keyring_search_reset (KEYRING_HANDLE hd);
|
||||
int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
||||
size_t ndesc, size_t *descindex);
|
||||
int keyring_rebuild_cache (void *);
|
||||
int keyring_rebuild_cache (void *token,int noisy);
|
||||
|
||||
#endif /*GPG_KEYRING_H*/
|
||||
|
@ -1,4 +1,23 @@
|
||||
/* Keyserver internals */
|
||||
/* keyserver-internal.h - Keyserver internals
|
||||
* Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef _KEYSERVER_INTERNAL_H_
|
||||
#define _KEYSERVER_INTERNAL_H_
|
||||
@ -8,14 +27,28 @@
|
||||
#include "../common/iobuf.h"
|
||||
#include "types.h"
|
||||
|
||||
void parse_keyserver_options(char *options);
|
||||
int parse_keyserver_uri(char *uri,
|
||||
const char *configname,unsigned int configlineno);
|
||||
int parse_keyserver_options(char *options);
|
||||
void free_keyserver_spec(struct keyserver_spec *keyserver);
|
||||
struct keyserver_spec *keyserver_match(struct keyserver_spec *spec);
|
||||
struct keyserver_spec *parse_keyserver_uri(const char *string,
|
||||
int require_scheme,
|
||||
const char *configname,
|
||||
unsigned int configlineno);
|
||||
struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig);
|
||||
int keyserver_export(STRLIST users);
|
||||
int keyserver_import(STRLIST users);
|
||||
int keyserver_import_fprint(const byte *fprint,size_t fprint_len);
|
||||
int keyserver_import_keyid(u32 *keyid);
|
||||
int keyserver_import_fprint(const byte *fprint,size_t fprint_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver);
|
||||
int keyserver_refresh(STRLIST users);
|
||||
int keyserver_search(STRLIST tokens);
|
||||
int keyserver_fetch(STRLIST urilist);
|
||||
int keyserver_import_cert(const char *name,
|
||||
unsigned char **fpr,size_t *fpr_len);
|
||||
int keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len);
|
||||
int keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver);
|
||||
int keyserver_import_ldap(const char *name,
|
||||
unsigned char **fpr,size_t *fpr_len);
|
||||
|
||||
#endif /* !_KEYSERVER_INTERNAL_H_ */
|
||||
|
1322
g10/keyserver.c
1322
g10/keyserver.c
File diff suppressed because it is too large
Load Diff
150
g10/main.h
150
g10/main.h
@ -1,5 +1,6 @@
|
||||
/* main.h
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,28 +16,36 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef G10_MAIN_H
|
||||
#define G10_MAIN_H
|
||||
|
||||
#include "types.h"
|
||||
#include "gpg.h"
|
||||
#include "../common/iobuf.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
#include "keydb.h"
|
||||
|
||||
/* It could be argued that the default cipher should be 3DES rather
|
||||
than CAST5, and the default compression should be 0
|
||||
(i.e. uncompressed) rather than 1 (zip). */
|
||||
#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_CAST5
|
||||
#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_SHA1
|
||||
#define DEFAULT_COMPRESS_ALGO 1
|
||||
(i.e. uncompressed) rather than 1 (zip). However, the real world
|
||||
issues of speed and size come into play here. */
|
||||
|
||||
typedef struct {
|
||||
int header_okay;
|
||||
PK_LIST pk_list;
|
||||
cipher_filter_context_t cfx;
|
||||
#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_CAST5
|
||||
#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_SHA1
|
||||
#define DEFAULT_COMPRESS_ALGO COMPRESS_ALGO_ZIP
|
||||
#define DEFAULT_S2K_DIGEST_ALGO DIGEST_ALGO_SHA1
|
||||
|
||||
#define S2K_DIGEST_ALGO (opt.s2k_digest_algo?opt.s2k_digest_algo:DEFAULT_S2K_DIGEST_ALGO)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int header_okay;
|
||||
PK_LIST pk_list;
|
||||
DEK *symkey_dek;
|
||||
STRING2KEY *symkey_s2k;
|
||||
cipher_filter_context_t cfx;
|
||||
} encrypt_filter_context_t;
|
||||
|
||||
struct groupitem
|
||||
@ -46,7 +55,7 @@ struct groupitem
|
||||
struct groupitem *next;
|
||||
};
|
||||
|
||||
/*-- g10.c --*/
|
||||
/*-- gpg.c --*/
|
||||
extern int g10_errors_seen;
|
||||
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
|
||||
@ -64,18 +73,19 @@ char *make_radix64_string( const byte *data, size_t len );
|
||||
/*-- misc.c --*/
|
||||
void trap_unaligned(void);
|
||||
int disable_core_dumps(void);
|
||||
void register_secured_file (const char *fname);
|
||||
void unregister_secured_file (const char *fname);
|
||||
int is_secured_file (int fd);
|
||||
int is_secured_filename (const char *fname);
|
||||
u16 checksum_u16( unsigned n );
|
||||
u16 checksum( byte *p, unsigned n );
|
||||
u16 checksum_mpi( gcry_mpi_t a );
|
||||
u32 buffer_to_u32( const byte *buffer );
|
||||
const byte *get_session_marker( size_t *rlen );
|
||||
int openpgp_cipher_test_algo( int algo );
|
||||
int openpgp_pk_test_algo( int algo, unsigned int usage_flags );
|
||||
int openpgp_pk_test_algo( int algo );
|
||||
int openpgp_pk_algo_usage ( int algo );
|
||||
int openpgp_md_test_algo( int algo );
|
||||
int openpgp_md_map_name (const char *string);
|
||||
int openpgp_cipher_map_name (const char *string);
|
||||
int openpgp_pk_map_name (const char *string);
|
||||
|
||||
#ifdef USE_IDEA
|
||||
void idea_cipher_warn( int show );
|
||||
@ -91,9 +101,10 @@ struct expando_args
|
||||
};
|
||||
|
||||
char *pct_expando(const char *string,struct expando_args *args);
|
||||
int hextobyte( const char *s );
|
||||
void deprecated_warning(const char *configname,unsigned int configlineno,
|
||||
const char *option,const char *repl1,const char *repl2);
|
||||
void deprecated_command (const char *name);
|
||||
|
||||
const char *compress_algo_to_string(int algo);
|
||||
int string_to_compress_algo(const char *string);
|
||||
int check_compress_algo(int algo);
|
||||
@ -106,10 +117,19 @@ struct parse_options
|
||||
{
|
||||
char *name;
|
||||
unsigned int bit;
|
||||
char **value;
|
||||
char *help;
|
||||
};
|
||||
|
||||
int parse_options(char *str,unsigned int *options,struct parse_options *opts);
|
||||
|
||||
char *optsep(char **stringp);
|
||||
char *argsplit(char *string);
|
||||
int parse_options(char *str,unsigned int *options,
|
||||
struct parse_options *opts,int noisy);
|
||||
char *unescape_percent_string (const unsigned char *s);
|
||||
int has_invalid_email_chars (const char *s);
|
||||
int is_valid_mailbox (const char *name);
|
||||
const char *get_libexecdir (void);
|
||||
int path_access(const char *file,int mode);
|
||||
|
||||
/* Temporary helpers. */
|
||||
int pubkey_get_npkey( int algo );
|
||||
@ -117,31 +137,24 @@ int pubkey_get_nskey( int algo );
|
||||
int pubkey_get_nsig( int algo );
|
||||
int pubkey_get_nenc( int algo );
|
||||
unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey );
|
||||
|
||||
/* MPI helpers. */
|
||||
int mpi_write( iobuf_t out, gcry_mpi_t a );
|
||||
int mpi_write_opaque( iobuf_t out, gcry_mpi_t a );
|
||||
gcry_mpi_t mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure );
|
||||
gcry_mpi_t mpi_read_opaque(iobuf_t inp, unsigned int *ret_nread );
|
||||
int mpi_print( FILE *fp, gcry_mpi_t a, int mode );
|
||||
|
||||
|
||||
|
||||
|
||||
/*-- helptext.c --*/
|
||||
void display_online_help( const char *keyword );
|
||||
|
||||
/*-- encode.c --*/
|
||||
int setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
||||
int encode_symmetric( const char *filename );
|
||||
int encode_store( const char *filename );
|
||||
int encode_crypt( const char *filename, STRLIST remusr );
|
||||
int encode_crypt( const char *filename, STRLIST remusr, int use_symkey );
|
||||
void encode_crypt_files(int nfiles, char **files, STRLIST remusr);
|
||||
int encrypt_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len);
|
||||
|
||||
|
||||
/*-- sign.c --*/
|
||||
int complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md );
|
||||
int complete_sig( PKT_signature *sig, PKT_secret_key *sk, gcry_md_hd_t md );
|
||||
int sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
int do_encrypt, STRLIST remusr, const char *outfile );
|
||||
int clearsign_file( const char *fname, STRLIST locusr, const char *outfile );
|
||||
@ -149,31 +162,43 @@ int sign_symencrypt_file (const char *fname, STRLIST locusr);
|
||||
|
||||
/*-- sig-check.c --*/
|
||||
int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig);
|
||||
int check_backsig(PKT_public_key *main_pk,PKT_public_key *sub_pk,
|
||||
PKT_signature *backsig);
|
||||
int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );
|
||||
int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
PKT_public_key *ret_pk, int *is_selfsig,
|
||||
u32 *r_expiredate, int *r_expired );
|
||||
PKT_public_key *ret_pk, int *is_selfsig,
|
||||
u32 *r_expiredate, int *r_expired );
|
||||
|
||||
/*-- delkey.c --*/
|
||||
int delete_keys( STRLIST names, int secret, int allow_both );
|
||||
|
||||
/*-- keyedit.c --*/
|
||||
void keyedit_menu( const char *username, STRLIST locusr, STRLIST cmds,
|
||||
int sign_mode );
|
||||
void keyedit_menu( const char *username, STRLIST locusr,
|
||||
STRLIST commands, int quiet, int seckey_check );
|
||||
void show_basic_key_info (KBNODE keyblock);
|
||||
|
||||
/*-- keygen.c --*/
|
||||
u32 ask_expire_interval(int object);
|
||||
u32 parse_expire_string(const char *string);
|
||||
u32 ask_expire_interval(int object,const char *def_expire);
|
||||
u32 ask_expiredate(void);
|
||||
void generate_keypair( const char *fname, const char *card_serialno );
|
||||
void generate_keypair( const char *fname, const char *card_serialno,
|
||||
const char *backup_encryption_dir );
|
||||
int keygen_set_std_prefs (const char *string,int personal);
|
||||
PKT_user_id *keygen_get_std_prefs (void);
|
||||
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
|
||||
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
|
||||
int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
|
||||
int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
|
||||
int keygen_add_notations(PKT_signature *sig,void *opaque);
|
||||
int keygen_add_revkey(PKT_signature *sig, void *opaque);
|
||||
int make_backsig(PKT_signature *sig,PKT_public_key *pk,
|
||||
PKT_public_key *sub_pk,PKT_secret_key *sub_sk);
|
||||
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
|
||||
int keyno, const char *serialno);
|
||||
int save_unprotected_key_to_card (PKT_secret_key *sk, int keyno);
|
||||
#endif
|
||||
|
||||
/*-- openfile.c --*/
|
||||
int overwrite_filep( const char *fname );
|
||||
@ -185,29 +210,29 @@ void try_make_homedir( const char *fname );
|
||||
|
||||
/*-- seskey.c --*/
|
||||
void make_session_key( DEK *dek );
|
||||
gcry_mpi_t encode_session_key( DEK *dek, unsigned int nbits);
|
||||
gcry_mpi_t encode_md_value( int pubkey_algo, MD_HANDLE md,
|
||||
int hash_algo, unsigned nbits, int v3compathack );
|
||||
|
||||
/*-- comment.c --*/
|
||||
KBNODE make_comment_node_from_buffer (const char *s, size_t n);
|
||||
KBNODE make_comment_node( const char *s );
|
||||
KBNODE make_mpi_comment_node( const char *s, gcry_mpi_t a );
|
||||
gcry_mpi_t encode_session_key( DEK *dek, unsigned nbits );
|
||||
gcry_mpi_t encode_md_value( PKT_public_key *pk, PKT_secret_key *sk,
|
||||
gcry_md_hd_t md, int hash_algo );
|
||||
|
||||
/*-- import.c --*/
|
||||
int parse_import_options(char *str,unsigned int *options);
|
||||
int parse_import_options(char *str,unsigned int *options,int noisy);
|
||||
void import_keys( char **fnames, int nnames,
|
||||
void *stats_hd, unsigned int options );
|
||||
int import_keys_stream( iobuf_t inp,
|
||||
void *stats_hd, unsigned int options );
|
||||
int import_keys_stream( iobuf_t inp,void *stats_hd,unsigned char **fpr,
|
||||
size_t *fpr_len,unsigned int options );
|
||||
void *import_new_stats_handle (void);
|
||||
void import_release_stats_handle (void *p);
|
||||
void import_print_stats (void *hd);
|
||||
|
||||
int collapse_uids( KBNODE *keyblock );
|
||||
|
||||
int auto_create_card_key_stub ( const char *serialnostr,
|
||||
const unsigned char *fpr1,
|
||||
const unsigned char *fpr2,
|
||||
const unsigned char *fpr3);
|
||||
|
||||
/*-- export.c --*/
|
||||
int parse_export_options(char *str,unsigned int *options);
|
||||
int parse_export_options(char *str,unsigned int *options,int noisy);
|
||||
int export_pubkeys( STRLIST users, unsigned int options );
|
||||
int export_pubkeys_stream( iobuf_t out, STRLIST users,
|
||||
KBNODE *keyblock_out, unsigned int options );
|
||||
@ -221,7 +246,7 @@ int enarmor_file( const char *fname );
|
||||
/*-- revoke.c --*/
|
||||
struct revocation_reason_info;
|
||||
int gen_revoke( const char *uname );
|
||||
int gen_desig_revoke( const char *uname );
|
||||
int gen_desig_revoke( const char *uname, STRLIST locusr);
|
||||
int revocation_reason_build_cb( PKT_signature *sig, void *opaque );
|
||||
struct revocation_reason_info *
|
||||
ask_revocation_reason( int key_rev, int cert_rev, int hint );
|
||||
@ -230,17 +255,20 @@ void release_revocation_reason_info( struct revocation_reason_info *reason );
|
||||
/*-- keylist.c --*/
|
||||
void public_key_list( STRLIST list );
|
||||
void secret_key_list( STRLIST list );
|
||||
void print_subpackets_colon(PKT_signature *sig);
|
||||
void reorder_keyblock (KBNODE keyblock);
|
||||
void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
|
||||
void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode);
|
||||
void print_revokers(PKT_public_key *pk);
|
||||
void show_policy_url(PKT_signature *sig,int indent,int mode);
|
||||
void show_keyserver_url(PKT_signature *sig,int indent,int mode);
|
||||
void show_notation(PKT_signature *sig,int indent,int mode);
|
||||
void show_notation(PKT_signature *sig,int indent,int mode,int which);
|
||||
void dump_attribs(const PKT_user_id *uid,
|
||||
PKT_public_key *pk,PKT_secret_key *sk);
|
||||
void set_attrib_fd(int fd);
|
||||
void print_seckey_info (PKT_secret_key *sk);
|
||||
void print_pubkey_info (FILE *fp, PKT_public_key *pk);
|
||||
void print_card_key_info (FILE *fp, KBNODE keyblock);
|
||||
|
||||
/*-- verify.c --*/
|
||||
void print_file_status( int status, const char *name, int what );
|
||||
@ -249,24 +277,26 @@ int verify_files( int nfiles, char **files );
|
||||
|
||||
/*-- decrypt.c --*/
|
||||
int decrypt_message( const char *filename );
|
||||
void decrypt_messages(int nfiles, char **files);
|
||||
void decrypt_messages(int nfiles, char *files[]);
|
||||
|
||||
/*-- plaintext.c --*/
|
||||
int hash_datafiles( MD_HANDLE md, MD_HANDLE md2,
|
||||
int hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2,
|
||||
STRLIST files, const char *sigfilename, int textmode );
|
||||
|
||||
/*-- pipemode.c --*/
|
||||
void run_in_pipemode (void);
|
||||
|
||||
/*-- card-util.c --*/
|
||||
void change_pin (int no, int allow_admin);
|
||||
void card_status (FILE *fp, char *serialnobuf, size_t serialnobuflen);
|
||||
void card_edit (STRLIST commands);
|
||||
|
||||
/*-- signal.c --*/
|
||||
void init_signals(void);
|
||||
void pause_on_sigusr( int which );
|
||||
void block_all_signals(void);
|
||||
void unblock_all_signals(void);
|
||||
|
||||
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
/*-- card-util.c --*/
|
||||
void change_pin (int no, int allow_admin);
|
||||
void card_status (FILE *fp, char *serialno, size_t serialnobuflen);
|
||||
void card_edit (STRLIST commands);
|
||||
int card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
|
||||
int card_store_subkey (KBNODE node, int use);
|
||||
#endif
|
||||
|
||||
#endif /*G10_MAIN_H*/
|
||||
|
1303
g10/mainproc.c
1303
g10/mainproc.c
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -25,9 +26,9 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
|
||||
@ -38,7 +39,7 @@
|
||||
*/
|
||||
int
|
||||
md_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
size_t size = *ret_len;
|
||||
md_filter_context_t *mfx = opaque;
|
||||
@ -67,8 +68,8 @@ md_filter( void *opaque, int control,
|
||||
void
|
||||
free_md_filter_context( md_filter_context_t *mfx )
|
||||
{
|
||||
gcry_md_close (mfx->md);
|
||||
gcry_md_close (mfx->md2);
|
||||
gcry_md_close(mfx->md);
|
||||
gcry_md_close(mfx->md2);
|
||||
mfx->md = NULL;
|
||||
mfx->md2 = NULL;
|
||||
mfx->maxbuf_size = 0;
|
||||
|
1045
g10/misc.c
1045
g10/misc.c
File diff suppressed because it is too large
Load Diff
113
g10/openfile.c
113
g10/openfile.c
@ -1,5 +1,6 @@
|
||||
/* openfile.c
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -31,7 +33,6 @@
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "ttyio.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
@ -66,8 +67,8 @@
|
||||
int
|
||||
overwrite_filep( const char *fname )
|
||||
{
|
||||
if( !fname || (*fname == '-' && !fname[1]) )
|
||||
return 1; /* writing to stdout is always okay */
|
||||
if( iobuf_is_pipe_filename (fname) )
|
||||
return 1; /* Writing to stdout is always okay */
|
||||
|
||||
if( access( fname, F_OK ) )
|
||||
return 1; /* does not exist */
|
||||
@ -84,8 +85,10 @@ overwrite_filep( const char *fname )
|
||||
return 0; /* do not overwrite */
|
||||
|
||||
tty_printf(_("File `%s' exists. "), fname);
|
||||
if( cpr_enabled () )
|
||||
tty_printf ("\n");
|
||||
if( cpr_get_answer_is_yes("openfile.overwrite.okay",
|
||||
_("Overwrite (y/N)? ")) )
|
||||
_("Overwrite? (y/N) ")) )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -100,20 +103,20 @@ make_outfile_name( const char *iname )
|
||||
{
|
||||
size_t n;
|
||||
|
||||
if( (!iname || (*iname=='-' && !iname[1]) ))
|
||||
return xstrdup ("-");
|
||||
if ( iobuf_is_pipe_filename (iname) )
|
||||
return xstrdup("-");
|
||||
|
||||
n = strlen(iname);
|
||||
if( n > 4 && ( !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg")
|
||||
|| !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
|
||||
|| !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
|
||||
|| !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) {
|
||||
char *buf = xstrdup ( iname );
|
||||
char *buf = xstrdup( iname );
|
||||
buf[n-4] = 0;
|
||||
return buf;
|
||||
}
|
||||
else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) {
|
||||
char *buf = xstrdup ( iname );
|
||||
char *buf = xstrdup( iname );
|
||||
buf[n-5] = 0;
|
||||
return buf;
|
||||
}
|
||||
@ -144,19 +147,21 @@ ask_outfile_name( const char *name, size_t namelen )
|
||||
|
||||
n = strlen(s) + namelen + 10;
|
||||
defname = name && namelen? make_printable_string( name, namelen, 0): NULL;
|
||||
prompt = xmalloc (n);
|
||||
prompt = xmalloc(n);
|
||||
if( defname )
|
||||
sprintf(prompt, "%s [%s]: ", s, defname );
|
||||
else
|
||||
sprintf(prompt, "%s: ", s );
|
||||
tty_enable_completion(NULL);
|
||||
fname = cpr_get("openfile.askoutname", prompt );
|
||||
cpr_kill_prompt();
|
||||
xfree (prompt);
|
||||
tty_disable_completion();
|
||||
xfree(prompt);
|
||||
if( !*fname ) {
|
||||
xfree ( fname ); fname = NULL;
|
||||
xfree( fname ); fname = NULL;
|
||||
fname = defname; defname = NULL;
|
||||
}
|
||||
xfree (defname);
|
||||
xfree(defname);
|
||||
if (fname)
|
||||
trim_spaces (fname);
|
||||
return fname;
|
||||
@ -165,21 +170,22 @@ ask_outfile_name( const char *name, size_t namelen )
|
||||
|
||||
/****************
|
||||
* Make an output filename for the inputfile INAME.
|
||||
* Returns an iobuf_t and an errorcode
|
||||
* Returns an IOBUF and an errorcode
|
||||
* Mode 0 = use ".gpg"
|
||||
* 1 = use ".asc"
|
||||
* 2 = use ".sig"
|
||||
*/
|
||||
int
|
||||
open_outfile( const char *iname, int mode, iobuf_t *a )
|
||||
open_outfile( const char *iname, int mode, IOBUF *a )
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
*a = NULL;
|
||||
if( (!iname || (*iname=='-' && !iname[1])) && !opt.outfile ) {
|
||||
if( !(*a = iobuf_create(NULL)) ) {
|
||||
if( iobuf_is_pipe_filename (iname) && !opt.outfile ) {
|
||||
*a = iobuf_create(NULL);
|
||||
if( !*a ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error(_("%s: can't open: %s\n"), "[stdout]", strerror(errno) );
|
||||
log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
|
||||
}
|
||||
else if( opt.verbose )
|
||||
log_info(_("writing to stdout\n"));
|
||||
@ -207,7 +213,7 @@ open_outfile( const char *iname, int mode, iobuf_t *a )
|
||||
const char *newsfx = mode==1 ? ".asc" :
|
||||
mode==2 ? ".sig" : ".gpg";
|
||||
|
||||
buf = xmalloc (strlen(iname)+4+1);
|
||||
buf = xmalloc(strlen(iname)+4+1);
|
||||
strcpy(buf,iname);
|
||||
dot = strchr(buf, '.' );
|
||||
if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
|
||||
@ -223,7 +229,7 @@ open_outfile( const char *iname, int mode, iobuf_t *a )
|
||||
if (!buf)
|
||||
#endif /* USE_ONLY_8DOT3 */
|
||||
{
|
||||
buf = xmalloc (strlen(iname)+4+1);
|
||||
buf = xmalloc(strlen(iname)+4+1);
|
||||
strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
|
||||
mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
|
||||
}
|
||||
@ -237,7 +243,7 @@ open_outfile( const char *iname, int mode, iobuf_t *a )
|
||||
if ( !tmp || !*tmp )
|
||||
{
|
||||
xfree (tmp);
|
||||
rc = GPG_ERR_EEXIST;
|
||||
rc = gpg_error (GPG_ERR_EEXIST);
|
||||
break;
|
||||
}
|
||||
xfree (buf);
|
||||
@ -246,17 +252,27 @@ open_outfile( const char *iname, int mode, iobuf_t *a )
|
||||
|
||||
if( !rc )
|
||||
{
|
||||
if( !(*a = iobuf_create( name )) )
|
||||
if (is_secured_filename (name) )
|
||||
{
|
||||
*a = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
else
|
||||
*a = iobuf_create( name );
|
||||
if( !*a )
|
||||
{
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error(_("%s: can't create: %s\n"), name, strerror(errno) );
|
||||
log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
|
||||
}
|
||||
else if( opt.verbose )
|
||||
log_info(_("writing to `%s'\n"), name );
|
||||
}
|
||||
xfree (buf);
|
||||
xfree(buf);
|
||||
}
|
||||
|
||||
if (*a)
|
||||
iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -265,26 +281,32 @@ open_outfile( const char *iname, int mode, iobuf_t *a )
|
||||
* Try to open a file without the extension ".sig" or ".asc"
|
||||
* Return NULL if such a file is not available.
|
||||
*/
|
||||
iobuf_t
|
||||
IOBUF
|
||||
open_sigfile( const char *iname, progress_filter_context_t *pfx )
|
||||
{
|
||||
iobuf_t a = NULL;
|
||||
IOBUF a = NULL;
|
||||
size_t len;
|
||||
|
||||
if( iname && !(*iname == '-' && !iname[1]) ) {
|
||||
if( !iobuf_is_pipe_filename (iname) ) {
|
||||
len = strlen(iname);
|
||||
if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig")
|
||||
|| ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") )
|
||||
|| !strcmp(iname + len - 4, EXTSEP_S "asc")) ) {
|
||||
char *buf;
|
||||
buf = xstrdup (iname);
|
||||
buf = xstrdup(iname);
|
||||
buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
|
||||
a = iobuf_open( buf );
|
||||
if (a && is_secured_file (iobuf_get_fd (a)))
|
||||
{
|
||||
iobuf_close (a);
|
||||
a = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( a && opt.verbose )
|
||||
log_info(_("assuming signed data in `%s'\n"), buf );
|
||||
if (a && pfx)
|
||||
handle_progress (pfx, a, buf);
|
||||
xfree (buf);
|
||||
xfree(buf);
|
||||
}
|
||||
}
|
||||
return a;
|
||||
@ -308,23 +330,34 @@ copy_options_file( const char *destdir )
|
||||
if( opt.dry_run )
|
||||
return;
|
||||
|
||||
fname = xmalloc ( strlen(datadir) + strlen(destdir)
|
||||
+ strlen (SKELEXT) + 15 );
|
||||
fname = xmalloc( strlen(datadir) + strlen(destdir) + 15 );
|
||||
strcpy(stpcpy(fname, datadir), DIRSEP_S "gpg-conf" SKELEXT );
|
||||
src = fopen( fname, "r" );
|
||||
if (src && is_secured_file (fileno (src)))
|
||||
{
|
||||
fclose (src);
|
||||
src = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !src ) {
|
||||
log_error(_("%s: can't open: %s\n"), fname, strerror(errno) );
|
||||
xfree (fname);
|
||||
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
|
||||
xfree(fname);
|
||||
return;
|
||||
}
|
||||
strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" );
|
||||
oldmask=umask(077);
|
||||
dst = fopen( fname, "w" );
|
||||
if ( is_secured_filename (fname) )
|
||||
{
|
||||
dst = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
else
|
||||
dst = fopen( fname, "w" );
|
||||
umask(oldmask);
|
||||
if( !dst ) {
|
||||
log_error(_("%s: can't create: %s\n"), fname, strerror(errno) );
|
||||
log_error(_("can't create `%s': %s\n"), fname, strerror(errno) );
|
||||
fclose( src );
|
||||
xfree (fname);
|
||||
xfree(fname);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -354,7 +387,7 @@ copy_options_file( const char *destdir )
|
||||
log_info (_("WARNING: options in `%s'"
|
||||
" are not yet active during this run\n"),
|
||||
fname);
|
||||
xfree (fname);
|
||||
xfree(fname);
|
||||
}
|
||||
|
||||
|
||||
@ -380,10 +413,10 @@ try_make_homedir( const char *fname )
|
||||
&& !compare_filenames( fname, defhome ) )
|
||||
) {
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
log_fatal( _("%s: can't create directory: %s\n"),
|
||||
log_fatal( _("can't create directory `%s': %s\n"),
|
||||
fname, strerror(errno) );
|
||||
else if( !opt.quiet )
|
||||
log_info( _("%s: directory created\n"), fname );
|
||||
log_info( _("directory `%s' created\n"), fname );
|
||||
copy_options_file( fname );
|
||||
/* log_info(_("you have to start GnuPG again, " */
|
||||
/* "so it can read the new configuration file\n") ); */
|
||||
|
440
g10/options.h
440
g10/options.h
@ -1,6 +1,6 @@
|
||||
/* options.h
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,17 +16,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef G10_OPTIONS_H
|
||||
#define G10_OPTIONS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <types.h>
|
||||
#include "main.h"
|
||||
#include "packet.h"
|
||||
|
||||
#undef ENABLE_COMMENT_PACKETS /* don't create comment packets */
|
||||
|
||||
#ifndef EXTERN_UNLESS_MAIN_MODULE
|
||||
/* Norcraft can't cope with common symbols */
|
||||
#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
|
||||
@ -37,155 +37,215 @@
|
||||
#endif
|
||||
|
||||
EXTERN_UNLESS_MAIN_MODULE
|
||||
struct {
|
||||
int verbose;
|
||||
int quiet;
|
||||
unsigned debug;
|
||||
int armor;
|
||||
int compress;
|
||||
char *outfile;
|
||||
int dry_run;
|
||||
int list_only;
|
||||
int textmode;
|
||||
int expert;
|
||||
int ask_sig_expire;
|
||||
int ask_cert_expire;
|
||||
int batch; /* run in batch mode */
|
||||
int answer_yes; /* answer yes on most questions */
|
||||
int answer_no; /* answer no on most questions */
|
||||
int check_sigs; /* check key signatures */
|
||||
int with_colons;
|
||||
int with_key_data;
|
||||
int with_fingerprint; /* opt --with-fingerprint active */
|
||||
int fingerprint; /* list fingerprints */
|
||||
int list_sigs; /* list signatures */
|
||||
int no_armor;
|
||||
int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/
|
||||
int def_cipher_algo;
|
||||
int force_v3_sigs;
|
||||
int force_v4_certs;
|
||||
int force_mdc;
|
||||
int disable_mdc;
|
||||
int def_digest_algo;
|
||||
int cert_digest_algo;
|
||||
int def_compress_algo;
|
||||
const char *def_secret_key;
|
||||
char *def_recipient;
|
||||
int def_recipient_self;
|
||||
int def_cert_check_level;
|
||||
int sk_comments;
|
||||
int no_version;
|
||||
int marginals_needed;
|
||||
int completes_needed;
|
||||
int max_cert_depth;
|
||||
const char *homedir;
|
||||
const char *agent_program;
|
||||
char *display; /* 5 options to be passed to the gpg-agent */
|
||||
char *ttyname;
|
||||
char *ttytype;
|
||||
char *lc_ctype;
|
||||
char *lc_messages;
|
||||
struct
|
||||
{
|
||||
int verbose;
|
||||
int quiet;
|
||||
unsigned debug;
|
||||
int armor;
|
||||
char *outfile;
|
||||
off_t max_output;
|
||||
int dry_run;
|
||||
int list_only;
|
||||
int textmode;
|
||||
int expert;
|
||||
const char *def_sig_expire;
|
||||
int ask_sig_expire;
|
||||
const char *def_cert_expire;
|
||||
int ask_cert_expire;
|
||||
int batch; /* run in batch mode */
|
||||
int answer_yes; /* answer yes on most questions */
|
||||
int answer_no; /* answer no on most questions */
|
||||
int check_sigs; /* check key signatures */
|
||||
int with_colons;
|
||||
int with_key_data;
|
||||
int with_fingerprint; /* opt --with-fingerprint active */
|
||||
int fingerprint; /* list fingerprints */
|
||||
int list_sigs; /* list signatures */
|
||||
int no_armor;
|
||||
int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/
|
||||
int def_cipher_algo;
|
||||
int force_v3_sigs;
|
||||
int force_v4_certs;
|
||||
int force_mdc;
|
||||
int disable_mdc;
|
||||
int def_digest_algo;
|
||||
int cert_digest_algo;
|
||||
int compress_algo;
|
||||
int compress_level;
|
||||
int bz2_compress_level;
|
||||
int bz2_decompress_lowmem;
|
||||
const char *def_secret_key;
|
||||
char *def_recipient;
|
||||
int def_recipient_self;
|
||||
int def_cert_level;
|
||||
int min_cert_level;
|
||||
int ask_cert_level;
|
||||
int no_version;
|
||||
int marginals_needed;
|
||||
int completes_needed;
|
||||
int max_cert_depth;
|
||||
const char *homedir;
|
||||
const char *agent_program;
|
||||
char *display; /* 5 options to be passed to the gpg-agent */
|
||||
char *ttyname;
|
||||
char *ttytype;
|
||||
char *lc_ctype;
|
||||
char *lc_messages;
|
||||
|
||||
int skip_verify;
|
||||
int compress_keys;
|
||||
int compress_sigs;
|
||||
/* TM_CLASSIC must be zero to accomodate trustdbs generated before
|
||||
we started storing the trust model inside the trustdb. */
|
||||
enum {TM_CLASSIC=0, TM_PGP=1, TM_ALWAYS, TM_AUTO} trust_model;
|
||||
unsigned int force_ownertrust;
|
||||
enum
|
||||
{
|
||||
CO_GNUPG=0, CO_RFC2440, CO_RFC1991, CO_PGP2, CO_PGP6, CO_PGP7, CO_PGP8
|
||||
} compliance;
|
||||
int pgp2_workarounds;
|
||||
unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */
|
||||
int shm_coprocess;
|
||||
const char *set_filename;
|
||||
STRLIST comments;
|
||||
int throw_keyid;
|
||||
const char *photo_viewer;
|
||||
int s2k_mode;
|
||||
int s2k_digest_algo;
|
||||
int s2k_cipher_algo;
|
||||
int simple_sk_checksum; /* create the deprecated rfc2440 secret
|
||||
key protection*/
|
||||
int not_dash_escaped;
|
||||
int escape_from;
|
||||
int lock_once;
|
||||
char *keyserver_uri;
|
||||
char *keyserver_scheme;
|
||||
char *keyserver_host;
|
||||
char *keyserver_port;
|
||||
char *keyserver_opaque;
|
||||
int skip_verify;
|
||||
int compress_keys;
|
||||
int compress_sigs;
|
||||
/* TM_CLASSIC must be zero to accomodate trustdbs generated before
|
||||
we started storing the trust model inside the trustdb. */
|
||||
enum
|
||||
{
|
||||
TM_CLASSIC=0, TM_PGP=1, TM_EXTERNAL=2, TM_ALWAYS, TM_DIRECT, TM_AUTO
|
||||
} trust_model;
|
||||
int force_ownertrust;
|
||||
enum
|
||||
{
|
||||
CO_GNUPG=0, CO_RFC2440, CO_RFC1991, CO_PGP2, CO_PGP6, CO_PGP7, CO_PGP8
|
||||
} compliance;
|
||||
enum
|
||||
{
|
||||
KF_SHORT, KF_LONG, KF_0xSHORT, KF_0xLONG
|
||||
} keyid_format;
|
||||
int pgp2_workarounds;
|
||||
int shm_coprocess;
|
||||
const char *set_filename;
|
||||
STRLIST comments;
|
||||
int throw_keyid;
|
||||
const char *photo_viewer;
|
||||
int s2k_mode;
|
||||
int s2k_digest_algo;
|
||||
int s2k_cipher_algo;
|
||||
int simple_sk_checksum; /* create the deprecated rfc2440 secret
|
||||
key protection*/
|
||||
int not_dash_escaped;
|
||||
int escape_from;
|
||||
int lock_once;
|
||||
struct keyserver_spec
|
||||
{
|
||||
char *uri;
|
||||
char *scheme;
|
||||
char *auth;
|
||||
char *host;
|
||||
char *port;
|
||||
char *path;
|
||||
char *opaque;
|
||||
STRLIST options;
|
||||
struct
|
||||
{
|
||||
int verbose;
|
||||
int include_revoked;
|
||||
int include_disabled;
|
||||
int include_subkeys;
|
||||
int honor_http_proxy;
|
||||
int broken_http_proxy;
|
||||
int use_temp_files;
|
||||
int keep_temp_files;
|
||||
int fake_v3_keyids;
|
||||
int auto_key_retrieve;
|
||||
int try_dns_srv;
|
||||
unsigned int import_options;
|
||||
unsigned int export_options;
|
||||
STRLIST other;
|
||||
} keyserver_options;
|
||||
int exec_disable;
|
||||
int exec_path_set;
|
||||
unsigned int direct_uri:1;
|
||||
} flags;
|
||||
struct keyserver_spec *next;
|
||||
} *keyserver;
|
||||
struct
|
||||
{
|
||||
unsigned int options;
|
||||
unsigned int import_options;
|
||||
unsigned int export_options;
|
||||
unsigned int list_options;
|
||||
unsigned int verify_options;
|
||||
char *def_preference_list;
|
||||
prefitem_t *personal_cipher_prefs;
|
||||
prefitem_t *personal_digest_prefs;
|
||||
prefitem_t *personal_compress_prefs;
|
||||
int no_perm_warn;
|
||||
int no_mdc_warn;
|
||||
char *temp_dir;
|
||||
int no_encrypt_to;
|
||||
int interactive;
|
||||
STRLIST sig_notation_data;
|
||||
STRLIST cert_notation_data;
|
||||
STRLIST sig_policy_url;
|
||||
STRLIST cert_policy_url;
|
||||
STRLIST sig_keyserver_url;
|
||||
int use_embedded_filename;
|
||||
int allow_non_selfsigned_uid;
|
||||
int allow_freeform_uid;
|
||||
int no_literal;
|
||||
ulong set_filesize;
|
||||
int fast_list_mode;
|
||||
int fixed_list_mode;
|
||||
int ignore_time_conflict;
|
||||
int ignore_valid_from;
|
||||
int ignore_crc_error;
|
||||
int ignore_mdc_error;
|
||||
int command_fd;
|
||||
const char *override_session_key;
|
||||
int show_session_key;
|
||||
int use_agent;
|
||||
const char *gpg_agent_info;
|
||||
int merge_only;
|
||||
int try_all_secrets;
|
||||
int no_expensive_trust_checks;
|
||||
int no_sig_cache;
|
||||
int no_sig_create_check;
|
||||
int no_auto_check_trustdb;
|
||||
int preserve_permissions;
|
||||
int no_homedir_creation;
|
||||
struct groupitem *grouplist;
|
||||
int strict;
|
||||
int mangle_dos_filenames;
|
||||
int enable_progress_filter;
|
||||
STRLIST other;
|
||||
} keyserver_options;
|
||||
int exec_disable;
|
||||
int exec_path_set;
|
||||
unsigned int import_options;
|
||||
unsigned int export_options;
|
||||
unsigned int list_options;
|
||||
unsigned int verify_options;
|
||||
char *def_preference_list;
|
||||
prefitem_t *personal_cipher_prefs;
|
||||
prefitem_t *personal_digest_prefs;
|
||||
prefitem_t *personal_compress_prefs;
|
||||
int no_perm_warn;
|
||||
int no_mdc_warn;
|
||||
char *temp_dir;
|
||||
int no_encrypt_to;
|
||||
int interactive;
|
||||
struct notation *sig_notations;
|
||||
struct notation *cert_notations;
|
||||
STRLIST sig_policy_url;
|
||||
STRLIST cert_policy_url;
|
||||
STRLIST sig_keyserver_url;
|
||||
STRLIST cert_subpackets;
|
||||
STRLIST sig_subpackets;
|
||||
int use_embedded_filename;
|
||||
int allow_non_selfsigned_uid;
|
||||
int allow_freeform_uid;
|
||||
int no_literal;
|
||||
ulong set_filesize;
|
||||
int fast_list_mode;
|
||||
int fixed_list_mode;
|
||||
int ignore_time_conflict;
|
||||
int ignore_valid_from;
|
||||
int ignore_crc_error;
|
||||
int ignore_mdc_error;
|
||||
int command_fd;
|
||||
const char *override_session_key;
|
||||
int show_session_key;
|
||||
int use_agent;
|
||||
const char *gpg_agent_info;
|
||||
int try_all_secrets;
|
||||
int no_expensive_trust_checks;
|
||||
int no_sig_cache;
|
||||
int no_sig_create_check;
|
||||
int no_auto_check_trustdb;
|
||||
int preserve_permissions;
|
||||
int no_homedir_creation;
|
||||
struct groupitem *grouplist;
|
||||
int strict;
|
||||
int mangle_dos_filenames;
|
||||
int enable_progress_filter;
|
||||
unsigned int screen_columns;
|
||||
unsigned int screen_lines;
|
||||
byte *show_subpackets;
|
||||
int rfc2440_text;
|
||||
|
||||
/* If true, let write failures on the status-fd exit the process. */
|
||||
int exit_on_status_write_error;
|
||||
|
||||
/* If > 0, limit the number of card insertion prompts to this
|
||||
value. */
|
||||
int limit_card_insert_tries;
|
||||
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
/* FIXME: We don't needs this here as it is done in scdaemon. */
|
||||
const char *ctapi_driver; /* Library to access the ctAPI. */
|
||||
const char *pcsc_driver; /* Library to access the PC/SC system. */
|
||||
int disable_ccid; /* Disable the use of the internal CCID driver. */
|
||||
#endif /*ENABLE_CARD_SUPPORT*/
|
||||
|
||||
struct
|
||||
{
|
||||
/* If set, require an 0x19 backsig to be present on signatures
|
||||
made by signing subkeys. If not set, a missing backsig is not
|
||||
an error (but an invalid backsig still is). */
|
||||
unsigned int require_cross_cert:1;
|
||||
} flags;
|
||||
|
||||
/* Linked list of ways to find a key if the key isn't on the local
|
||||
keyring. */
|
||||
struct akl
|
||||
{
|
||||
enum {AKL_CERT, AKL_PKA, AKL_LDAP, AKL_KEYSERVER, AKL_SPEC} type;
|
||||
struct keyserver_spec *spec;
|
||||
struct akl *next;
|
||||
} *auto_key_locate;
|
||||
|
||||
/* True if multiple concatenated signatures may be verified. */
|
||||
int allow_multisig_verification;
|
||||
|
||||
} opt;
|
||||
|
||||
|
||||
#define EMUBUG_MDENCODE 4
|
||||
/* CTRL is used to keep some global variables we currently can't
|
||||
avoid. Future concurrent versions of gpg will put it into a per
|
||||
request structure CTRL. */
|
||||
EXTERN_UNLESS_MAIN_MODULE
|
||||
struct {
|
||||
int in_auto_key_retrieve; /* True if we are doing an
|
||||
auto_key_retrieve. */
|
||||
} glo_ctrl;
|
||||
|
||||
#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */
|
||||
#define DBG_MPI_VALUE 2 /* debug mpi details */
|
||||
@ -199,15 +259,24 @@ struct {
|
||||
#define DBG_TRUST_VALUE 256 /* debug the trustdb */
|
||||
#define DBG_HASHING_VALUE 512 /* debug hashing operations */
|
||||
#define DBG_EXTPROG_VALUE 1024 /* debug external program calls */
|
||||
|
||||
#define DBG_CARD_IO_VALUE 2048 /* debug smart card I/O. */
|
||||
|
||||
#define DBG_PACKET (opt.debug & DBG_PACKET_VALUE)
|
||||
#define DBG_CIPHER (opt.debug & DBG_CIPHER_VALUE)
|
||||
#define DBG_FILTER (opt.debug & DBG_FILTER_VALUE)
|
||||
#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
|
||||
#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE)
|
||||
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
||||
#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE)
|
||||
#define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE)
|
||||
|
||||
/* FIXME: We need to check whey we did not put this into opt. */
|
||||
#define DBG_MEMORY memory_debug_mode
|
||||
#define DBG_MEMSTAT memory_stat_debug_mode
|
||||
|
||||
EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode;
|
||||
EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
|
||||
|
||||
|
||||
|
||||
#define GNUPG (opt.compliance==CO_GNUPG)
|
||||
#define RFC1991 (opt.compliance==CO_RFC1991 || opt.compliance==CO_PGP2)
|
||||
@ -217,39 +286,54 @@ struct {
|
||||
#define PGP7 (opt.compliance==CO_PGP7)
|
||||
#define PGP8 (opt.compliance==CO_PGP8)
|
||||
|
||||
/* Various option flags */
|
||||
/* Various option flags. Note that there should be no common string
|
||||
names between the IMPORT_ and EXPORT_ flags as they can be mixed in
|
||||
the keyserver-options option. */
|
||||
|
||||
#define IMPORT_ALLOW_LOCAL_SIGS 1
|
||||
#define IMPORT_REPAIR_PKS_SUBKEY_BUG 2
|
||||
#define IMPORT_FAST_IMPORT 4
|
||||
#define IMPORT_SK2PK 8
|
||||
#define IMPORT_LOCAL_SIGS (1<<0)
|
||||
#define IMPORT_REPAIR_PKS_SUBKEY_BUG (1<<1)
|
||||
#define IMPORT_FAST (1<<2)
|
||||
#define IMPORT_SK2PK (1<<3)
|
||||
#define IMPORT_MERGE_ONLY (1<<4)
|
||||
#define IMPORT_MINIMAL (1<<5)
|
||||
#define IMPORT_CLEAN (1<<6)
|
||||
|
||||
#define EXPORT_INCLUDE_NON_RFC 1
|
||||
#define EXPORT_INCLUDE_LOCAL_SIGS 2
|
||||
#define EXPORT_INCLUDE_ATTRIBUTES 4
|
||||
#define EXPORT_INCLUDE_SENSITIVE_REVKEYS 8
|
||||
#define EXPORT_SEXP_FORMAT 16
|
||||
#define EXPORT_LOCAL_SIGS (1<<0)
|
||||
#define EXPORT_ATTRIBUTES (1<<1)
|
||||
#define EXPORT_SENSITIVE_REVKEYS (1<<2)
|
||||
#define EXPORT_RESET_SUBKEY_PASSWD (1<<3)
|
||||
#define EXPORT_MINIMAL (1<<4)
|
||||
#define EXPORT_CLEAN (1<<5)
|
||||
|
||||
#define LIST_SHOW_PHOTOS (1<<0)
|
||||
#define LIST_SHOW_POLICY_URLS (1<<1)
|
||||
#define LIST_SHOW_STD_NOTATIONS (1<<2)
|
||||
#define LIST_SHOW_USER_NOTATIONS (1<<3)
|
||||
#define LIST_SHOW_NOTATIONS (LIST_SHOW_STD_NOTATIONS|LIST_SHOW_USER_NOTATIONS)
|
||||
#define LIST_SHOW_KEYSERVER_URLS (1<<4)
|
||||
#define LIST_SHOW_UID_VALIDITY (1<<5)
|
||||
#define LIST_SHOW_UNUSABLE_UIDS (1<<6)
|
||||
#define LIST_SHOW_UNUSABLE_SUBKEYS (1<<7)
|
||||
#define LIST_SHOW_KEYRING (1<<8)
|
||||
#define LIST_SHOW_SIG_EXPIRE (1<<9)
|
||||
#define LIST_SHOW_SIG_SUBPACKETS (1<<10)
|
||||
|
||||
#define LIST_SHOW_PHOTOS 1
|
||||
#define LIST_SHOW_POLICY 2
|
||||
#define LIST_SHOW_NOTATION 4
|
||||
#define LIST_SHOW_KEYSERVER 8
|
||||
#define LIST_SHOW_VALIDITY 16
|
||||
#define LIST_SHOW_LONG_KEYID 32
|
||||
#define LIST_SHOW_KEYRING 64
|
||||
#define LIST_SHOW_SIG_EXPIRE 128
|
||||
#define VERIFY_SHOW_PHOTOS (1<<0)
|
||||
#define VERIFY_SHOW_POLICY_URLS (1<<1)
|
||||
#define VERIFY_SHOW_STD_NOTATIONS (1<<2)
|
||||
#define VERIFY_SHOW_USER_NOTATIONS (1<<3)
|
||||
#define VERIFY_SHOW_NOTATIONS (VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_USER_NOTATIONS)
|
||||
#define VERIFY_SHOW_KEYSERVER_URLS (1<<4)
|
||||
#define VERIFY_SHOW_UID_VALIDITY (1<<5)
|
||||
#define VERIFY_SHOW_UNUSABLE_UIDS (1<<6)
|
||||
#define VERIFY_PKA_LOOKUPS (1<<7)
|
||||
#define VERIFY_PKA_TRUST_INCREASE (1<<8)
|
||||
|
||||
|
||||
#define VERIFY_SHOW_PHOTOS 1
|
||||
#define VERIFY_SHOW_POLICY 2
|
||||
#define VERIFY_SHOW_NOTATION 4
|
||||
#define VERIFY_SHOW_KEYSERVER 8
|
||||
#define VERIFY_SHOW_VALIDITY 16
|
||||
#define VERIFY_SHOW_LONG_KEYID 32
|
||||
#define KEYSERVER_USE_TEMP_FILES (1<<0)
|
||||
#define KEYSERVER_KEEP_TEMP_FILES (1<<1)
|
||||
#define KEYSERVER_ADD_FAKE_V3 (1<<2)
|
||||
#define KEYSERVER_AUTO_KEY_RETRIEVE (1<<3)
|
||||
#define KEYSERVER_HONOR_KEYSERVER_URL (1<<4)
|
||||
#define KEYSERVER_HONOR_PKA_RECORD (1<<5)
|
||||
|
||||
#endif /*G10_OPTIONS_H*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
202
g10/packet.h
202
g10/packet.h
@ -1,6 +1,6 @@
|
||||
/* packet.h - packet definitions
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
/* packet.h - OpenPGP packet definitions
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,21 +16,18 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_PACKET_H
|
||||
#define G10_PACKET_H
|
||||
|
||||
#include "gpg.h"
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "../common/iobuf.h"
|
||||
#include "../jnlib/strlist.h"
|
||||
#include "cipher.h"
|
||||
#include "filter.h"
|
||||
#include "global.h"
|
||||
|
||||
#define DEBUG_PARSE_PACKET 1
|
||||
|
||||
@ -124,36 +121,56 @@ struct revocation_key {
|
||||
byte fpr[MAX_FINGERPRINT_LEN];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ulong local_id; /* internal use, valid if > 0 */
|
||||
struct {
|
||||
unsigned checked:1; /* signature has been checked */
|
||||
unsigned valid:1; /* signature is good (if checked is set) */
|
||||
unsigned unknown_critical:1;
|
||||
unsigned exportable:1;
|
||||
unsigned revocable:1;
|
||||
unsigned policy_url:1; /* At least one policy URL is present */
|
||||
unsigned notation:1; /* At least one notation is present */
|
||||
unsigned pref_ks:1; /* At least one preferred keyserver is present */
|
||||
unsigned expired:1;
|
||||
} flags;
|
||||
u32 keyid[2]; /* 64 bit keyid */
|
||||
u32 timestamp; /* signature made */
|
||||
u32 expiredate; /* expires at this date or 0 if not at all */
|
||||
byte version;
|
||||
byte sig_class; /* sig classification, append for MD calculation*/
|
||||
byte pubkey_algo; /* algorithm used for public key scheme */
|
||||
/* (PUBKEY_ALGO_xxx) */
|
||||
byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
|
||||
byte trust_depth;
|
||||
byte trust_value;
|
||||
const byte *trust_regexp;
|
||||
struct revocation_key **revkey;
|
||||
int numrevkeys;
|
||||
subpktarea_t *hashed; /* all subpackets with hashed data (v4 only) */
|
||||
subpktarea_t *unhashed; /* ditto for unhashed data */
|
||||
byte digest_start[2]; /* first 2 bytes of the digest */
|
||||
gcry_mpi_t data[PUBKEY_MAX_NSIG];
|
||||
|
||||
/* Object to keep information about a PKA DNS record. */
|
||||
typedef struct
|
||||
{
|
||||
int valid; /* An actual PKA record exists for EMAIL. */
|
||||
int checked; /* Set to true if the FPR has been checked against the
|
||||
actual key. */
|
||||
char *uri; /* Malloced string with the URI. NULL if the URI is
|
||||
not available.*/
|
||||
unsigned char fpr[20]; /* The fingerprint as stored in the PKA RR. */
|
||||
char email[1];/* The email address from the notation data. */
|
||||
} pka_info_t;
|
||||
|
||||
|
||||
/* Object to keep information pertaining to a signature. */
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned checked:1; /* Signature has been checked. */
|
||||
unsigned valid:1; /* Signature is good (if checked is set). */
|
||||
unsigned chosen_selfsig:1; /* A selfsig that is the chosen one. */
|
||||
unsigned unknown_critical:1;
|
||||
unsigned exportable:1;
|
||||
unsigned revocable:1;
|
||||
unsigned policy_url:1; /* At least one policy URL is present */
|
||||
unsigned notation:1; /* At least one notation is present */
|
||||
unsigned pref_ks:1; /* At least one preferred keyserver is present */
|
||||
unsigned expired:1;
|
||||
unsigned pka_tried:1; /* Set if we tried to retrieve the PKA record. */
|
||||
} flags;
|
||||
u32 keyid[2]; /* 64 bit keyid */
|
||||
u32 timestamp; /* Signature made (seconds since Epoch). */
|
||||
u32 expiredate; /* Expires at this date or 0 if not at all. */
|
||||
byte version;
|
||||
byte sig_class; /* Sig classification, append for MD calculation. */
|
||||
byte pubkey_algo; /* Algorithm used for public key scheme */
|
||||
/* (PUBKEY_ALGO_xxx) */
|
||||
byte digest_algo; /* Algorithm used for digest (DIGEST_ALGO_xxxx). */
|
||||
byte trust_depth;
|
||||
byte trust_value;
|
||||
const byte *trust_regexp;
|
||||
struct revocation_key **revkey;
|
||||
int numrevkeys;
|
||||
pka_info_t *pka_info; /* Malloced PKA data or NULL if not
|
||||
available. See also flags.pka_tried. */
|
||||
subpktarea_t *hashed; /* All subpackets with hashed data (v4 only). */
|
||||
subpktarea_t *unhashed; /* Ditto for unhashed data. */
|
||||
byte digest_start[2]; /* First 2 bytes of the digest. */
|
||||
gcry_mpi_t data[PUBKEY_MAX_NSIG];
|
||||
} PKT_signature;
|
||||
|
||||
#define ATTRIB_IMAGE 1
|
||||
@ -165,41 +182,57 @@ struct user_attribute {
|
||||
u32 len;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int ref; /* reference counter */
|
||||
int len; /* length of the name */
|
||||
struct user_attribute *attribs;
|
||||
int numattribs;
|
||||
byte *attrib_data; /* if this is not NULL, the packet is an attribute */
|
||||
unsigned long attrib_len;
|
||||
byte *namehash;
|
||||
int help_key_usage;
|
||||
u32 help_key_expire;
|
||||
int help_full_count;
|
||||
int help_marginal_count;
|
||||
int is_primary; /* 2 if set via the primary flag, 1 if calculated */
|
||||
int is_revoked;
|
||||
int is_expired;
|
||||
u32 expiredate; /* expires at this date or 0 if not at all */
|
||||
prefitem_t *prefs; /* list of preferences (may be NULL)*/
|
||||
int mdc_feature;
|
||||
int ks_modify;
|
||||
u32 created; /* according to the self-signature */
|
||||
byte selfsigversion;
|
||||
char name[1];
|
||||
typedef struct
|
||||
{
|
||||
int ref; /* reference counter */
|
||||
int len; /* length of the name */
|
||||
struct user_attribute *attribs;
|
||||
int numattribs;
|
||||
byte *attrib_data; /* if this is not NULL, the packet is an attribute */
|
||||
unsigned long attrib_len;
|
||||
byte *namehash;
|
||||
int help_key_usage;
|
||||
u32 help_key_expire;
|
||||
int help_full_count;
|
||||
int help_marginal_count;
|
||||
int is_primary; /* 2 if set via the primary flag, 1 if calculated */
|
||||
int is_revoked;
|
||||
int is_expired;
|
||||
u32 expiredate; /* expires at this date or 0 if not at all */
|
||||
prefitem_t *prefs; /* list of preferences (may be NULL)*/
|
||||
u32 created; /* according to the self-signature */
|
||||
byte selfsigversion;
|
||||
struct
|
||||
{
|
||||
/* TODO: Move more flags here */
|
||||
unsigned mdc:1;
|
||||
unsigned ks_modify:1;
|
||||
unsigned compacted:1;
|
||||
} flags;
|
||||
char name[1];
|
||||
} PKT_user_id;
|
||||
|
||||
struct revoke_info
|
||||
{
|
||||
/* revoked at this date */
|
||||
u32 date;
|
||||
/* the keyid of the revoking key (selfsig or designated revoker) */
|
||||
u32 keyid[2];
|
||||
/* the algo of the revoking key */
|
||||
byte algo;
|
||||
};
|
||||
|
||||
/****************
|
||||
* Note about the pkey/skey elements: We assume that the secret keys
|
||||
* has the same elemts as the public key at the begin of the array, so
|
||||
* that npkey < nskey and it is possible to compare the secret and
|
||||
* public keys by comparing the first npkey elements of pkey against skey.
|
||||
* public keys by comparing the first npkey elements of pkey againts skey.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 timestamp; /* key made */
|
||||
u32 expiredate; /* expires at this date or 0 if not at all */
|
||||
u32 max_expiredate; /* must not expire past this date */
|
||||
struct revoke_info revoked;
|
||||
byte hdrbytes; /* number of header bytes */
|
||||
byte version;
|
||||
byte selfsigversion; /* highest version of all of the self-sigs */
|
||||
@ -208,10 +241,13 @@ typedef struct {
|
||||
byte req_usage; /* hack to pass a request to getkey() */
|
||||
byte req_algo; /* Ditto */
|
||||
u32 has_expired; /* set to the expiration date if expired */
|
||||
int is_revoked; /* key has been revoked */
|
||||
int is_revoked; /* key has been revoked, 1 if by the
|
||||
owner, 2 if by a designated revoker */
|
||||
int maybe_revoked; /* a designated revocation is present, but
|
||||
without the key to check it */
|
||||
int is_valid; /* key (especially subkey) is valid */
|
||||
int dont_cache; /* do not cache this */
|
||||
ulong local_id; /* internal use, valid if > 0 */
|
||||
byte backsig; /* 0=none, 1=bad, 2=good */
|
||||
u32 main_keyid[2]; /* keyid of the primary key */
|
||||
u32 keyid[2]; /* calculated by keyid_from_pk() */
|
||||
byte is_primary;
|
||||
@ -273,15 +309,16 @@ typedef struct {
|
||||
u32 len; /* reserved */
|
||||
byte new_ctb;
|
||||
byte algorithm;
|
||||
iobuf_t buf; /* iobuf_t reference */
|
||||
iobuf_t buf; /* IOBUF reference */
|
||||
} PKT_compressed;
|
||||
|
||||
typedef struct {
|
||||
u32 len; /* length of encrypted data */
|
||||
int extralen; /* this is (blocksize+2) */
|
||||
byte new_ctb; /* uses a new CTB */
|
||||
byte is_partial; /* partial length encoded */
|
||||
byte mdc_method; /* > 0: integrity protected encrypted data packet */
|
||||
iobuf_t buf; /* iobuf_t reference */
|
||||
iobuf_t buf; /* IOBUF reference */
|
||||
} PKT_encrypted;
|
||||
|
||||
typedef struct {
|
||||
@ -295,7 +332,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
u32 len; /* length of encrypted data */
|
||||
iobuf_t buf; /* iobuf_t reference */
|
||||
iobuf_t buf; /* IOBUF reference */
|
||||
byte new_ctb;
|
||||
byte is_partial; /* partial length encoded */
|
||||
int mode;
|
||||
@ -364,9 +401,25 @@ typedef enum {
|
||||
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
|
||||
SIGSUBPKT_FEATURES =30, /* feature flags */
|
||||
|
||||
SIGSUBPKT_SIGNATURE =32, /* embedded signature */
|
||||
|
||||
SIGSUBPKT_FLAG_CRITICAL=128
|
||||
} sigsubpkttype_t;
|
||||
|
||||
struct notation
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
char *altvalue;
|
||||
unsigned char *bdat;
|
||||
size_t blen;
|
||||
struct
|
||||
{
|
||||
unsigned int critical:1;
|
||||
unsigned int ignore:1;
|
||||
} flags;
|
||||
struct notation *next;
|
||||
};
|
||||
|
||||
/*-- mainproc.c --*/
|
||||
int proc_packets( void *ctx, iobuf_t a );
|
||||
@ -407,6 +460,8 @@ int copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff );
|
||||
int skip_some_packets( iobuf_t inp, unsigned n );
|
||||
#endif
|
||||
|
||||
int parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
|
||||
PKT_signature *sig );
|
||||
const byte *enum_sig_subpkt ( const subpktarea_t *subpkts,
|
||||
sigsubpkttype_t reqtype,
|
||||
size_t *ret_n, int *start, int *critical );
|
||||
@ -427,7 +482,6 @@ PACKET *create_gpg_control ( ctrlpkttype_t type,
|
||||
/*-- build-packet.c --*/
|
||||
int build_packet( iobuf_t inp, PACKET *pkt );
|
||||
u32 calc_packet_length( PACKET *pkt );
|
||||
void hash_public_key( MD_HANDLE md, PKT_public_key *pk );
|
||||
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
||||
const byte *buffer, size_t buflen );
|
||||
void build_sig_subpkt_from_sig( PKT_signature *sig );
|
||||
@ -435,6 +489,9 @@ int delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type );
|
||||
void build_attribute_subpkt(PKT_user_id *uid,byte type,
|
||||
const void *buf,u32 buflen,
|
||||
const void *header,u32 headerlen);
|
||||
struct notation *string_to_notation(const char *string,int is_utf8);
|
||||
struct notation *sig_to_notation(PKT_signature *sig);
|
||||
void free_notation(struct notation *notation);
|
||||
|
||||
/*-- free-packet.c --*/
|
||||
void free_symkey_enc( PKT_symkey_enc *enc );
|
||||
@ -463,8 +520,8 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
|
||||
|
||||
|
||||
/*-- sig-check.c --*/
|
||||
int signature_check( PKT_signature *sig, MD_HANDLE digest );
|
||||
int signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
|
||||
int signature_check( PKT_signature *sig, gcry_md_hd_t digest );
|
||||
int signature_check2( PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
|
||||
int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
|
||||
|
||||
/*-- seckey-cert.c --*/
|
||||
@ -485,13 +542,10 @@ int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek );
|
||||
|
||||
/*-- plaintext.c --*/
|
||||
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
int nooutput, int clearsig, int *create_failed );
|
||||
int ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
|
||||
int nooutput, int clearsig );
|
||||
int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
|
||||
const char *inname, int textmode );
|
||||
|
||||
/*-- comment.c --*/
|
||||
int write_comment( iobuf_t out, const char *s );
|
||||
|
||||
/*-- sign.c --*/
|
||||
int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
PKT_user_id *uid, PKT_public_key *subpk,
|
||||
|
1099
g10/parse-packet.c
1099
g10/parse-packet.c
File diff suppressed because it is too large
Load Diff
1203
g10/passphrase.c
1203
g10/passphrase.c
File diff suppressed because it is too large
Load Diff
107
g10/photoid.c
107
g10/photoid.c
@ -1,5 +1,5 @@
|
||||
/* photoid.c - photo ID handling code
|
||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -28,6 +29,8 @@
|
||||
# define VER_PLATFORM_WIN32_WINDOWS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "gpg.h"
|
||||
#include "packet.h"
|
||||
#include "status.h"
|
||||
#include "exec.h"
|
||||
@ -35,21 +38,23 @@
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
#include "photoid.h"
|
||||
#include "ttyio.h"
|
||||
|
||||
/* Generate a new photo id packet, or return NULL if canceled */
|
||||
PKT_user_id *generate_photo_id(PKT_public_key *pk)
|
||||
PKT_user_id *
|
||||
generate_photo_id(PKT_public_key *pk,const char *photo_name)
|
||||
{
|
||||
PKT_user_id *uid;
|
||||
int error=1,i;
|
||||
unsigned int len;
|
||||
char *filename=NULL;
|
||||
char *filename;
|
||||
byte *photo=NULL;
|
||||
byte header[16];
|
||||
iobuf_t file;
|
||||
IOBUF file;
|
||||
int overflow;
|
||||
|
||||
header[0]=0x10; /* little side of photo header length */
|
||||
header[1]=0; /* big side of photo header length */
|
||||
@ -60,48 +65,78 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
|
||||
header[i]=0;
|
||||
|
||||
#define EXTRA_UID_NAME_SPACE 71
|
||||
uid=xcalloc (1,sizeof(*uid)+71);
|
||||
uid=xmalloc_clear(sizeof(*uid)+71);
|
||||
|
||||
printf(_("\nPick an image to use for your photo ID. "
|
||||
"The image must be a JPEG file.\n"
|
||||
"Remember that the image is stored within your public key. "
|
||||
"If you use a\n"
|
||||
"very large picture, your key will become very large as well!\n"
|
||||
"Keeping the image close to 240x288 is a good size to use.\n"));
|
||||
if(photo_name && *photo_name)
|
||||
filename=make_filename(photo_name,(void *)NULL);
|
||||
else
|
||||
{
|
||||
tty_printf(_("\nPick an image to use for your photo ID."
|
||||
" The image must be a JPEG file.\n"
|
||||
"Remember that the image is stored within your public key."
|
||||
" If you use a\n"
|
||||
"very large picture, your key will become very large"
|
||||
" as well!\n"
|
||||
"Keeping the image close to 240x288 is a good size"
|
||||
" to use.\n"));
|
||||
filename=NULL;
|
||||
}
|
||||
|
||||
while(photo==NULL)
|
||||
{
|
||||
printf("\n");
|
||||
if(filename==NULL)
|
||||
{
|
||||
char *tempname;
|
||||
|
||||
xfree (filename);
|
||||
tty_printf("\n");
|
||||
|
||||
filename=cpr_get("photoid.jpeg.add",
|
||||
_("Enter JPEG filename for photo ID: "));
|
||||
tty_enable_completion(NULL);
|
||||
|
||||
if(strlen(filename)==0)
|
||||
goto scram;
|
||||
tempname=cpr_get("photoid.jpeg.add",
|
||||
_("Enter JPEG filename for photo ID: "));
|
||||
|
||||
tty_disable_completion();
|
||||
|
||||
filename=make_filename(tempname,(void *)NULL);
|
||||
|
||||
xfree(tempname);
|
||||
|
||||
if(strlen(filename)==0)
|
||||
goto scram;
|
||||
}
|
||||
|
||||
file=iobuf_open(filename);
|
||||
if (file && is_secured_file (iobuf_get_fd (file)))
|
||||
{
|
||||
iobuf_close (file);
|
||||
file = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if(!file)
|
||||
{
|
||||
log_error(_("Unable to open photo \"%s\": %s\n"),
|
||||
log_error(_("unable to open JPEG file `%s': %s\n"),
|
||||
filename,strerror(errno));
|
||||
xfree(filename);
|
||||
filename=NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
len=iobuf_get_filelength(file);
|
||||
if(len>6144)
|
||||
|
||||
len=iobuf_get_filelength(file, &overflow);
|
||||
if(len>6144 || overflow)
|
||||
{
|
||||
printf("This JPEG is really large (%d bytes) !\n",len);
|
||||
tty_printf( _("This JPEG is really large (%d bytes) !\n"),len);
|
||||
if(!cpr_get_answer_is_yes("photoid.jpeg.size",
|
||||
_("Are you sure you want to use it (y/N)? ")))
|
||||
_("Are you sure you want to use it? (y/N) ")))
|
||||
{
|
||||
iobuf_close(file);
|
||||
xfree(filename);
|
||||
filename=NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
photo=xmalloc (len);
|
||||
photo=xmalloc(len);
|
||||
iobuf_read(file,photo,len);
|
||||
iobuf_close(file);
|
||||
|
||||
@ -109,9 +144,11 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
|
||||
if(photo[0]!=0xFF || photo[1]!=0xD8 ||
|
||||
photo[6]!='J' || photo[7]!='F' || photo[8]!='I' || photo[9]!='F')
|
||||
{
|
||||
log_error(_("\"%s\" is not a JPEG file\n"),filename);
|
||||
xfree (photo);
|
||||
log_error(_("`%s' is not a JPEG file\n"),filename);
|
||||
xfree(photo);
|
||||
photo=NULL;
|
||||
xfree(filename);
|
||||
filename=NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -132,8 +169,10 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
|
||||
goto scram;
|
||||
case 0:
|
||||
free_attributes(uid);
|
||||
xfree (photo);
|
||||
xfree(photo);
|
||||
photo=NULL;
|
||||
xfree(filename);
|
||||
filename=NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -143,13 +182,13 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
|
||||
uid->ref=1;
|
||||
|
||||
scram:
|
||||
xfree (filename);
|
||||
xfree (photo);
|
||||
xfree(filename);
|
||||
xfree(photo);
|
||||
|
||||
if(error)
|
||||
{
|
||||
free_attributes(uid);
|
||||
xfree (uid);
|
||||
xfree(uid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -283,7 +322,7 @@ void show_photos(const struct user_attribute *attrs,
|
||||
if(!command)
|
||||
goto fail;
|
||||
|
||||
name=xmalloc (16+strlen(EXTSEP_S)+
|
||||
name=xmalloc(16+strlen(EXTSEP_S)+
|
||||
strlen(image_type_to_string(args.imagetype,0))+1);
|
||||
|
||||
/* Make the filename. Notice we are not using the image
|
||||
@ -302,7 +341,7 @@ void show_photos(const struct user_attribute *attrs,
|
||||
|
||||
if(exec_write(&spawn,NULL,command,name,1,1)!=0)
|
||||
{
|
||||
xfree (name);
|
||||
xfree(name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -311,7 +350,7 @@ void show_photos(const struct user_attribute *attrs,
|
||||
image_type_to_string(args.imagetype,2));
|
||||
#endif
|
||||
|
||||
xfree (name);
|
||||
xfree(name);
|
||||
|
||||
fwrite(&attrs[i].data[offset],attrs[i].len-offset,1,spawn->tochild);
|
||||
|
||||
|
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
/* Photo ID functions */
|
||||
@ -25,7 +26,7 @@
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
PKT_user_id *generate_photo_id(PKT_public_key *pk);
|
||||
PKT_user_id *generate_photo_id(PKT_public_key *pk,const char *filename);
|
||||
int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len);
|
||||
char *image_type_to_string(byte type,int style);
|
||||
void show_photos(const struct user_attribute *attrs,
|
||||
|
317
g10/pipemode.c
317
g10/pipemode.c
@ -1,317 +0,0 @@
|
||||
/* pipemode.c - pipemode handler
|
||||
* Copyright (C) 1998, 1990, 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "status.h"
|
||||
#include "filter.h"
|
||||
|
||||
|
||||
#define CONTROL_PACKET_SPACE 30
|
||||
#define FAKED_LITERAL_PACKET_SPACE (9+2+2)
|
||||
|
||||
|
||||
enum pipemode_state_e {
|
||||
STX_init = 0,
|
||||
STX_wait_operation,
|
||||
STX_begin,
|
||||
STX_text,
|
||||
STX_detached_signature,
|
||||
STX_detached_signature_wait_text,
|
||||
STX_signed_data,
|
||||
STX_wait_init
|
||||
};
|
||||
|
||||
struct pipemode_context_s {
|
||||
enum pipemode_state_e state;
|
||||
int operation;
|
||||
int stop;
|
||||
int block_mode;
|
||||
UnarmorPump unarmor_ctx;
|
||||
};
|
||||
|
||||
|
||||
static size_t
|
||||
make_control ( byte *buf, int code, int operation )
|
||||
{
|
||||
const byte *sesmark;
|
||||
size_t sesmarklen, n=0;;
|
||||
|
||||
sesmark = get_session_marker( &sesmarklen );
|
||||
if ( sesmarklen > 20 )
|
||||
BUG();
|
||||
|
||||
buf[n++] = 0xff; /* new format, type 63, 1 length byte */
|
||||
n++; /* length will fixed below */
|
||||
memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
|
||||
buf[n++] = CTRLPKT_PIPEMODE;
|
||||
buf[n++] = code;
|
||||
buf[n++] = operation;
|
||||
buf[1] = n-2;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
pipemode_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
size_t size = *ret_len;
|
||||
struct pipemode_context_s *stx = opaque;
|
||||
int rc=0;
|
||||
size_t n = 0;
|
||||
int esc = 0;
|
||||
|
||||
if( control == IOBUFCTRL_UNDERFLOW ) {
|
||||
*ret_len = 0;
|
||||
/* reserve some space for one control packet */
|
||||
if ( size <= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE )
|
||||
BUG();
|
||||
size -= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE;
|
||||
|
||||
if ( stx->block_mode ) {
|
||||
/* reserve 2 bytes for the block length */
|
||||
buf[n++] = 0;
|
||||
buf[n++] = 0;
|
||||
}
|
||||
|
||||
|
||||
while ( n < size ) {
|
||||
/* FIXME: we have to make sure that we have a large enough
|
||||
* buffer for a control packet even after we already read
|
||||
* something. The easest way to do this is probably by ungetting
|
||||
* the control sequence and returning the buffer we have
|
||||
* already assembled */
|
||||
int c = iobuf_get (a);
|
||||
if (c == -1) {
|
||||
if ( stx->state != STX_init ) {
|
||||
log_error ("EOF encountered at wrong state\n");
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( esc ) {
|
||||
switch (c) {
|
||||
case '@':
|
||||
if ( stx->state == STX_text ) {
|
||||
buf[n++] = c;
|
||||
break;
|
||||
}
|
||||
else if ( stx->state == STX_detached_signature ) {
|
||||
esc = 0;
|
||||
goto do_unarmor; /* not a very elegant solution */
|
||||
}
|
||||
else if ( stx->state == STX_detached_signature_wait_text) {
|
||||
esc = 0;
|
||||
break; /* just ignore it in this state */
|
||||
}
|
||||
log_error ("@@ not allowed in current state\n");
|
||||
return -1;
|
||||
case '<': /* begin of stream part */
|
||||
if ( stx->state != STX_init ) {
|
||||
log_error ("nested begin of stream\n");
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
stx->state = STX_wait_operation;
|
||||
stx->block_mode = 0;
|
||||
unarmor_pump_release (stx->unarmor_ctx);
|
||||
stx->unarmor_ctx = NULL;
|
||||
break;
|
||||
case '>': /* end of stream part */
|
||||
if ( stx->state != STX_wait_init ) {
|
||||
log_error ("invalid state for @>\n");
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
stx->state = STX_init;
|
||||
break;
|
||||
case 'V': /* operation = verify */
|
||||
case 'E': /* operation = encrypt */
|
||||
case 'S': /* operation = sign */
|
||||
case 'B': /* operation = detach sign */
|
||||
case 'C': /* operation = clearsign */
|
||||
case 'D': /* operation = decrypt */
|
||||
if ( stx->state != STX_wait_operation ) {
|
||||
log_error ("invalid state for operation code\n");
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
stx->operation = c;
|
||||
if ( stx->operation == 'B') {
|
||||
stx->state = STX_detached_signature;
|
||||
if ( !opt.no_armor )
|
||||
stx->unarmor_ctx = unarmor_pump_new ();
|
||||
}
|
||||
else
|
||||
stx->state = STX_begin;
|
||||
n += make_control ( buf+n, 1, stx->operation );
|
||||
/* must leave after a control packet */
|
||||
goto leave;
|
||||
|
||||
case 't': /* plaintext text follows */
|
||||
if ( stx->state == STX_detached_signature_wait_text )
|
||||
stx->state = STX_detached_signature;
|
||||
if ( stx->state == STX_detached_signature ) {
|
||||
if ( stx->operation != 'B' ) {
|
||||
log_error ("invalid operation for this state\n");
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
stx->state = STX_signed_data;
|
||||
n += make_control ( buf+n, 2, 'B' );
|
||||
/* and now we fake a literal data packet much the same
|
||||
* as in armor.c */
|
||||
buf[n++] = 0xaf; /* old packet format, type 11,
|
||||
var length */
|
||||
buf[n++] = 0; /* set the length header */
|
||||
buf[n++] = 6;
|
||||
buf[n++] = 'b'; /* we ignore it anyway */
|
||||
buf[n++] = 0; /* namelength */
|
||||
memset(buf+n, 0, 4); /* timestamp */
|
||||
n += 4;
|
||||
/* and return now so that we are sure to have
|
||||
* more space in the bufer for the next control
|
||||
* packet */
|
||||
stx->block_mode = 1;
|
||||
goto leave2;
|
||||
}
|
||||
else {
|
||||
log_error ("invalid state for @t\n");
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '.': /* ready */
|
||||
if ( stx->state == STX_signed_data ) {
|
||||
if (stx->block_mode) {
|
||||
buf[0] = (n-2) >> 8;
|
||||
buf[1] = (n-2);
|
||||
if ( buf[0] || buf[1] ) {
|
||||
/* end of blocks marker */
|
||||
buf[n++] = 0;
|
||||
buf[n++] = 0;
|
||||
}
|
||||
stx->block_mode = 0;
|
||||
}
|
||||
n += make_control ( buf+n, 3, 'B' );
|
||||
}
|
||||
else {
|
||||
log_error ("invalid state for @.\n");
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
stx->state = STX_wait_init;
|
||||
goto leave;
|
||||
|
||||
default:
|
||||
log_error ("invalid escape sequence 0x%02x in stream\n",
|
||||
c);
|
||||
stx->stop = 1;
|
||||
return -1;
|
||||
}
|
||||
esc = 0;
|
||||
}
|
||||
else if (c == '@')
|
||||
esc = 1;
|
||||
else if (stx->unarmor_ctx) {
|
||||
do_unarmor: /* used to handle a @@ */
|
||||
c = unarmor_pump (stx->unarmor_ctx, c);
|
||||
if ( !(c & ~255) )
|
||||
buf[n++] = c;
|
||||
else if ( c < 0 ) {
|
||||
/* end of armor or error - we don't care becuase
|
||||
the armor can be modified anyway. The unarmored
|
||||
stuff should stand for itself. */
|
||||
unarmor_pump_release (stx->unarmor_ctx);
|
||||
stx->unarmor_ctx = NULL;
|
||||
stx->state = STX_detached_signature_wait_text;
|
||||
}
|
||||
}
|
||||
else if (stx->state == STX_detached_signature_wait_text)
|
||||
; /* just wait */
|
||||
else
|
||||
buf[n++] = c;
|
||||
}
|
||||
|
||||
leave:
|
||||
if ( !n ) {
|
||||
stx->stop = 1;
|
||||
rc = -1; /* eof */
|
||||
}
|
||||
if ( stx->block_mode ) {
|
||||
/* fixup the block length */
|
||||
buf[0] = (n-2) >> 8;
|
||||
buf[1] = (n-2);
|
||||
}
|
||||
leave2:
|
||||
/*log_hexdump ("pipemode:", buf, n );*/
|
||||
*ret_len = n;
|
||||
}
|
||||
else if( control == IOBUFCTRL_DESC )
|
||||
*(char**)buf = "pipemode_filter";
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
run_in_pipemode(void)
|
||||
{
|
||||
iobuf_t fp;
|
||||
armor_filter_context_t afx;
|
||||
struct pipemode_context_s stx;
|
||||
int rc;
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &stx, 0, sizeof stx);
|
||||
|
||||
fp = iobuf_open("-");
|
||||
iobuf_push_filter (fp, pipemode_filter, &stx );
|
||||
|
||||
do {
|
||||
write_status (STATUS_BEGIN_STREAM);
|
||||
rc = proc_packets( NULL, fp );
|
||||
write_status (STATUS_END_STREAM);
|
||||
} while ( !stx.stop );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1155
g10/pkclist.c
1155
g10/pkclist.c
File diff suppressed because it is too large
Load Diff
279
g10/plaintext.c
279
g10/plaintext.c
@ -1,6 +1,6 @@
|
||||
/* plaintext.c - process plaintext packets
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -25,13 +26,13 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#include <fcntl.h> /* for setmode() */
|
||||
#endif
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "ttyio.h"
|
||||
@ -41,7 +42,6 @@
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Handle a plaintext packet. If MFX is not NULL, update the MDs
|
||||
* Note: we should use the filter stuff here, but we have to add some
|
||||
@ -50,27 +50,41 @@
|
||||
*/
|
||||
int
|
||||
handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
int nooutput, int clearsig, int *create_failed )
|
||||
int nooutput, int clearsig )
|
||||
{
|
||||
char *fname = NULL;
|
||||
FILE *fp = NULL;
|
||||
static off_t count=0;
|
||||
int rc = 0;
|
||||
int c;
|
||||
int convert = pt->mode == 't';
|
||||
int convert = (pt->mode == 't' || pt->mode == 'u');
|
||||
#ifdef __riscos__
|
||||
int filetype = 0xfff;
|
||||
#endif
|
||||
int dummy_create_failed;
|
||||
|
||||
if (!create_failed)
|
||||
create_failed = &dummy_create_failed;
|
||||
*create_failed = 0;
|
||||
/* Let people know what the plaintext info is. This allows the
|
||||
receiving program to try and do something different based on
|
||||
the format code (say, recode UTF-8 to local). */
|
||||
if(!nooutput && is_status_enabled())
|
||||
{
|
||||
char status[50];
|
||||
|
||||
sprintf(status,"%X %lu ",(byte)pt->mode,(ulong)pt->timestamp);
|
||||
write_status_text_and_buffer(STATUS_PLAINTEXT,
|
||||
status,pt->name,pt->namelen,0);
|
||||
|
||||
if(!pt->is_partial)
|
||||
{
|
||||
sprintf(status,"%lu",(ulong)pt->len);
|
||||
write_status_text(STATUS_PLAINTEXT_LENGTH,status);
|
||||
}
|
||||
}
|
||||
|
||||
/* create the filename as C string */
|
||||
if( nooutput )
|
||||
;
|
||||
else if( opt.outfile ) {
|
||||
fname = xmalloc ( strlen( opt.outfile ) + 1);
|
||||
fname = xmalloc( strlen( opt.outfile ) + 1);
|
||||
strcpy(fname, opt.outfile );
|
||||
}
|
||||
else if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) {
|
||||
@ -82,8 +96,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
if( !fname )
|
||||
fname = ask_outfile_name( pt->name, pt->namelen );
|
||||
if( !fname ) {
|
||||
*create_failed = 1;
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = gpg_error (GPG_ERR_GENERAL) /* Can't create file. */
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
@ -93,20 +106,20 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
|
||||
if( nooutput )
|
||||
;
|
||||
else if( !*fname || (*fname=='-' && !fname[1])) {
|
||||
/* no filename or "-" given; write to stdout */
|
||||
else if ( iobuf_is_pipe_filename (fname) || !*fname)
|
||||
{
|
||||
/* No filename or "-" given; write to stdout. */
|
||||
fp = stdout;
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
setmode ( fileno(fp) , O_BINARY );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
while( !overwrite_filep (fname) ) {
|
||||
char *tmp = ask_outfile_name (NULL, 0);
|
||||
if ( !tmp || !*tmp ) {
|
||||
xfree (tmp);
|
||||
*create_failed = 1;
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
xfree (fname);
|
||||
@ -117,26 +130,34 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
#ifndef __riscos__
|
||||
if( fp || nooutput )
|
||||
;
|
||||
else if( !(fp = fopen(fname,"wb")) ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
else if (is_secured_filename (fname))
|
||||
{
|
||||
errno = EPERM;
|
||||
log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
|
||||
*create_failed = 1;
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else if( !(fp = fopen(fname,"wb")) ) {
|
||||
log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
#else /* __riscos__ */
|
||||
/* Convert all '.' in fname to '/' -- we don't create directories! */
|
||||
for( c=0; fname[c]; ++c )
|
||||
if( fname[c] == '.' )
|
||||
fname[c] = '/';
|
||||
/* If no output filename was given, i.e. we constructed it,
|
||||
convert all '.' in fname to '/' but not vice versa as
|
||||
we don't create directories! */
|
||||
if( !opt.outfile )
|
||||
for( c=0; fname[c]; ++c )
|
||||
if( fname[c] == '.' )
|
||||
fname[c] = '/';
|
||||
|
||||
if( fp || nooutput )
|
||||
;
|
||||
else {
|
||||
fp = fopen(fname,"wb");
|
||||
if( !fp ) {
|
||||
rc == gpg_error_from_errno (errno);
|
||||
log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
|
||||
*create_failed = 1;
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
if (errno == 106)
|
||||
log_info("Do output file and input file have the same name?\n");
|
||||
goto leave;
|
||||
@ -156,15 +177,21 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
#endif /* __riscos__ */
|
||||
|
||||
if( !pt->is_partial ) {
|
||||
/* we have an actual length (which might be zero). */
|
||||
assert( !clearsig );
|
||||
/* We have an actual length (which might be zero). */
|
||||
|
||||
if (clearsig) {
|
||||
log_error ("clearsig encountered while not expected\n");
|
||||
rc = G10ERR_UNEXPECTED;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( convert ) { /* text mode */
|
||||
for( ; pt->len; pt->len-- ) {
|
||||
if( (c = iobuf_get(pt->buf)) == -1 ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error("Problem reading source (%u bytes remaining)\n",
|
||||
(unsigned)pt->len);
|
||||
goto leave;
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error ("problem reading source (%u bytes remaining)\n",
|
||||
(unsigned)pt->len);
|
||||
goto leave;
|
||||
}
|
||||
if( mfx->md )
|
||||
gcry_md_putc (mfx->md, c );
|
||||
@ -172,65 +199,93 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
if( c == '\r' ) /* convert to native line ending */
|
||||
continue; /* fixme: this hack might be too simple */
|
||||
#endif
|
||||
if( fp ) {
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
if( fp )
|
||||
{
|
||||
if(opt.max_output && (++count)>opt.max_output)
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname,"exceeded --max-output limit\n");
|
||||
rc = gpg_error (GPG_ERR_GENERAL);
|
||||
goto leave;
|
||||
}
|
||||
else if( putc( c, fp ) == EOF )
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* binary mode */
|
||||
byte *buffer = xmalloc ( 32768 );
|
||||
byte *buffer = xmalloc( 32768 );
|
||||
while( pt->len ) {
|
||||
int len = pt->len > 32768 ? 32768 : pt->len;
|
||||
len = iobuf_read( pt->buf, buffer, len );
|
||||
if( len == -1 ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error("Problem reading source (%u bytes remaining)\n",
|
||||
(unsigned)pt->len);
|
||||
xfree ( buffer );
|
||||
rc = G10ERR_READ_FILE;
|
||||
xfree( buffer );
|
||||
goto leave;
|
||||
}
|
||||
if( mfx->md )
|
||||
gcry_md_write( mfx->md, buffer, len );
|
||||
if( fp ) {
|
||||
if( fwrite( buffer, 1, len, fp ) != len ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
gcry_md_write ( mfx->md, buffer, len );
|
||||
if( fp )
|
||||
{
|
||||
if(opt.max_output && (count+=len)>opt.max_output)
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname,"exceeded --max-output limit\n");
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
xfree( buffer );
|
||||
goto leave;
|
||||
}
|
||||
else if( fwrite( buffer, 1, len, fp ) != len )
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
xfree ( buffer );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
xfree( buffer );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pt->len -= len;
|
||||
}
|
||||
xfree ( buffer );
|
||||
xfree( buffer );
|
||||
}
|
||||
}
|
||||
else if( !clearsig ) {
|
||||
if( convert ) { /* text mode */
|
||||
while( (c = iobuf_get(pt->buf)) != -1 ) {
|
||||
if( mfx->md )
|
||||
gcry_md_putc (mfx->md, c );
|
||||
md_putc(mfx->md, c );
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
if( convert && c == '\r' )
|
||||
continue; /* fixme: this hack might be too simple */
|
||||
#endif
|
||||
if( fp ) {
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
if( fp )
|
||||
{
|
||||
if(opt.max_output && (++count)>opt.max_output)
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname,"exceeded --max-output limit\n");
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else if( putc( c, fp ) == EOF )
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* binary mode */
|
||||
byte *buffer = xmalloc ( 32768 );
|
||||
byte *buffer = xmalloc( 32768 );
|
||||
int eof;
|
||||
for( eof=0; !eof; ) {
|
||||
/* Why do we check for len < 32768:
|
||||
@ -245,18 +300,27 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
if( len < 32768 )
|
||||
eof = 1;
|
||||
if( mfx->md )
|
||||
gcry_md_write( mfx->md, buffer, len );
|
||||
if( fp ) {
|
||||
if( fwrite( buffer, 1, len, fp ) != len ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
md_write( mfx->md, buffer, len );
|
||||
if( fp )
|
||||
{
|
||||
if(opt.max_output && (count+=len)>opt.max_output)
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
xfree ( buffer );
|
||||
fname,"exceeded --max-output limit\n");
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
xfree( buffer );
|
||||
goto leave;
|
||||
}
|
||||
else if( fwrite( buffer, 1, len, fp ) != len ) {
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
xfree( buffer );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xfree ( buffer );
|
||||
xfree( buffer );
|
||||
}
|
||||
pt->buf = NULL;
|
||||
}
|
||||
@ -264,19 +328,28 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
int state = 0;
|
||||
|
||||
while( (c = iobuf_get(pt->buf)) != -1 ) {
|
||||
if( fp ) {
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
if( fp )
|
||||
{
|
||||
if(opt.max_output && (++count)>opt.max_output)
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
fname,"exceeded --max-output limit\n");
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( putc( c, fp ) == EOF )
|
||||
{
|
||||
log_error("Error writing to `%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
if( !mfx->md )
|
||||
continue;
|
||||
if( state == 2 ) {
|
||||
gcry_md_putc (mfx->md, '\r' );
|
||||
gcry_md_putc (mfx->md, '\n' );
|
||||
md_putc(mfx->md, '\r' );
|
||||
md_putc(mfx->md, '\n' );
|
||||
state = 0;
|
||||
}
|
||||
if( !state ) {
|
||||
@ -285,18 +358,18 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
else if( c == '\n' )
|
||||
state = 2;
|
||||
else
|
||||
gcry_md_putc (mfx->md, c );
|
||||
md_putc(mfx->md, c );
|
||||
}
|
||||
else if( state == 1 ) {
|
||||
if( c == '\n' )
|
||||
state = 2;
|
||||
else {
|
||||
gcry_md_putc (mfx->md, '\r' );
|
||||
md_putc(mfx->md, '\r' );
|
||||
if( c == '\r' )
|
||||
state = 1;
|
||||
else {
|
||||
state = 0;
|
||||
gcry_md_putc (mfx->md, c );
|
||||
md_putc(mfx->md, c );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -305,9 +378,9 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
}
|
||||
|
||||
if( fp && fp != stdout && fclose(fp) ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error("Error closing `%s': %s\n", fname, strerror(errno) );
|
||||
fp = NULL;
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
fp = NULL;
|
||||
@ -315,12 +388,12 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||
leave:
|
||||
if( fp && fp != stdout )
|
||||
fclose(fp);
|
||||
xfree (fname);
|
||||
xfree(fname);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
do_hash( MD_HANDLE md, MD_HANDLE md2, iobuf_t fp, int textmode )
|
||||
do_hash( gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode )
|
||||
{
|
||||
text_filter_context_t tfx;
|
||||
int c;
|
||||
@ -365,12 +438,12 @@ do_hash( MD_HANDLE md, MD_HANDLE md2, iobuf_t fp, int textmode )
|
||||
* INFILE is the name of the input file.
|
||||
*/
|
||||
int
|
||||
ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
|
||||
ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
|
||||
const char *inname, int textmode )
|
||||
{
|
||||
progress_filter_context_t pfx;
|
||||
char *answer = NULL;
|
||||
iobuf_t fp;
|
||||
IOBUF fp;
|
||||
int rc = 0;
|
||||
|
||||
fp = open_sigfile( inname, &pfx ); /* open default file */
|
||||
@ -379,24 +452,37 @@ ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
|
||||
int any=0;
|
||||
tty_printf(_("Detached signature.\n"));
|
||||
do {
|
||||
xfree (answer);
|
||||
answer = cpr_get("detached_signature.filename",
|
||||
char *name;
|
||||
xfree(answer);
|
||||
tty_enable_completion(NULL);
|
||||
name = cpr_get("detached_signature.filename",
|
||||
_("Please enter name of data file: "));
|
||||
tty_disable_completion();
|
||||
cpr_kill_prompt();
|
||||
answer=make_filename(name,(void *)NULL);
|
||||
xfree(name);
|
||||
|
||||
if( any && !*answer ) {
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE*/
|
||||
goto leave;
|
||||
}
|
||||
fp = iobuf_open(answer);
|
||||
if (fp && is_secured_file (iobuf_get_fd (fp)))
|
||||
{
|
||||
iobuf_close (fp);
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !fp && errno == ENOENT ) {
|
||||
tty_printf("No such file, try again or hit enter to quit.\n");
|
||||
any++;
|
||||
}
|
||||
else if( !fp ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error("can't open `%s': %s\n", answer, strerror(errno) );
|
||||
else if( !fp )
|
||||
{
|
||||
log_error(_("can't open `%s': %s\n"), answer, strerror(errno));
|
||||
rc = G10ERR_READ_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
} while( !fp );
|
||||
}
|
||||
|
||||
@ -410,7 +496,7 @@ ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
|
||||
iobuf_close(fp);
|
||||
|
||||
leave:
|
||||
xfree (answer);
|
||||
xfree(answer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -421,11 +507,11 @@ ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
|
||||
* If FILES is NULL, hash stdin.
|
||||
*/
|
||||
int
|
||||
hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files,
|
||||
hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2, STRLIST files,
|
||||
const char *sigfilename, int textmode )
|
||||
{
|
||||
progress_filter_context_t pfx;
|
||||
iobuf_t fp;
|
||||
IOBUF fp;
|
||||
STRLIST sl;
|
||||
|
||||
if( !files ) {
|
||||
@ -437,17 +523,22 @@ hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files,
|
||||
return 0;
|
||||
}
|
||||
log_error (_("no signed data\n"));
|
||||
return GPG_ERR_NO_DATA;
|
||||
return gpg_error (GPG_ERR_NO_DATA);
|
||||
}
|
||||
|
||||
|
||||
for (sl=files; sl; sl = sl->next ) {
|
||||
fp = iobuf_open( sl->d );
|
||||
if (fp && is_secured_file (iobuf_get_fd (fp)))
|
||||
{
|
||||
iobuf_close (fp);
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !fp ) {
|
||||
int tmperr = gpg_error_from_errno (errno);
|
||||
log_error(_("can't open signed data `%s'\n"),
|
||||
print_fname_stdin(sl->d));
|
||||
return tmperr;
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
handle_progress (&pfx, fp, sl->d);
|
||||
do_hash( md, md2, fp, textmode );
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* progress.c
|
||||
/* progress.c - emit progress status lines
|
||||
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -33,7 +34,7 @@
|
||||
*/
|
||||
int
|
||||
progress_filter (void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
int rc = 0;
|
||||
progress_filter_context_t *pfx = opaque;
|
||||
@ -96,7 +97,7 @@ progress_filter (void *opaque, int control,
|
||||
}
|
||||
|
||||
void
|
||||
handle_progress (progress_filter_context_t *pfx, iobuf_t inp, const char *name)
|
||||
handle_progress (progress_filter_context_t *pfx, IOBUF inp, const char *name)
|
||||
{
|
||||
off_t filesize = 0;
|
||||
|
||||
@ -106,8 +107,8 @@ handle_progress (progress_filter_context_t *pfx, iobuf_t inp, const char *name)
|
||||
if (!is_status_enabled ())
|
||||
return;
|
||||
|
||||
if (name && *name && !(*name == '-' && !name[1]))
|
||||
filesize = iobuf_get_filelength (inp);
|
||||
if ( !iobuf_is_pipe_filename (name) && *name )
|
||||
filesize = iobuf_get_filelength (inp, NULL);
|
||||
else if (opt.set_filesize)
|
||||
filesize = opt.set_filesize;
|
||||
|
||||
|
314
g10/pubkey-enc.c
314
g10/pubkey-enc.c
@ -1,6 +1,6 @@
|
||||
/* pubkey-enc.c - public key encoded packet handling
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -27,9 +28,7 @@
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "packet.h"
|
||||
#include "mpi.h"
|
||||
#include "keydb.h"
|
||||
#include "trustdb.h"
|
||||
#include "cipher.h"
|
||||
@ -38,7 +37,7 @@
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
#include "pkglue.h"
|
||||
#include "call-agent.h"
|
||||
|
||||
|
||||
static int get_it( PKT_pubkey_enc *k,
|
||||
DEK *dek, PKT_secret_key *sk, u32 *keyid );
|
||||
@ -77,12 +76,12 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
|
||||
PKT_secret_key *sk = NULL;
|
||||
int rc;
|
||||
|
||||
rc = openpgp_pk_test_algo (k->pubkey_algo, PUBKEY_USAGE_ENC);
|
||||
rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
|
||||
if( rc )
|
||||
goto leave;
|
||||
|
||||
if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) {
|
||||
sk = xcalloc (1, sizeof *sk );
|
||||
sk = xmalloc_clear( sizeof *sk );
|
||||
sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/
|
||||
if( !(rc = get_seckey( sk, k->keyid )) )
|
||||
rc = get_it( k, dek, sk, k->keyid );
|
||||
@ -95,34 +94,49 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
|
||||
for(;;) {
|
||||
if( sk )
|
||||
free_secret_key( sk );
|
||||
sk = xcalloc (1, sizeof *sk );
|
||||
sk = xmalloc_clear( sizeof *sk );
|
||||
rc=enum_secret_keys( &enum_context, sk, 1, 0);
|
||||
if( rc ) {
|
||||
rc = GPG_ERR_NO_SECKEY;
|
||||
rc = G10ERR_NO_SECKEY;
|
||||
break;
|
||||
}
|
||||
if( sk->pubkey_algo != k->pubkey_algo )
|
||||
continue;
|
||||
keyid_from_sk( sk, keyid );
|
||||
log_info(_("anonymous recipient; trying secret key %08lX ...\n"),
|
||||
(ulong)keyid[1] );
|
||||
log_info(_("anonymous recipient; trying secret key %s ...\n"),
|
||||
keystr(keyid));
|
||||
|
||||
if(!opt.try_all_secrets && !is_status_enabled())
|
||||
{
|
||||
p=get_last_passphrase();
|
||||
set_next_passphrase(p);
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
}
|
||||
|
||||
rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask
|
||||
only
|
||||
once */
|
||||
if( !rc )
|
||||
{
|
||||
rc = get_it( k, dek, sk, keyid );
|
||||
if( !rc ) {
|
||||
/* Successfully checked the secret key (either it was
|
||||
a card, had no passphrase, or had the right
|
||||
passphrase) but couldn't decrypt the session key,
|
||||
so thus that key is not the anonymous recipient.
|
||||
Move the next passphrase into last for the next
|
||||
round. We only do this if the secret key was
|
||||
successfully checked as in the normal case,
|
||||
check_secret_key handles this for us via
|
||||
passphrase_to_dek */
|
||||
if(rc)
|
||||
next_to_last_passphrase();
|
||||
}
|
||||
|
||||
if( !rc )
|
||||
{
|
||||
log_info(_("okay, we are the anonymous recipient.\n") );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */
|
||||
}
|
||||
@ -138,15 +152,17 @@ static int
|
||||
get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
{
|
||||
int rc;
|
||||
gcry_mpi_t plain_dek = NULL;
|
||||
gcry_mpi_t plain_dek = NULL;
|
||||
byte *frame = NULL;
|
||||
unsigned n, nframe;
|
||||
u16 csum, csum2;
|
||||
|
||||
int card = 0;
|
||||
|
||||
if (sk->is_protected && sk->protect.s2k.mode == 1002)
|
||||
{ /* FIXME: Note that we do only support RSA for now. */
|
||||
char *rbuf;
|
||||
{ /* Note, that we only support RSA for now. */
|
||||
#ifdef ENABLE_CARD_SUPPORT
|
||||
unsigned char *rbuf;
|
||||
size_t rbuflen;
|
||||
char *snbuf;
|
||||
unsigned char *indata = NULL;
|
||||
@ -154,9 +170,8 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
|
||||
snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
|
||||
|
||||
if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen,
|
||||
enc->data[0]))
|
||||
BUG();
|
||||
if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
|
||||
BUG ();
|
||||
|
||||
rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
|
||||
xfree (snbuf);
|
||||
@ -167,148 +182,145 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
frame = rbuf;
|
||||
nframe = rbuflen;
|
||||
card = 1;
|
||||
#else
|
||||
rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
goto leave;
|
||||
#endif /*!ENABLE_CARD_SUPPORT*/
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey);
|
||||
rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
|
||||
if( rc )
|
||||
goto leave;
|
||||
goto leave;
|
||||
if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
|
||||
BUG();
|
||||
gcry_mpi_release (plain_dek); plain_dek = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Now get the DEK (data encryption key) from the frame
|
||||
*
|
||||
* Old versions encode the DEK in in this format (msb is left):
|
||||
*
|
||||
* 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2
|
||||
*
|
||||
* Later versions encode the DEK like this:
|
||||
*
|
||||
* 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
|
||||
*
|
||||
* (mpi_get_buffer already removed the leading zero).
|
||||
*
|
||||
* RND are non-zero randow bytes.
|
||||
* A is the cipher algorithm
|
||||
* DEK is the encryption key (session key) with length k
|
||||
* CSUM
|
||||
*/
|
||||
if( DBG_CIPHER )
|
||||
log_printhex ("DEK frame:", frame, nframe );
|
||||
n=0;
|
||||
if (!card)
|
||||
{
|
||||
if( n + 7 > nframe )
|
||||
{ rc = GPG_ERR_WRONG_SECKEY; goto leave; }
|
||||
if( frame[n] == 1 && frame[nframe-1] == 2 ) {
|
||||
log_info(_("old encoding of the DEK is not supported\n"));
|
||||
rc = GPG_ERR_CIPHER_ALGO;
|
||||
goto leave;
|
||||
}
|
||||
if( frame[n] != 2 ) /* somethink is wrong */
|
||||
{ rc = GPG_ERR_WRONG_SECKEY; goto leave; }
|
||||
for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
|
||||
;
|
||||
n++; /* and the zero byte */
|
||||
}
|
||||
|
||||
if( n + 4 > nframe )
|
||||
{ rc = GPG_ERR_WRONG_SECKEY; goto leave; }
|
||||
dek->keylen = nframe - (n+1) - 2;
|
||||
dek->algo = frame[n++];
|
||||
if( dek->algo == CIPHER_ALGO_IDEA )
|
||||
write_status(STATUS_RSA_OR_IDEA);
|
||||
rc = openpgp_cipher_test_algo (dek->algo);
|
||||
if( rc ) {
|
||||
if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
|
||||
log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
|
||||
dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
|
||||
if(dek->algo==CIPHER_ALGO_IDEA)
|
||||
idea_cipher_warn(0);
|
||||
}
|
||||
dek->algo = 0;
|
||||
goto leave;
|
||||
}
|
||||
if( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) {
|
||||
rc = GPG_ERR_WRONG_SECKEY;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* copy the key to DEK and compare the checksum */
|
||||
csum = frame[nframe-2] << 8;
|
||||
csum |= frame[nframe-1];
|
||||
memcpy( dek->key, frame+n, dek->keylen );
|
||||
for( csum2=0, n=0; n < dek->keylen; n++ )
|
||||
csum2 += dek->key[n];
|
||||
if( csum != csum2 ) {
|
||||
rc = GPG_ERR_WRONG_SECKEY;
|
||||
goto leave;
|
||||
}
|
||||
if( DBG_CIPHER )
|
||||
log_printhex ("DEK is:", dek->key, dek->keylen );
|
||||
/* check that the algo is in the preferences and whether it has expired */
|
||||
{
|
||||
PKT_public_key *pk = NULL;
|
||||
KBNODE pkb = get_pubkeyblock (keyid);
|
||||
|
||||
if( !pkb ) {
|
||||
rc = -1;
|
||||
log_error("oops: public key not found for preference check\n");
|
||||
}
|
||||
else if( pkb->pkt->pkt.public_key->selfsigversion > 3
|
||||
&& dek->algo != CIPHER_ALGO_3DES
|
||||
&& !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ) ) {
|
||||
/* Don't print a note while we are not on verbose mode,
|
||||
* the cipher is blowfish and the preferences have twofish
|
||||
* listed */
|
||||
if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
|
||||
|| !is_algo_in_prefs( pkb, PREFTYPE_SYM, CIPHER_ALGO_TWOFISH))
|
||||
log_info(_(
|
||||
"NOTE: cipher algorithm %d not found in preferences\n"),
|
||||
dek->algo );
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
KBNODE k;
|
||||
|
||||
for (k=pkb; k; k = k->next) {
|
||||
if (k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
|
||||
u32 aki[2];
|
||||
keyid_from_pk(k->pkt->pkt.public_key, aki);
|
||||
|
||||
if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
|
||||
pk = k->pkt->pkt.public_key;
|
||||
break;
|
||||
}
|
||||
/* Now get the DEK (data encryption key) from the frame
|
||||
*
|
||||
* Old versions encode the DEK in in this format (msb is left):
|
||||
*
|
||||
* 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2
|
||||
*
|
||||
* Later versions encode the DEK like this:
|
||||
*
|
||||
* 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
|
||||
*
|
||||
* (mpi_get_buffer already removed the leading zero).
|
||||
*
|
||||
* RND are non-zero randow bytes.
|
||||
* A is the cipher algorithm
|
||||
* DEK is the encryption key (session key) with length k
|
||||
* CSUM
|
||||
*/
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK frame:", frame, nframe );
|
||||
n=0;
|
||||
if (!card)
|
||||
{
|
||||
if( n + 7 > nframe )
|
||||
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
||||
if( frame[n] == 1 && frame[nframe-1] == 2 ) {
|
||||
log_info(_("old encoding of the DEK is not supported\n"));
|
||||
rc = G10ERR_CIPHER_ALGO;
|
||||
goto leave;
|
||||
}
|
||||
if( frame[n] != 2 ) /* somethink is wrong */
|
||||
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
||||
for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
|
||||
;
|
||||
n++; /* and the zero byte */
|
||||
}
|
||||
if (!pk)
|
||||
BUG ();
|
||||
if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
|
||||
log_info(_("NOTE: secret key %08lX expired at %s\n"),
|
||||
(ulong)keyid[1], asctimestamp( pk->expiredate) );
|
||||
}
|
||||
|
||||
if( n + 4 > nframe )
|
||||
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
||||
|
||||
dek->keylen = nframe - (n+1) - 2;
|
||||
dek->algo = frame[n++];
|
||||
if( dek->algo == CIPHER_ALGO_IDEA )
|
||||
write_status(STATUS_RSA_OR_IDEA);
|
||||
rc = openpgp_cipher_test_algo (dek->algo);
|
||||
if( rc ) {
|
||||
if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
|
||||
log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
|
||||
dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
|
||||
if(dek->algo==CIPHER_ALGO_IDEA)
|
||||
idea_cipher_warn(0);
|
||||
}
|
||||
dek->algo = 0;
|
||||
goto leave;
|
||||
}
|
||||
if ( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) {
|
||||
rc = GPG_ERR_WRONG_SECKEY;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if ( pk && pk->is_revoked ) {
|
||||
log_info( _("NOTE: key has been revoked") );
|
||||
putc( '\n', log_get_stream() );
|
||||
show_revocation_reason( pk, 1 );
|
||||
/* copy the key to DEK and compare the checksum */
|
||||
csum = frame[nframe-2] << 8;
|
||||
csum |= frame[nframe-1];
|
||||
memcpy( dek->key, frame+n, dek->keylen );
|
||||
for( csum2=0, n=0; n < dek->keylen; n++ )
|
||||
csum2 += dek->key[n];
|
||||
if( csum != csum2 ) {
|
||||
rc = G10ERR_WRONG_SECKEY;
|
||||
goto leave;
|
||||
}
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is:", dek->key, dek->keylen );
|
||||
/* check that the algo is in the preferences and whether it has expired */
|
||||
{
|
||||
PKT_public_key *pk = NULL;
|
||||
KBNODE pkb = get_pubkeyblock (keyid);
|
||||
|
||||
if( !pkb ) {
|
||||
rc = -1;
|
||||
log_error("oops: public key not found for preference check\n");
|
||||
}
|
||||
else if(pkb->pkt->pkt.public_key->selfsigversion > 3
|
||||
&& dek->algo != CIPHER_ALGO_3DES
|
||||
&& !opt.quiet
|
||||
&& !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ))
|
||||
log_info (_("WARNING: cipher algorithm %s not found in recipient"
|
||||
" preferences\n"), gcry_cipher_algo_name (dek->algo));
|
||||
if (!rc) {
|
||||
KBNODE k;
|
||||
|
||||
for (k=pkb; k; k = k->next) {
|
||||
if (k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
|
||||
u32 aki[2];
|
||||
keyid_from_pk(k->pkt->pkt.public_key, aki);
|
||||
|
||||
if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
|
||||
pk = k->pkt->pkt.public_key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pk)
|
||||
BUG ();
|
||||
if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
|
||||
log_info(_("NOTE: secret key %s expired at %s\n"),
|
||||
keystr(keyid), asctimestamp( pk->expiredate) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( pk && pk->is_revoked ) {
|
||||
log_info( _("NOTE: key has been revoked") );
|
||||
putc( '\n', log_get_stream() );
|
||||
show_revocation_reason( pk, 1 );
|
||||
}
|
||||
|
||||
release_kbnode (pkb);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
release_kbnode (pkb);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
gcry_mpi_release (plain_dek);
|
||||
xfree (frame);
|
||||
return rc;
|
||||
leave:
|
||||
gcry_mpi_release (plain_dek);
|
||||
xfree (frame);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -324,21 +336,21 @@ get_override_session_key( DEK *dek, const char *string )
|
||||
int i;
|
||||
|
||||
if ( !string )
|
||||
return GPG_ERR_BAD_KEY;
|
||||
return G10ERR_BAD_KEY;
|
||||
dek->algo = atoi(string);
|
||||
if ( dek->algo < 1 )
|
||||
return GPG_ERR_BAD_KEY;
|
||||
return G10ERR_BAD_KEY;
|
||||
if ( !(s = strchr ( string, ':' )) )
|
||||
return GPG_ERR_BAD_KEY;
|
||||
return G10ERR_BAD_KEY;
|
||||
s++;
|
||||
for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) {
|
||||
int c = hextobyte ( s );
|
||||
if (c == -1)
|
||||
return GPG_ERR_BAD_KEY;
|
||||
return G10ERR_BAD_KEY;
|
||||
dek->key[i] = c;
|
||||
}
|
||||
if ( *s )
|
||||
return GPG_ERR_BAD_KEY;
|
||||
return G10ERR_BAD_KEY;
|
||||
dek->keylen = i;
|
||||
return 0;
|
||||
}
|
||||
|
174
g10/revoke.c
174
g10/revoke.c
@ -1,5 +1,6 @@
|
||||
/* revoke.c
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
* 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -26,11 +28,11 @@
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "ttyio.h"
|
||||
@ -59,15 +61,15 @@ revocation_reason_build_cb( PKT_signature *sig, void *opaque )
|
||||
ud = native_to_utf8( reason->desc );
|
||||
buflen += strlen(ud);
|
||||
}
|
||||
buffer = xmalloc ( buflen );
|
||||
buffer = xmalloc( buflen );
|
||||
*buffer = reason->code;
|
||||
if( ud ) {
|
||||
memcpy(buffer+1, ud, strlen(ud) );
|
||||
xfree ( ud );
|
||||
xfree( ud );
|
||||
}
|
||||
|
||||
build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
|
||||
xfree ( buffer );
|
||||
xfree( buffer );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -76,7 +78,7 @@ revocation_reason_build_cb( PKT_signature *sig, void *opaque )
|
||||
and pick a user ID that has a uid signature, and include it if
|
||||
possible. */
|
||||
static int
|
||||
export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
export_minimal_pk(IOBUF out,KBNODE keyblock,
|
||||
PKT_signature *revsig,PKT_signature *revkey)
|
||||
{
|
||||
KBNODE node;
|
||||
@ -89,8 +91,8 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
node=find_kbnode(keyblock,PKT_PUBLIC_KEY);
|
||||
if(!node)
|
||||
{
|
||||
log_error(_("key incomplete\n"));
|
||||
return GPG_ERR_GENERAL;
|
||||
log_error("key incomplete\n");
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
keyid_from_pk(node->pkt->pkt.public_key,keyid);
|
||||
@ -99,7 +101,7 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
rc=build_packet(out,&pkt);
|
||||
if(rc)
|
||||
{
|
||||
log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -113,7 +115,7 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
rc=build_packet(out,&pkt);
|
||||
if(rc)
|
||||
{
|
||||
log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -125,7 +127,7 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
rc=build_packet(out,&pkt);
|
||||
if(rc)
|
||||
{
|
||||
log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -142,8 +144,8 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
break;
|
||||
else
|
||||
{
|
||||
log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]);
|
||||
return GPG_ERR_GENERAL;
|
||||
log_error(_("key %s has no user IDs\n"),keystr(keyid));
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +173,7 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
rc=build_packet(out,&pkt);
|
||||
if(rc)
|
||||
{
|
||||
log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -183,7 +185,7 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
rc=build_packet(out,&pkt);
|
||||
if(rc)
|
||||
{
|
||||
log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -195,39 +197,41 @@ export_minimal_pk(iobuf_t out,KBNODE keyblock,
|
||||
* Generate a revocation certificate for UNAME via a designated revoker
|
||||
*/
|
||||
int
|
||||
gen_desig_revoke( const char *uname )
|
||||
gen_desig_revoke( const char *uname, STRLIST locusr )
|
||||
{
|
||||
int rc = 0;
|
||||
armor_filter_context_t afx;
|
||||
PKT_public_key *pk = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
PKT_signature *sig = NULL;
|
||||
iobuf_t out = NULL;
|
||||
IOBUF out = NULL;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
KEYDB_HANDLE kdbhd;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
KBNODE keyblock=NULL,node;
|
||||
u32 keyid[2];
|
||||
int i,any=0;
|
||||
SK_LIST sk_list=NULL;
|
||||
|
||||
if( opt.batch ) {
|
||||
log_error(_("sorry, can't do this in batch mode\n"));
|
||||
return GPG_ERR_GENERAL;
|
||||
}
|
||||
if( opt.batch )
|
||||
{
|
||||
log_error(_("can't do this in batch mode\n"));
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
|
||||
kdbhd = keydb_new (0);
|
||||
classify_user_id (uname, &desc);
|
||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID;
|
||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
|
||||
if (rc) {
|
||||
log_error (_("key `%s' not found: %s\n"),uname, gpg_strerror (rc));
|
||||
log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||
if( rc ) {
|
||||
log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
|
||||
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -243,6 +247,13 @@ gen_desig_revoke( const char *uname )
|
||||
|
||||
keyid_from_pk(pk,keyid);
|
||||
|
||||
if(locusr)
|
||||
{
|
||||
rc=build_sk_list(locusr,&sk_list,0,PUBKEY_USAGE_CERT);
|
||||
if(rc)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Are we a designated revoker for this key? */
|
||||
|
||||
if(!pk->revkey && pk->numrevkeys)
|
||||
@ -250,12 +261,39 @@ gen_desig_revoke( const char *uname )
|
||||
|
||||
for(i=0;i<pk->numrevkeys;i++)
|
||||
{
|
||||
SK_LIST list;
|
||||
|
||||
if(sk)
|
||||
free_secret_key(sk);
|
||||
|
||||
sk=xcalloc (1,sizeof(*sk));
|
||||
if(sk_list)
|
||||
{
|
||||
for(list=sk_list;list;list=list->next)
|
||||
{
|
||||
byte fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
|
||||
rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
|
||||
fingerprint_from_sk(list->sk,fpr,&fprlen);
|
||||
|
||||
/* Don't get involved with keys that don't have 160
|
||||
bit fingerprints */
|
||||
if(fprlen!=20)
|
||||
continue;
|
||||
|
||||
if(memcmp(fpr,pk->revkey[i].fpr,20)==0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(list)
|
||||
sk=copy_secret_key(NULL,list->sk);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
sk=xmalloc_secure_clear(sizeof(*sk));
|
||||
rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
|
||||
}
|
||||
|
||||
/* We have the revocation key */
|
||||
if(!rc)
|
||||
@ -275,7 +313,7 @@ gen_desig_revoke( const char *uname )
|
||||
tty_printf("\n");
|
||||
|
||||
if( !cpr_get_answer_is_yes("gen_desig_revoke.okay",
|
||||
_("Create a revocation certificate for this key? ")) )
|
||||
_("Create a designated revocation certificate for this key? (y/N) ")))
|
||||
continue;
|
||||
|
||||
/* get the reason for the revocation (this is always v4) */
|
||||
@ -294,7 +332,8 @@ gen_desig_revoke( const char *uname )
|
||||
goto leave;
|
||||
|
||||
afx.what = 1;
|
||||
afx.hdrlines = "Comment: A revocation certificate should follow\n";
|
||||
afx.hdrlines = "Comment: A designated revocation certificate"
|
||||
" should follow\n";
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
|
||||
/* create it */
|
||||
@ -302,7 +341,7 @@ gen_desig_revoke( const char *uname )
|
||||
0, 0, 0,
|
||||
revocation_reason_build_cb, reason );
|
||||
if( rc ) {
|
||||
log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
|
||||
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -371,7 +410,7 @@ gen_desig_revoke( const char *uname )
|
||||
}
|
||||
|
||||
if(!any)
|
||||
log_error(_("no revocation keys found for `%s'\n"),uname);
|
||||
log_error(_("no revocation keys found for \"%s\"\n"),uname);
|
||||
|
||||
leave:
|
||||
if( pk )
|
||||
@ -381,6 +420,8 @@ gen_desig_revoke( const char *uname )
|
||||
if( sig )
|
||||
free_seckey_enc( sig );
|
||||
|
||||
release_sk_list(sk_list);
|
||||
|
||||
if( rc )
|
||||
iobuf_cancel(out);
|
||||
else
|
||||
@ -403,17 +444,18 @@ gen_revoke( const char *uname )
|
||||
PKT_public_key *pk = NULL;
|
||||
PKT_signature *sig = NULL;
|
||||
u32 sk_keyid[2];
|
||||
iobuf_t out = NULL;
|
||||
IOBUF out = NULL;
|
||||
KBNODE keyblock = NULL, pub_keyblock = NULL;
|
||||
KBNODE node;
|
||||
KEYDB_HANDLE kdbhd;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
|
||||
if( opt.batch ) {
|
||||
log_error(_("sorry, can't do this in batch mode\n"));
|
||||
return GPG_ERR_GENERAL;
|
||||
}
|
||||
if( opt.batch )
|
||||
{
|
||||
log_error(_("can't do this in batch mode\n"));
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
init_packet( &pkt );
|
||||
@ -423,16 +465,17 @@ gen_revoke( const char *uname )
|
||||
*/
|
||||
kdbhd = keydb_new (1);
|
||||
classify_user_id (uname, &desc);
|
||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID;
|
||||
if (rc) {
|
||||
log_error (_("secret key `%s' not found: %s\n"),
|
||||
uname, gpg_strerror (rc));
|
||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("secret key \"%s\" not found: %s\n"),
|
||||
uname, g10_errstr (rc));
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||
if( rc ) {
|
||||
log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
|
||||
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -447,14 +490,14 @@ gen_revoke( const char *uname )
|
||||
keyid_from_sk( sk, sk_keyid );
|
||||
print_seckey_info (sk);
|
||||
|
||||
pk = xcalloc (1, sizeof *pk );
|
||||
pk = xmalloc_clear( sizeof *pk );
|
||||
|
||||
/* FIXME: We should get the public key direct from the secret one */
|
||||
|
||||
pub_keyblock=get_pubkeyblock(sk_keyid);
|
||||
if(!pub_keyblock)
|
||||
{
|
||||
log_error(_("no corresponding public key: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -466,16 +509,17 @@ gen_revoke( const char *uname )
|
||||
|
||||
if( cmp_public_secret_key( pk, sk ) ) {
|
||||
log_error(_("public key does not match secret key!\n") );
|
||||
rc = GPG_ERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
tty_printf("\n");
|
||||
if( !cpr_get_answer_is_yes("gen_revoke.okay",
|
||||
_("Create a revocation certificate for this key? ")) ){
|
||||
_("Create a revocation certificate for this key? (y/N) ")) )
|
||||
{
|
||||
rc = 0;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if(sk->version>=4 || opt.force_v4_certs) {
|
||||
/* get the reason for the revocation */
|
||||
@ -489,13 +533,17 @@ gen_revoke( const char *uname )
|
||||
switch( is_secret_key_protected( sk ) ) {
|
||||
case -1:
|
||||
log_error(_("unknown protection algorithm\n"));
|
||||
rc = GPG_ERR_PUBKEY_ALGO;
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
break;
|
||||
case -3:
|
||||
tty_printf (_("Secret parts of primary key are not available.\n"));
|
||||
rc = G10ERR_NO_SECKEY;
|
||||
break;
|
||||
case 0:
|
||||
tty_printf(_("NOTE: This key is not protected!\n"));
|
||||
break;
|
||||
default:
|
||||
rc = check_secret_key( sk, 0 );
|
||||
rc = check_secret_key( sk, 0 );
|
||||
break;
|
||||
}
|
||||
if( rc )
|
||||
@ -517,7 +565,7 @@ gen_revoke( const char *uname )
|
||||
opt.force_v4_certs?4:0, 0, 0,
|
||||
revocation_reason_build_cb, reason );
|
||||
if( rc ) {
|
||||
log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
|
||||
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -537,7 +585,7 @@ gen_revoke( const char *uname )
|
||||
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
@ -581,7 +629,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
||||
|
||||
do {
|
||||
code=-1;
|
||||
xfree (description);
|
||||
xfree(description);
|
||||
description = NULL;
|
||||
|
||||
tty_printf(_("Please select the reason for the revocation:\n"));
|
||||
@ -612,7 +660,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
||||
n = -1;
|
||||
else
|
||||
n = atoi(answer);
|
||||
xfree (answer);
|
||||
xfree(answer);
|
||||
if( n == 0 ) {
|
||||
code = 0x00; /* no particular reason */
|
||||
code_text = text_0;
|
||||
@ -644,25 +692,25 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
||||
trim_trailing_ws( answer, strlen(answer) );
|
||||
cpr_kill_prompt();
|
||||
if( !*answer ) {
|
||||
xfree (answer);
|
||||
xfree(answer);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
char *p = make_printable_string( answer, strlen(answer), 0 );
|
||||
xfree (answer);
|
||||
xfree(answer);
|
||||
answer = p;
|
||||
}
|
||||
|
||||
if( !description )
|
||||
description = xstrdup (answer);
|
||||
description = xstrdup(answer);
|
||||
else {
|
||||
char *p = xmalloc ( strlen(description) + strlen(answer) + 2 );
|
||||
char *p = xmalloc( strlen(description) + strlen(answer) + 2 );
|
||||
strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
|
||||
xfree (description);
|
||||
xfree(description);
|
||||
description = p;
|
||||
}
|
||||
xfree (answer);
|
||||
xfree(answer);
|
||||
}
|
||||
|
||||
tty_printf(_("Reason for revocation: %s\n"), code_text );
|
||||
@ -672,9 +720,9 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
||||
tty_printf("%s\n", description );
|
||||
|
||||
} while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
|
||||
_("Is this okay? ")) );
|
||||
_("Is this okay? (y/N) ")) );
|
||||
|
||||
reason = xmalloc ( sizeof *reason );
|
||||
reason = xmalloc( sizeof *reason );
|
||||
reason->code = code;
|
||||
reason->desc = description;
|
||||
return reason;
|
||||
@ -684,7 +732,7 @@ void
|
||||
release_revocation_reason_info( struct revocation_reason_info *reason )
|
||||
{
|
||||
if( reason ) {
|
||||
xfree ( reason->desc );
|
||||
xfree ( reason );
|
||||
xfree( reason->desc );
|
||||
xfree( reason );
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* seckey-cert.c - secret key certificate packet handling
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -27,9 +28,7 @@
|
||||
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "packet.h"
|
||||
#include "mpi.h"
|
||||
#include "keydb.h"
|
||||
#include "cipher.h"
|
||||
#include "main.h"
|
||||
@ -42,21 +41,21 @@ static int
|
||||
do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
int *canceled )
|
||||
{
|
||||
gpg_error_t err;
|
||||
byte *buffer;
|
||||
u16 csum=0;
|
||||
int i, res;
|
||||
unsigned nbytes;
|
||||
gpg_error_t rc;
|
||||
unsigned int nbytes;
|
||||
|
||||
if( sk->is_protected ) { /* remove the protection */
|
||||
DEK *dek = NULL;
|
||||
u32 keyid[4]; /* 4! because we need two of them */
|
||||
CIPHER_HANDLE cipher_hd=NULL;
|
||||
gcry_cipher_hd_t cipher_hd=NULL;
|
||||
PKT_secret_key *save_sk;
|
||||
|
||||
if( sk->protect.s2k.mode == 1001 ) {
|
||||
log_info(_("secret key parts are not available\n"));
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
if( sk->protect.algo == CIPHER_ALGO_NONE )
|
||||
BUG();
|
||||
@ -68,8 +67,14 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
write_status (STATUS_RSA_OR_IDEA);
|
||||
idea_cipher_warn (0);
|
||||
}
|
||||
return GPG_ERR_CIPHER_ALGO;
|
||||
return G10ERR_CIPHER_ALGO;
|
||||
}
|
||||
if(gcry_md_test_algo (sk->protect.s2k.hash_algo))
|
||||
{
|
||||
log_info(_("protection digest %d is not supported\n"),
|
||||
sk->protect.s2k.hash_algo);
|
||||
return G10ERR_DIGEST_ALGO;
|
||||
}
|
||||
keyid_from_sk( sk, keyid );
|
||||
keyid[2] = keyid[3] = 0;
|
||||
if( !sk->is_primary ) {
|
||||
@ -80,39 +85,45 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
&sk->protect.s2k, mode,
|
||||
tryagain_text, canceled );
|
||||
if (!dek && canceled && *canceled)
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
rc = gcry_cipher_open (&cipher_hd, sk->protect.algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
GCRY_CIPHER_SECURE
|
||||
| (sk->protect.algo >= 100 ?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC));
|
||||
if (rc)
|
||||
log_fatal ("cipher open failed: %s\n", gpg_strerror (rc) );
|
||||
|
||||
rc = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen);
|
||||
if (rc)
|
||||
log_fatal ("set key failed: %s\n", gpg_strerror (rc) );
|
||||
err = gcry_cipher_open (&cipher_hd, sk->protect.algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
(GCRY_CIPHER_SECURE
|
||||
| (sk->protect.algo >= 100 ?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC)));
|
||||
if (err)
|
||||
log_fatal ("cipher open failed: %s\n", gpg_strerror (err) );
|
||||
|
||||
xfree (dek);
|
||||
err = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen);
|
||||
if (err)
|
||||
log_fatal ("set key failed: %s\n", gpg_strerror (err) );
|
||||
|
||||
xfree(dek);
|
||||
save_sk = copy_secret_key( NULL, sk );
|
||||
gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen);
|
||||
|
||||
gcry_cipher_setiv ( cipher_hd, sk->protect.iv, sk->protect.ivlen );
|
||||
|
||||
csum = 0;
|
||||
if( sk->version >= 4 ) {
|
||||
int ndata;
|
||||
unsigned int ndatabits;
|
||||
int ndata;
|
||||
unsigned int ndatabits;
|
||||
byte *p, *data;
|
||||
u16 csumc = 0;
|
||||
|
||||
i = pubkey_get_npkey(sk->pubkey_algo);
|
||||
assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE ));
|
||||
p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits );
|
||||
|
||||
assert ( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE ));
|
||||
p = gcry_mpi_get_opaque ( sk->skey[i], &ndatabits );
|
||||
ndata = (ndatabits+7)/8;
|
||||
|
||||
if ( ndata > 1 )
|
||||
csumc = p[ndata-2] << 8 | p[ndata-1];
|
||||
data = gcry_xmalloc_secure ( ndata );
|
||||
gcry_cipher_decrypt( cipher_hd, data, ndata, p, ndata );
|
||||
gcry_mpi_release ( sk->skey[i] ); sk->skey[i] = NULL ;
|
||||
data = xmalloc_secure ( ndata );
|
||||
gcry_cipher_decrypt ( cipher_hd, data, ndata, p, ndata );
|
||||
gcry_mpi_release (sk->skey[i]); sk->skey[i] = NULL ;
|
||||
|
||||
p = data;
|
||||
if (sk->protect.sha1chk) {
|
||||
/* This is the new SHA1 checksum method to detect
|
||||
@ -126,18 +137,19 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
gcry_md_hd_t h;
|
||||
|
||||
if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1))
|
||||
BUG(); /* algo not available */
|
||||
BUG(); /* Algo not available. */
|
||||
gcry_md_write (h, data, ndata - 20);
|
||||
gcry_md_final (h);
|
||||
if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1),
|
||||
data + ndata - 20, 20) ) {
|
||||
/* digest does match. We have to keep the old
|
||||
data + ndata - 20, 20) )
|
||||
{
|
||||
/* Digest does match. We have to keep the old
|
||||
style checksum in sk->csum, so that the
|
||||
test used for unprotected keys does work.
|
||||
This test gets used when we are adding new
|
||||
keys. */
|
||||
sk->csum = csum = checksum (data, ndata-20);
|
||||
}
|
||||
}
|
||||
gcry_md_close (h);
|
||||
}
|
||||
}
|
||||
@ -156,24 +168,27 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* must check it here otherwise the mpi_read_xx would fail
|
||||
|
||||
/* Must check it here otherwise the mpi_read_xx would fail
|
||||
because the length may have an arbitrary value */
|
||||
if( sk->csum == csum ) {
|
||||
for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
|
||||
assert( gcry_is_secure( p ) );
|
||||
res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
|
||||
p, ndata, &nbytes);
|
||||
if( res )
|
||||
log_bug ("gcry_mpi_scan failed in do_check: %s\n",
|
||||
gpg_strerror (res));
|
||||
if ( gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
|
||||
p, ndata, &nbytes))
|
||||
{
|
||||
/* Checksum was okay, but not correctly
|
||||
decrypted. */
|
||||
sk->csum = 0;
|
||||
csum = 1;
|
||||
break;
|
||||
}
|
||||
ndata -= nbytes;
|
||||
p += nbytes;
|
||||
}
|
||||
/* Note: at this point ndata should be 2 for a simple
|
||||
checksum or 20 for the sha1 digest */
|
||||
}
|
||||
xfree (data);
|
||||
xfree(data);
|
||||
}
|
||||
else {
|
||||
for(i=pubkey_get_npkey(sk->pubkey_algo);
|
||||
@ -182,12 +197,12 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
int ndata;
|
||||
unsigned int ndatabits;
|
||||
|
||||
assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
|
||||
p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits );
|
||||
assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
|
||||
p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
|
||||
ndata = (ndatabits+7)/8;
|
||||
assert (ndata >= 2);
|
||||
assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
|
||||
buffer = gcry_xmalloc_secure (ndata);
|
||||
buffer = xmalloc_secure (ndata);
|
||||
gcry_cipher_sync (cipher_hd);
|
||||
buffer[0] = p[0];
|
||||
buffer[1] = p[1];
|
||||
@ -195,33 +210,39 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
p+2, ndata-2);
|
||||
csum += checksum (buffer, ndata);
|
||||
gcry_mpi_release (sk->skey[i]);
|
||||
res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_USG,
|
||||
buffer, ndata, &ndata );
|
||||
if( res )
|
||||
log_bug ("gcry_mpi_scan failed in do_check: %s\n",
|
||||
gpg_strerror (res));
|
||||
|
||||
assert (sk->skey[i]);
|
||||
err = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_USG,
|
||||
buffer, ndata, &ndata );
|
||||
xfree (buffer);
|
||||
if (err)
|
||||
{
|
||||
/* Checksum was okay, but not correctly
|
||||
decrypted. */
|
||||
sk->csum = 0;
|
||||
csum = 1;
|
||||
break;
|
||||
}
|
||||
/* csum += checksum_mpi (sk->skey[i]); */
|
||||
}
|
||||
}
|
||||
gcry_cipher_close (cipher_hd);
|
||||
/* now let's see whether we have used the right passphrase */
|
||||
gcry_cipher_close ( cipher_hd );
|
||||
|
||||
/* Now let's see whether we have used the correct passphrase. */
|
||||
if( csum != sk->csum ) {
|
||||
copy_secret_key( sk, save_sk );
|
||||
passphrase_clear_cache ( keyid, sk->pubkey_algo );
|
||||
passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
|
||||
free_secret_key( save_sk );
|
||||
return gpg_error (GPG_ERR_BAD_PASSPHRASE);
|
||||
return G10ERR_BAD_PASS;
|
||||
}
|
||||
|
||||
/* The checksum may fail, so we also check the key itself. */
|
||||
res = pk_check_secret_key ( sk->pubkey_algo, sk->skey );
|
||||
if( res ) {
|
||||
copy_secret_key( sk, save_sk );
|
||||
passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
|
||||
free_secret_key( save_sk );
|
||||
return G10ERR_BAD_PASS;
|
||||
}
|
||||
/* the checksum may fail, so we also check the key itself */
|
||||
res = pk_check_secret_key (sk->pubkey_algo, sk->skey);
|
||||
if (res) {
|
||||
copy_secret_key( sk, save_sk );
|
||||
passphrase_clear_cache ( keyid, sk->pubkey_algo );
|
||||
free_secret_key( save_sk );
|
||||
return gpg_error (GPG_ERR_BAD_PASSPHRASE);
|
||||
}
|
||||
free_secret_key( save_sk );
|
||||
sk->is_protected = 0;
|
||||
}
|
||||
@ -232,7 +253,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
|
||||
csum += checksum_mpi( sk->skey[i] );
|
||||
}
|
||||
if( csum != sk->csum )
|
||||
return GPG_ERR_CHECKSUM;
|
||||
return G10ERR_CHECKSUM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -252,7 +273,7 @@ check_secret_key( PKT_secret_key *sk, int n )
|
||||
int i,mode;
|
||||
|
||||
if (sk && sk->is_protected && sk->protect.s2k.mode == 1002)
|
||||
return 0; /* Let the scdaemon handle it. */
|
||||
return 0; /* Let the scdaemon handle this. */
|
||||
|
||||
if(n<0)
|
||||
{
|
||||
@ -265,7 +286,7 @@ check_secret_key( PKT_secret_key *sk, int n )
|
||||
if( n < 1 )
|
||||
n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */
|
||||
|
||||
for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) {
|
||||
for(i=0; i < n && gpg_err_code (rc) == G10ERR_BAD_PASS; i++ ) {
|
||||
int canceled = 0;
|
||||
const char *tryagain = NULL;
|
||||
if (i) {
|
||||
@ -273,8 +294,7 @@ check_secret_key( PKT_secret_key *sk, int n )
|
||||
log_info (_("%s ...\n"), _(tryagain));
|
||||
}
|
||||
rc = do_check( sk, tryagain, mode, &canceled );
|
||||
if( gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
|
||||
&& is_status_enabled() ) {
|
||||
if ( gpg_err_code (rc) == G10ERR_BAD_PASS && is_status_enabled () ) {
|
||||
u32 kid[2];
|
||||
char buf[50];
|
||||
|
||||
@ -296,13 +316,14 @@ check_secret_key( PKT_secret_key *sk, int n )
|
||||
* check whether the secret key is protected.
|
||||
* Returns: 0 not protected, -1 on error or the protection algorithm
|
||||
* -2 indicates a card stub.
|
||||
* -3 indicates a not-online stub.
|
||||
*/
|
||||
int
|
||||
is_secret_key_protected( PKT_secret_key *sk )
|
||||
{
|
||||
return sk->is_protected?
|
||||
sk->protect.s2k.mode == 1002? -2
|
||||
: sk->protect.algo : 0;
|
||||
sk->protect.s2k.mode == 1002? -2 :
|
||||
sk->protect.s2k.mode == 1001? -3 : sk->protect.algo : 0;
|
||||
}
|
||||
|
||||
|
||||
@ -324,54 +345,52 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
if( !sk->is_protected ) { /* okay, apply the protection */
|
||||
gcry_cipher_hd_t cipher_hd=NULL;
|
||||
|
||||
if( openpgp_cipher_test_algo( sk->protect.algo ) )
|
||||
{
|
||||
rc = gpg_error (GPG_ERR_CIPHER_ALGO); /* unsupport
|
||||
protection
|
||||
algorithm */
|
||||
}
|
||||
if ( openpgp_cipher_test_algo ( sk->protect.algo ) ) {
|
||||
/* Unsupport protection algorithm. */
|
||||
rc = gpg_error (GPG_ERR_CIPHER_ALGO);
|
||||
}
|
||||
else {
|
||||
print_cipher_algo_note( sk->protect.algo );
|
||||
rc = gcry_cipher_open (&cipher_hd, sk->protect.algo,
|
||||
|
||||
if ( gcry_cipher_open (&cipher_hd, sk->protect.algo,
|
||||
GCRY_CIPHER_MODE_CFB,
|
||||
GCRY_CIPHER_SECURE
|
||||
| (sk->protect.algo >= 100 ?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC) );
|
||||
if (rc)
|
||||
(GCRY_CIPHER_SECURE
|
||||
| (sk->protect.algo >= 100 ?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC))) )
|
||||
BUG();
|
||||
if( gcry_cipher_setkey( cipher_hd, dek->key, dek->keylen ) )
|
||||
if ( gcry_cipher_setkey ( cipher_hd, dek->key, dek->keylen ) )
|
||||
log_info(_("WARNING: Weak key detected"
|
||||
" - please change passphrase again.\n"));
|
||||
sk->protect.ivlen = gcry_cipher_get_algo_blklen(sk->protect.algo);
|
||||
sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo);
|
||||
assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
|
||||
if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 )
|
||||
BUG(); /* yes, we are very careful */
|
||||
gcry_create_nonce (sk->protect.iv, sk->protect.ivlen);
|
||||
gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
|
||||
gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen);
|
||||
if( sk->version >= 4 ) {
|
||||
unsigned char *bufarr[PUBKEY_MAX_NSKEY];
|
||||
byte *bufarr[PUBKEY_MAX_NSKEY];
|
||||
unsigned narr[PUBKEY_MAX_NSKEY];
|
||||
unsigned nbits[PUBKEY_MAX_NSKEY];
|
||||
int ndata=0;
|
||||
byte *p, *data;
|
||||
|
||||
for(j=0, i = pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) {
|
||||
assert( !gcry_mpi_get_flag( sk->skey[i],
|
||||
GCRYMPI_FLAG_OPAQUE ));
|
||||
|
||||
if( gcry_mpi_aprint( GCRYMPI_FMT_USG, bufarr+j,
|
||||
for (j=0, i = pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ )
|
||||
{
|
||||
assert (!gcry_mpi_get_flag (sk->skey[i],
|
||||
GCRYMPI_FLAG_OPAQUE));
|
||||
if (gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j,
|
||||
narr+j, sk->skey[i]))
|
||||
BUG();
|
||||
|
||||
nbits[j] = gcry_mpi_get_nbits( sk->skey[i] );
|
||||
BUG();
|
||||
nbits[j] = gcry_mpi_get_nbits (sk->skey[i]);
|
||||
ndata += narr[j] + 2;
|
||||
}
|
||||
for( ; j < PUBKEY_MAX_NSKEY; j++ )
|
||||
bufarr[j] = NULL;
|
||||
}
|
||||
for ( ; j < PUBKEY_MAX_NSKEY; j++ )
|
||||
bufarr[j] = NULL;
|
||||
|
||||
ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */
|
||||
|
||||
data = xmalloc_secure ( ndata );
|
||||
data = xmalloc_secure( ndata );
|
||||
p = data;
|
||||
for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) {
|
||||
p[0] = nbits[j] >> 8 ;
|
||||
@ -379,7 +398,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
p += 2;
|
||||
memcpy(p, bufarr[j], narr[j] );
|
||||
p += narr[j];
|
||||
xfree (bufarr[j]);
|
||||
xfree(bufarr[j]);
|
||||
}
|
||||
|
||||
if (opt.simple_sk_checksum) {
|
||||
@ -395,10 +414,10 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
gcry_md_hd_t h;
|
||||
|
||||
if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
|
||||
BUG(); /* algo not available */
|
||||
BUG(); /* Algo not available. */
|
||||
gcry_md_write (h, data, ndata - 20);
|
||||
gcry_md_final (h);
|
||||
memcpy (p, gcry_md_read (h, GCRY_MD_SHA1), 20);
|
||||
memcpy (p, gcry_md_read (h, DIGEST_ALGO_SHA1), 20);
|
||||
p += 20;
|
||||
gcry_md_close (h);
|
||||
sk->csum = csum = 0;
|
||||
@ -406,14 +425,15 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
}
|
||||
assert( p == data+ndata );
|
||||
|
||||
gcry_cipher_encrypt( cipher_hd, data, ndata, NULL, 0 );
|
||||
for(i = pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
|
||||
gcry_mpi_release ( sk->skey[i] );
|
||||
gcry_cipher_encrypt (cipher_hd, data, ndata, NULL, 0);
|
||||
for (i = pubkey_get_npkey(sk->pubkey_algo);
|
||||
i < pubkey_get_nskey(sk->pubkey_algo); i++ )
|
||||
{
|
||||
gcry_mpi_release (sk->skey[i]);
|
||||
sk->skey[i] = NULL;
|
||||
}
|
||||
}
|
||||
i = pubkey_get_npkey(sk->pubkey_algo);
|
||||
sk->skey[i] = gcry_mpi_set_opaque(NULL, data, ndata*8);
|
||||
sk->skey[i] = gcry_mpi_set_opaque (NULL, data, ndata*8 );
|
||||
}
|
||||
else {
|
||||
csum = 0;
|
||||
@ -423,30 +443,33 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
|
||||
unsigned int nbits;
|
||||
|
||||
csum += checksum_mpi (sk->skey[i]);
|
||||
if( gcry_mpi_aprint( GCRYMPI_FMT_USG, &buffer,
|
||||
&nbytes, sk->skey[i] ) )
|
||||
BUG();
|
||||
|
||||
if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer,
|
||||
&nbytes, sk->skey[i] ))
|
||||
BUG();
|
||||
gcry_cipher_sync (cipher_hd);
|
||||
assert (!gcry_mpi_get_flag( sk->skey[i],
|
||||
GCRYMPI_FLAG_OPAQUE ));
|
||||
data = xmalloc (nbytes+2);
|
||||
nbits = gcry_mpi_get_nbits (sk->skey[i]);
|
||||
assert (!gcry_mpi_get_flag (sk->skey[i],
|
||||
GCRYMPI_FLAG_OPAQUE));
|
||||
|
||||
data = xmalloc (nbytes+2); /* fixme: need xtrymalloc. */
|
||||
nbits = gcry_mpi_get_nbits (sk->skey[i]);
|
||||
assert (nbytes == (nbits + 7)/8);
|
||||
data[0] = nbits >> 8;
|
||||
data[1] = nbits;
|
||||
gcry_cipher_encrypt (cipher_hd, data+2, nbytes,
|
||||
buffer, nbytes);
|
||||
xfree ( buffer );
|
||||
xfree( buffer );
|
||||
|
||||
gcry_mpi_release (sk->skey[i]);
|
||||
sk->skey[i] = gcry_mpi_set_opaque (NULL, data,
|
||||
(nbytes+2)*8);
|
||||
sk->skey[i] = gcry_mpi_set_opaque (NULL,
|
||||
data, (nbytes+2)*8 );
|
||||
}
|
||||
sk->csum = csum;
|
||||
}
|
||||
sk->is_protected = 1;
|
||||
gcry_cipher_close( cipher_hd );
|
||||
gcry_cipher_close (cipher_hd);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
193
g10/seskey.c
193
g10/seskey.c
@ -1,5 +1,6 @@
|
||||
/* seskey.c - make sesssion keys etc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -27,10 +29,9 @@
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "mpi.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
#include "options.h"
|
||||
|
||||
|
||||
/****************
|
||||
* Make a session key and put it into DEK
|
||||
@ -38,35 +39,33 @@
|
||||
void
|
||||
make_session_key( DEK *dek )
|
||||
{
|
||||
gcry_cipher_hd_t chd;
|
||||
int i, rc;
|
||||
gcry_cipher_hd_t chd;
|
||||
int i, rc;
|
||||
|
||||
dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
|
||||
dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
|
||||
|
||||
if (gcry_cipher_open (&chd, dek->algo, GCRY_CIPHER_MODE_CFB,
|
||||
if (gcry_cipher_open (&chd, dek->algo, GCRY_CIPHER_MODE_CFB,
|
||||
(GCRY_CIPHER_SECURE
|
||||
| (dek->algo >= 100 ?
|
||||
0 : GCRY_CIPHER_ENABLE_SYNC))) )
|
||||
BUG();
|
||||
|
||||
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
|
||||
for (i=0; i < 16; i++ )
|
||||
{
|
||||
rc = gcry_cipher_setkey (chd, dek->key, dek->keylen);
|
||||
if (!rc)
|
||||
{
|
||||
gcry_cipher_close (chd);
|
||||
return;
|
||||
}
|
||||
if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
|
||||
BUG();
|
||||
log_info (_("weak key created - retrying\n") );
|
||||
/* Renew the session key until we get a non-weak key. */
|
||||
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
|
||||
}
|
||||
|
||||
log_fatal (_("cannot avoid weak key for symmetric cipher; "
|
||||
"tried %d times!\n"), i);
|
||||
BUG();
|
||||
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
|
||||
for (i=0; i < 16; i++ )
|
||||
{
|
||||
rc = gcry_cipher_setkey (chd, dek->key, dek->keylen);
|
||||
if (!rc)
|
||||
{
|
||||
gcry_cipher_close (chd);
|
||||
return;
|
||||
}
|
||||
if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
|
||||
BUG();
|
||||
log_info(_("weak key created - retrying\n") );
|
||||
/* Renew the session key until we get a non-weak key. */
|
||||
gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM);
|
||||
}
|
||||
log_fatal (_("cannot avoid weak key for symmetric cipher; "
|
||||
"tried %d times!\n"), i);
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +84,7 @@ encode_session_key (DEK *dek, unsigned int nbits)
|
||||
u16 csum;
|
||||
gcry_mpi_t a;
|
||||
|
||||
/* the current limitation is that we can only use a session key
|
||||
/* The current limitation is that we can only use a session key
|
||||
* whose length is a multiple of BITS_PER_MPI_LIMB
|
||||
* I think we can live with that.
|
||||
*/
|
||||
@ -110,14 +109,14 @@ encode_session_key (DEK *dek, unsigned int nbits)
|
||||
for( p = dek->key, i=0; i < dek->keylen; i++ )
|
||||
csum += *p++;
|
||||
|
||||
frame = gcry_xmalloc_secure ( nframe );
|
||||
frame = xmalloc_secure( nframe );
|
||||
n = 0;
|
||||
frame[n++] = 0;
|
||||
frame[n++] = 2;
|
||||
i = nframe - 6 - dek->keylen;
|
||||
assert( i > 0 );
|
||||
p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
|
||||
/* replace zero bytes by new values */
|
||||
/* Replace zero bytes by new values. */
|
||||
for(;;) {
|
||||
int j, k;
|
||||
byte *pp;
|
||||
@ -128,36 +127,35 @@ encode_session_key (DEK *dek, unsigned int nbits)
|
||||
k++;
|
||||
if( !k )
|
||||
break; /* okay: no zero bytes */
|
||||
k += k/128; /* better get some more */
|
||||
pp = gcry_random_bytes_secure( k, GCRY_STRONG_RANDOM);
|
||||
for(j=0; j < i && k ; j++ )
|
||||
k += k/128 + 3; /* better get some more */
|
||||
pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
|
||||
for(j=0; j < i && k ;) {
|
||||
if( !p[j] )
|
||||
p[j] = pp[--k];
|
||||
xfree (pp);
|
||||
if (p[j])
|
||||
j++;
|
||||
}
|
||||
xfree(pp);
|
||||
}
|
||||
memcpy( frame+n, p, i );
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
n += i;
|
||||
frame[n++] = 0;
|
||||
frame[n++] = dek->algo;
|
||||
memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen;
|
||||
frame[n++] = csum >>8;
|
||||
frame[n++] = csum;
|
||||
assert (n == nframe);
|
||||
|
||||
if (DBG_CIPHER)
|
||||
log_printhex ("encoded session key:", frame, nframe );
|
||||
|
||||
assert( n == nframe );
|
||||
if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
|
||||
BUG();
|
||||
xfree (frame);
|
||||
xfree(frame);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
static gcry_mpi_t
|
||||
do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
|
||||
const byte *asn, size_t asnlen, int v3compathack )
|
||||
const byte *asn, size_t asnlen )
|
||||
{
|
||||
int nframe = (nbits+7) / 8;
|
||||
byte *frame;
|
||||
@ -170,14 +168,14 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
|
||||
|
||||
/* We encode the MD in this way:
|
||||
*
|
||||
* 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
|
||||
* 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
|
||||
*
|
||||
* PAD consists of FF bytes.
|
||||
*/
|
||||
frame = gcry_md_is_secure (md)? xmalloc_secure (nframe): xmalloc (nframe);
|
||||
frame = gcry_md_is_secure (md)? xmalloc_secure (nframe) : xmalloc (nframe);
|
||||
n = 0;
|
||||
frame[n++] = 0;
|
||||
frame[n++] = v3compathack? algo : 1; /* block type */
|
||||
frame[n++] = 1; /* block type */
|
||||
i = nframe - len - asnlen -3 ;
|
||||
assert( i > 1 );
|
||||
memset( frame+n, 0xff, i ); n += i;
|
||||
@ -185,36 +183,83 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
|
||||
memcpy( frame+n, asn, asnlen ); n += asnlen;
|
||||
memcpy( frame+n, gcry_md_read (md, algo), len ); n += len;
|
||||
assert( n == nframe );
|
||||
|
||||
if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe ))
|
||||
BUG();
|
||||
xfree (frame);
|
||||
xfree(frame);
|
||||
|
||||
/* Note that PGP before version 2.3 encoded the MD as:
|
||||
*
|
||||
* 0 1 MD(16 bytes) 0 PAD(n bytes) 1
|
||||
*
|
||||
* The MD is always 16 bytes here because it's always MD5. We do
|
||||
* not support pre-v2.3 signatures, but I'm including this comment
|
||||
* so the information is easily found in the future.
|
||||
*/
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Encode a message digest into an MPI.
|
||||
* v3compathack is used to work around a bug in old GnuPG versions
|
||||
* which did put the algo identifier inseatd of the block type 1 into
|
||||
* the encoded value. Setting this flag forces the old behaviour.
|
||||
* If it's for a DSA signature, make sure that the hash is large
|
||||
* enough to fill up q. If the hash is too big, take the leftmost
|
||||
* bits.
|
||||
*/
|
||||
gcry_mpi_t
|
||||
encode_md_value (int pubkey_algo, gcry_md_hd_t md, int hash_algo,
|
||||
unsigned int nbits, int v3compathack )
|
||||
encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
|
||||
gcry_md_hd_t md, int hash_algo)
|
||||
{
|
||||
int algo = hash_algo? hash_algo : gcry_md_get_algo (md);
|
||||
gcry_mpi_t frame;
|
||||
|
||||
if (pubkey_algo == GCRY_PK_DSA)
|
||||
|
||||
assert(hash_algo);
|
||||
assert(pk || sk);
|
||||
|
||||
if((pk?pk->pubkey_algo:sk->pubkey_algo) == GCRY_PK_DSA)
|
||||
{
|
||||
size_t n = gcry_md_get_algo_dlen(hash_algo);
|
||||
if (n != 20)
|
||||
{
|
||||
log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
|
||||
return NULL;
|
||||
}
|
||||
if (gcry_mpi_scan( &frame, GCRYMPI_FMT_USG,
|
||||
gcry_md_read (md, hash_algo), n, &n ) )
|
||||
/* It's a DSA signature, so find out the size of q. */
|
||||
|
||||
unsigned int qbytes = gcry_mpi_get_nbits (pk?pk->pkey[1]:sk->skey[1]);
|
||||
size_t n;
|
||||
|
||||
/* Make sure it is a multiple of 8 bits. */
|
||||
|
||||
if(qbytes%8)
|
||||
{
|
||||
log_error(_("DSA requires the hash length to be a"
|
||||
" multiple of 8 bits\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Don't allow any q smaller than 160 bits. This might need a
|
||||
revisit as the DSA2 design firms up, but for now, we don't
|
||||
want someone to issue signatures from a key with a 16-bit q
|
||||
or something like that, which would look correct but allow
|
||||
trivial forgeries. Yes, I know this rules out using MD5 with
|
||||
DSA. ;) */
|
||||
|
||||
if(qbytes<160)
|
||||
{
|
||||
log_error(_("DSA key %s uses an unsafe (%u bit) hash\n"),
|
||||
pk?keystr_from_pk(pk):keystr_from_sk(sk),qbytes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qbytes/=8;
|
||||
|
||||
/* Check if we're too short. Too long is safe as we'll
|
||||
automatically left-truncate. */
|
||||
|
||||
if(gcry_md_get_algo_dlen (hash_algo) < qbytes)
|
||||
{
|
||||
log_error(_("DSA key %s requires a %u bit or larger hash\n"),
|
||||
pk?keystr_from_pk(pk):keystr_from_sk(sk),qbytes*8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG,
|
||||
gcry_md_read (md, hash_algo), n, &n))
|
||||
BUG();
|
||||
}
|
||||
else
|
||||
@ -222,23 +267,19 @@ encode_md_value (int pubkey_algo, gcry_md_hd_t md, int hash_algo,
|
||||
gpg_error_t rc;
|
||||
byte *asn;
|
||||
size_t asnlen;
|
||||
|
||||
rc = gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, NULL, &asnlen);
|
||||
|
||||
rc = gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, NULL, &asnlen);
|
||||
if (rc)
|
||||
log_fatal("can't get OID of algo %d: %s\n",
|
||||
algo, gpg_strerror (rc));
|
||||
log_fatal ("can't get OID of algo %d: %s\n",
|
||||
hash_algo, gpg_strerror (rc));
|
||||
asn = xmalloc (asnlen);
|
||||
if( gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, asn, &asnlen ) )
|
||||
if ( gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, asn, &asnlen) )
|
||||
BUG();
|
||||
frame = do_encode_md( md, algo, gcry_md_get_algo_dlen( algo ),
|
||||
nbits, asn, asnlen, v3compathack );
|
||||
frame = do_encode_md (md, hash_algo, gcry_md_get_algo_dlen (hash_algo),
|
||||
gcry_mpi_get_nbits (pk?pk->pkey[0]:sk->skey[0]),
|
||||
asn, asnlen);
|
||||
xfree (asn);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
354
g10/sig-check.c
354
g10/sig-check.c
@ -1,6 +1,6 @@
|
||||
/* sig-check.c - Check a signature
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
* 2004, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -28,8 +29,6 @@
|
||||
#include "gpg.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "memory.h"
|
||||
#include "mpi.h"
|
||||
#include "keydb.h"
|
||||
#include "cipher.h"
|
||||
#include "main.h"
|
||||
@ -38,13 +37,17 @@
|
||||
#include "options.h"
|
||||
#include "pkglue.h"
|
||||
|
||||
struct cmp_help_context_s {
|
||||
PKT_signature *sig;
|
||||
MD_HANDLE md;
|
||||
/* Context used by the compare function. */
|
||||
struct cmp_help_context_s
|
||||
{
|
||||
PKT_signature *sig;
|
||||
gcry_md_hd_t md;
|
||||
};
|
||||
|
||||
|
||||
static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
|
||||
|
||||
static int do_check( PKT_public_key *pk, PKT_signature *sig,
|
||||
gcry_md_hd_t digest,
|
||||
int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
|
||||
|
||||
/****************
|
||||
@ -53,37 +56,72 @@ static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
|
||||
* is able to append some data, before finalizing the digest.
|
||||
*/
|
||||
int
|
||||
signature_check( PKT_signature *sig, MD_HANDLE digest )
|
||||
signature_check (PKT_signature *sig, gcry_md_hd_t digest)
|
||||
{
|
||||
return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
|
||||
}
|
||||
|
||||
int
|
||||
signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
|
||||
signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
|
||||
int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
|
||||
{
|
||||
PKT_public_key *pk = xcalloc (1, sizeof *pk );
|
||||
PKT_public_key *pk = xmalloc_clear( sizeof *pk );
|
||||
int rc=0;
|
||||
|
||||
/* Sanity check that the md has a context for the hash that the
|
||||
sig is expecting. This can happen if a onepass sig header does
|
||||
not match the actual sig, and also if the clearsign "Hash:"
|
||||
header is missing or does not match the actual sig. */
|
||||
if ( (rc=openpgp_md_test_algo(sig->digest_algo)) )
|
||||
; /* We don't have this digest. */
|
||||
else if ((rc=openpgp_pk_test_algo(sig->pubkey_algo)))
|
||||
; /* We don't have this pubkey algo. */
|
||||
else if (!gcry_md_is_enabled (digest,sig->digest_algo))
|
||||
{
|
||||
/* Sanity check that the md has a context for the hash that the
|
||||
sig is expecting. This can happen if a onepass sig header does
|
||||
not match the actual sig, and also if the clearsign "Hash:"
|
||||
header is missing or does not match the actual sig. */
|
||||
|
||||
if(!gcry_md_is_enabled (digest,sig->digest_algo)) {
|
||||
log_info(_("WARNING: signature digest conflict in message\n"));
|
||||
rc=GPG_ERR_GENERAL;
|
||||
}
|
||||
rc=G10ERR_GENERAL;
|
||||
}
|
||||
else if( get_pubkey( pk, sig->keyid ) )
|
||||
rc = GPG_ERR_NO_PUBKEY;
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
else if(!pk->is_valid && !pk->is_primary)
|
||||
rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an
|
||||
rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
|
||||
invalid subkey */
|
||||
else {
|
||||
if (r_expiredate)
|
||||
*r_expiredate = pk->expiredate;
|
||||
else
|
||||
{
|
||||
if(r_expiredate)
|
||||
*r_expiredate = pk->expiredate;
|
||||
|
||||
rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
|
||||
}
|
||||
|
||||
/* Check the backsig. This is a 0x19 signature from the
|
||||
subkey on the primary key. The idea here is that it should
|
||||
not be possible for someone to "steal" subkeys and claim
|
||||
them as their own. The attacker couldn't actually use the
|
||||
subkey, but they could try and claim ownership of any
|
||||
signaures issued by it. */
|
||||
if(rc==0 && !pk->is_primary && pk->backsig<2)
|
||||
{
|
||||
if(pk->backsig==0)
|
||||
{
|
||||
log_info(_("WARNING: signing subkey %s is not"
|
||||
" cross-certified\n"),keystr_from_pk(pk));
|
||||
log_info(_("please see %s for more information\n"),
|
||||
"http://www.gnupg.org/faq/subkey-cross-certify.html");
|
||||
/* --require-cross-certification makes this warning an
|
||||
error. TODO: change the default to require this
|
||||
after more keys have backsigs. */
|
||||
if(opt.flags.require_cross_cert)
|
||||
rc=G10ERR_GENERAL;
|
||||
}
|
||||
else if(pk->backsig==1)
|
||||
{
|
||||
log_info(_("WARNING: signing subkey %s has an invalid"
|
||||
" cross-certification\n"),keystr_from_pk(pk));
|
||||
rc=G10ERR_GENERAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_public_key( pk );
|
||||
|
||||
@ -96,35 +134,38 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
|
||||
* one second. Some remote batch processing applications might
|
||||
* like this feature here */
|
||||
gcry_md_hd_t md;
|
||||
|
||||
u32 a = sig->timestamp;
|
||||
int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
|
||||
byte *p, *buffer;
|
||||
|
||||
gcry_md_open (&md, GCRY_MD_RMD160, 0);
|
||||
if (gcry_md_open (&md, GCRY_MD_RMD160, 0))
|
||||
BUG ();
|
||||
|
||||
/* FIXME: Why the hell are we updating DIGEST here??? */
|
||||
gcry_md_putc( digest, sig->pubkey_algo );
|
||||
gcry_md_putc( digest, sig->digest_algo );
|
||||
gcry_md_putc( digest, (a >> 24) & 0xff );
|
||||
gcry_md_putc( digest, (a >> 16) & 0xff );
|
||||
gcry_md_putc( digest, (a >> 8) & 0xff );
|
||||
gcry_md_putc( digest, a & 0xff );
|
||||
gcry_md_putc( digest, (a >> 8) & 0xff );
|
||||
gcry_md_putc( digest, a & 0xff );
|
||||
for(i=0; i < nsig; i++ ) {
|
||||
size_t n;
|
||||
unsigned char *tmp;
|
||||
|
||||
if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i]))
|
||||
BUG();
|
||||
|
||||
BUG();
|
||||
gcry_md_write (md, tmp, n);
|
||||
xfree (tmp);
|
||||
}
|
||||
gcry_md_final( md );
|
||||
p = make_radix64_string( gcry_md_read( md, 0 ), 20 );
|
||||
buffer = xmalloc ( strlen(p) + 60 );
|
||||
gcry_md_final (md);
|
||||
p = make_radix64_string ( gcry_md_read( md, 0 ), 20 );
|
||||
buffer = xmalloc( strlen(p) + 60 );
|
||||
sprintf( buffer, "%s %s %lu",
|
||||
p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
|
||||
write_status_text( STATUS_SIG_ID, buffer );
|
||||
xfree (buffer);
|
||||
xfree (p);
|
||||
xfree(buffer);
|
||||
xfree(p);
|
||||
gcry_md_close(md);
|
||||
}
|
||||
|
||||
@ -134,58 +175,51 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
|
||||
|
||||
static int
|
||||
do_check_messages( PKT_public_key *pk, PKT_signature *sig,
|
||||
int *r_expired, int *r_revoked )
|
||||
int *r_expired, int *r_revoked )
|
||||
{
|
||||
u32 cur_time;
|
||||
|
||||
if (r_expired)
|
||||
if(r_expired)
|
||||
*r_expired = 0;
|
||||
if (r_revoked)
|
||||
if(r_revoked)
|
||||
*r_revoked = 0;
|
||||
if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
|
||||
log_info(_("key %08lX: this is a PGP generated "
|
||||
"ElGamal key which is NOT secure for signatures!\n"),
|
||||
(ulong)keyid_from_pk(pk,NULL));
|
||||
return GPG_ERR_PUBKEY_ALGO;
|
||||
}
|
||||
|
||||
if( pk->timestamp > sig->timestamp ) {
|
||||
if( pk->timestamp > sig->timestamp )
|
||||
{
|
||||
ulong d = pk->timestamp - sig->timestamp;
|
||||
log_info( d==1
|
||||
? _("public key %08lX is %lu second newer than the signature\n")
|
||||
: _("public key %08lX is %lu seconds newer than the signature\n"),
|
||||
(ulong)keyid_from_pk(pk,NULL),d );
|
||||
log_info(d==1
|
||||
?_("public key %s is %lu second newer than the signature\n")
|
||||
:_("public key %s is %lu seconds newer than the signature\n"),
|
||||
keystr_from_pk(pk),d );
|
||||
if( !opt.ignore_time_conflict )
|
||||
return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature */
|
||||
}
|
||||
return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */
|
||||
}
|
||||
|
||||
cur_time = make_timestamp();
|
||||
if( pk->timestamp > cur_time ) {
|
||||
if( pk->timestamp > cur_time )
|
||||
{
|
||||
ulong d = pk->timestamp - cur_time;
|
||||
log_info( d==1 ? _("key %08lX has been created %lu second "
|
||||
"in future (time warp or clock problem)\n")
|
||||
: _("key %08lX has been created %lu seconds "
|
||||
"in future (time warp or clock problem)\n"),
|
||||
(ulong)keyid_from_pk(pk,NULL),d );
|
||||
log_info( d==1
|
||||
? _("key %s was created %lu second"
|
||||
" in the future (time warp or clock problem)\n")
|
||||
: _("key %s was created %lu seconds"
|
||||
" in the future (time warp or clock problem)\n"),
|
||||
keystr_from_pk(pk),d );
|
||||
if( !opt.ignore_time_conflict )
|
||||
return GPG_ERR_TIME_CONFLICT;
|
||||
}
|
||||
return G10ERR_TIME_CONFLICT;
|
||||
}
|
||||
|
||||
if( pk->expiredate && pk->expiredate < cur_time ) {
|
||||
char buf[11];
|
||||
if (opt.verbose) {
|
||||
u32 tmp_kid[2];
|
||||
|
||||
keyid_from_pk( pk, tmp_kid );
|
||||
log_info(_("NOTE: signature key %08lX expired %s\n"),
|
||||
(ulong)tmp_kid[1], asctimestamp( pk->expiredate ) );
|
||||
}
|
||||
if (opt.verbose)
|
||||
log_info(_("NOTE: signature key %s expired %s\n"),
|
||||
keystr_from_pk(pk), asctimestamp( pk->expiredate ) );
|
||||
/* SIGEXPIRED is deprecated. Use KEYEXPIRED. */
|
||||
sprintf(buf,"%lu",(ulong)pk->expiredate);
|
||||
write_status_text(STATUS_KEYEXPIRED,buf);
|
||||
write_status(STATUS_SIGEXPIRED);
|
||||
if (r_expired)
|
||||
*r_expired = 1;
|
||||
if(r_expired)
|
||||
*r_expired = 1;
|
||||
}
|
||||
|
||||
if(pk->is_revoked && r_revoked)
|
||||
@ -196,25 +230,21 @@ do_check_messages( PKT_public_key *pk, PKT_signature *sig,
|
||||
|
||||
|
||||
static int
|
||||
do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
|
||||
do_check( PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest,
|
||||
int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
|
||||
{
|
||||
gcry_mpi_t result = NULL;
|
||||
int rc=0;
|
||||
int rc = 0;
|
||||
struct cmp_help_context_s ctx;
|
||||
|
||||
if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
|
||||
return rc;
|
||||
if( (rc=gcry_md_test_algo(sig->digest_algo)) )
|
||||
return rc;
|
||||
if( (rc=gcry_pk_test_algo(sig->pubkey_algo)) )
|
||||
return rc;
|
||||
|
||||
/* make sure the digest algo is enabled (in case of a detached
|
||||
signature)*/
|
||||
gcry_md_enable( digest, sig->digest_algo );
|
||||
/* Make sure the digest algo is enabled (in case of a detached
|
||||
signature). */
|
||||
gcry_md_enable (digest, sig->digest_algo);
|
||||
|
||||
/* complete the digest */
|
||||
/* Complete the digest. */
|
||||
if( sig->version >= 4 )
|
||||
gcry_md_putc( digest, sig->version );
|
||||
gcry_md_putc( digest, sig->sig_class );
|
||||
@ -253,38 +283,22 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
|
||||
buf[5] = n;
|
||||
gcry_md_write( digest, buf, 6 );
|
||||
}
|
||||
gcry_md_final (digest);
|
||||
gcry_md_final( digest );
|
||||
|
||||
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
|
||||
mpi_get_nbits(pk->pkey[0]), 0 );
|
||||
result = encode_md_value( pk, NULL, digest, sig->digest_algo );
|
||||
if (!result)
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
ctx.sig = sig;
|
||||
ctx.md = digest;
|
||||
rc = pk_verify ( pk->pubkey_algo, result, sig->data, pk->pkey);
|
||||
gcry_mpi_release ( result );
|
||||
if( (opt.emulate_bugs & EMUBUG_MDENCODE)
|
||||
&& gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE
|
||||
&& is_ELGAMAL(pk->pubkey_algo) ) {
|
||||
/* In this case we try again because old GnuPG versions didn't encode
|
||||
* the hash right. There is no problem with DSA however */
|
||||
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
|
||||
mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
|
||||
if (!result)
|
||||
rc = GPG_ERR_GENERAL;
|
||||
else {
|
||||
ctx.sig = sig;
|
||||
ctx.md = digest;
|
||||
rc = pk_verify (pk->pubkey_algo, result, sig->data, pk->pkey);
|
||||
}
|
||||
}
|
||||
rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey );
|
||||
gcry_mpi_release (result);
|
||||
|
||||
if( !rc && sig->flags.unknown_critical ) {
|
||||
log_info(_("assuming bad signature from key %08lX "
|
||||
"due to an unknown critical bit\n"),
|
||||
(ulong)keyid_from_pk(pk,NULL));
|
||||
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
|
||||
}
|
||||
if( !rc && sig->flags.unknown_critical )
|
||||
{
|
||||
log_info(_("assuming bad signature from key %s"
|
||||
" due to an unknown critical bit\n"),keystr_from_pk(pk));
|
||||
rc = G10ERR_BAD_SIGN;
|
||||
}
|
||||
|
||||
if(!rc && ret_pk)
|
||||
copy_public_key(ret_pk,pk);
|
||||
@ -293,6 +307,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
|
||||
{
|
||||
@ -342,34 +357,36 @@ cache_sig_result ( PKT_signature *sig, int result )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check the revocation keys to see if any of them have revoked our
|
||||
pk. sig is the revocation sig. pk is the key it is on. This code
|
||||
will need to be modified if gpg ever becomes multi-threaded. Note
|
||||
that this guarantees that a designated revocation sig will never be
|
||||
considered valid unless it is actually valid, as well as being
|
||||
issued by a revocation key in a valid direct signature. Note that
|
||||
this is written so that a revoked revoker can still issue
|
||||
issued by a revocation key in a valid direct signature. Note also
|
||||
that this is written so that a revoked revoker can still issue
|
||||
revocations: i.e. If A revokes B, but A is revoked, B is still
|
||||
revoked. I'm not completely convinced this is the proper behavior,
|
||||
but it matches how PGP does it. -dms */
|
||||
|
||||
/* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not
|
||||
revoked */
|
||||
revoked. It is important that G10ERR_NO_PUBKEY is only returned
|
||||
when a revocation signature is from a valid revocation key
|
||||
designated in a revkey subpacket, but the revocation key itself
|
||||
isn't present. */
|
||||
int
|
||||
check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
|
||||
{
|
||||
static int busy=0;
|
||||
int i,rc=GPG_ERR_GENERAL;
|
||||
int i,rc=G10ERR_GENERAL;
|
||||
|
||||
assert(IS_KEY_REV(sig));
|
||||
assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
|
||||
|
||||
if(busy)
|
||||
{
|
||||
/* return -1 (i.e. not revoked), but mark the pk as uncacheable
|
||||
as we don't really know its revocation status until it is
|
||||
checked directly. */
|
||||
/* return an error (i.e. not revoked), but mark the pk as
|
||||
uncacheable as we don't really know its revocation status
|
||||
until it is checked directly. */
|
||||
|
||||
pk->dont_cache=1;
|
||||
return rc;
|
||||
@ -394,7 +411,8 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
|
||||
gcry_md_open (&md, sig->digest_algo,0);
|
||||
if (gcry_md_open (&md, sig->digest_algo, 0))
|
||||
BUG ();
|
||||
hash_public_key(md,pk);
|
||||
rc=signature_check(sig,md);
|
||||
cache_sig_result(sig,rc);
|
||||
@ -407,6 +425,39 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Backsigs (0x19) have the same format as binding sigs (0x18), but
|
||||
this function is simpler than check_key_signature in a few ways.
|
||||
For example, there is no support for expiring backsigs since it is
|
||||
questionable what such a thing actually means. Note also that the
|
||||
sig cache check here, unlike other sig caches in GnuPG, is not
|
||||
persistent. */
|
||||
int
|
||||
check_backsig(PKT_public_key *main_pk,PKT_public_key *sub_pk,
|
||||
PKT_signature *backsig)
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
int rc;
|
||||
|
||||
if(!opt.no_sig_cache && backsig->flags.checked)
|
||||
{
|
||||
if((rc=openpgp_md_test_algo (backsig->digest_algo)))
|
||||
return rc;
|
||||
|
||||
return backsig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE);
|
||||
}
|
||||
|
||||
if (gcry_md_open (&md, backsig->digest_algo,0))
|
||||
BUG ();
|
||||
hash_public_key(md,main_pk);
|
||||
hash_public_key(md,sub_pk);
|
||||
rc=do_check(sub_pk,backsig,md,NULL,NULL,NULL);
|
||||
cache_sig_result(backsig,rc);
|
||||
gcry_md_close(md);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* check the signature pointed to by NODE. This is a key signature.
|
||||
* If the function detects a self-signature, it uses the PK from
|
||||
@ -415,7 +466,7 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
|
||||
int
|
||||
check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
|
||||
{
|
||||
return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL);
|
||||
return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL );
|
||||
}
|
||||
|
||||
/* If check_pk is set, then use it to check the signature in node
|
||||
@ -427,9 +478,9 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
|
||||
int
|
||||
check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
PKT_public_key *ret_pk, int *is_selfsig,
|
||||
u32 *r_expiredate, int *r_expired )
|
||||
u32 *r_expiredate, int *r_expired )
|
||||
{
|
||||
MD_HANDLE md;
|
||||
gcry_md_hd_t md;
|
||||
PKT_public_key *pk;
|
||||
PKT_signature *sig;
|
||||
int algo;
|
||||
@ -448,7 +499,10 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
sig = node->pkt->pkt.signature;
|
||||
algo = sig->digest_algo;
|
||||
|
||||
/* check whether we have cached the result of a previous signature check.*/
|
||||
/* Check whether we have cached the result of a previous signature
|
||||
check. Note that we may no longer have the pubkey or hash
|
||||
needed to verify a sig, but can still use the cached value. A
|
||||
cache refresh detects and clears these cases. */
|
||||
if ( !opt.no_sig_cache ) {
|
||||
if (sig->flags.checked) { /*cached status available*/
|
||||
if( is_selfsig ) {
|
||||
@ -458,7 +512,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
|
||||
*is_selfsig = 1;
|
||||
}
|
||||
/* BUG: This is wrong for non-self-sigs. Needs to be the
|
||||
/* BUG: This is wrong for non-self-sigs.. needs to be the
|
||||
actual pk */
|
||||
if((rc=do_check_messages(pk,sig,r_expired,NULL)))
|
||||
return rc;
|
||||
@ -466,8 +520,10 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
}
|
||||
}
|
||||
|
||||
if( (rc=gcry_md_test_algo(algo)) )
|
||||
return rc;
|
||||
if( (rc=openpgp_pk_test_algo(sig->pubkey_algo)) )
|
||||
return rc;
|
||||
if( (rc=openpgp_md_test_algo(algo)) )
|
||||
return rc;
|
||||
|
||||
if( sig->sig_class == 0x20 ) { /* key revocation */
|
||||
u32 keyid[2];
|
||||
@ -478,7 +534,8 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
rc=check_revocation_keys(pk,sig);
|
||||
else
|
||||
{
|
||||
gcry_md_open (&md, algo, 0 );
|
||||
if (gcry_md_open (&md, algo, 0 ))
|
||||
BUG ();
|
||||
hash_public_key( md, pk );
|
||||
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
|
||||
cache_sig_result ( sig, rc );
|
||||
@ -489,20 +546,21 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
|
||||
|
||||
if( snode ) {
|
||||
gcry_md_open (&md, algo, 0 );
|
||||
if (gcry_md_open (&md, algo, 0))
|
||||
BUG ();
|
||||
hash_public_key( md, pk );
|
||||
hash_public_key( md, snode->pkt->pkt.public_key );
|
||||
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
|
||||
cache_sig_result ( sig, rc );
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info (_("key %08lX: no subkey for subkey "
|
||||
"revocation signature\n"),
|
||||
(ulong)keyid_from_pk (pk, NULL));
|
||||
rc = GPG_ERR_SIG_CLASS;
|
||||
}
|
||||
log_info (_("key %s: no subkey for subkey"
|
||||
" revocation signature\n"),keystr_from_pk(pk));
|
||||
rc = G10ERR_SIG_CLASS;
|
||||
}
|
||||
}
|
||||
else if( sig->sig_class == 0x18 ) { /* key binding */
|
||||
KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
|
||||
@ -515,23 +573,25 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
|
||||
*is_selfsig = 1;
|
||||
}
|
||||
gcry_md_open (&md, algo, 0 );
|
||||
if (gcry_md_open (&md, algo, 0))
|
||||
BUG ();
|
||||
hash_public_key( md, pk );
|
||||
hash_public_key( md, snode->pkt->pkt.public_key );
|
||||
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
|
||||
cache_sig_result ( sig, rc );
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info(_("key %08lX: no subkey for subkey "
|
||||
"binding signature\n"),
|
||||
(ulong)keyid_from_pk (pk, NULL));
|
||||
rc = GPG_ERR_SIG_CLASS;
|
||||
}
|
||||
log_info(_("key %s: no subkey for subkey"
|
||||
" binding signature\n"),keystr_from_pk(pk));
|
||||
rc = G10ERR_SIG_CLASS;
|
||||
}
|
||||
}
|
||||
else if( sig->sig_class == 0x1f ) { /* direct key signature */
|
||||
gcry_md_open (&md, algo, 0 );
|
||||
if (gcry_md_open (&md, algo, 0 ))
|
||||
BUG ();
|
||||
hash_public_key( md, pk );
|
||||
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
|
||||
cache_sig_result ( sig, rc );
|
||||
@ -544,7 +604,8 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
u32 keyid[2];
|
||||
|
||||
keyid_from_pk( pk, keyid );
|
||||
gcry_md_open (&md, algo, 0 );
|
||||
if (gcry_md_open (&md, algo, 0 ))
|
||||
BUG ();
|
||||
hash_public_key( md, pk );
|
||||
hash_uid_node( unode, md, sig );
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
|
||||
@ -554,21 +615,20 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
|
||||
rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
|
||||
}
|
||||
else if (check_pk)
|
||||
rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk);
|
||||
rc=do_check(check_pk,sig,md,r_expired,NULL,ret_pk);
|
||||
else
|
||||
rc = signature_check2( sig, md, r_expiredate, r_expired,
|
||||
NULL, ret_pk);
|
||||
rc=signature_check2(sig,md,r_expiredate,r_expired,NULL,ret_pk);
|
||||
|
||||
cache_sig_result ( sig, rc );
|
||||
gcry_md_close(md);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if (!opt.quiet)
|
||||
log_info ("key %08lX: no user ID for key signature packet "
|
||||
"of class %02x\n",
|
||||
(ulong)keyid_from_pk (pk, NULL), sig->sig_class );
|
||||
rc = GPG_ERR_SIG_CLASS;
|
||||
}
|
||||
log_info ("key %s: no user ID for key signature packet"
|
||||
" of class %02x\n",keystr_from_pk(pk),sig->sig_class);
|
||||
rc = G10ERR_SIG_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
636
g10/sign.c
636
g10/sign.c
File diff suppressed because it is too large
Load Diff
84
g10/signal.c
84
g10/signal.c
@ -1,5 +1,6 @@
|
||||
/* signal.c - signal handling
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -26,22 +28,28 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "errors.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "ttyio.h"
|
||||
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
void init_signals(void) {}
|
||||
void pause_on_sigusr(int which) {}
|
||||
#else
|
||||
static volatile int caught_fatal_sig = 0;
|
||||
static volatile int caught_sigusr1 = 0;
|
||||
|
||||
static void
|
||||
init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
|
||||
{
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
|
||||
struct sigaction oact, nact;
|
||||
|
||||
@ -65,20 +73,8 @@ init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
|
||||
signal (sig, SIG_IGN);
|
||||
}
|
||||
#endif
|
||||
#endif /*!HAVE_DOSISH_SYSTEM*/
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_signal_name( int signum )
|
||||
{
|
||||
#if defined(SYS_SIGLIST_DECLARED) && defined(NSIG)
|
||||
return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?";
|
||||
#else
|
||||
return "some signal";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static RETSIGTYPE
|
||||
got_fatal_signal( int sig )
|
||||
{
|
||||
@ -89,14 +85,33 @@ got_fatal_signal( int sig )
|
||||
caught_fatal_sig = 1;
|
||||
|
||||
gcry_control (GCRYCTL_TERM_SECMEM );
|
||||
/* better don't transtale these messages */
|
||||
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
rl_free_line_state ();
|
||||
rl_cleanup_after_signal ();
|
||||
#endif
|
||||
|
||||
/* Better don't translate these messages. */
|
||||
write(2, "\n", 1 );
|
||||
s = "?" /* FIXME: log_get_name()*/; if( s ) write(2, s, strlen(s) );
|
||||
s = log_get_name(); if( s ) write(2, s, strlen(s) );
|
||||
write(2, ": ", 2 );
|
||||
s = get_signal_name(sig); write(2, s, strlen(s) );
|
||||
|
||||
#if HAVE_DECL_SYS_SIGLIST && defined(NSIG)
|
||||
s = (sig >= 0 && sig < NSIG) ? sys_siglist[sig] : "?";
|
||||
write (2, s, strlen(s) );
|
||||
#else
|
||||
write (2, "signal ", 7 );
|
||||
if (sig < 0 || sig >=100)
|
||||
write (2, "?", 1);
|
||||
else {
|
||||
if (sig >= 10)
|
||||
write (2, "0123456789"+(sig/10), 1 );
|
||||
write (2, "0123456789"+(sig%10), 1 );
|
||||
}
|
||||
#endif
|
||||
write(2, " caught ... exiting\n", 20 );
|
||||
|
||||
/* reset action to default action and raise signal again */
|
||||
/* Reset action to default action and raise signal again. */
|
||||
init_one_signal (sig, SIG_DFL, 0);
|
||||
dotlock_remove_lockfiles ();
|
||||
#ifdef __riscos__
|
||||
@ -116,7 +131,6 @@ got_usr_signal( int sig )
|
||||
void
|
||||
init_signals()
|
||||
{
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
init_one_signal (SIGINT, got_fatal_signal, 1 );
|
||||
init_one_signal (SIGHUP, got_fatal_signal, 1 );
|
||||
init_one_signal (SIGTERM, got_fatal_signal, 1 );
|
||||
@ -124,14 +138,12 @@ init_signals()
|
||||
init_one_signal (SIGSEGV, got_fatal_signal, 1 );
|
||||
init_one_signal (SIGUSR1, got_usr_signal, 0 );
|
||||
init_one_signal (SIGPIPE, SIG_IGN, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pause_on_sigusr( int which )
|
||||
{
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
|
||||
sigset_t mask, oldmask;
|
||||
|
||||
@ -150,16 +162,15 @@ pause_on_sigusr( int which )
|
||||
while (!caught_sigusr1)
|
||||
sigpause(SIGUSR1);
|
||||
caught_sigusr1 = 0;
|
||||
sigrelse(SIGUSR1);
|
||||
#endif /*!HAVE_SIGPROCMASK && HAVE_SISET_T*/
|
||||
#endif
|
||||
sigrelse(SIGUSR1);
|
||||
#endif /*! HAVE_SIGPROCMASK && HAVE_SIGSET_T */
|
||||
}
|
||||
|
||||
|
||||
/* Disabled - see comment in tdbio.c:tdbio_begin_transaction() */
|
||||
#if 0
|
||||
static void
|
||||
do_block( int block )
|
||||
{
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
static int is_blocked;
|
||||
#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
|
||||
static sigset_t oldmask;
|
||||
@ -179,14 +190,14 @@ do_block( int block )
|
||||
sigprocmask( SIG_SETMASK, &oldmask, NULL );
|
||||
is_blocked = 0;
|
||||
}
|
||||
#else /*!HAVE_SIGPROCMASK*/
|
||||
#else /*! HAVE_SIGPROCMASK && HAVE_SIGSET_T */
|
||||
|
||||
#if defined(NSIG)
|
||||
# define SIGSMAX (NSIG)
|
||||
#define SIGSMAX (NSIG)
|
||||
#elif defined(MAXSIG)
|
||||
# define SIGSMAX (MAXSIG+1)
|
||||
#define SIGSMAX (MAXSIG+1)
|
||||
#else
|
||||
# error "define SIGSMAX to the number of signals on your platform plus one"
|
||||
#error "define SIGSMAX to the number of signals on your platform plus one"
|
||||
#endif
|
||||
|
||||
static void (*disposition[SIGSMAX])(int);
|
||||
@ -208,11 +219,9 @@ do_block( int block )
|
||||
}
|
||||
is_blocked = 0;
|
||||
}
|
||||
#endif /*!HAVE_SIGPROCMASK*/
|
||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||
#endif /*! HAVE_SIGPROCMASK && HAVE_SIGSET_T */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
block_all_signals()
|
||||
{
|
||||
@ -224,3 +233,6 @@ unblock_all_signals()
|
||||
{
|
||||
do_block(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !HAVE_DOSISH_SYSTEM */
|
||||
|
126
g10/skclist.c
126
g10/skclist.c
@ -1,5 +1,5 @@
|
||||
/* skclist.c
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
/* skclist.c - Build a list of secret keys
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -25,11 +26,11 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
#include "cipher.h"
|
||||
@ -43,11 +44,41 @@ release_sk_list( SK_LIST sk_list )
|
||||
for( ; sk_list; sk_list = sk_rover ) {
|
||||
sk_rover = sk_list->next;
|
||||
free_secret_key( sk_list->sk );
|
||||
xfree ( sk_list );
|
||||
xfree( sk_list );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check that we are only using keys which don't have
|
||||
* the string "(insecure!)" or "not secure" or "do not use"
|
||||
* in one of the user ids
|
||||
*/
|
||||
static int
|
||||
is_insecure( PKT_secret_key *sk )
|
||||
{
|
||||
u32 keyid[2];
|
||||
KBNODE node = NULL, u;
|
||||
int insecure = 0;
|
||||
|
||||
keyid_from_sk( sk, keyid );
|
||||
node = get_pubkeyblock( keyid );
|
||||
for ( u = node; u; u = u->next ) {
|
||||
if ( u->pkt->pkttype == PKT_USER_ID ) {
|
||||
PKT_user_id *id = u->pkt->pkt.user_id;
|
||||
if ( id->attrib_data )
|
||||
continue; /* skip attribute packets */
|
||||
if ( strstr( id->name, "(insecure!)" )
|
||||
|| strstr( id->name, "not secure" )
|
||||
|| strstr( id->name, "do not use" ) ) {
|
||||
insecure = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
release_kbnode( node );
|
||||
|
||||
return insecure;
|
||||
}
|
||||
|
||||
static int
|
||||
key_present_in_sk_list(SK_LIST sk_list, PKT_secret_key *sk)
|
||||
@ -77,37 +108,41 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
|
||||
SK_LIST sk_list = NULL;
|
||||
int rc;
|
||||
|
||||
if( !locusr ) { /* use the default one */
|
||||
if( !locusr )
|
||||
{ /* use the default one */
|
||||
PKT_secret_key *sk;
|
||||
|
||||
sk = xcalloc (1, sizeof *sk );
|
||||
sk = xmalloc_clear( sizeof *sk );
|
||||
sk->req_usage = use;
|
||||
if( (rc = get_seckey_byname( sk, NULL, unlock )) ) {
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error("no default secret key: %s\n", gpg_strerror (rc) );
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error("no default secret key: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) {
|
||||
else if( !(rc=openpgp_pk_test_algo2 (sk->pubkey_algo, use)) )
|
||||
{
|
||||
SK_LIST r;
|
||||
|
||||
if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
|
||||
&& sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
|
||||
log_info("this is a PGP generated "
|
||||
"ElGamal key which is NOT secure for signatures!\n");
|
||||
if( random_is_faked() && !is_insecure( sk ) )
|
||||
{
|
||||
log_info(_("key is not flagged as insecure - "
|
||||
"can't use it with the faked RNG!\n"));
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
}
|
||||
else {
|
||||
r = xmalloc ( sizeof *r );
|
||||
}
|
||||
else
|
||||
{
|
||||
r = xmalloc( sizeof *r );
|
||||
r->sk = sk; sk = NULL;
|
||||
r->next = sk_list;
|
||||
r->mark = 0;
|
||||
sk_list = r;
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error("invalid default secret key: %s\n", gpg_strerror (rc) );
|
||||
}
|
||||
}
|
||||
log_error("invalid default secret key: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
STRLIST locusr_orig = locusr;
|
||||
for(; locusr; locusr = locusr->next ) {
|
||||
@ -118,36 +153,47 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
|
||||
* won't catch all duplicates because the user IDs may be
|
||||
* specified in different ways.
|
||||
*/
|
||||
if ( is_duplicated_entry ( locusr_orig, locusr ) ) {
|
||||
log_error(_("skipped `%s': duplicated\n"), locusr->d );
|
||||
if ( is_duplicated_entry ( locusr_orig, locusr ) )
|
||||
{
|
||||
log_error(_("skipped \"%s\": duplicated\n"), locusr->d );
|
||||
continue;
|
||||
}
|
||||
sk = xcalloc (1, sizeof *sk );
|
||||
}
|
||||
sk = xmalloc_clear( sizeof *sk );
|
||||
sk->req_usage = use;
|
||||
if( (rc = get_seckey_byname( sk, locusr->d, 0 )) ) {
|
||||
if( (rc = get_seckey_byname( sk, locusr->d, 0 )) )
|
||||
{
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) );
|
||||
}
|
||||
log_error(_("skipped \"%s\": %s\n"),
|
||||
locusr->d, g10_errstr(rc) );
|
||||
}
|
||||
else if ( key_present_in_sk_list(sk_list, sk) == 0) {
|
||||
free_secret_key(sk); sk = NULL;
|
||||
log_info(_("skipped: secret key already present\n"));
|
||||
}
|
||||
else if ( unlock && (rc = check_secret_key( sk, 0 )) ) {
|
||||
else if ( unlock && (rc = check_secret_key( sk, 0 )) )
|
||||
{
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) );
|
||||
}
|
||||
log_error(_("skipped \"%s\": %s\n"),
|
||||
locusr->d, g10_errstr(rc) );
|
||||
}
|
||||
else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) {
|
||||
SK_LIST r;
|
||||
|
||||
if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
|
||||
&& sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
|
||||
log_info(_("skipped `%s': this is a PGP generated "
|
||||
"ElGamal key which is not secure for signatures!\n"),
|
||||
locusr->d );
|
||||
&& sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E )
|
||||
{
|
||||
log_info(_("skipped \"%s\": %s\n"),locusr->d,
|
||||
_("this is a PGP generated Elgamal key which"
|
||||
" is not secure for signatures!"));
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
}
|
||||
else if( random_is_faked() && !is_insecure( sk ) ) {
|
||||
log_info(_("key is not flagged as insecure - "
|
||||
"can't use it with the faked RNG!\n"));
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
}
|
||||
else {
|
||||
r = xmalloc ( sizeof *r );
|
||||
r = xmalloc( sizeof *r );
|
||||
r->sk = sk; sk = NULL;
|
||||
r->next = sk_list;
|
||||
r->mark = 0;
|
||||
@ -156,7 +202,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
|
||||
}
|
||||
else {
|
||||
free_secret_key( sk ); sk = NULL;
|
||||
log_error("skipped `%s': %s\n", locusr->d, gpg_strerror (rc) );
|
||||
log_error("skipped \"%s\": %s\n", locusr->d, g10_errstr(rc) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,7 +210,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
|
||||
|
||||
if( !rc && !sk_list ) {
|
||||
log_error("no valid signators\n");
|
||||
rc = GPG_ERR_NO_USER_ID;
|
||||
rc = G10ERR_NO_USER_ID;
|
||||
}
|
||||
|
||||
if( rc )
|
||||
|
326
g10/status.c
326
g10/status.c
@ -1,6 +1,6 @@
|
||||
/* status.c
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
/* status.c - Status message and command-fd interface
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
* 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,7 +16,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -44,98 +45,145 @@ static FILE *statusfp;
|
||||
|
||||
|
||||
static void
|
||||
progress_cb (void *ctx, const char *what, int printchar, int current, int total)
|
||||
progress_cb ( void *ctx, int c )
|
||||
{
|
||||
char buf[150];
|
||||
|
||||
if (printchar == '\n')
|
||||
printchar = 'X';
|
||||
|
||||
sprintf (buf, "%.20s %c %d %d", what, printchar, current, total);
|
||||
write_status_text (STATUS_PROGRESS, buf);
|
||||
char buf[50];
|
||||
|
||||
if ( c == '\n' )
|
||||
sprintf ( buf, "%.20s X 100 100", (char*)ctx );
|
||||
else
|
||||
sprintf ( buf, "%.20s %c 0 0", (char*)ctx, c );
|
||||
write_status_text ( STATUS_PROGRESS, buf );
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_status_string ( int no )
|
||||
{
|
||||
const char *s;
|
||||
const char *s;
|
||||
|
||||
switch( no ) {
|
||||
case STATUS_ENTER : s = "ENTER"; break;
|
||||
case STATUS_LEAVE : s = "LEAVE"; break;
|
||||
case STATUS_ABORT : s = "ABORT"; break;
|
||||
case STATUS_GOODSIG: s = "GOODSIG"; break;
|
||||
case STATUS_KEYEXPIRED: s = "KEYEXPIRED"; break;
|
||||
case STATUS_KEYREVOKED: s = "KEYREVOKED"; break;
|
||||
case STATUS_BADSIG : s = "BADSIG"; break;
|
||||
case STATUS_ERRSIG : s = "ERRSIG"; break;
|
||||
case STATUS_BADARMOR : s = "BADARMOR"; break;
|
||||
case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break;
|
||||
case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break;
|
||||
case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break;
|
||||
case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break;
|
||||
case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break;
|
||||
case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break;
|
||||
case STATUS_GET_BOOL : s = "GET_BOOL"; break;
|
||||
case STATUS_GET_LINE : s = "GET_LINE"; break;
|
||||
case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break;
|
||||
case STATUS_GOT_IT : s = "GOT_IT"; break;
|
||||
case STATUS_SHM_INFO : s = "SHM_INFO"; break;
|
||||
case STATUS_SHM_GET : s = "SHM_GET"; break;
|
||||
case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break;
|
||||
case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break;
|
||||
case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break;
|
||||
case STATUS_VALIDSIG : s = "VALIDSIG"; break;
|
||||
case STATUS_SIG_ID : s = "SIG_ID"; break;
|
||||
case STATUS_ENC_TO : s = "ENC_TO"; break;
|
||||
case STATUS_NODATA : s = "NODATA"; break;
|
||||
case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break;
|
||||
case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break;
|
||||
case STATUS_NO_SECKEY : s = "NO_SECKEY"; break;
|
||||
case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break;
|
||||
case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break;
|
||||
case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break;
|
||||
case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break;
|
||||
case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break;
|
||||
case STATUS_GOODMDC : s = "GOODMDC"; break;
|
||||
case STATUS_BADMDC : s = "BADMDC"; break;
|
||||
case STATUS_ERRMDC : s = "ERRMDC"; break;
|
||||
case STATUS_IMPORTED : s = "IMPORTED"; break;
|
||||
case STATUS_IMPORT_OK : s = "IMPORT_OK"; break;
|
||||
case STATUS_IMPORT_CHECK : s = "IMPORT_CHECK"; break;
|
||||
case STATUS_IMPORT_RES : s = "IMPORT_RES"; break;
|
||||
case STATUS_FILE_START : s = "FILE_START"; break;
|
||||
case STATUS_FILE_DONE : s = "FILE_DONE"; break;
|
||||
case STATUS_FILE_ERROR : s = "FILE_ERROR"; break;
|
||||
case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break;
|
||||
case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break;
|
||||
case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break;
|
||||
case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break;
|
||||
case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break;
|
||||
case STATUS_PROGRESS : s = "PROGRESS"; break;
|
||||
case STATUS_SIG_CREATED : s = "SIG_CREATED"; break;
|
||||
case STATUS_SESSION_KEY : s = "SESSION_KEY"; break;
|
||||
case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break;
|
||||
case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break;
|
||||
case STATUS_POLICY_URL : s = "POLICY_URL" ; break;
|
||||
case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break;
|
||||
case STATUS_END_STREAM : s = "END_STREAM"; break;
|
||||
case STATUS_KEY_CREATED : s = "KEY_CREATED"; break;
|
||||
case STATUS_USERID_HINT : s = "USERID_HINT"; break;
|
||||
case STATUS_UNEXPECTED : s = "UNEXPECTED"; break;
|
||||
case STATUS_INV_RECP : s = "INV_RECP"; break;
|
||||
case STATUS_NO_RECP : s = "NO_RECP"; break;
|
||||
case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break;
|
||||
case STATUS_SIGEXPIRED : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break;
|
||||
case STATUS_EXPSIG : s = "EXPSIG"; break;
|
||||
case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break;
|
||||
case STATUS_REVKEYSIG : s = "REVKEYSIG"; break;
|
||||
case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break;
|
||||
default: s = "?"; break;
|
||||
switch( no )
|
||||
{
|
||||
case STATUS_ENTER : s = "ENTER"; break;
|
||||
case STATUS_LEAVE : s = "LEAVE"; break;
|
||||
case STATUS_ABORT : s = "ABORT"; break;
|
||||
case STATUS_NEWSIG : s = "NEWSIG"; break;
|
||||
case STATUS_GOODSIG: s = "GOODSIG"; break;
|
||||
case STATUS_KEYEXPIRED: s = "KEYEXPIRED"; break;
|
||||
case STATUS_KEYREVOKED: s = "KEYREVOKED"; break;
|
||||
case STATUS_BADSIG : s = "BADSIG"; break;
|
||||
case STATUS_ERRSIG : s = "ERRSIG"; break;
|
||||
case STATUS_BADARMOR : s = "BADARMOR"; break;
|
||||
case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break;
|
||||
case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break;
|
||||
case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break;
|
||||
case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break;
|
||||
case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break;
|
||||
case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break;
|
||||
case STATUS_GET_BOOL : s = "GET_BOOL"; break;
|
||||
case STATUS_GET_LINE : s = "GET_LINE"; break;
|
||||
case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break;
|
||||
case STATUS_GOT_IT : s = "GOT_IT"; break;
|
||||
case STATUS_SHM_INFO : s = "SHM_INFO"; break;
|
||||
case STATUS_SHM_GET : s = "SHM_GET"; break;
|
||||
case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break;
|
||||
case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break;
|
||||
case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break;
|
||||
case STATUS_VALIDSIG : s = "VALIDSIG"; break;
|
||||
case STATUS_SIG_ID : s = "SIG_ID"; break;
|
||||
case STATUS_ENC_TO : s = "ENC_TO"; break;
|
||||
case STATUS_NODATA : s = "NODATA"; break;
|
||||
case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break;
|
||||
case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break;
|
||||
case STATUS_NO_SECKEY : s = "NO_SECKEY"; break;
|
||||
case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break;
|
||||
case STATUS_NEED_PASSPHRASE_PIN: s = "NEED_PASSPHRASE_PIN"; break;
|
||||
case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break;
|
||||
case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break;
|
||||
case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break;
|
||||
case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break;
|
||||
case STATUS_GOODMDC : s = "GOODMDC"; break;
|
||||
case STATUS_BADMDC : s = "BADMDC"; break;
|
||||
case STATUS_ERRMDC : s = "ERRMDC"; break;
|
||||
case STATUS_IMPORTED : s = "IMPORTED"; break;
|
||||
case STATUS_IMPORT_OK : s = "IMPORT_OK"; break;
|
||||
case STATUS_IMPORT_CHECK : s = "IMPORT_CHECK"; break;
|
||||
case STATUS_IMPORT_RES : s = "IMPORT_RES"; break;
|
||||
case STATUS_FILE_START : s = "FILE_START"; break;
|
||||
case STATUS_FILE_DONE : s = "FILE_DONE"; break;
|
||||
case STATUS_FILE_ERROR : s = "FILE_ERROR"; break;
|
||||
case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break;
|
||||
case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break;
|
||||
case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break;
|
||||
case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break;
|
||||
case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break;
|
||||
case STATUS_PROGRESS : s = "PROGRESS"; break;
|
||||
case STATUS_SIG_CREATED : s = "SIG_CREATED"; break;
|
||||
case STATUS_SESSION_KEY : s = "SESSION_KEY"; break;
|
||||
case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break;
|
||||
case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break;
|
||||
case STATUS_POLICY_URL : s = "POLICY_URL" ; break;
|
||||
case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break;
|
||||
case STATUS_END_STREAM : s = "END_STREAM"; break;
|
||||
case STATUS_KEY_CREATED : s = "KEY_CREATED"; break;
|
||||
case STATUS_KEY_NOT_CREATED: s = "KEY_NOT_CREATED"; break;
|
||||
case STATUS_USERID_HINT : s = "USERID_HINT"; break;
|
||||
case STATUS_UNEXPECTED : s = "UNEXPECTED"; break;
|
||||
case STATUS_INV_RECP : s = "INV_RECP"; break;
|
||||
case STATUS_NO_RECP : s = "NO_RECP"; break;
|
||||
case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break;
|
||||
case STATUS_SIGEXPIRED : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break;
|
||||
case STATUS_EXPSIG : s = "EXPSIG"; break;
|
||||
case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break;
|
||||
case STATUS_REVKEYSIG : s = "REVKEYSIG"; break;
|
||||
case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break;
|
||||
case STATUS_CARDCTRL : s = "CARDCTRL"; break;
|
||||
case STATUS_PLAINTEXT : s = "PLAINTEXT"; break;
|
||||
case STATUS_PLAINTEXT_LENGTH:s = "PLAINTEXT_LENGTH"; break;
|
||||
case STATUS_SIG_SUBPACKET : s = "SIG_SUBPACKET"; break;
|
||||
case STATUS_SC_OP_SUCCESS : s = "SC_OP_SUCCESS"; break;
|
||||
case STATUS_SC_OP_FAILURE : s = "SC_OP_FAILURE"; break;
|
||||
case STATUS_BACKUP_KEY_CREATED:s="BACKUP_KEY_CREATED"; break;
|
||||
case STATUS_PKA_TRUST_BAD : s = "PKA_TRUST_BAD"; break;
|
||||
case STATUS_PKA_TRUST_GOOD : s = "PKA_TRUST_GOOD"; break;
|
||||
case STATUS_BEGIN_SIGNING : s = "BEGIN_SIGNING"; break;
|
||||
default: s = "?"; break;
|
||||
}
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if the status message NO may currently be issued. We
|
||||
need this to avoid syncronisation problem while auto retrieving a
|
||||
key. There it may happen that a status NODATA is issued for a non
|
||||
available key and the user may falsely interpret this has a missing
|
||||
signature. */
|
||||
static int
|
||||
status_currently_allowed (int no)
|
||||
{
|
||||
if (!glo_ctrl.in_auto_key_retrieve)
|
||||
return 1; /* Yes. */
|
||||
|
||||
/* We allow some statis anyway, so that import statistics are
|
||||
correct and to avoid problems if the retriebval subsystem will
|
||||
prompt the user. */
|
||||
switch (no)
|
||||
{
|
||||
case STATUS_GET_BOOL:
|
||||
case STATUS_GET_LINE:
|
||||
case STATUS_GET_HIDDEN:
|
||||
case STATUS_GOT_IT:
|
||||
case STATUS_IMPORTED:
|
||||
case STATUS_IMPORT_OK:
|
||||
case STATUS_IMPORT_CHECK:
|
||||
case STATUS_IMPORT_RES:
|
||||
return 1; /* Yes. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0; /* No. */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_status_fd ( int fd )
|
||||
{
|
||||
@ -161,7 +209,9 @@ set_status_fd ( int fd )
|
||||
fd, strerror(errno));
|
||||
}
|
||||
last_fd = fd;
|
||||
gcry_set_progress_handler (progress_cb, NULL);
|
||||
register_primegen_progress ( progress_cb, "primegen" );
|
||||
register_pk_dsa_progress ( progress_cb, "pk_dsa" );
|
||||
register_pk_elg_progress ( progress_cb, "pk_elg" );
|
||||
}
|
||||
|
||||
int
|
||||
@ -179,8 +229,8 @@ write_status ( int no )
|
||||
void
|
||||
write_status_text ( int no, const char *text)
|
||||
{
|
||||
if( !statusfp )
|
||||
return; /* not enabled */
|
||||
if( !statusfp || !status_currently_allowed (no) )
|
||||
return; /* Not enabled or allowed. */
|
||||
|
||||
fputs ( "[GNUPG:] ", statusfp );
|
||||
fputs ( get_status_string (no), statusfp );
|
||||
@ -196,7 +246,8 @@ write_status_text ( int no, const char *text)
|
||||
}
|
||||
}
|
||||
putc ('\n',statusfp);
|
||||
fflush (statusfp);
|
||||
if ( fflush (statusfp) && opt.exit_on_status_write_error )
|
||||
g10_exit (0);
|
||||
}
|
||||
|
||||
|
||||
@ -215,8 +266,8 @@ write_status_text_and_buffer ( int no, const char *string,
|
||||
int lower_limit = ' ';
|
||||
size_t n, count, dowrap;
|
||||
|
||||
if( !statusfp )
|
||||
return; /* not enabled */
|
||||
if( !statusfp || !status_currently_allowed (no) )
|
||||
return; /* Not enabled or allowed. */
|
||||
|
||||
if (wrap == -1) {
|
||||
lower_limit--;
|
||||
@ -260,7 +311,8 @@ write_status_text_and_buffer ( int no, const char *string,
|
||||
} while ( len );
|
||||
|
||||
putc ('\n',statusfp);
|
||||
fflush (statusfp);
|
||||
if ( fflush (statusfp) && opt.exit_on_status_write_error )
|
||||
g10_exit (0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -308,6 +360,9 @@ do_get_from_fd( const char *keyword, int hidden, int bool )
|
||||
int i, len;
|
||||
char *string;
|
||||
|
||||
if(statusfp!=stdout)
|
||||
fflush(stdout);
|
||||
|
||||
write_status_text( bool? STATUS_GET_BOOL :
|
||||
hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword );
|
||||
|
||||
@ -348,6 +403,10 @@ cpr_enabled()
|
||||
{
|
||||
if( opt.command_fd != -1 )
|
||||
return 1;
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -358,6 +417,10 @@ cpr_get_no_help( const char *keyword, const char *prompt )
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return do_get_from_fd ( keyword, 0, 0 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return do_shm_get( keyword, 0, 0 );
|
||||
#endif
|
||||
for(;;) {
|
||||
p = tty_get( prompt );
|
||||
return p;
|
||||
@ -371,10 +434,14 @@ cpr_get( const char *keyword, const char *prompt )
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return do_get_from_fd ( keyword, 0, 0 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return do_shm_get( keyword, 0, 0 );
|
||||
#endif
|
||||
for(;;) {
|
||||
p = tty_get( prompt );
|
||||
if( *p=='?' && !p[1] && !(keyword && !*keyword)) {
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
display_online_help( keyword );
|
||||
}
|
||||
else
|
||||
@ -390,7 +457,7 @@ cpr_get_utf8( const char *keyword, const char *prompt )
|
||||
p = cpr_get( keyword, prompt );
|
||||
if( p ) {
|
||||
char *utf8 = native_to_utf8( p );
|
||||
xfree ( p );
|
||||
xfree( p );
|
||||
p = utf8;
|
||||
}
|
||||
return p;
|
||||
@ -403,10 +470,14 @@ cpr_get_hidden( const char *keyword, const char *prompt )
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return do_get_from_fd ( keyword, 1, 0 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return do_shm_get( keyword, 1, 0 );
|
||||
#endif
|
||||
for(;;) {
|
||||
p = tty_get_hidden( prompt );
|
||||
if( *p == '?' && !p[1] ) {
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
display_online_help( keyword );
|
||||
}
|
||||
else
|
||||
@ -419,6 +490,10 @@ cpr_kill_prompt(void)
|
||||
{
|
||||
if( opt.command_fd != -1 )
|
||||
return;
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return;
|
||||
#endif
|
||||
tty_kill_prompt();
|
||||
return;
|
||||
}
|
||||
@ -431,17 +506,21 @@ cpr_get_answer_is_yes( const char *keyword, const char *prompt )
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return !!do_get_from_fd ( keyword, 0, 1 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return !!do_shm_get( keyword, 0, 1 );
|
||||
#endif
|
||||
for(;;) {
|
||||
p = tty_get( prompt );
|
||||
trim_spaces(p); /* it is okay to do this here */
|
||||
if( *p == '?' && !p[1] ) {
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
display_online_help( keyword );
|
||||
}
|
||||
else {
|
||||
tty_kill_prompt();
|
||||
yes = answer_is_yes(p);
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
return yes;
|
||||
}
|
||||
}
|
||||
@ -455,18 +534,65 @@ cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt )
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
return !!do_get_from_fd ( keyword, 0, 1 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
if( opt.shm_coprocess )
|
||||
return !!do_shm_get( keyword, 0, 1 );
|
||||
#endif
|
||||
for(;;) {
|
||||
p = tty_get( prompt );
|
||||
trim_spaces(p); /* it is okay to do this here */
|
||||
if( *p == '?' && !p[1] ) {
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
display_online_help( keyword );
|
||||
}
|
||||
else {
|
||||
tty_kill_prompt();
|
||||
yes = answer_is_yes_no_quit(p);
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
return yes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cpr_get_answer_okay_cancel (const char *keyword,
|
||||
const char *prompt,
|
||||
int def_answer)
|
||||
{
|
||||
int yes;
|
||||
char *answer = NULL;
|
||||
char *p;
|
||||
|
||||
if( opt.command_fd != -1 )
|
||||
answer = do_get_from_fd ( keyword, 0, 0 );
|
||||
#ifdef USE_SHM_COPROCESSING
|
||||
else if( opt.shm_coprocess )
|
||||
answer = do_shm_get( keyword, 0, 0 );
|
||||
#endif
|
||||
|
||||
if (answer)
|
||||
{
|
||||
yes = answer_is_okay_cancel (answer, def_answer);
|
||||
xfree (answer);
|
||||
return yes;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
p = tty_get( prompt );
|
||||
trim_spaces(p); /* it is okay to do this here */
|
||||
if (*p == '?' && !p[1])
|
||||
{
|
||||
xfree(p);
|
||||
display_online_help (keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
tty_kill_prompt();
|
||||
yes = answer_is_okay_cancel (p, def_answer);
|
||||
xfree(p);
|
||||
return yes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
g10/status.h
32
g10/status.h
@ -1,5 +1,6 @@
|
||||
/* status.h
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
* 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,12 +16,12 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef G10_STATUS_H
|
||||
#define G10_STATUS_H
|
||||
|
||||
|
||||
#define STATUS_ENTER 1
|
||||
#define STATUS_LEAVE 2
|
||||
#define STATUS_ABORT 3
|
||||
@ -29,7 +30,6 @@
|
||||
#define STATUS_BADSIG 5
|
||||
#define STATUS_ERRSIG 6
|
||||
|
||||
|
||||
#define STATUS_BADARMOR 7
|
||||
|
||||
#define STATUS_RSA_OR_IDEA 8
|
||||
@ -100,6 +100,26 @@
|
||||
#define STATUS_IMPORT_OK 68
|
||||
#define STATUS_IMPORT_CHECK 69
|
||||
#define STATUS_REVKEYSIG 70
|
||||
#define STATUS_CARDCTRL 71
|
||||
#define STATUS_NEWSIG 72
|
||||
#define STATUS_PLAINTEXT 73
|
||||
#define STATUS_PLAINTEXT_LENGTH 74
|
||||
#define STATUS_KEY_NOT_CREATED 75
|
||||
#define STATUS_NEED_PASSPHRASE_PIN 76
|
||||
#define STATUS_SIG_SUBPACKET 77
|
||||
|
||||
/* Extra status codes for certain smartcard operations. Primary
|
||||
useful to double check that change PIN worked as expected. */
|
||||
#define STATUS_SC_OP_FAILURE 79
|
||||
#define STATUS_SC_OP_SUCCESS 80
|
||||
|
||||
#define STATUS_BACKUP_KEY_CREATED 81
|
||||
|
||||
#define STATUS_PKA_TRUST_BAD 82
|
||||
#define STATUS_PKA_TRUST_GOOD 83
|
||||
|
||||
#define STATUS_BEGIN_SIGNING 84
|
||||
|
||||
|
||||
/*-- status.c --*/
|
||||
void set_status_fd ( int fd );
|
||||
@ -119,6 +139,8 @@ char *cpr_get_hidden( const char *keyword, const char *prompt );
|
||||
void cpr_kill_prompt(void);
|
||||
int cpr_get_answer_is_yes( const char *keyword, const char *prompt );
|
||||
int cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt );
|
||||
|
||||
int cpr_get_answer_okay_cancel (const char *keyword,
|
||||
const char *prompt,
|
||||
int def_answer);
|
||||
|
||||
#endif /*G10_STATUS_H*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* tdbdump.c
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -34,7 +35,6 @@
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "trustdb.h"
|
||||
#include "options.h"
|
||||
@ -58,7 +58,7 @@ write_record( TRUSTREC *rec )
|
||||
if( !rc )
|
||||
return;
|
||||
log_error(_("trust record %lu, type %d: write failed: %s\n"),
|
||||
rec->recnum, rec->rectype, gpg_strerror (rc) );
|
||||
rec->recnum, rec->rectype, g10_errstr(rc) );
|
||||
tdbio_invalid();
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ import_ownertrust( const char *fname )
|
||||
int rc;
|
||||
|
||||
init_trustdb();
|
||||
if( !fname || (*fname == '-' && !fname[1]) ) {
|
||||
if( iobuf_is_pipe_filename (fname) ) {
|
||||
fp = stdin;
|
||||
fname = "[stdin]";
|
||||
is_stdin = 1;
|
||||
@ -142,6 +142,14 @@ import_ownertrust( const char *fname )
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_secured_file (fileno (fp)))
|
||||
{
|
||||
fclose (fp);
|
||||
errno = EPERM;
|
||||
log_error (_("can't open `%s': %s\n"), fname, strerror(errno) );
|
||||
return;
|
||||
}
|
||||
|
||||
while( fgets( line, DIM(line)-1, fp ) ) {
|
||||
TRUSTREC rec;
|
||||
|
||||
@ -149,24 +157,26 @@ import_ownertrust( const char *fname )
|
||||
continue;
|
||||
n = strlen(line);
|
||||
if( line[n-1] != '\n' ) {
|
||||
log_error (_("\b%s: line too long\n"), fname );
|
||||
log_error (_("error in `%s': %s\n"), fname, _("line too long") );
|
||||
/* ... or last line does not have a LF */
|
||||
break; /* can't continue */
|
||||
}
|
||||
for(p = line; *p && *p != ':' ; p++ )
|
||||
if( !hexdigitp (p) )
|
||||
if( !hexdigitp(p) )
|
||||
break;
|
||||
if( *p != ':' ) {
|
||||
log_error (_("\b%s: error: missing colon\n"), fname );
|
||||
log_error (_("error in `%s': %s\n"), fname, _("colon missing") );
|
||||
continue;
|
||||
}
|
||||
fprlen = p - line;
|
||||
if( fprlen != 32 && fprlen != 40 ) {
|
||||
log_error (_("\b%s: error: invalid fingerprint\n"), fname );
|
||||
log_error (_("error in `%s': %s\n"),
|
||||
fname, _("invalid fingerprint") );
|
||||
continue;
|
||||
}
|
||||
if( sscanf(p, ":%u:", &otrust ) != 1 ) {
|
||||
log_error (_("\b%s: error: no ownertrust value\n"), fname );
|
||||
log_error (_("error in `%s': %s\n"),
|
||||
fname, _("ownertrust value missing"));
|
||||
continue;
|
||||
}
|
||||
if( !otrust )
|
||||
@ -202,11 +212,11 @@ import_ownertrust( const char *fname )
|
||||
any = 1;
|
||||
}
|
||||
else /* error */
|
||||
log_error (_("\b%s: error finding trust record: %s\n"),
|
||||
fname, gpg_strerror (rc));
|
||||
log_error (_("error finding trust record in `%s': %s\n"),
|
||||
fname, g10_errstr(rc));
|
||||
}
|
||||
if( ferror(fp) )
|
||||
log_error (_("\b%s: read error: %s\n"), fname, strerror(errno) );
|
||||
log_error ( _("read error in `%s': %s\n"), fname, strerror(errno) );
|
||||
if( !is_stdin )
|
||||
fclose(fp);
|
||||
|
||||
@ -215,7 +225,7 @@ import_ownertrust( const char *fname )
|
||||
revalidation_mark ();
|
||||
rc = tdbio_sync ();
|
||||
if (rc)
|
||||
log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) );
|
||||
log_error (_("trustdb: sync failed: %s\n"), g10_errstr(rc) );
|
||||
}
|
||||
|
||||
}
|
||||
|
325
g10/tdbio.c
325
g10/tdbio.c
@ -1,4 +1,4 @@
|
||||
/* tdbio.c
|
||||
/* tdbio.c - trust databse I/O operations
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -32,7 +33,6 @@
|
||||
#include "gpg.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
@ -123,21 +123,21 @@ get_record_from_cache( ulong recno )
|
||||
static int
|
||||
write_cache_item( CACHE_CTRL r )
|
||||
{
|
||||
gpg_error_t err;
|
||||
int n;
|
||||
gpg_error_t rc;
|
||||
|
||||
if( lseek( db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
err = gpg_error_from_errno (errno);
|
||||
log_error(_("trustdb rec %lu: lseek failed: %s\n"),
|
||||
r->recno, strerror(errno) );
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
n = write( db_fd, r->data, TRUST_RECORD_LEN);
|
||||
if( n != TRUST_RECORD_LEN ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
err = gpg_error_from_errno (errno);
|
||||
log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
|
||||
r->recno, n, strerror(errno) );
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
r->flags.dirty = 0;
|
||||
return 0;
|
||||
@ -191,7 +191,7 @@ put_record_into_cache( ulong recno, const char *data )
|
||||
}
|
||||
/* see whether we reached the limit */
|
||||
if( cache_entries < MAX_CACHE_ENTRIES_SOFT ) { /* no */
|
||||
r = xmalloc ( sizeof *r );
|
||||
r = xmalloc( sizeof *r );
|
||||
r->flags.used = 1;
|
||||
r->recno = recno;
|
||||
memcpy( r->data, data, TRUST_RECORD_LEN );
|
||||
@ -234,7 +234,7 @@ put_record_into_cache( ulong recno, const char *data )
|
||||
if( cache_entries < MAX_CACHE_ENTRIES_HARD ) { /* no */
|
||||
if( opt.debug && !(cache_entries % 100) )
|
||||
log_debug("increasing tdbio cache size\n");
|
||||
r = xmalloc ( sizeof *r );
|
||||
r = xmalloc( sizeof *r );
|
||||
r->flags.used = 1;
|
||||
r->recno = recno;
|
||||
memcpy( r->data, data, TRUST_RECORD_LEN );
|
||||
@ -246,7 +246,7 @@ put_record_into_cache( ulong recno, const char *data )
|
||||
return 0;
|
||||
}
|
||||
log_info(_("trustdb transaction too large\n"));
|
||||
return GPG_ERR_RESOURCE_LIMIT;
|
||||
return G10ERR_RESOURCE_LIMIT;
|
||||
}
|
||||
if( dirty_count ) {
|
||||
int n = dirty_count / 5; /* discard some dirty entries */
|
||||
@ -336,7 +336,6 @@ tdbio_sync()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* The transaction code is disabled in the 1.2.x branch, as it is not
|
||||
yet used. It will be enabled in 1.3.x. */
|
||||
@ -375,11 +374,10 @@ tdbio_end_transaction()
|
||||
else
|
||||
is_locked = 1;
|
||||
}
|
||||
#warning block_all_signals is not yet available in ../common/signals.c
|
||||
/* block_all_signals(); */
|
||||
block_all_signals();
|
||||
in_transaction = 0;
|
||||
rc = tdbio_sync();
|
||||
/* unblock_all_signals(); */
|
||||
unblock_all_signals();
|
||||
if( !opt.lock_once ) {
|
||||
if( !release_dotlock( lockhandle ) )
|
||||
is_locked = 0;
|
||||
@ -410,9 +408,7 @@ tdbio_cancel_transaction()
|
||||
in_transaction = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* transaction code */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/********************************************************
|
||||
@ -502,9 +498,9 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
|
||||
if( access( fname, R_OK ) ) {
|
||||
if( errno != ENOENT ) {
|
||||
log_error( _("%s: can't access: %s\n"), fname, strerror(errno) );
|
||||
xfree (fname);
|
||||
return GPG_ERR_TRUSTDB;
|
||||
log_error( _("can't access `%s': %s\n"), fname, strerror(errno) );
|
||||
xfree(fname);
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
if( create ) {
|
||||
FILE *fp;
|
||||
@ -521,37 +517,42 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
}
|
||||
*p = DIRSEP_C;
|
||||
|
||||
xfree (db_name);
|
||||
xfree(db_name);
|
||||
db_name = fname;
|
||||
#ifdef __riscos__
|
||||
if( !lockhandle )
|
||||
lockhandle = create_dotlock( db_name );
|
||||
if( !lockhandle )
|
||||
log_fatal( _("%s: can't create lock\n"), db_name );
|
||||
log_fatal( _("can't create lock for `%s'\n"), db_name );
|
||||
if( make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal( _("%s: can't make lock\n"), db_name );
|
||||
log_fatal( _("can't lock `%s'\n"), db_name );
|
||||
#endif /* __riscos__ */
|
||||
oldmask=umask(077);
|
||||
fp =fopen( fname, "wb" );
|
||||
if (is_secured_filename (fname)) {
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
else
|
||||
fp =fopen( fname, "wb" );
|
||||
umask(oldmask);
|
||||
if( !fp )
|
||||
log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) );
|
||||
log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) );
|
||||
fclose(fp);
|
||||
db_fd = open( db_name, O_RDWR | MY_O_BINARY );
|
||||
if( db_fd == -1 )
|
||||
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
|
||||
log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) );
|
||||
|
||||
#ifndef __riscos__
|
||||
if( !lockhandle )
|
||||
lockhandle = create_dotlock( db_name );
|
||||
if( !lockhandle )
|
||||
log_fatal( _("%s: can't create lock\n"), db_name );
|
||||
log_fatal( _("can't create lock for `%s'\n"), db_name );
|
||||
#endif /* !__riscos__ */
|
||||
|
||||
rc = create_version_record ();
|
||||
if( rc )
|
||||
log_fatal( _("%s: failed to create version record: %s"),
|
||||
fname, gpg_strerror (rc));
|
||||
fname, g10_errstr(rc));
|
||||
/* and read again to check that we are okay */
|
||||
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
|
||||
log_fatal( _("%s: invalid trustdb created\n"), db_name );
|
||||
@ -562,7 +563,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
xfree (db_name);
|
||||
xfree(db_name);
|
||||
db_name = fname;
|
||||
return 0;
|
||||
}
|
||||
@ -588,30 +589,26 @@ open_db()
|
||||
if (!lockhandle )
|
||||
lockhandle = create_dotlock( db_name );
|
||||
if (!lockhandle )
|
||||
log_fatal( _("%s: can't create lock\n"), db_name );
|
||||
log_fatal( _("can't create lock for `%s'\n"), db_name );
|
||||
#ifdef __riscos__
|
||||
if (make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal( _("%s: can't make lock\n"), db_name );
|
||||
log_fatal( _("can't lock `%s'\n"), db_name );
|
||||
#endif /* __riscos__ */
|
||||
db_fd = open (db_name, O_RDWR | MY_O_BINARY );
|
||||
if (db_fd == -1 && errno == EACCES) {
|
||||
if (db_fd == -1 && (errno == EACCES
|
||||
#ifdef EROFS
|
||||
|| errno == EROFS)
|
||||
#endif
|
||||
) {
|
||||
db_fd = open (db_name, O_RDONLY | MY_O_BINARY );
|
||||
if (db_fd != -1)
|
||||
log_info (_("NOTE: trustdb not writable\n"));
|
||||
}
|
||||
if ( db_fd == -1 )
|
||||
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
|
||||
log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) );
|
||||
register_secured_file (db_name);
|
||||
|
||||
/* check whether we need to do a version migration */
|
||||
do
|
||||
n = read (db_fd, buf, 5);
|
||||
while (n==-1 && errno == EINTR);
|
||||
if (n == 5 && !memcmp (buf, "\x01gpg\x02", 5))
|
||||
{
|
||||
migrate_from_v2 ();
|
||||
}
|
||||
|
||||
/* read the version record */
|
||||
/* Read the version record. */
|
||||
if (tdbio_read_record (0, &rec, RECTYPE_VER ) )
|
||||
log_fatal( _("%s: invalid trustdb\n"), db_name );
|
||||
}
|
||||
@ -646,7 +643,7 @@ create_hashtable( TRUSTREC *vr, int type )
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_fatal( _("%s: failed to create hashtable: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
/* update the version record */
|
||||
rc = tdbio_write_record( vr );
|
||||
@ -654,7 +651,7 @@ create_hashtable( TRUSTREC *vr, int type )
|
||||
rc = tdbio_sync();
|
||||
if( rc )
|
||||
log_fatal( _("%s: error updating version record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
|
||||
|
||||
@ -671,7 +668,7 @@ tdbio_db_matches_options()
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
|
||||
yes_no = vr.r.ver.marginals == opt.marginals_needed
|
||||
&& vr.r.ver.completes == opt.completes_needed
|
||||
@ -691,7 +688,7 @@ tdbio_read_model(void)
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
return vr.r.ver.trust_model;
|
||||
}
|
||||
|
||||
@ -707,7 +704,7 @@ tdbio_read_nextcheck ()
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
return vr.r.ver.nextcheck;
|
||||
}
|
||||
|
||||
@ -721,7 +718,7 @@ tdbio_write_nextcheck (ulong stamp)
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
|
||||
if (vr.r.ver.nextcheck == stamp)
|
||||
return 0;
|
||||
@ -730,7 +727,7 @@ tdbio_write_nextcheck (ulong stamp)
|
||||
rc = tdbio_write_record( &vr );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error writing version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -751,7 +748,7 @@ get_trusthashrec(void)
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
if( !vr.r.ver.trusthashtbl )
|
||||
create_hashtable( &vr, 0 );
|
||||
|
||||
@ -782,9 +779,8 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
hashrec += msb / ITEMS_PER_HTBL_RECORD;
|
||||
rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
|
||||
if( rc ) {
|
||||
log_error ("upd_hashtable in `%s': read failed: %s\n", db_name,
|
||||
gpg_strerror (rc) );
|
||||
return rc;
|
||||
log_error("upd_hashtable: read failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
|
||||
@ -792,8 +788,8 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc ) {
|
||||
log_error ("upd_hashtable in `%s': write htbl failed: %s\n",
|
||||
db_name, gpg_strerror (rc) );
|
||||
log_error("upd_hashtable: write htbl failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -802,7 +798,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rc = tdbio_read_record( item, &rec, 0 );
|
||||
if( rc ) {
|
||||
log_error( "upd_hashtable: read item failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -811,7 +807,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
level++;
|
||||
if( level >= keylen ) {
|
||||
log_error( "hashtable has invalid indirections.\n");
|
||||
return GPG_ERR_TRUSTDB;
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
goto next_level;
|
||||
}
|
||||
@ -828,7 +824,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
&rec, RECTYPE_HLST);
|
||||
if( rc ) {
|
||||
log_error( "upd_hashtable: read hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -843,7 +839,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_error( "upd_hashtable: write hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc; /* done */
|
||||
}
|
||||
}
|
||||
@ -852,7 +848,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
&rec, RECTYPE_HLST );
|
||||
if( rc ) {
|
||||
log_error( "upd_hashtable: read hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -861,7 +857,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc ) {
|
||||
log_error( "upd_hashtable: write hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
memset( &rec, 0, sizeof rec );
|
||||
@ -871,7 +867,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_error( "upd_hashtable: write ext hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc; /* done */
|
||||
}
|
||||
} /* end loop over hlst slots */
|
||||
@ -889,7 +885,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc ) {
|
||||
log_error( "upd_hashtable: write new hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
/* update the hashtable record */
|
||||
@ -897,14 +893,14 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rc = tdbio_write_record( &lastrec );
|
||||
if( rc )
|
||||
log_error( "upd_hashtable: update htbl failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc; /* ready */
|
||||
}
|
||||
else {
|
||||
log_error( "hashtbl %lu: %lu/%d points to an invalid record %lu\n",
|
||||
table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
|
||||
list_trustdb(NULL);
|
||||
return GPG_ERR_TRUSTDB;
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
}
|
||||
|
||||
@ -931,8 +927,8 @@ drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
|
||||
hashrec += msb / ITEMS_PER_HTBL_RECORD;
|
||||
rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
|
||||
if( rc ) {
|
||||
log_error ("drop_from_hashtable `%s': read failed: %s\n",
|
||||
db_name, gpg_strerror (rc) );
|
||||
log_error("drop_from_hashtable: read failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -944,15 +940,15 @@ drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
|
||||
rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_error ("drop_from_hashtable `%s': write htbl failed: %s\n",
|
||||
db_name, gpg_strerror (rc) );
|
||||
log_error("drop_from_hashtable: write htbl failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = tdbio_read_record( item, &rec, 0 );
|
||||
if( rc ) {
|
||||
log_error( "drop_from_hashtable: read item failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -961,7 +957,7 @@ drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
|
||||
level++;
|
||||
if( level >= keylen ) {
|
||||
log_error( "hashtable has invalid indirections.\n");
|
||||
return GPG_ERR_TRUSTDB;
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
goto next_level;
|
||||
}
|
||||
@ -973,9 +969,8 @@ drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
|
||||
rec.r.hlst.rnum[i] = 0; /* drop */
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_error ("drop_from_hashtable `%s': "
|
||||
"write htbl failed: %s\n",
|
||||
db_name, gpg_strerror (rc) );
|
||||
log_error("drop_from_hashtable: write htbl failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -984,7 +979,7 @@ drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
|
||||
&rec, RECTYPE_HLST);
|
||||
if( rc ) {
|
||||
log_error( "drop_from_hashtable: read hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -995,7 +990,7 @@ drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
|
||||
|
||||
log_error( "hashtbl %lu: %lu/%d points to wrong record %lu\n",
|
||||
table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
|
||||
return GPG_ERR_TRUSTDB;
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
|
||||
|
||||
@ -1021,8 +1016,7 @@ lookup_hashtable( ulong table, const byte *key, size_t keylen,
|
||||
hashrec += msb / ITEMS_PER_HTBL_RECORD;
|
||||
rc = tdbio_read_record( hashrec, rec, RECTYPE_HTBL );
|
||||
if( rc ) {
|
||||
log_error ("lookup_hashtable in `%s' failed: %s\n",
|
||||
db_name, gpg_strerror (rc) );
|
||||
log_error("lookup_hashtable failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1032,16 +1026,15 @@ lookup_hashtable( ulong table, const byte *key, size_t keylen,
|
||||
|
||||
rc = tdbio_read_record( item, rec, 0 );
|
||||
if( rc ) {
|
||||
log_error ("hashtable `%s' read failed: %s\n",
|
||||
db_name, gpg_strerror (rc) );
|
||||
log_error( "hashtable read failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
if( rec->rectype == RECTYPE_HTBL ) {
|
||||
hashrec = item;
|
||||
level++;
|
||||
if( level >= keylen ) {
|
||||
log_error ("hashtable `%s' has invalid indirections\n", db_name);
|
||||
return GPG_ERR_TRUSTDB;
|
||||
log_error("hashtable has invalid indirections\n");
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
goto next_level;
|
||||
}
|
||||
@ -1056,7 +1049,7 @@ lookup_hashtable( ulong table, const byte *key, size_t keylen,
|
||||
rc = tdbio_read_record( rec->r.hlst.rnum[i], &tmp, 0 );
|
||||
if( rc ) {
|
||||
log_error( "lookup_hashtable: read item failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
if( (*cmpfnc)( cmpdata, &tmp ) ) {
|
||||
@ -1069,7 +1062,7 @@ lookup_hashtable( ulong table, const byte *key, size_t keylen,
|
||||
rc = tdbio_read_record( rec->r.hlst.next, rec, RECTYPE_HLST );
|
||||
if( rc ) {
|
||||
log_error( "lookup_hashtable: read hlst failed: %s\n",
|
||||
gpg_strerror (rc) );
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -1164,7 +1157,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
{
|
||||
byte readbuf[TRUST_RECORD_LEN];
|
||||
const byte *buf, *p;
|
||||
int rc = 0;
|
||||
gpg_error_t err = 0;
|
||||
int n, i;
|
||||
|
||||
if( db_fd == -1 )
|
||||
@ -1172,19 +1165,19 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
buf = get_record_from_cache( recnum );
|
||||
if( !buf ) {
|
||||
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
err = gpg_error_from_errno (errno);
|
||||
log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
n = read( db_fd, readbuf, TRUST_RECORD_LEN);
|
||||
if( !n ) {
|
||||
return -1; /* eof */
|
||||
}
|
||||
else if( n != TRUST_RECORD_LEN ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
err = gpg_error_from_errno (errno);
|
||||
log_error(_("trustdb: read failed (n=%d): %s\n"), n,
|
||||
strerror(errno) );
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
buf = readbuf;
|
||||
}
|
||||
@ -1195,7 +1188,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
if( expected && rec->rectype != expected ) {
|
||||
log_error("%lu: read expected rec type %d, got %d\n",
|
||||
recnum, expected, rec->rectype );
|
||||
return GPG_ERR_TRUSTDB;
|
||||
return gpg_error (GPG_ERR_TRUSTDB);
|
||||
}
|
||||
p++; /* skip reserved byte */
|
||||
switch( rec->rectype ) {
|
||||
@ -1204,7 +1197,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
case RECTYPE_VER: /* version record */
|
||||
if( memcmp(buf+1, "gpg", 3 ) ) {
|
||||
log_error( _("%s: not a trustdb file\n"), db_name );
|
||||
rc = GPG_ERR_TRUSTDB;
|
||||
err = gpg_error (GPG_ERR_TRUSTDB);
|
||||
}
|
||||
p += 2; /* skip "gpg" */
|
||||
rec->r.ver.version = *p++;
|
||||
@ -1223,12 +1216,12 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
if( recnum ) {
|
||||
log_error( _("%s: version record with recnum %lu\n"), db_name,
|
||||
(ulong)recnum );
|
||||
rc = GPG_ERR_TRUSTDB;
|
||||
err = gpg_error (GPG_ERR_TRUSTDB);
|
||||
}
|
||||
else if( rec->r.ver.version != 3 ) {
|
||||
log_error( _("%s: invalid file version %d\n"), db_name,
|
||||
rec->r.ver.version );
|
||||
rc = GPG_ERR_TRUSTDB;
|
||||
err = gpg_error (GPG_ERR_TRUSTDB);
|
||||
}
|
||||
break;
|
||||
case RECTYPE_FREE:
|
||||
@ -1263,11 +1256,11 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
default:
|
||||
log_error( "%s: invalid record type %d at recnum %lu\n",
|
||||
db_name, rec->rectype, (ulong)recnum );
|
||||
rc = GPG_ERR_TRUSTDB;
|
||||
err = gpg_error (GPG_ERR_TRUSTDB);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -1379,7 +1372,7 @@ tdbio_delete_record( ulong recnum )
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
|
||||
rec.recnum = recnum;
|
||||
rec.rectype = RECTYPE_FREE;
|
||||
@ -1406,13 +1399,13 @@ tdbio_new_recnum()
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
if( vr.r.ver.firstfree ) {
|
||||
recnum = vr.r.ver.firstfree;
|
||||
rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
|
||||
if( rc ) {
|
||||
log_error( _("%s: error reading free record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
/* update dir record */
|
||||
@ -1420,7 +1413,7 @@ tdbio_new_recnum()
|
||||
rc = tdbio_write_record( &vr );
|
||||
if( rc ) {
|
||||
log_error( _("%s: error writing dir record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
db_name, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
/*zero out the new record */
|
||||
@ -1430,7 +1423,7 @@ tdbio_new_recnum()
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_fatal(_("%s: failed to zero a record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
else { /* not found, append a new record */
|
||||
offset = lseek( db_fd, 0, SEEK_END );
|
||||
@ -1460,7 +1453,7 @@ tdbio_new_recnum()
|
||||
|
||||
if( rc )
|
||||
log_fatal(_("%s: failed to append a record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
return recnum ;
|
||||
}
|
||||
@ -1508,129 +1501,3 @@ tdbio_invalid(void)
|
||||
g10_exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2)
|
||||
* to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs
|
||||
* only to scan the tdb and insert new the new trust records. The old ones are
|
||||
* obsolte from now on
|
||||
*/
|
||||
static void
|
||||
migrate_from_v2 ()
|
||||
{
|
||||
TRUSTREC rec;
|
||||
int i, n;
|
||||
struct {
|
||||
ulong keyrecno;
|
||||
byte ot;
|
||||
byte okay;
|
||||
byte fpr[20];
|
||||
} *ottable;
|
||||
int ottable_size, ottable_used;
|
||||
byte oldbuf[40];
|
||||
ulong recno;
|
||||
int rc, count;
|
||||
|
||||
ottable_size = 5;
|
||||
ottable = xmalloc (ottable_size * sizeof *ottable);
|
||||
ottable_used = 0;
|
||||
|
||||
/* We have some restrictions here. We can't use the version record
|
||||
* and we can't use any of the old hashtables because we dropped the
|
||||
* code. So we first collect all ownertrusts and then use a second
|
||||
* pass fo find the associated keys. We have to do this all without using
|
||||
* the regular record read functions.
|
||||
*/
|
||||
|
||||
/* get all the ownertrusts */
|
||||
if (lseek (db_fd, 0, SEEK_SET ) == -1 )
|
||||
log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
|
||||
for (recno=0;;recno++)
|
||||
{
|
||||
do
|
||||
n = read (db_fd, oldbuf, 40);
|
||||
while (n==-1 && errno == EINTR);
|
||||
if (!n)
|
||||
break; /* eof */
|
||||
if (n != 40)
|
||||
log_fatal ("migrate_vfrom_v2: read error or short read\n");
|
||||
|
||||
if (*oldbuf != 2)
|
||||
continue;
|
||||
|
||||
/* v2 dir record */
|
||||
if (ottable_used == ottable_size)
|
||||
{
|
||||
ottable_size += 1000;
|
||||
ottable = xrealloc (ottable, ottable_size * sizeof *ottable);
|
||||
}
|
||||
ottable[ottable_used].keyrecno = buftoulong (oldbuf+6);
|
||||
ottable[ottable_used].ot = oldbuf[18];
|
||||
ottable[ottable_used].okay = 0;
|
||||
memset (ottable[ottable_used].fpr,0, 20);
|
||||
if (ottable[ottable_used].keyrecno && ottable[ottable_used].ot)
|
||||
ottable_used++;
|
||||
}
|
||||
log_info ("found %d ownertrust records\n", ottable_used);
|
||||
|
||||
/* Read again and find the fingerprints */
|
||||
if (lseek (db_fd, 0, SEEK_SET ) == -1 )
|
||||
log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
|
||||
for (recno=0;;recno++)
|
||||
{
|
||||
do
|
||||
n = read (db_fd, oldbuf, 40);
|
||||
while (n==-1 && errno == EINTR);
|
||||
if (!n)
|
||||
break; /* eof */
|
||||
if (n != 40)
|
||||
log_fatal ("migrate_from_v2: read error or short read\n");
|
||||
|
||||
if (*oldbuf != 3)
|
||||
continue;
|
||||
|
||||
/* v2 key record */
|
||||
for (i=0; i < ottable_used; i++)
|
||||
{
|
||||
if (ottable[i].keyrecno == recno)
|
||||
{
|
||||
memcpy (ottable[i].fpr, oldbuf+20, 20);
|
||||
ottable[i].okay = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* got everything - create the v3 trustdb */
|
||||
if (ftruncate (db_fd, 0))
|
||||
log_fatal ("can't truncate `%s': %s\n", db_name, strerror (errno) );
|
||||
if (create_version_record ())
|
||||
log_fatal ("failed to recreate version record of `%s'\n", db_name);
|
||||
|
||||
/* access the hash table, so it is store just after the version record,
|
||||
* this is not needed put a dump is more pretty */
|
||||
get_trusthashrec ();
|
||||
|
||||
/* And insert the old ownertrust values */
|
||||
count = 0;
|
||||
for (i=0; i < ottable_used; i++)
|
||||
{
|
||||
if (!ottable[i].okay)
|
||||
continue;
|
||||
|
||||
memset (&rec, 0, sizeof rec);
|
||||
rec.recnum = tdbio_new_recnum ();
|
||||
rec.rectype = RECTYPE_TRUST;
|
||||
memcpy(rec.r.trust.fingerprint, ottable[i].fpr, 20);
|
||||
rec.r.trust.ownertrust = ottable[i].ot;
|
||||
if (tdbio_write_record (&rec))
|
||||
log_fatal ("failed to write trust record of `%s'\n", db_name);
|
||||
count++;
|
||||
}
|
||||
|
||||
revalidation_mark ();
|
||||
rc = tdbio_sync ();
|
||||
if (rc)
|
||||
log_fatal ("failed to sync `%s'\n", db_name);
|
||||
log_info ("migrated %d version 2 ownertrusts\n", count);
|
||||
xfree (ottable);
|
||||
}
|
||||
|
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_TDBIO_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* textfilter.c
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -28,11 +29,11 @@
|
||||
#include "gpg.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "filter.h"
|
||||
#include "i18n.h"
|
||||
#include "options.h"
|
||||
#include "status.h"
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#define LF "\r\n"
|
||||
@ -62,17 +63,9 @@ len_without_trailing_chars( byte *line, unsigned len, const char *trimchars )
|
||||
return mark? (mark - line) : len;
|
||||
}
|
||||
|
||||
unsigned
|
||||
len_without_trailing_ws( byte *line, unsigned len )
|
||||
{
|
||||
return len_without_trailing_chars( line, len, " \t\r\n" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
standard( text_filter_context_t *tfx, iobuf_t a,
|
||||
standard( text_filter_context_t *tfx, IOBUF a,
|
||||
byte *buf, size_t size, size_t *ret_len)
|
||||
{
|
||||
int rc=0;
|
||||
@ -102,7 +95,30 @@ standard( text_filter_context_t *tfx, iobuf_t a,
|
||||
break;
|
||||
}
|
||||
lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n';
|
||||
tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len );
|
||||
|
||||
/* The story behind this is that 2440 says that textmode
|
||||
hashes should canonicalize line endings to CRLF and remove
|
||||
spaces and tabs. 2440bis-12 says to just canonicalize to
|
||||
CRLF. 1.4.0 was released using the bis-12 behavior, but it
|
||||
was discovered that many mail clients do not canonicalize
|
||||
PGP/MIME signature text appropriately (and were relying on
|
||||
GnuPG to handle trailing spaces). So, we default to the
|
||||
2440 behavior, but use the 2440bis-12 behavior if the user
|
||||
specifies --no-rfc2440-text. The default will be changed
|
||||
at some point in the future when the mail clients have been
|
||||
upgraded. Aside from PGP/MIME and broken mail clients,
|
||||
this makes no difference to any signatures in the real
|
||||
world except for a textmode detached signature. PGP always
|
||||
used the 2440bis-12 behavior (ignoring 2440 itself), so
|
||||
this actually makes us compatible with PGP textmode
|
||||
detached signatures for the first time. */
|
||||
if(opt.rfc2440_text)
|
||||
tfx->buffer_len=trim_trailing_chars(tfx->buffer,tfx->buffer_len,
|
||||
" \t\r\n");
|
||||
else
|
||||
tfx->buffer_len=trim_trailing_chars(tfx->buffer,tfx->buffer_len,
|
||||
"\r\n");
|
||||
|
||||
if( lf_seen ) {
|
||||
tfx->buffer[tfx->buffer_len++] = '\r';
|
||||
tfx->buffer[tfx->buffer_len++] = '\n';
|
||||
@ -113,15 +129,13 @@ standard( text_filter_context_t *tfx, iobuf_t a,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* The filter is used to make canonical text: Lines are terminated by
|
||||
* CR, LF, trailing white spaces are removed.
|
||||
*/
|
||||
int
|
||||
text_filter( void *opaque, int control,
|
||||
iobuf_t a, byte *buf, size_t *ret_len)
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
{
|
||||
size_t size = *ret_len;
|
||||
text_filter_context_t *tfx = opaque;
|
||||
@ -134,7 +148,7 @@ text_filter( void *opaque, int control,
|
||||
if( tfx->truncated )
|
||||
log_error(_("can't handle text lines longer than %d characters\n"),
|
||||
MAX_LINELEN );
|
||||
xfree ( tfx->buffer );
|
||||
xfree( tfx->buffer );
|
||||
tfx->buffer = NULL;
|
||||
}
|
||||
else if( control == IOBUFCTRL_DESC )
|
||||
@ -148,13 +162,13 @@ text_filter( void *opaque, int control,
|
||||
* md is updated as required by rfc2440
|
||||
*/
|
||||
int
|
||||
copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md,
|
||||
copy_clearsig_text( IOBUF out, IOBUF inp, gcry_md_hd_t md,
|
||||
int escape_dash, int escape_from, int pgp2mode )
|
||||
{
|
||||
unsigned maxlen;
|
||||
unsigned int maxlen;
|
||||
byte *buffer = NULL; /* malloced buffer */
|
||||
unsigned bufsize; /* and size of this buffer */
|
||||
unsigned n;
|
||||
unsigned int bufsize; /* and size of this buffer */
|
||||
unsigned int n;
|
||||
int truncated = 0;
|
||||
int pending_lf = 0;
|
||||
|
||||
@ -164,6 +178,8 @@ copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md,
|
||||
if( !escape_dash )
|
||||
escape_from = 0;
|
||||
|
||||
write_status (STATUS_BEGIN_SIGNING);
|
||||
|
||||
for(;;) {
|
||||
maxlen = MAX_LINELEN;
|
||||
n = iobuf_read_line( inp, &buffer, &bufsize, &maxlen );
|
||||
@ -176,15 +192,16 @@ copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md,
|
||||
/* update the message digest */
|
||||
if( escape_dash ) {
|
||||
if( pending_lf ) {
|
||||
gcry_md_putc( md, '\r' );
|
||||
gcry_md_putc( md, '\n' );
|
||||
gcry_md_putc ( md, '\r' );
|
||||
gcry_md_putc ( md, '\n' );
|
||||
}
|
||||
gcry_md_write( md, buffer,
|
||||
len_without_trailing_chars( buffer, n,
|
||||
pgp2mode? " \r\n":" \t\r\n"));
|
||||
gcry_md_write ( md, buffer,
|
||||
len_without_trailing_chars (buffer, n,
|
||||
pgp2mode?
|
||||
" \r\n":" \t\r\n"));
|
||||
}
|
||||
else
|
||||
gcry_md_write( md, buffer, n );
|
||||
gcry_md_write ( md, buffer, n );
|
||||
pending_lf = buffer[n-1] == '\n';
|
||||
|
||||
/* write the output */
|
||||
|
656
g10/trustdb.c
656
g10/trustdb.c
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/* trustdb.h - Trust database
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
|
||||
* Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -16,13 +16,13 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_TRUSTDB_H
|
||||
#define G10_TRUSTDB_H
|
||||
|
||||
|
||||
/* Trust values must be sorted in ascending order */
|
||||
#define TRUST_MASK 15
|
||||
#define TRUST_UNKNOWN 0 /* o: not yet calculated/assigned */
|
||||
@ -38,19 +38,26 @@
|
||||
#define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */
|
||||
#define TRUST_FLAG_PENDING_CHECK 256 /* a check-trustdb is pending */
|
||||
|
||||
#define NAMEHASH_HASH DIGEST_ALGO_RMD160
|
||||
#define NAMEHASH_LEN 20
|
||||
|
||||
/*-- trustdb.c --*/
|
||||
void register_trusted_keyid(u32 *keyid);
|
||||
void register_trusted_key( const char *string );
|
||||
void check_trustdb (void);
|
||||
void update_trustdb (void);
|
||||
int setup_trustdb( int level, const char *dbname );
|
||||
void init_trustdb( void );
|
||||
void check_trustdb_stale(void);
|
||||
void sync_trustdb( void );
|
||||
|
||||
const char *uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid);
|
||||
const char *trust_value_to_string (unsigned int value);
|
||||
int string_to_trust_value (const char *str);
|
||||
|
||||
void revalidation_mark (void);
|
||||
int trustdb_pending_check(void);
|
||||
void trustdb_check_or_update(void);
|
||||
|
||||
int cache_disabled_value(PKT_public_key *pk);
|
||||
|
||||
@ -75,6 +82,11 @@ const char *get_ownertrust_string (PKT_public_key *pk);
|
||||
void update_ownertrust (PKT_public_key *pk, unsigned int new_trust );
|
||||
int clear_ownertrusts (PKT_public_key *pk);
|
||||
|
||||
void clean_one_uid(KBNODE keyblock,KBNODE uidnode,int noisy,int self_only,
|
||||
int *uids_cleaned,int *sigs_cleaned);
|
||||
void clean_key(KBNODE keyblock,int noisy,int self_only,
|
||||
int *uids_cleaned,int *sigs_cleaned);
|
||||
|
||||
/*-- tdbdump.c --*/
|
||||
void list_trustdb(const char *username);
|
||||
void export_ownertrust(void);
|
||||
|
40
g10/verify.c
40
g10/verify.c
@ -1,5 +1,5 @@
|
||||
/* verify.c - verify signed data
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
/* verify.c - Verify signed data
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -24,14 +25,13 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h> /* for isatty() */
|
||||
|
||||
#include "gpg.h"
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "status.h"
|
||||
@ -54,7 +54,7 @@
|
||||
int
|
||||
verify_signatures( int nfiles, char **files )
|
||||
{
|
||||
iobuf_t fp;
|
||||
IOBUF fp;
|
||||
armor_filter_context_t afx;
|
||||
progress_filter_context_t pfx;
|
||||
const char *sigfile;
|
||||
@ -91,11 +91,17 @@ verify_signatures( int nfiles, char **files )
|
||||
|
||||
/* open the signature file */
|
||||
fp = iobuf_open(sigfile);
|
||||
if (fp && is_secured_file (iobuf_get_fd (fp)))
|
||||
{
|
||||
iobuf_close (fp);
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !fp ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error(_("can't open `%s': %s\n"),
|
||||
print_fname_stdin(sigfile), strerror (errno));
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
handle_progress (&pfx, fp, sigfile);
|
||||
|
||||
@ -103,12 +109,12 @@ verify_signatures( int nfiles, char **files )
|
||||
iobuf_push_filter( fp, armor_filter, &afx );
|
||||
|
||||
sl = NULL;
|
||||
for(i=1 ; i < nfiles; i++ )
|
||||
for(i=nfiles-1 ; i > 0 ; i-- )
|
||||
add_to_strlist( &sl, files[i] );
|
||||
rc = proc_signature_packets( NULL, fp, sl, sigfile );
|
||||
free_strlist(sl);
|
||||
iobuf_close(fp);
|
||||
if( afx.no_openpgp_data && rc == -1 ) {
|
||||
if( (afx.no_openpgp_data && rc == -1) || rc == G10ERR_NO_DATA ) {
|
||||
log_error(_("the signature could not be verified.\n"
|
||||
"Please remember that the signature file (.sig or .asc)\n"
|
||||
"should be the first file given on the command line.\n") );
|
||||
@ -122,23 +128,31 @@ verify_signatures( int nfiles, char **files )
|
||||
void
|
||||
print_file_status( int status, const char *name, int what )
|
||||
{
|
||||
char *p = xmalloc (strlen(name)+10);
|
||||
char *p = xmalloc(strlen(name)+10);
|
||||
sprintf(p, "%d %s", what, name );
|
||||
write_status_text( status, p );
|
||||
xfree (p);
|
||||
xfree(p);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
verify_one_file( const char *name )
|
||||
{
|
||||
iobuf_t fp;
|
||||
IOBUF fp;
|
||||
armor_filter_context_t afx;
|
||||
progress_filter_context_t pfx;
|
||||
int rc;
|
||||
|
||||
print_file_status( STATUS_FILE_START, name, 1 );
|
||||
fp = iobuf_open(name);
|
||||
if (fp)
|
||||
iobuf_ioctl (fp,3,1,NULL); /* disable fd caching */
|
||||
if (fp && is_secured_file (iobuf_get_fd (fp)))
|
||||
{
|
||||
iobuf_close (fp);
|
||||
fp = NULL;
|
||||
errno = EPERM;
|
||||
}
|
||||
if( !fp ) {
|
||||
rc = gpg_error_from_errno (errno);
|
||||
log_error(_("can't open `%s': %s\n"),
|
||||
@ -179,7 +193,7 @@ verify_files( int nfiles, char **files )
|
||||
lno++;
|
||||
if( !*line || line[strlen(line)-1] != '\n' ) {
|
||||
log_error(_("input line %u too long or missing LF\n"), lno );
|
||||
return GPG_ERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
/* This code does not work on MSDOS but how cares there are
|
||||
* also no script languages available. We don't strip any
|
||||
|
@ -1,3 +1,7 @@
|
||||
2006-04-18 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keyserver.h, i18n.h, http.h, cipher.h: Updated to gpg 1.4.3.
|
||||
|
||||
2003-09-04 David Shaw <dshaw@jabberwocky.com>
|
||||
|
||||
* cipher.h: Drop TIGER/192 support.
|
||||
|
114
include/cipher.h
114
include/cipher.h
@ -1,97 +1,101 @@
|
||||
/* cipher.h
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
/* cipher.h - Definitions for OpenPGP
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GNUPG is free software; you can redistribute it and/or modify
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNUPG is distributed in the hope that it will be useful,
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef G10_CIPHER_H
|
||||
#define G10_CIPHER_H
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
#define CIPHER_ALGO_NONE GCRY_CIPHER_NONE
|
||||
#define CIPHER_ALGO_IDEA GCRY_CIPHER_IDEA
|
||||
#define CIPHER_ALGO_3DES GCRY_CIPHER_3DES
|
||||
#define CIPHER_ALGO_CAST5 GCRY_CIPHER_CAST5
|
||||
#define CIPHER_ALGO_BLOWFISH GCRY_CIPHER_BLOWFISH /* 128 bit */
|
||||
#define CIPHER_ALGO_SAFER_SK128 GCRY_CIPHER_SK128
|
||||
#define CIPHER_ALGO_DES_SK GCRY_CIPHER_DES_SK
|
||||
#define CIPHER_ALGO_AES GCRY_CIPHER_AES
|
||||
#define CIPHER_ALGO_AES192 GCRY_CIPHER_AES192
|
||||
#define CIPHER_ALGO_AES256 GCRY_CIPHER_AES256
|
||||
/* Macros for compatibility with older libgcrypt versions. */
|
||||
#ifndef GCRY_PK_USAGE_CERT
|
||||
# define GCRY_PK_USAGE_CERT 4
|
||||
# define GCRY_PK_USAGE_AUTH 8
|
||||
# define GCRY_PK_USAGE_UNKN 128
|
||||
#endif
|
||||
|
||||
|
||||
/* Constants for OpenPGP. */
|
||||
|
||||
#define CIPHER_ALGO_NONE /* 0 */ GCRY_CIPHER_NONE
|
||||
#define CIPHER_ALGO_IDEA /* 1 */ GCRY_CIPHER_IDEA
|
||||
#define CIPHER_ALGO_3DES /* 2 */ GCRY_CIPHER_3DES
|
||||
#define CIPHER_ALGO_CAST5 /* 3 */ GCRY_CIPHER_CAST5
|
||||
#define CIPHER_ALGO_BLOWFISH /* 4 */ GCRY_CIPHER_BLOWFISH /* 128 bit */
|
||||
/* 5 & 6 are reserved */
|
||||
#define CIPHER_ALGO_AES /* 7 */ GCRY_CIPHER_AES
|
||||
#define CIPHER_ALGO_AES192 /* 8 */ GCRY_CIPHER_AES192
|
||||
#define CIPHER_ALGO_AES256 /* 9 */ GCRY_CIPHER_AES256
|
||||
#define CIPHER_ALGO_RIJNDAEL CIPHER_ALGO_AES
|
||||
#define CIPHER_ALGO_RIJNDAEL192 CIPHER_ALGO_AES192
|
||||
#define CIPHER_ALGO_RIJNDAEL256 CIPHER_ALGO_AES256
|
||||
#define CIPHER_ALGO_TWOFISH GCRY_CIPHER_TWOFISH /* 256 bit */
|
||||
#define CIPHER_ALGO_DUMMY 110 /* no encryption at all */
|
||||
#define CIPHER_ALGO_TWOFISH /* 10 */ GCRY_CIPHER_TWOFISH /* 256 bit */
|
||||
#define CIPHER_ALGO_DUMMY 110 /* No encryption at all. */
|
||||
|
||||
#define PUBKEY_ALGO_RSA GCRY_PK_RSA
|
||||
#define PUBKEY_ALGO_RSA_E GCRY_PK_RSA_E
|
||||
#define PUBKEY_ALGO_RSA_S GCRY_PK_RSA_S
|
||||
#define PUBKEY_ALGO_ELGAMAL_E GCRY_PK_ELG_E
|
||||
#define PUBKEY_ALGO_DSA GCRY_PK_DSA
|
||||
#define PUBKEY_ALGO_ELGAMAL GCRY_PK_ELG
|
||||
#define PUBKEY_ALGO_RSA /* 1 */ GCRY_PK_RSA
|
||||
#define PUBKEY_ALGO_RSA_E /* 2 */ GCRY_PK_RSA_E /* RSA encrypt only. */
|
||||
#define PUBKEY_ALGO_RSA_S /* 3 */ GCRY_PK_RSA_S /* RSA sign only. */
|
||||
#define PUBKEY_ALGO_ELGAMAL_E /* 16 */ GCRY_PK_ELG_E /* Elgamal encr only */
|
||||
#define PUBKEY_ALGO_DSA /* 17 */ GCRY_PK_DSA
|
||||
#define PUBKEY_ALGO_ELGAMAL /* 20 */ GCRY_PK_ELG /* Elgamal encr+sign */
|
||||
|
||||
#define PUBKEY_USAGE_SIG GCRY_PK_USAGE_SIGN
|
||||
#define PUBKEY_USAGE_ENC GCRY_PK_USAGE_ENCR
|
||||
#define PUBKEY_USAGE_CERT 4 /* key is also good to certify other keys*/
|
||||
#define PUBKEY_USAGE_AUTH 8
|
||||
#define PUBKEY_USAGE_SIG GCRY_PK_USAGE_SIGN /* Good for signatures. */
|
||||
#define PUBKEY_USAGE_ENC GCRY_PK_USAGE_ENCR /* Good for encryption. */
|
||||
#define PUBKEY_USAGE_CERT GCRY_PK_USAGE_CERT /* Also good to certify keys. */
|
||||
#define PUBKEY_USAGE_AUTH GCRY_PK_USAGE_AUTH /* Good for authentication. */
|
||||
#define PUBKEY_USAGE_UNKNOWN GCRY_PK_USAGE_UNKN /* Unknown usage flag. */
|
||||
|
||||
#define DIGEST_ALGO_MD5 GCRY_MD_MD5
|
||||
#define DIGEST_ALGO_SHA1 GCRY_MD_SHA1
|
||||
#define DIGEST_ALGO_RMD160 GCRY_MD_RMD160
|
||||
#define DIGEST_ALGO_SHA256 GCRY_MD_SHA256
|
||||
#define DIGEST_ALGO_SHA384 GCRY_MD_SHA384
|
||||
#define DIGEST_ALGO_SHA512 GCRY_MD_SHA512
|
||||
#define DIGEST_ALGO_MD5 /* 1 */ GCRY_MD_MD5
|
||||
#define DIGEST_ALGO_SHA1 /* 2 */ GCRY_MD_SHA1
|
||||
#define DIGEST_ALGO_RMD160 /* 3 */ GCRY_MD_RMD160
|
||||
/* 4, 5, 6, and 7 are reserved */
|
||||
#define DIGEST_ALGO_SHA256 /* 8 */ GCRY_MD_SHA256
|
||||
#define DIGEST_ALGO_SHA384 /* 9 */ GCRY_MD_SHA384
|
||||
#define DIGEST_ALGO_SHA512 /* 10 */ GCRY_MD_SHA512
|
||||
|
||||
#define COMPRESS_ALGO_NONE 0
|
||||
#define COMPRESS_ALGO_ZIP 1
|
||||
#define COMPRESS_ALGO_ZLIB 2
|
||||
#define COMPRESS_ALGO_BZIP2 3
|
||||
|
||||
#define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
|
||||
|| (a)==PUBKEY_ALGO_RSA_S )
|
||||
#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E)
|
||||
#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL_E)
|
||||
#define is_DSA(a) ((a)==PUBKEY_ALGO_DSA)
|
||||
|
||||
typedef struct {
|
||||
int algo;
|
||||
int keylen;
|
||||
int algo_info_printed;
|
||||
int use_mdc;
|
||||
byte key[32]; /* this is the largest used keylen (256 bit) */
|
||||
/* The data encryption key object. */
|
||||
typedef struct
|
||||
{
|
||||
int algo;
|
||||
int keylen;
|
||||
int algo_info_printed;
|
||||
int use_mdc;
|
||||
int symmetric;
|
||||
byte key[32]; /* This is the largest used keylen (256 bit). */
|
||||
} DEK;
|
||||
|
||||
|
||||
#ifndef EXTERN_UNLESS_MAIN_MODULE
|
||||
#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
|
||||
#define EXTERN_UNLESS_MAIN_MODULE extern
|
||||
#else
|
||||
#define EXTERN_UNLESS_MAIN_MODULE
|
||||
#endif
|
||||
#endif
|
||||
EXTERN_UNLESS_MAIN_MODULE int g10_opt_verbose;
|
||||
EXTERN_UNLESS_MAIN_MODULE const char *g10_opt_homedir;
|
||||
|
||||
|
||||
|
||||
/* Constants to allocate static MPI arrays. */
|
||||
#define PUBKEY_MAX_NPKEY 4
|
||||
#define PUBKEY_MAX_NSKEY 6
|
||||
#define PUBKEY_MAX_NSIG 2
|
||||
#define PUBKEY_MAX_NENC 2
|
||||
|
||||
#define MD_HANDLE gcry_md_hd_t
|
||||
#define CIPHER_HANDLE gcry_cipher_hd_t
|
||||
|
||||
#endif /*G10_CIPHER_H*/
|
||||
|
@ -1,21 +1,22 @@
|
||||
/* host2net.h - Some macros
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GNUPG is free software; you can redistribute it and/or modify
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNUPG is distributed in the hope that it will be useful,
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_HOST2NET_H
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* http.h - HTTP protocol handler
|
||||
* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1999, 2000, 2001, 2003, 2004,
|
||||
* 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -15,12 +16,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_HTTP_H
|
||||
#define G10_HTTP_H 1
|
||||
|
||||
#include "iobuf.h"
|
||||
#include "../common/iobuf.h"
|
||||
|
||||
struct uri_tuple {
|
||||
struct uri_tuple *next;
|
||||
@ -34,6 +37,7 @@ typedef struct uri_tuple *URI_TUPLE;
|
||||
struct parsed_uri {
|
||||
/* all these pointers point into buffer; most stuff is not escaped */
|
||||
char *scheme; /* pointer to the scheme string (lowercase) */
|
||||
char *auth; /* username/password for basic auth */
|
||||
char *host; /* host (converted to lowercase) */
|
||||
ushort port; /* port (always set if the host is set) */
|
||||
char *path; /* the path */
|
||||
@ -49,19 +53,20 @@ typedef enum {
|
||||
HTTP_REQ_POST = 3
|
||||
} HTTP_REQ_TYPE;
|
||||
|
||||
enum { /* put flag values into an enum, so that gdb can display them */
|
||||
HTTP_FLAG_TRY_PROXY = 1,
|
||||
HTTP_FLAG_NO_SHUTDOWN = 2,
|
||||
HTTP_FLAG_TRY_SRV = 3
|
||||
};
|
||||
/* put flag values into an enum, so that gdb can display them */
|
||||
enum
|
||||
{
|
||||
HTTP_FLAG_NO_SHUTDOWN = 1,
|
||||
HTTP_FLAG_TRY_SRV = 2
|
||||
};
|
||||
|
||||
struct http_context {
|
||||
int initialized;
|
||||
unsigned int status_code;
|
||||
int sock;
|
||||
int in_data;
|
||||
IOBUF fp_read;
|
||||
IOBUF fp_write;
|
||||
iobuf_t fp_read;
|
||||
iobuf_t fp_write;
|
||||
int is_http_0_9;
|
||||
PARSED_URI uri;
|
||||
HTTP_REQ_TYPE req_type;
|
||||
@ -72,11 +77,11 @@ struct http_context {
|
||||
typedef struct http_context *HTTP_HD;
|
||||
|
||||
int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
|
||||
unsigned int flags );
|
||||
char *auth, unsigned int flags, const char *proxy );
|
||||
void http_start_data( HTTP_HD hd );
|
||||
int http_wait_response( HTTP_HD hd, unsigned int *ret_status );
|
||||
void http_close( HTTP_HD hd );
|
||||
|
||||
int http_open_document( HTTP_HD hd, const char *document, unsigned int flags );
|
||||
int http_open_document( HTTP_HD hd, const char *document, char *auth,
|
||||
unsigned int flags, const char *proxy );
|
||||
|
||||
#endif /*G10_HTTP_H*/
|
||||
|
@ -15,14 +15,15 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_I18N_H
|
||||
#define G10_I18N_H
|
||||
|
||||
#ifdef USE_SIMPLE_GETTEXT
|
||||
int set_gettext_file( const char *filename );
|
||||
int set_gettext_file( const char *filename, const char *regkey );
|
||||
const char *gettext( const char *msgid );
|
||||
|
||||
#define _(a) gettext (a)
|
||||
|
@ -1,21 +1,22 @@
|
||||
/* keyserver.h
|
||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GNUPG is free software; you can redistribute it and/or modify
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNUPG is distributed in the hope that it will be useful,
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef _KEYSERVER_H_
|
||||
@ -35,6 +36,7 @@
|
||||
#define KEYSERVER_KEY_EXISTS 7 /* key already exists */
|
||||
#define KEYSERVER_KEY_INCOMPLETE 8 /* key incomplete (EOF) */
|
||||
#define KEYSERVER_UNREACHABLE 9 /* unable to contact keyserver */
|
||||
#define KEYSERVER_TIMEOUT 10 /* timeout while accessing keyserver */
|
||||
|
||||
/* Must be 127 due to shell internal magic. */
|
||||
#define KEYSERVER_SCHEME_NOT_FOUND 127
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef G10_MEMORY_H
|
||||
#define G10_MEMORY_H
|
||||
|
||||
#error this file should not be used anymore
|
||||
|
||||
#ifdef M_DEBUG
|
||||
#ifndef STR
|
||||
#define STR(v) #v
|
||||
|
@ -30,6 +30,8 @@
|
||||
#ifndef G10_MPI_H
|
||||
#define G10_MPI_H
|
||||
|
||||
#error this file should not be used anymore
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
#if 0
|
||||
|
@ -1,21 +1,22 @@
|
||||
/* types.h - some common typedefs
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GNUPG is free software; you can redistribute it and/or modify
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNUPG is distributed in the hope that it will be useful,
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef G10_TYPES_H
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef G10_UTIL_H
|
||||
#define G10_UTIL_H
|
||||
|
||||
#warning oops, using old util.h
|
||||
#error this file should not be used anymore
|
||||
#if 0 /* Dont use it anymore */
|
||||
|
||||
#if defined (__MINGW32__) || defined (__CYGWIN32__)
|
||||
|
@ -15,7 +15,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
#ifndef G10_ZLIB_RISCOS_H
|
||||
#define G10_ZLIB_RISCOS_H
|
||||
|
@ -1,3 +1,8 @@
|
||||
2006-04-18 Werner Koch <wk@g10code.com>
|
||||
|
||||
* libjnlib-config.h (JNLIB_NEED_UTF8CONF): Defined.
|
||||
* strlist.c (add_to_strlist2) [JNLIB_NEED_UTF8CONV]: Enabled.
|
||||
|
||||
2005-06-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* stringhelp.c (sanitize_buffer): Make P a void*.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* libjnlib-config.h - local configuration of the jnlib functions
|
||||
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -29,6 +29,9 @@
|
||||
#include <gcrypt.h> /* gcry_malloc & Cie. */
|
||||
#include "logging.h"
|
||||
|
||||
/* We require support for utf-8 conversion. */
|
||||
#define JNLIB_NEED_UTF8CONF 1
|
||||
|
||||
#ifdef USE_SIMPLE_GETTEXT
|
||||
int set_gettext_file( const char *filename );
|
||||
const char *gettext( const char *msgid );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* strlist.c - string helpers
|
||||
* Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 2000, 2001, 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -26,7 +26,9 @@
|
||||
|
||||
#include "libjnlib-config.h"
|
||||
#include "strlist.h"
|
||||
|
||||
#ifdef JNLIB_NEED_UTF8CONV
|
||||
#include "utf8conv.h"
|
||||
#endif
|
||||
|
||||
void
|
||||
free_strlist( strlist_t sl )
|
||||
@ -53,26 +55,26 @@ add_to_strlist( strlist_t *list, const char *string )
|
||||
return sl;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/****************
|
||||
* same as add_to_strlist() but if is_utf8 is *not* set a conversion
|
||||
* to UTF8 is done
|
||||
*/
|
||||
|
||||
/* Same as add_to_strlist() but if is_utf8 is *not* set, a conversion
|
||||
to UTF-8 is done. */
|
||||
#ifdef JNLIB_NEED_UTF8CONV
|
||||
strlist_t
|
||||
add_to_strlist2( strlist_t *list, const char *string, int is_utf8 )
|
||||
{
|
||||
strlist_t sl;
|
||||
|
||||
if( is_utf8 )
|
||||
sl = add_to_strlist( list, string );
|
||||
else {
|
||||
char *p = native_to_utf8( string );
|
||||
sl = add_to_strlist( list, p );
|
||||
m_free( p );
|
||||
strlist_t sl;
|
||||
|
||||
if (is_utf8)
|
||||
sl = add_to_strlist( list, string );
|
||||
else
|
||||
{
|
||||
char *p = native_to_utf8( string );
|
||||
sl = add_to_strlist( list, p );
|
||||
jnlib_free ( p );
|
||||
}
|
||||
return sl;
|
||||
return sl;
|
||||
}
|
||||
#endif
|
||||
#endif /* JNLIB_NEED_UTF8CONV*/
|
||||
|
||||
strlist_t
|
||||
append_to_strlist( strlist_t *list, const char *string )
|
||||
|
@ -32,8 +32,7 @@ typedef struct string_list *strlist_t;
|
||||
void free_strlist (strlist_t sl);
|
||||
strlist_t add_to_strlist (strlist_t *list, const char *string);
|
||||
|
||||
/*strlist_t add_to_strlist2( strlist_t *list,
|
||||
const char *string, int is_utf8);*/
|
||||
strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8);
|
||||
|
||||
strlist_t append_to_strlist (strlist_t *list, const char *string);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user