1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

This commit was manufactured by cvs2svn to create branch

'GNUPG-1-9-BRANCH'.
This commit is contained in:
Repo Admin 2002-10-19 07:55:27 +00:00
parent 8d76177f10
commit 82a17c9fb3
563 changed files with 0 additions and 267875 deletions

View file

@ -1,102 +0,0 @@
2002-08-10 Werner Koch <wk@gnupg.org>
* keybox-search.c (blob_cmp_fpr_part): New.
(has_short_kid, has_long_kid): Implemented.
2002-07-22 Werner Koch <wk@gnupg.org>
* keybox-defs.h: New BLOBTYPTE_EMPTY.
* keybox-dump.c (_keybox_dump_blob): Handle new type.
* keybox-file.c (_keybox_read_blob): Skip over empty blobs. Store
the file offset.
* keybox-blob.c (_keybox_new_blob): Add new arg OFF.
(_keybox_get_blob_fileoffset): New.
* keybox-update.c (keybox_delete): Implemented.
2002-06-19 Werner Koch <wk@gnupg.org>
* keybox-init.c (keybox_set_ephemeral): New.
* keybox-blob.c (create_blob_header): Store epheermal flag.
(_keybox_create_x509_blob): Pass epheermal flag on.
* keybox-update.c (keybox_insert_cert): Ditto.
* keybox-search.c (blob_get_blob_flags): New.
(keybox_search): Ignore ephemeral blobs when not in ephemeral mode.
* keybox-dump.c (_keybox_dump_blob): Print blob flags as strings.
2002-02-25 Werner Koch <wk@gnupg.org>
* keybox-search.c (blob_cmp_mail): Use case-insensitive compare
because mail addresses are in general case insensitive (well
RFC2822 allows for case sensitive mailbox parts, but this is in
general considired a Bad Thing). Add additional substr parameter
to allow for substring matches within the mail address. Change
all callers to pass this along.
(blob_cmp_name): Likewise but do the case-insensitive search only
in sub string mode.
(keybox_search): Implement MAILSUB and SUBSTR mode.
2002-01-21 Werner Koch <wk@gnupg.org>
* keybox-search.c (keybox_search): Allow KEYDB_SEARCH_MODE_FPR20.
2002-01-15 Werner Koch <wk@gnupg.org>
* keybox-search.c (blob_cmp_fpr): New.
(has_fingerprint): Implemented;
2001-12-20 Werner Koch <wk@gnupg.org>
* keybox-blob.c (_keybox_create_x509_blob): Skip the leading
parenthesis of the serial number's S-exp.
(_keybox_create_x509_blob): And fixed length calculation.
(create_blob_header): Don't add an offset when writing the serial.
2001-12-18 Werner Koch <wk@gnupg.org>
* Makefile.am (AM_CPPFLAGS): Add flags for libksba
* keybox-blob.c (_keybox_create_x509_blob): Use
gcry_sexp_canon_len to get the length of the serial number.
(_keybox_release_blob): Need to use a new serialbuf to free the memory.
2001-12-17 Werner Koch <wk@gnupg.org>
* keybox-search.c: Changed the way the serial number is
represented.
2001-12-15 Werner Koch <wk@gnupg.org>
* keybox-search.c (blob_cmp_name): There is no terminating 0 stored
for the uid; fixed length compare.
2001-12-14 Werner Koch <wk@gnupg.org>
* keybox-blob.c (x509_email_kludge): New.
(_keybox_create_x509_blob): Insert an extra email address if the
subject's DN has an email part.
* keybox-defs.h: Added the xtoi_2 and digitp macros.
2001-12-13 Werner Koch <wk@gnupg.org>
* keybox-search.c (blob_cmp_name): Kludge to allow searching for
more than one name.
(has_subject_or_alt): New.
(blob_cmp_mail): New.
(has_mail): New.
(keybox_search): Implemented exact search and exact mail search.
* kbx/keybox-blob.c (_keybox_create_x509_blob): Insert alternate
names.
Copyright 2001 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
modifications, as long as this notice is preserved.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View file

@ -1,53 +0,0 @@
# Keybox Makefile
# 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
## Process this file with automake to produce Makefile.in
localedir = $(datadir)/locale
INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\"
EXTRA_DIST = mkerrors
AM_CPPFLAGS = $(KSBA_CFLAGS) $(LIBGCRYPT_CLFAGS)
BUILT_SOURCES = keybox-errors.c
noinst_LIBRARIES = libkeybox.a
bin_PROGRAMS = kbxutil
common_sources = \
keybox.h keybox-defs.h keybox-search-desc.h \
keybox-util.c \
keybox-errors.c \
keybox-init.c \
keybox-blob.c \
keybox-file.c \
keybox-search.c \
keybox-update.c \
keybox-dump.c
libkeybox_a_SOURCES = $(common_sources)
kbxutil_SOURCES = kbxutil.c $(common_sources)
kbxutil_LDADD = ../jnlib/libjnlib.a $(KSBA_LIBS) $(LIBGCRYPT_LIBS)
keybox-errors.c : keybox.h mkerrors
$(srcdir)/mkerrors < $(srcdir)/keybox.h > keybox-errors.c

View file

@ -1,338 +0,0 @@
/* kbxutil.c - The Keybox utility
* Copyright (C) 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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <gcrypt.h>
#include "../jnlib/logging.h"
#include "../jnlib/argparse.h"
#include "../jnlib/stringhelp.h"
#include "../common/i18n.h"
#include "keybox-defs.h"
enum cmd_and_opt_values {
aNull = 0,
oArmor = 'a',
oDryRun = 'n',
oOutput = 'o',
oQuiet = 'q',
oVerbose = 'v',
aNoSuchCmd = 500, /* force other values not to be a letter */
aFindByFpr,
aFindByKid,
aFindByUid,
oDebug,
oDebugAll,
oNoArmor,
aTest
};
static ARGPARSE_OPTS opts[] = {
{ 300, NULL, 0, N_("@Commands:\n ") },
{ aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" },
{ aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" },
{ aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" },
{ 301, NULL, 0, N_("@\nOptions:\n ") },
{ oArmor, "armor", 0, N_("create ascii armored output")},
{ oArmor, "armour", 0, "@" },
{ oOutput, "output", 2, N_("use as output file")},
{ oVerbose, "verbose", 0, N_("verbose") },
{ oQuiet, "quiet", 0, N_("be somewhat more quiet") },
{ oDryRun, "dry-run", 0, N_("do not make any changes") },
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
{0} /* end of list */
};
void myexit (int rc);
int keybox_errors_seen = 0;
static const char *
my_strusage( int level )
{
const char *p;
switch( level ) {
case 11: p = "kbxutil (GnuPG)";
break;
case 13: p = VERSION; break;
case 17: p = PRINTABLE_OS_NAME; break;
case 19: p =
_("Please report bugs to " PACKAGE_BUGREPORT ".\n");
break;
case 1:
case 40: p =
_("Usage: kbxutil [options] [files] (-h for help)");
break;
case 41: p =
_("Syntax: kbxutil [options] [files]\n"
"list, export, import Keybox data\n");
break;
default: p = NULL;
}
return p;
}
static void
i18n_init(void)
{
#ifdef USE_SIMPLE_GETTEXT
set_gettext_file( PACKAGE );
#else
#ifdef ENABLE_NLS
#ifdef HAVE_LC_MESSAGES
setlocale( LC_TIME, "" );
setlocale( LC_MESSAGES, "" );
#else
setlocale( LC_ALL, "" );
#endif
bindtextdomain( PACKAGE, LOCALEDIR );
textdomain( PACKAGE );
#endif
#endif
}
/* static void */
/* wrong_args( const char *text ) */
/* { */
/* log_error("usage: kbxutil %s\n", text); */
/* myexit ( 1 ); */
/* } */
#if 0
static int
hextobyte( const byte *s )
{
int c;
if( *s >= '0' && *s <= '9' )
c = 16 * (*s - '0');
else if( *s >= 'A' && *s <= 'F' )
c = 16 * (10 + *s - 'A');
else if( *s >= 'a' && *s <= 'f' )
c = 16 * (10 + *s - 'a');
else
return -1;
s++;
if( *s >= '0' && *s <= '9' )
c += *s - '0';
else if( *s >= 'A' && *s <= 'F' )
c += 10 + *s - 'A';
else if( *s >= 'a' && *s <= 'f' )
c += 10 + *s - 'a';
else
return -1;
return c;
}
#endif
#if 0
static char *
format_fingerprint ( const char *s )
{
int i, c;
byte fpr[20];
for (i=0; i < 20 && *s; ) {
if ( *s == ' ' || *s == '\t' ) {
s++;
continue;
}
c = hextobyte(s);
if (c == -1) {
return NULL;
}
fpr[i++] = c;
s += 2;
}
return gcry_xstrdup ( fpr );
}
#endif
#if 0
static int
format_keyid ( const char *s, u32 *kid )
{
char helpbuf[9];
switch ( strlen ( s ) ) {
case 8:
kid[0] = 0;
kid[1] = strtoul( s, NULL, 16 );
return 10;
case 16:
mem2str( helpbuf, s, 9 );
kid[0] = strtoul( helpbuf, NULL, 16 );
kid[1] = strtoul( s+8, NULL, 16 );
return 11;
}
return 0; /* error */
}
#endif
int
main( int argc, char **argv )
{
ARGPARSE_ARGS pargs;
enum cmd_and_opt_values cmd = 0;
set_strusage( my_strusage );
/*log_set_name("kbxutil"); fixme */
#if 0
/* check that the libraries are suitable. Do it here because
* the option parse may need services of the library */
if ( !gcry_check_version ( "1.1.4" ) )
{
log_fatal(_("libgcrypt is too old (need %s, have %s)\n"),
"1.1.4", gcry_check_version(NULL) );
}
#endif
/*create_dotlock(NULL); register locking cleanup */
i18n_init();
/* We need to use the gcry malloc function because jnlib does use them */
keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1; /* do not remove the args */
while (arg_parse( &pargs, opts) )
{
switch (pargs.r_opt)
{
case oVerbose:
/*opt.verbose++;*/
/*gcry_control( GCRYCTL_SET_VERBOSITY, (int)opt.verbose );*/
break;
case oDebug:
/*opt.debug |= pargs.r.ret_ulong; */
break;
case oDebugAll:
/*opt.debug = ~0;*/
break;
case aFindByFpr:
case aFindByKid:
case aFindByUid:
cmd = pargs.r_opt;
break;
default:
pargs.err = 2;
break;
}
}
if (log_get_errorcount(0) )
myexit(2);
if (!cmd)
{ /* default is to list a KBX file */
if (!argc)
_keybox_dump_file (NULL, stdout);
else
{
for (; argc; argc--, argv++)
_keybox_dump_file (*argv, stdout);
}
}
#if 0
else if ( cmd == aFindByFpr ) {
char *fpr;
if ( argc != 2 )
wrong_args ("kbxfile foingerprint");
fpr = format_fingerprint ( argv[1] );
if ( !fpr )
log_error ("invalid formatted fingerprint\n");
else {
kbxfile_search_by_fpr ( argv[0], fpr );
gcry_free ( fpr );
}
}
else if ( cmd == aFindByKid ) {
u32 kid[2];
int mode;
if ( argc != 2 )
wrong_args ("kbxfile short-or-long-keyid");
mode = format_keyid ( argv[1], kid );
if ( !mode )
log_error ("invalid formatted keyID\n");
else {
kbxfile_search_by_kid ( argv[0], kid, mode );
}
}
else if ( cmd == aFindByUid ) {
if ( argc != 2 )
wrong_args ("kbxfile userID");
kbxfile_search_by_uid ( argv[0], argv[1] );
}
#endif
else
log_error ("unsupported action\n");
myexit(0);
return 8; /*NEVER REACHED*/
}
void
myexit( int rc )
{
/* if( opt.debug & DBG_MEMSTAT_VALUE ) {*/
/* gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); */
/* gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); */
/* }*/
/* if( opt.debug ) */
/* gcry_control( GCRYCTL_DUMP_SECMEM_STATS ); */
rc = rc? rc : log_get_errorcount(0)? 2 :
keybox_errors_seen? 1 : 0;
exit(rc );
}

File diff suppressed because it is too large Load diff

View file

@ -1,179 +0,0 @@
/* keybox-defs.h - interal Keybox defintions
* 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 KEYBOX_DEFS_H
#define KEYBOX_DEFS_H 1
#include <sys/types.h> /* off_t */
#include "keybox.h"
#ifndef HAVE_BYTE_TYPEDEF
typedef unsigned char byte; /* fixme */
#endif
#ifndef HAVE_U16_TYPEDEF
typedef unsigned short u16; /* fixme */
#endif
#ifndef HAVE_U32_TYPEDEF
typedef unsigned int u32; /* fixme */
#endif
enum {
BLOBTYPE_EMPTY = 0,
BLOBTYPE_HEADER = 1,
BLOBTYPE_PGP = 2,
BLOBTYPE_X509 = 3
};
typedef struct keyboxblob *KEYBOXBLOB;
typedef struct keybox_name *KB_NAME;
typedef struct keybox_name const * CONST_KB_NAME;
struct keybox_name {
struct keybox_name *next;
int secret;
/*DOTLOCK lockhd;*/
int is_locked;
int did_full_scan;
char fname[1];
};
struct keybox_handle {
CONST_KB_NAME kb;
int secret; /* this is for a secret keybox */
FILE *fp;
int eof;
int error;
int ephemeral;
struct {
KEYBOXBLOB blob;
off_t offset;
size_t pk_no;
size_t uid_no;
unsigned int n_packets; /*used for delete and update*/
} found;
struct {
char *name;
char *pattern;
} word_match;
};
/* Don't know whether this is needed: */
/* static struct { */
/* const char *homedir; */
/* int dry_run; */
/* int quiet; */
/* int verbose; */
/* int preserve_permissions; */
/* } keybox_opt; */
/*-- keybox-blob.c --*/
#ifdef KEYBOX_WITH_OPENPGP
/* fixme */
#endif /*KEYBOX_WITH_OPENPGP*/
#ifdef KEYBOX_WITH_X509
int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
unsigned char *sha1_digest, int as_ephemeral);
#endif /*KEYBOX_WITH_X509*/
int _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen,
off_t off);
void _keybox_release_blob (KEYBOXBLOB blob);
const char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n);
off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob);
/*-- keybox-file.c --*/
int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp);
int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp);
/*-- keybox-dump.c --*/
int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp);
int _keybox_dump_file (const char *filename, FILE *outfp);
/*-- keybox-util.c --*/
void *_keybox_malloc (size_t n);
void *_keybox_calloc (size_t n, size_t m);
void *_keybox_realloc (void *p, size_t n);
void _keybox_free (void *p);
#define xtrymalloc(a) _keybox_malloc ((a))
#define xtrycalloc(a,b) _keybox_calloc ((a),(b))
#define xtryrealloc(a,b) _keybox_realloc((a),(b))
#define xfree(a) _keybox_free ((a))
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member)
#ifndef STR
#define STR(v) #v
#endif
#define STR2(v) STR(v)
/*
a couple of handy macros
*/
#define return_if_fail(expr) do { \
if (!(expr)) { \
fprintf (stderr, "%s:%d: assertion `%s' failed\n", \
__FILE__, __LINE__, #expr ); \
return; \
} } while (0)
#define return_null_if_fail(expr) do { \
if (!(expr)) { \
fprintf (stderr, "%s:%d: assertion `%s' failed\n", \
__FILE__, __LINE__, #expr ); \
return NULL; \
} } while (0)
#define return_val_if_fail(expr,val) do { \
if (!(expr)) { \
fprintf (stderr, "%s:%d: assertion `%s' failed\n", \
__FILE__, __LINE__, #expr ); \
return (val); \
} } while (0)
#define never_reached() do { \
fprintf (stderr, "%s:%d: oops; should never get here\n", \
__FILE__, __LINE__ ); \
} while (0)
/* some macros to replace ctype ones and avoid locale problems */
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
#define hexdigitp(a) (digitp (a) \
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
/* the atoi macros assume that the buffer has only valid digits */
#define atoi_1(p) (*(p) - '0' )
#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
#endif /*KEYBOX_DEFS_H*/

View file

@ -1,346 +0,0 @@
/* keybox-dump.c - Debug helpers
* 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
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "keybox-defs.h"
static ulong
get32 (const byte *buffer)
{
ulong a;
a = *buffer << 24;
a |= buffer[1] << 16;
a |= buffer[2] << 8;
a |= buffer[3];
return a;
}
static ulong
get16 (const byte *buffer)
{
ulong a;
a = *buffer << 8;
a |= buffer[1];
return a;
}
void
print_string (FILE *fp, const byte *p, size_t n, int delim)
{
for ( ; n; n--, p++ )
{
if (*p < 0x20 || (*p >= 0x7f && *p < 0xa0) || *p == delim)
{
putc('\\', fp);
if( *p == '\n' )
putc('n', fp);
else if( *p == '\r' )
putc('r', fp);
else if( *p == '\f' )
putc('f', fp);
else if( *p == '\v' )
putc('v', fp);
else if( *p == '\b' )
putc('b', fp);
else if( !*p )
putc('0', fp);
else
fprintf(fp, "x%02x", *p );
}
else
putc(*p, fp);
}
}
static int
dump_header_blob (const byte *buffer, size_t length, FILE *fp)
{
fprintf (fp, "Version: %d\n", buffer[5]);
if ( memcmp (buffer+8, "KBXf", 4))
fprintf (fp, "[Error: invalid magic number]\n");
return 0;
}
/* Dump one block to FP */
int
_keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
{
const byte *buffer;
size_t length;
int type;
ulong n, nkeys, keyinfolen;
ulong nuids, uidinfolen;
ulong nsigs, siginfolen;
ulong rawdata_off, rawdata_len;
ulong nserial;
const byte *p;
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
{
fprintf (fp, "[blob too short]\n");
return -1;
}
n = get32( buffer );
if (n > length)
fprintf (fp, "[blob larger than length - output truncated]\n");
else
length = n; /* ignore the rest */
fprintf (fp, "Length: %lu\n", n );
type = buffer[4];
switch (type)
{
case BLOBTYPE_EMPTY:
fprintf (fp, "Type: Empty\n");
return 0;
case BLOBTYPE_HEADER:
fprintf (fp, "Type: Header\n");
return dump_header_blob (buffer, length, fp);
case BLOBTYPE_PGP:
fprintf (fp, "Type: OpenPGP\n");
break;
case BLOBTYPE_X509:
fprintf (fp, "Type: X.509\n");
break;
default:
fprintf (fp, "Type: %d\n", type);
fprintf (fp, "[can't dump this blob type]\n");
return 0;
}
fprintf (fp, "Version: %d\n", buffer[5]);
n = get16 (buffer + 6);
fprintf( fp, "Blob-Flags: %04lX", n);
if (n)
{
int any = 0;
fputs (" (", fp);
if ((n & 1))
{
fputs ("secret", fp);
any++;
}
if ((n & 2))
{
if (any)
putc (',', fp);
fputs ("ephemeral", fp);
any++;
}
putc (')', fp);
}
putc ('\n', fp);
rawdata_off = get32 (buffer + 8);
rawdata_len = get32 (buffer + 12);
fprintf( fp, "Data-Offset: %lu\n", rawdata_off );
fprintf( fp, "Data-Length: %lu\n", rawdata_len );
nkeys = get16 (buffer + 16);
fprintf (fp, "Key-Count: %lu\n", nkeys );
if (!nkeys)
fprintf (fp, "[Error: no keys]\n");
if (nkeys > 1 && type == BLOBTYPE_X509)
fprintf (fp, "[Error: only one key allowed for X509]\n");
keyinfolen = get16 (buffer + 18 );
fprintf (fp, "Key-Info-Length: %lu\n", keyinfolen);
/* fixme: check bounds */
p = buffer + 20;
for (n=0; n < nkeys; n++, p += keyinfolen)
{
int i;
ulong kidoff, kflags;
fprintf (fp, "Key-Fpr[%lu]: ", n );
for (i=0; i < 20; i++ )
fprintf (fp, "%02X", p[i]);
kidoff = get32 (p + 20);
fprintf (fp, "\nKey-Kid-Off[%lu]: %lu\n", n, kidoff );
fprintf (fp, "Key-Kid[%lu]: ", n );
/* fixme: check bounds */
for (i=0; i < 8; i++ )
fprintf (fp, "%02X", buffer[kidoff+i] );
kflags = get16 (p + 24 );
fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags);
}
/* serial number */
fputs ("Serial-No: ", fp);
nserial = get16 (p);
p += 2;
if (!nserial)
fputs ("none", fp);
else
{
for (; nserial; nserial--, p++)
fprintf (fp, "%02X", *p);
}
putc ('\n', fp);
/* user IDs */
nuids = get16 (p);
fprintf (fp, "Uid-Count: %lu\n", nuids );
uidinfolen = get16 (p + 2);
fprintf (fp, "Uid-Info-Length: %lu\n", uidinfolen);
/* fixme: check bounds */
p += 4;
for (n=0; n < nuids; n++, p += uidinfolen)
{
ulong uidoff, uidlen, uflags;
uidoff = get32( p );
uidlen = get32( p+4 );
if (type == BLOBTYPE_X509 && !n)
{
fprintf (fp, "Issuer-Off: %lu\n", uidoff );
fprintf (fp, "Issuer-Len: %lu\n", uidlen );
fprintf (fp, "Issuer: \"");
}
else if (type == BLOBTYPE_X509 && n == 1)
{
fprintf (fp, "Subject-Off: %lu\n", uidoff );
fprintf (fp, "Subject-Len: %lu\n", uidlen );
fprintf (fp, "Subject: \"");
}
else
{
fprintf (fp, "Uid-Off[%lu]: %lu\n", n, uidoff );
fprintf (fp, "Uid-Len[%lu]: %lu\n", n, uidlen );
fprintf (fp, "Uid[%lu]: \"", n );
}
print_string (fp, buffer+uidoff, uidlen, '\"');
fputs ("\"\n", fp);
uflags = get16 (p + 8);
if (type == BLOBTYPE_X509 && !n)
{
fprintf (fp, "Issuer-Flags: %04lX\n", uflags );
fprintf (fp, "Issuer-Validity: %d\n", p[10] );
}
else if (type == BLOBTYPE_X509 && n == 1)
{
fprintf (fp, "Subject-Flags: %04lX\n", uflags );
fprintf (fp, "Subject-Validity: %d\n", p[10] );
}
else
{
fprintf (fp, "Uid-Flags[%lu]: %04lX\n", n, uflags );
fprintf (fp, "Uid-Validity[%lu]: %d\n", n, p[10] );
}
}
nsigs = get16 (p);
fprintf (fp, "Sig-Count: %lu\n", nsigs );
siginfolen = get16 (p + 2);
fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen );
/* fixme: check bounds */
p += 4;
for (n=0; n < nsigs; n++, p += siginfolen)
{
ulong sflags;
sflags = get32 (p);
fprintf (fp, "Sig-Expire[%lu]: ", n );
if (!sflags)
fputs ("[not checked]", fp);
else if (sflags == 1 )
fputs ("[missing key]", fp);
else if (sflags == 2 )
fputs ("[bad signature]", fp);
else if (sflags < 0x10000000)
fprintf (fp, "[bad flag %0lx]", sflags);
else if (sflags == 0xffffffff)
fputs ("0", fp );
else
fputs ("a time"/*strtimestamp( sflags )*/, fp );
putc ('\n', fp );
}
fprintf (fp, "Ownertrust: %d\n", p[0] );
fprintf (fp, "All-Validity: %d\n", p[1] );
p += 4;
n = get32 (p); p += 4;
fprintf (fp, "Recheck-After: %s\n", /*n? strtimestamp(n) :*/ "0" );
n = get32 (p ); p += 4;
fprintf( fp, "Latest-Timestamp: %s\n", "0"/*strtimestamp(n)*/ );
n = get32 (p ); p += 4;
fprintf (fp, "Created-At: %s\n", "0"/*strtimestamp(n)*/ );
n = get32 (p ); p += 4;
fprintf (fp, "Reserved-Space: %lu\n", n );
/* check that the keyblock is at the correct offset and other bounds */
/*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/
return 0;
}
int
_keybox_dump_file (const char *filename, FILE *outfp)
{
FILE *fp;
KEYBOXBLOB blob;
int rc;
unsigned long count = 0;
if (!filename)
{
filename = "-";
fp = stdin;
}
else
fp = fopen (filename, "rb");
if (!fp)
{
fprintf (outfp, "can't open `%s': %s\n", filename, strerror(errno));
return KEYBOX_File_Error;
}
while ( !(rc = _keybox_read_blob (&blob, fp)) )
{
fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
_keybox_dump_blob (blob, outfp);
_keybox_release_blob (blob);
fprintf (outfp, "END-RECORD\n");
count++;
}
if (rc == -1)
rc = 0;
if (rc)
fprintf (outfp, "error reading `%s': %s\n", filename,
rc == KEYBOX_Read_Error? keybox_strerror(rc):strerror (errno));
if (fp != stdin)
fclose (fp);
return rc;
}

View file

@ -1,102 +0,0 @@
/* keybox-file.c - file oeprations
* 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
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "keybox-defs.h"
/* Read a block at the current postion and return it in r_blob.
r_blob may be NULL to simply skip the current block */
int
_keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp)
{
char *image;
size_t imagelen = 0;
int c1, c2, c3, c4, type;
int rc;
off_t off;
again:
*r_blob = NULL;
off = ftello (fp);
if (off == (off_t)-1)
return KEYBOX_Read_Error;
if ((c1 = getc (fp)) == EOF
|| (c2 = getc (fp)) == EOF
|| (c3 = getc (fp)) == EOF
|| (c4 = getc (fp)) == EOF
|| (type = getc (fp)) == EOF)
{
if ( c1 == EOF && !ferror (fp) )
return -1; /* eof */
return KEYBOX_Read_Error;
}
imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4;
if (imagelen > 500000) /* sanity check */
return KEYBOX_Blob_Too_Large;
if (imagelen < 5)
return KEYBOX_Blob_Too_Short;
if (!type)
{
/* special treatment for empty blobs. */
if (fseek (fp, imagelen-5, SEEK_CUR))
return KEYBOX_Read_Error;
goto again;
}
image = xtrymalloc (imagelen);
if (!image)
return KEYBOX_Out_Of_Core;
image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4; image[4] = type;
if (fread (image+5, imagelen-5, 1, fp) != 1)
{
xfree (image);
return KEYBOX_Read_Error;
}
rc = r_blob? _keybox_new_blob (r_blob, image, imagelen, off) : 0;
if (rc || !r_blob)
xfree (image);
return rc;
}
/* Write the block to the current file position */
int
_keybox_write_blob (KEYBOXBLOB blob, FILE *fp)
{
const char *image;
size_t length;
image = _keybox_get_blob_image (blob, &length);
if (fwrite (image, length, 1, fp) != 1)
{
return KEYBOX_Write_Error;
}
return 0;
}

View file

@ -1,127 +0,0 @@
/* keybox-init.c - Initalization of the library
* Copyright (C) 2001 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include "keybox-defs.h"
#define compare_filenames strcmp
static KB_NAME kb_names;
/*
Register a filename for plain keybox files. Returns a pointer to be
used to create a handles etc or NULL to indicate that it has already
been registered */
void *
keybox_register_file (const char *fname, int secret)
{
KB_NAME kr;
for (kr=kb_names; kr; kr = kr->next)
{
if ( !compare_filenames (kr->fname, fname) )
return NULL; /* already registered */
}
kr = xtrymalloc (sizeof *kr + strlen (fname));
if (!kr)
return NULL;
strcpy (kr->fname, fname);
kr->secret = !!secret;
/* kr->lockhd = NULL;*/
kr->is_locked = 0;
kr->did_full_scan = 0;
/* keep a list of all issued pointers */
kr->next = kb_names;
kb_names = kr;
/* create the offset table the first time a function here is used */
/* if (!kb_offtbl) */
/* kb_offtbl = new_offset_hash_table (); */
return kr;
}
int
keybox_is_writable (void *token)
{
KB_NAME r = token;
return r? !access (r->fname, W_OK) : 0;
}
/* Create a new handle for the resource associated with TOKEN. SECRET
is just a cross-check.
The returned handle must be released using keybox_release (). */
KEYBOX_HANDLE
keybox_new (void *token, int secret)
{
KEYBOX_HANDLE hd;
KB_NAME resource = token;
assert (resource && !resource->secret == !secret);
hd = xtrycalloc (1, sizeof *hd);
if (hd)
{
hd->kb = resource;
hd->secret = !!secret;
}
return hd;
}
void
keybox_release (KEYBOX_HANDLE hd)
{
if (!hd)
return;
_keybox_release_blob (hd->found.blob);
xfree (hd->word_match.name);
xfree (hd->word_match.pattern);
xfree (hd);
}
const char *
keybox_get_resource_name (KEYBOX_HANDLE hd)
{
if (!hd || !hd->kb)
return NULL;
return hd->kb->fname;
}
int
keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes)
{
if (!hd)
return KEYBOX_Invalid_Handle;
hd->ephemeral = yes;
return 0;
}

View file

@ -1,810 +0,0 @@
/* keybox-search.c - Search operations
* Copyright (C) 2001, 2002 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "../jnlib/stringhelp.h" /* ascii_xxxx() */
#include "keybox-defs.h"
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
struct sn_array_s {
int snlen;
unsigned char *sn;
};
static ulong
get32 (const byte *buffer)
{
ulong a;
a = *buffer << 24;
a |= buffer[1] << 16;
a |= buffer[2] << 8;
a |= buffer[3];
return a;
}
static ulong
get16 (const byte *buffer)
{
ulong a;
a = *buffer << 8;
a |= buffer[1];
return a;
}
static int
blob_get_type (KEYBOXBLOB blob)
{
const unsigned char *buffer;
size_t length;
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
return -1; /* blob too short */
return buffer[4];
}
static unsigned int
blob_get_blob_flags (KEYBOXBLOB blob)
{
const unsigned char *buffer;
size_t length;
buffer = _keybox_get_blob_image (blob, &length);
if (length < 8)
return 0; /* oops */
return get16 (buffer + 6);
}
static int
blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
{
const unsigned char *buffer;
size_t length;
size_t pos, off;
size_t nkeys, keyinfolen;
size_t nserial;
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
return 0; /* blob too short */
/*keys*/
nkeys = get16 (buffer + 16);
keyinfolen = get16 (buffer + 18 );
if (keyinfolen < 28)
return 0; /* invalid blob */
pos = 20 + keyinfolen*nkeys;
if (pos+2 > length)
return 0; /* out of bounds */
/*serial*/
nserial = get16 (buffer+pos);
off = pos + 2;
if (off+nserial > length)
return 0; /* out of bounds */
return nserial == snlen && !memcmp (buffer+off, sn, snlen);
}
static int
blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
{
const unsigned char *buffer;
size_t length;
size_t pos, off;
size_t nkeys, keyinfolen;
int idx;
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
return 0; /* blob too short */
/*keys*/
nkeys = get16 (buffer + 16);
keyinfolen = get16 (buffer + 18 );
if (keyinfolen < 28)
return 0; /* invalid blob */
pos = 20;
if (pos + keyinfolen*nkeys > length)
return 0; /* out of bounds */
for (idx=0; idx < nkeys; idx++)
{
off = pos + idx*keyinfolen;
if (!memcmp (buffer + off, fpr, 20))
return 1; /* found */
}
return 0; /* not found */
}
static int
blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
int fproff, int fprlen)
{
const unsigned char *buffer;
size_t length;
size_t pos, off;
size_t nkeys, keyinfolen;
int idx;
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
return 0; /* blob too short */
/*keys*/
nkeys = get16 (buffer + 16);
keyinfolen = get16 (buffer + 18 );
if (keyinfolen < 28)
return 0; /* invalid blob */
pos = 20;
if (pos + keyinfolen*nkeys > length)
return 0; /* out of bounds */
for (idx=0; idx < nkeys; idx++)
{
off = pos + idx*keyinfolen;
if (!memcmp (buffer + off + fproff, fpr, fprlen))
return 1; /* found */
}
return 0; /* not found */
}
static int
blob_cmp_name (KEYBOXBLOB blob, int idx,
const char *name, size_t namelen, int substr)
{
const unsigned char *buffer;
size_t length;
size_t pos, off, len;
size_t nkeys, keyinfolen;
size_t nuids, uidinfolen;
size_t nserial;
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
return 0; /* blob too short */
/*keys*/
nkeys = get16 (buffer + 16);
keyinfolen = get16 (buffer + 18 );
if (keyinfolen < 28)
return 0; /* invalid blob */
pos = 20 + keyinfolen*nkeys;
if (pos+2 > length)
return 0; /* out of bounds */
/*serial*/
nserial = get16 (buffer+pos);
pos += 2 + nserial;
if (pos+4 > length)
return 0; /* out of bounds */
/* user ids*/
nuids = get16 (buffer + pos); pos += 2;
uidinfolen = get16 (buffer + pos); pos += 2;
if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */)
return 0; /* invalid blob */
if (pos + uidinfolen*nuids > length)
return 0; /* out of bounds */
if (idx < 0)
{ /* compare all names starting with that (negated) index */
idx = -idx;
for ( ;idx < nuids; idx++)
{
size_t mypos = pos;
mypos += idx*uidinfolen;
off = get32 (buffer+mypos);
len = get32 (buffer+mypos+4);
if (off+len > length)
return 0; /* error: better stop here out of bounds */
if (len < 2)
continue; /* empty name or 0 not stored */
len--;
if (substr)
{
if (ascii_memcasemem (buffer+off, len, name, namelen))
return 1; /* found */
}
else
{
if (len == namelen && !memcmp (buffer+off, name, len))
return 1; /* found */
}
}
return 0; /* not found */
}
else
{
if (idx > nuids)
return 0; /* no user ID with that idx */
pos += idx*uidinfolen;
off = get32 (buffer+pos);
len = get32 (buffer+pos+4);
if (off+len > length)
return 0; /* out of bounds */
if (len < 1)
return 0; /* empty name */
if (substr)
{
return !!ascii_memcasemem (buffer+off, len, name, namelen);
}
else
{
return len == namelen && !memcmp (buffer+off, name, len);
}
}
}
/* compare all email addresses of the subject. With SUBSTR given as
True a substring search is done in the mail address */
static int
blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr)
{
const unsigned char *buffer;
size_t length;
size_t pos, off, len;
size_t nkeys, keyinfolen;
size_t nuids, uidinfolen;
size_t nserial;
int idx;
/* fixme: this code is common to blob_cmp_mail */
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
return 0; /* blob too short */
/*keys*/
nkeys = get16 (buffer + 16);
keyinfolen = get16 (buffer + 18 );
if (keyinfolen < 28)
return 0; /* invalid blob */
pos = 20 + keyinfolen*nkeys;
if (pos+2 > length)
return 0; /* out of bounds */
/*serial*/
nserial = get16 (buffer+pos);
pos += 2 + nserial;
if (pos+4 > length)
return 0; /* out of bounds */
/* user ids*/
nuids = get16 (buffer + pos); pos += 2;
uidinfolen = get16 (buffer + pos); pos += 2;
if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */)
return 0; /* invalid blob */
if (pos + uidinfolen*nuids > length)
return 0; /* out of bounds */
if (namelen < 1)
return 0;
for (idx=1 ;idx < nuids; idx++)
{
size_t mypos = pos;
mypos += idx*uidinfolen;
off = get32 (buffer+mypos);
len = get32 (buffer+mypos+4);
if (off+len > length)
return 0; /* error: better stop here out of bounds */
if (len < 2 || buffer[off] != '<')
continue; /* empty name or trailing 0 not stored */
len--; /* one back */
if ( len < 3 || buffer[off+len] != '>')
continue; /* not a proper email address */
len--;
if (substr)
{
if (ascii_memcasemem (buffer+off+1, len, name, namelen))
return 1; /* found */
}
else
{
if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len))
return 1; /* found */
}
}
return 0; /* not found */
}
/*
The has_foo functions are used as helpers for search
*/
static int
has_short_kid (KEYBOXBLOB blob, const unsigned char *kid)
{
return blob_cmp_fpr_part (blob, kid+4, 16, 4);
}
static int
has_long_kid (KEYBOXBLOB blob, const unsigned char *kid)
{
return blob_cmp_fpr_part (blob, kid, 12, 8);
}
static int
has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr)
{
return blob_cmp_fpr (blob, fpr);
}
static int
has_issuer (KEYBOXBLOB blob, const char *name)
{
size_t namelen;
return_val_if_fail (name, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
namelen = strlen (name);
return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0);
}
static int
has_issuer_sn (KEYBOXBLOB blob, const char *name,
const unsigned char *sn, int snlen)
{
size_t namelen;
return_val_if_fail (name, 0);
return_val_if_fail (sn, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
namelen = strlen (name);
return (blob_cmp_sn (blob, sn, snlen)
&& blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0));
}
static int
has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
{
return_val_if_fail (sn, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
return blob_cmp_sn (blob, sn, snlen);
}
static int
has_subject (KEYBOXBLOB blob, const char *name)
{
size_t namelen;
return_val_if_fail (name, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
namelen = strlen (name);
return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0);
}
static int
has_subject_or_alt (KEYBOXBLOB blob, const char *name, int substr)
{
size_t namelen;
return_val_if_fail (name, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
namelen = strlen (name);
return blob_cmp_name (blob, -1 /* all subject names*/, name,
namelen, substr);
}
static int
has_mail (KEYBOXBLOB blob, const char *name, int substr)
{
size_t namelen;
return_val_if_fail (name, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
namelen = strlen (name);
if (namelen && name[namelen-1] == '>')
namelen--;
return blob_cmp_mail (blob, name, namelen, substr);
}
static void
release_sn_array (struct sn_array_s *array, size_t size)
{
size_t n;
for (n=0; n < size; n++)
xfree (array[n].sn);
xfree (array);
}
/*
The search API
*/
int
keybox_search_reset (KEYBOX_HANDLE hd)
{
if (!hd)
return KEYBOX_Invalid_Value;
if (hd->found.blob)
{
_keybox_release_blob (hd->found.blob);
hd->found.blob = NULL;
}
if (hd->fp)
{
fclose (hd->fp);
hd->fp = NULL;
}
hd->error = 0;
hd->eof = 0;
return 0;
}
/* Note: When in ephemeral mode the search function does visit all
blobs but in standard mode, blobs flagged as ephemeral are ignored. */
int
keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
{
int rc;
size_t n;
int need_words, any_skip;
KEYBOXBLOB blob = NULL;
struct sn_array_s *sn_array = NULL;
if (!hd)
return KEYBOX_Invalid_Value;
/* clear last found result */
if (hd->found.blob)
{
_keybox_release_blob (hd->found.blob);
hd->found.blob = NULL;
}
if (hd->error)
return hd->error; /* still in error state */
if (hd->eof)
return -1; /* still EOF */
/* figure out what information we need */
need_words = any_skip = 0;
for (n=0; n < ndesc; n++)
{
switch (desc[n].mode)
{
case KEYDB_SEARCH_MODE_WORDS:
need_words = 1;
break;
case KEYDB_SEARCH_MODE_FIRST:
/* always restart the search in this mode */
keybox_search_reset (hd);
break;
default:
break;
}
if (desc[n].skipfnc)
any_skip = 1;
if (desc[n].snlen == -1 && !sn_array)
{
sn_array = xtrycalloc (ndesc, sizeof *sn_array);
if (!sn_array)
return (hd->error = KEYBOX_Out_Of_Core);
}
}
if (!hd->fp)
{
hd->fp = fopen (hd->kb->fname, "rb");
if (!hd->fp)
{
xfree (sn_array);
return (hd->error = KEYBOX_File_Open_Error);
}
}
/* kludge: we need to convert an SN given as hexstring to it's
binary representation - in some cases we are not able to store it
in the search descriptor, because due to its usgae it is not
possible to free allocated memory */
if (sn_array)
{
const unsigned char *s;
int i, odd;
size_t snlen;
for (n=0; n < ndesc; n++)
{
if (!desc[n].sn)
;
else if (desc[n].snlen == -1)
{
unsigned char *sn;
s = desc[n].sn;
for (i=0; *s && *s != '/'; s++, i++)
;
odd = (i & 1);
snlen = (i+1)/2;
sn_array[n].sn = xtrymalloc (snlen);
if (!sn_array[n].sn)
{
release_sn_array (sn_array, n);
return (hd->error = KEYBOX_Out_Of_Core);
}
sn_array[n].snlen = snlen;
sn = sn_array[n].sn;
s = desc[n].sn;
if (odd)
{
*sn++ = xtoi_1 (s);
s++;
}
for (; *s && *s != '/'; s += 2)
*sn++ = xtoi_2 (s);
}
else
{
const unsigned char *sn;
sn = desc[n].sn;
snlen = desc[n].snlen;
sn_array[n].sn = xtrymalloc (snlen);
if (!sn_array[n].sn)
{
release_sn_array (sn_array, n);
return (hd->error = KEYBOX_Out_Of_Core);
}
sn_array[n].snlen = snlen;
memcpy (sn_array[n].sn, sn, snlen);
}
}
}
for (;;)
{
unsigned int blobflags;
_keybox_release_blob (blob); blob = NULL;
rc = _keybox_read_blob (&blob, hd->fp);
if (rc)
break;
blobflags = blob_get_blob_flags (blob);
if (!hd->ephemeral && (blobflags & 2))
continue; /* not in ephemeral mode but blob is flagged ephemeral */
for (n=0; n < ndesc; n++)
{
switch (desc[n].mode)
{
case KEYDB_SEARCH_MODE_NONE:
never_reached ();
break;
case KEYDB_SEARCH_MODE_EXACT:
if (has_subject_or_alt (blob, desc[n].u.name, 0))
goto found;
break;
case KEYDB_SEARCH_MODE_MAIL:
if (has_mail (blob, desc[n].u.name, 0))
goto found;
break;
case KEYDB_SEARCH_MODE_MAILSUB:
if (has_mail (blob, desc[n].u.name, 1))
goto found;
break;
case KEYDB_SEARCH_MODE_SUBSTR:
if (has_subject_or_alt (blob, desc[n].u.name, 1))
goto found;
break;
case KEYDB_SEARCH_MODE_MAILEND:
case KEYDB_SEARCH_MODE_WORDS:
never_reached (); /* not yet implemented */
break;
case KEYDB_SEARCH_MODE_ISSUER:
if (has_issuer (blob, desc[n].u.name))
goto found;
break;
case KEYDB_SEARCH_MODE_ISSUER_SN:
if (has_issuer_sn (blob, desc[n].u.name,
sn_array? sn_array[n].sn : desc[n].sn,
sn_array? sn_array[n].snlen : desc[n].snlen))
goto found;
break;
case KEYDB_SEARCH_MODE_SN:
if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn,
sn_array? sn_array[n].snlen : desc[n].snlen))
goto found;
break;
case KEYDB_SEARCH_MODE_SUBJECT:
if (has_subject (blob, desc[n].u.name))
goto found;
break;
case KEYDB_SEARCH_MODE_SHORT_KID:
if (has_short_kid (blob, desc[n].u.kid))
goto found;
break;
case KEYDB_SEARCH_MODE_LONG_KID:
if (has_long_kid (blob, desc[n].u.kid))
goto found;
break;
case KEYDB_SEARCH_MODE_FPR:
case KEYDB_SEARCH_MODE_FPR20:
if (has_fingerprint (blob, desc[n].u.fpr))
goto found;
break;
case KEYDB_SEARCH_MODE_FIRST:
goto found;
break;
case KEYDB_SEARCH_MODE_NEXT:
goto found;
break;
default:
rc = KEYBOX_Invalid_Value;
goto found;
}
}
continue;
found:
for (n=any_skip?0:ndesc; n < ndesc; n++)
{
/* if (desc[n].skipfnc */
/* && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */
/* break; */
}
if (n == ndesc)
break; /* got it */
}
if (!rc)
{
hd->found.blob = blob;
}
else if (rc == -1)
{
_keybox_release_blob (blob);
hd->eof = 1;
}
else
{
_keybox_release_blob (blob);
hd->error = rc;
}
if (sn_array)
release_sn_array (sn_array, ndesc);
return rc;
}
/*
Functions to return a certificate or a keyblock. To be used after
a successful search operation.
*/
#ifdef KEYBOX_WITH_X509
/*
Return the last found cert. Caller must free it.
*/
int
keybox_get_cert (KEYBOX_HANDLE hd, KsbaCert *r_cert)
{
const unsigned char *buffer;
size_t length;
size_t cert_off, cert_len;
KsbaReader reader = NULL;
KsbaCert cert = NULL;
int rc;
if (!hd)
return KEYBOX_Invalid_Value;
if (!hd->found.blob)
return KEYBOX_Nothing_Found;
if (blob_get_type (hd->found.blob) != BLOBTYPE_X509)
return KEYBOX_Wrong_Blob_Type;
buffer = _keybox_get_blob_image (hd->found.blob, &length);
if (length < 40)
return KEYBOX_Blob_Too_Short;
cert_off = get32 (buffer+8);
cert_len = get32 (buffer+12);
if (cert_off+cert_len > length)
return KEYBOX_Blob_Too_Short;
reader = ksba_reader_new ();
if (!reader)
return KEYBOX_Out_Of_Core;
rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
if (rc)
{
ksba_reader_release (reader);
/* fixme: need to map the error codes */
return KEYBOX_General_Error;
}
cert = ksba_cert_new ();
if (!cert)
{
ksba_reader_release (reader);
return KEYBOX_Out_Of_Core;
}
rc = ksba_cert_read_der (cert, reader);
if (rc)
{
ksba_cert_release (cert);
ksba_reader_release (reader);
/* fixme: need to map the error codes */
return KEYBOX_General_Error;
}
*r_cert = cert;
ksba_reader_release (reader);
return 0;
}
#endif /*KEYBOX_WITH_X509*/

View file

@ -1,433 +0,0 @@
/* keybox-update.c - keybox update operations
* 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
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "keybox-defs.h"
#define EXTSEP_S "."
static int
create_tmp_file (const char *template,
char **r_bakfname, char **r_tmpfname, FILE **r_fp)
{
char *bakfname, *tmpfname;
*r_bakfname = NULL;
*r_tmpfname = NULL;
# ifdef USE_ONLY_8DOT3
/* Here is another Windoze bug?:
* you cant rename("pubring.kbx.tmp", "pubring.kbx");
* but rename("pubring.kbx.tmp", "pubring.aaa");
* works. So we replace .kbx by .bak or .tmp
*/
if (strlen (template) > 4
&& !strcmp (template+strlen(template)-4, EXTSEP_S "kbx") )
{
bakfname = xtrymalloc (strlen (template) + 1);
if (!bakfname)
return KEYBOX_Out_Of_Core;
strcpy (bakfname, template);
strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak");
tmpfname = xtrymalloc (strlen (template) + 1);
if (!tmpfname)
{
xfree (bakfname);
return KEYBOX_Out_Of_Core;
}
strcpy (tmpfname,template);
strcpy (tmpfname + strlen (template)-4, EXTSEP_S "tmp");
}
else
{ /* file does not end with kbx; hmmm */
bakfname = xtrymalloc ( strlen (template) + 5);
if (!bakfname)
return KEYBOX_Out_Of_Core;
strcpy (stpcpy (bakfname, template), EXTSEP_S "bak");
tmpfname = xtrymalloc ( strlen (template) + 5);
if (!tmpfname)
{
xfree (bakfname);
return KEYBOX_Out_Of_Core;
}
strcpy (stpcpy (tmpfname, template), EXTSEP_S "tmp");
}
# else /* Posix file names */
bakfname = xtrymalloc (strlen (template) + 2);
if (!bakfname)
return KEYBOX_Out_Of_Core;
strcpy (stpcpy (bakfname,template),"~");
tmpfname = xtrymalloc ( strlen (template) + 5);
if (!tmpfname)
{
xfree (bakfname);
return KEYBOX_Out_Of_Core;
}
strcpy (stpcpy (tmpfname,template), EXTSEP_S "tmp");
# endif /* Posix filename */
*r_fp = fopen (tmpfname, "wb");
if (!*r_fp)
{
xfree (tmpfname);
xfree (bakfname);
return KEYBOX_File_Create_Error;
}
*r_bakfname = bakfname;
*r_tmpfname = tmpfname;
return 0;
}
static int
rename_tmp_file (const char *bakfname, const char *tmpfname,
const char *fname, int secret )
{
int rc=0;
/* restrict the permissions for secret keyboxs */
#ifndef HAVE_DOSISH_SYSTEM
/* if (secret && !opt.preserve_permissions) */
/* { */
/* if (chmod (tmpfname, S_IRUSR | S_IWUSR) ) */
/* { */
/* log_debug ("chmod of `%s' failed: %s\n", */
/* tmpfname, strerror(errno) ); */
/* return KEYBOX_Write_File; */
/* } */
/* } */
#endif
/* fixme: invalidate close caches (not used with stdio)*/
/* iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); */
/* iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); */
/* iobuf_ioctl (NULL, 2, 0, (char*)fname ); */
/* first make a backup file except for secret keyboxs */
if (!secret)
{
#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
remove (bakfname);
#endif
if (rename (fname, bakfname) )
{
return KEYBOX_File_Error;
}
}
/* then rename the file */
#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
remove (fname);
#endif
if (rename (tmpfname, fname) )
{
rc = KEYBOX_File_Error;
if (secret)
{
/* log_info ("WARNING: 2 files with confidential" */
/* " information exists.\n"); */
/* log_info ("%s is the unchanged one\n", fname ); */
/* log_info ("%s is the new one\n", tmpfname ); */
/* log_info ("Please fix this possible security flaw\n"); */
}
return rc;
}
return 0;
}
/* Perform insert/delete/update operation.
mode 1 = insert
2 = delete
3 = update
*/
static int
blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
int secret, off_t start_offset, unsigned int n_packets )
{
FILE *fp, *newfp;
int rc=0;
char *bakfname = NULL;
char *tmpfname = NULL;
char buffer[4096];
int nread, nbytes;
/* Open the source file. Because we do a rename, we have to check the
permissions of the file */
if (access (fname, W_OK))
return KEYBOX_Write_Error;
fp = fopen (fname, "rb");
if (mode == 1 && !fp && errno == ENOENT)
{ /* insert mode but file does not exist: create a new keybox file */
newfp = fopen (fname, "wb");
if (!newfp )
{
return KEYBOX_File_Create_Error;
}
rc = _keybox_write_blob (blob, newfp);
if (rc)
{
return rc;
}
if ( fclose (newfp) )
{
return KEYBOX_File_Create_Error;
}
/* if (chmod( fname, S_IRUSR | S_IWUSR )) */
/* { */
/* log_debug ("%s: chmod failed: %s\n", fname, strerror(errno) ); */
/* return KEYBOX_File_Error; */
/* } */
return 0; /* ready */
}
if (!fp)
{
rc = KEYBOX_File_Open_Error;
goto leave;
}
/* create the new file */
rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
if (rc)
{
fclose(fp);
goto leave;
}
/* prepare for insert */
if (mode == 1)
{
/* copy everything to the new file */
while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 )
{
if (fwrite (buffer, nread, 1, newfp) != 1)
{
rc = KEYBOX_Write_Error;
goto leave;
}
}
if (ferror (fp))
{
rc = KEYBOX_Read_Error;
goto leave;
}
}
/* prepare for delete or update */
if ( mode == 2 || mode == 3 )
{
off_t current = 0;
/* copy first part to the new file */
while ( current < start_offset )
{
nbytes = DIM(buffer);
if (current + nbytes > start_offset)
nbytes = start_offset - current;
nread = fread (buffer, 1, nbytes, fp);
if (!fread)
break;
current += nread;
if (fwrite (buffer, nread, 1, newfp) != 1)
{
rc = KEYBOX_Write_Error;
goto leave;
}
}
if (ferror (fp))
{
rc = KEYBOX_Read_Error;
goto leave;
}
/* skip this blob */
rc = _keybox_read_blob (NULL, fp);
if (rc)
return rc;
}
/* Do an insert or update */
if ( mode == 1 || mode == 3 )
{
rc = _keybox_write_blob (blob, newfp);
if (rc)
return rc;
}
/* copy the rest of the packet for an delete or update */
if (mode == 2 || mode == 3)
{
while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 )
{
if (fwrite (buffer, nread, 1, newfp) != 1)
{
rc = KEYBOX_Write_Error;
goto leave;
}
}
if (ferror (fp))
{
rc = KEYBOX_Read_Error;
goto leave;
}
}
/* close both files */
if (fclose(fp))
{
rc = KEYBOX_File_Close_Error;
fclose (newfp);
goto leave;
}
if (fclose(newfp))
{
rc = KEYBOX_File_Close_Error;
goto leave;
}
rc = rename_tmp_file (bakfname, tmpfname, fname, secret);
leave:
xfree(bakfname);
xfree(tmpfname);
return rc;
}
#ifdef KEYBOX_WITH_X509
int
keybox_insert_cert (KEYBOX_HANDLE hd, KsbaCert cert,
unsigned char *sha1_digest)
{
int rc;
const char *fname;
KEYBOXBLOB blob;
if (!hd)
return KEYBOX_Invalid_Handle;
if (!hd->kb)
return KEYBOX_Invalid_Handle;
fname = hd->kb->fname;
if (!fname)
return KEYBOX_Invalid_Handle;
/* close this one otherwise we will mess up the position for a next
search. Fixme: it would be better to adjust the position after
the write opertions. */
if (hd->fp)
{
fclose (hd->fp);
hd->fp = NULL;
}
rc = _keybox_create_x509_blob (&blob, cert, sha1_digest, hd->ephemeral);
if (!rc)
{
rc = blob_filecopy (1, fname, blob, hd->secret, 0, 0 );
_keybox_release_blob (blob);
/* if (!rc && !hd->secret && kb_offtbl) */
/* { */
/* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */
/* } */
}
return rc;
}
int
keybox_update_cert (KEYBOX_HANDLE hd, KsbaCert cert,
unsigned char *sha1_digest)
{
return -1;
}
#endif /*KEYBOX_WITH_X509*/
int
keybox_delete (KEYBOX_HANDLE hd)
{
off_t off;
const char *fname;
FILE *fp;
int rc;
if (!hd)
return KEYBOX_Invalid_Value;
if (!hd->found.blob)
return KEYBOX_Nothing_Found;
if (!hd->kb)
return KEYBOX_Invalid_Handle;
fname = hd->kb->fname;
if (!fname)
return KEYBOX_Invalid_Handle;
off = _keybox_get_blob_fileoffset (hd->found.blob);
if (off == (off_t)-1)
return KEYBOX_General_Error;
off += 4;
if (hd->fp)
{
fclose (hd->fp);
hd->fp = NULL;
}
fp = fopen (hd->kb->fname, "r+b");
if (!fp)
return KEYBOX_File_Open_Error;
if (fseeko (fp, off, SEEK_SET))
rc = KEYBOX_Write_Error;
else if (putc (0, fp) == EOF)
rc = KEYBOX_Write_Error;
else
rc = 0;
if (fclose (fp))
{
if (!rc)
rc = KEYBOX_File_Close_Error;
}
return rc;
}

View file

@ -1,125 +0,0 @@
/* keybox.h - Keybox operations
* 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 KEYBOX_H
#define KEYBOX_H 1
#ifdef __cplusplus
extern "C" {
#if 0
}
#endif
#endif
#include "keybox-search-desc.h"
#define KEYBOX_WITH_OPENPGP 1
#define KEYBOX_WITH_X509 1
#ifdef KEYBOX_WITH_OPENPGP
# undef KEYBOX_WITH_OPENPGP
/*#include <lib-to-handle-gpg-data-structs.h>*/
#endif
#ifdef KEYBOX_WITH_X509
# include <ksba.h>
#endif
typedef enum {
KEYBOX_No_Error = 0,
KEYBOX_General_Error = 1,
KEYBOX_Out_Of_Core = 2,
KEYBOX_Invalid_Value = 3,
KEYBOX_Timeout = 4,
KEYBOX_Read_Error = 5,
KEYBOX_Write_Error = 6,
KEYBOX_File_Error = 7,
KEYBOX_Blob_Too_Short = 8,
KEYBOX_Blob_Too_Large = 9,
KEYBOX_Invalid_Handle = 10,
KEYBOX_File_Create_Error = 11,
KEYBOX_File_Open_Error = 12,
KEYBOX_File_Close_Error = 13,
KEYBOX_Nothing_Found = 14,
KEYBOX_Wrong_Blob_Type = 15,
KEYBOX_Missing_Value = 16,
} KeyboxError;
typedef struct keybox_handle *KEYBOX_HANDLE;
/*-- keybox-init.c --*/
void *keybox_register_file (const char *fname, int secret);
int keybox_is_writable (void *token);
KEYBOX_HANDLE keybox_new (void *token, int secret);
void keybox_release (KEYBOX_HANDLE hd);
const char *keybox_get_resource_name (KEYBOX_HANDLE hd);
int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
/*-- keybox-search.c --*/
#ifdef KEYBOX_WITH_X509
int keybox_get_cert (KEYBOX_HANDLE hd, KsbaCert *ret_cert);
#endif /*KEYBOX_WITH_X509*/
int keybox_search_reset (KEYBOX_HANDLE hd);
int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc);
/*-- keybox-update.c --*/
#ifdef KEYBOX_WITH_X509
int keybox_insert_cert (KEYBOX_HANDLE hd, KsbaCert cert,
unsigned char *sha1_digest);
int keybox_update_cert (KEYBOX_HANDLE hd, KsbaCert cert,
unsigned char *sha1_digest);
#endif /*KEYBOX_WITH_X509*/
int keybox_delete (KEYBOX_HANDLE hd);
/*-- --*/
#if 0
int keybox_lock (KEYBOX_HANDLE hd, int yes);
int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb);
int keybox_locate_writable (KEYBOX_HANDLE hd);
int keybox_search_reset (KEYBOX_HANDLE hd);
int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc);
int keybox_rebuild_cache (void *);
#endif
/*-- keybox-util.c --*/
void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
void *(*new_realloc_func)(void *p, size_t n),
void (*new_free_func)(void*) );
/*-- keybox-errors.c (built) --*/
const char *keybox_strerror (KeyboxError err);
#ifdef __cplusplus
}
#endif
#endif /*KEYBOX_H*/