mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Started with keybox implementation by basing it on code from the GnuPG
devel branch.
This commit is contained in:
parent
7c708298d2
commit
fcfec25620
337
kbx/kbxutil.c
Normal file
337
kbx/kbxutil.c
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/* 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 "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, GNUPG_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 becuase jnlib does use them */
|
||||||
|
keybox_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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
755
kbx/keybox-blob.c
Normal file
755
kbx/keybox-blob.c
Normal file
@ -0,0 +1,755 @@
|
|||||||
|
/* keybox-blob.c - KBX Blob handling
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* The keybox data formats
|
||||||
|
|
||||||
|
The KeyBox uses an augmented OpenPGP/X.509 key format. This makes
|
||||||
|
random access to a keyblock/Certificate easier and also gives the
|
||||||
|
opportunity to store additional information (e.g. the fingerprint)
|
||||||
|
along with the key. All integers are stored in network byte order,
|
||||||
|
offsets are counted from the beginning of the Blob.
|
||||||
|
|
||||||
|
The first record of a plain KBX file has a special format:
|
||||||
|
|
||||||
|
u32 length of the first record
|
||||||
|
byte Blob type (1)
|
||||||
|
byte version number (1)
|
||||||
|
byte reserved
|
||||||
|
byte reserved
|
||||||
|
u32 magic 'KBXf'
|
||||||
|
byte pgp_marginals used for validity calculation of this file
|
||||||
|
byte pgp_completes ditto.
|
||||||
|
byte pgp_cert_depth ditto.
|
||||||
|
|
||||||
|
The OpenPGP KBX Blob looks like this:
|
||||||
|
|
||||||
|
u32 length of this blob (including these 4 bytes)
|
||||||
|
byte Blob type (2)
|
||||||
|
byte version number of this blob type (1)
|
||||||
|
u16 Blob flags
|
||||||
|
bit 0 = contains secret key material
|
||||||
|
|
||||||
|
u32 offset to the OpenPGP keyblock
|
||||||
|
u32 length of the keyblock
|
||||||
|
u16 number of keys (at least 1!)
|
||||||
|
u16 size of additional key information
|
||||||
|
n times:
|
||||||
|
b20 The keys fingerprint
|
||||||
|
(fingerprints are always 20 bytes, MD5 left padded with zeroes)
|
||||||
|
u32 offset to the n-th key's keyID (a keyID is always 8 byte)
|
||||||
|
u16 special key flags
|
||||||
|
bit 0 =
|
||||||
|
u16 reserved
|
||||||
|
u16 number of user IDs
|
||||||
|
u16 size of additional user ID information
|
||||||
|
n times:
|
||||||
|
u32 offset to the n-th user ID
|
||||||
|
u32 length of this user ID.
|
||||||
|
u16 special user ID flags.
|
||||||
|
bit 0 =
|
||||||
|
byte validity
|
||||||
|
byte reserved
|
||||||
|
u16 number of signatures
|
||||||
|
u16 size of signature information (4)
|
||||||
|
u32 expiration time of signature with some special values:
|
||||||
|
0x00000000 = not checked
|
||||||
|
0x00000001 = missing key
|
||||||
|
0x00000002 = bad signature
|
||||||
|
0x10000000 = valid and expires at some date in 1978.
|
||||||
|
0xffffffff = valid and does not expire
|
||||||
|
u8 assigned ownertrust
|
||||||
|
u8 all_validity
|
||||||
|
u16 reserved
|
||||||
|
u32 recheck_after
|
||||||
|
u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
|
||||||
|
u32 Blob created at
|
||||||
|
u32 size of reserved space (not including this field)
|
||||||
|
reserved space
|
||||||
|
|
||||||
|
Here we might want to put other data
|
||||||
|
|
||||||
|
Here comes the keyblock
|
||||||
|
|
||||||
|
maybe we put a signature here later.
|
||||||
|
|
||||||
|
b16 MD5 checksum (useful for KS syncronisation)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <gcrypt.h>
|
||||||
|
|
||||||
|
#include "keybox-defs.h"
|
||||||
|
|
||||||
|
/* special values of the signature status */
|
||||||
|
#define SF_NONE(a) ( !(a) )
|
||||||
|
#define SF_NOKEY(a) ((a) & (1<<0))
|
||||||
|
#define SF_BAD(a) ((a) & (1<<1))
|
||||||
|
#define SF_VALID(a) ((a) & (1<<29))
|
||||||
|
|
||||||
|
|
||||||
|
struct membuf {
|
||||||
|
size_t len;
|
||||||
|
size_t size;
|
||||||
|
char *buf;
|
||||||
|
int out_of_core;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* #if MAX_FINGERPRINT_LEN < 20 */
|
||||||
|
/* #error fingerprints are 20 bytes */
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
struct keyboxblob_key {
|
||||||
|
char fpr[20];
|
||||||
|
u32 off_kid;
|
||||||
|
ulong off_kid_addr;
|
||||||
|
u16 flags;
|
||||||
|
};
|
||||||
|
struct keyboxblob_uid {
|
||||||
|
ulong off_addr;
|
||||||
|
u32 len;
|
||||||
|
u16 flags;
|
||||||
|
byte validity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct keyid_list {
|
||||||
|
struct keyid_list *next;
|
||||||
|
int seqno;
|
||||||
|
byte kid[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fixup_list {
|
||||||
|
struct fixup_list *next;
|
||||||
|
u32 off;
|
||||||
|
u32 val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct keyboxblob {
|
||||||
|
byte *blob;
|
||||||
|
size_t bloblen;
|
||||||
|
|
||||||
|
/* stuff used only by keybox_create_blob */
|
||||||
|
int nkeys;
|
||||||
|
struct keyboxblob_key *keys;
|
||||||
|
int nuids;
|
||||||
|
struct keyboxblob_uid *uids;
|
||||||
|
int nsigs;
|
||||||
|
u32 *sigs;
|
||||||
|
struct fixup_list *fixups;
|
||||||
|
|
||||||
|
struct keyid_list *temp_kids;
|
||||||
|
struct membuf *buf; /* temporary store for the blob */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* A simple implemnation of a dynamic buffer. Use init_membuf() to
|
||||||
|
create a buffer, put_membuf to append bytes and get_membuf to
|
||||||
|
release and return the buffer. Allocation errors are detected but
|
||||||
|
only returned at the final get_membuf(), this helps not to clutter
|
||||||
|
the code with out of core checks. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_membuf (struct membuf *mb, int initiallen)
|
||||||
|
{
|
||||||
|
mb->len = 0;
|
||||||
|
mb->size = initiallen;
|
||||||
|
mb->out_of_core = 0;
|
||||||
|
mb->buf = xtrymalloc (initiallen);
|
||||||
|
if (!mb->buf)
|
||||||
|
mb->out_of_core = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_membuf (struct membuf *mb, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
if (mb->out_of_core)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mb->len + len >= mb->size)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
mb->size += len + 1024;
|
||||||
|
p = xtryrealloc (mb->buf, mb->size);
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
mb->out_of_core = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mb->buf = p;
|
||||||
|
}
|
||||||
|
memcpy (mb->buf + mb->len, buf, len);
|
||||||
|
mb->len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
get_membuf (struct membuf *mb, size_t *len)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (mb->out_of_core)
|
||||||
|
{
|
||||||
|
xfree (mb->buf);
|
||||||
|
mb->buf = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = mb->buf;
|
||||||
|
*len = mb->len;
|
||||||
|
mb->buf = NULL;
|
||||||
|
mb->out_of_core = 1; /* don't allow a reuse */
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
put8 (struct membuf *mb, byte a )
|
||||||
|
{
|
||||||
|
put_membuf (mb, &a, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put16 (struct membuf *mb, u16 a )
|
||||||
|
{
|
||||||
|
unsigned char tmp[2];
|
||||||
|
tmp[0] = a>>8;
|
||||||
|
tmp[1] = a;
|
||||||
|
put_membuf (mb, tmp, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
put32 (struct membuf *mb, u32 a )
|
||||||
|
{
|
||||||
|
unsigned char tmp[4];
|
||||||
|
tmp[0] = a>>24;
|
||||||
|
tmp[1] = a>>16;
|
||||||
|
tmp[2] = a>>8;
|
||||||
|
tmp[3] = a;
|
||||||
|
put_membuf (mb, tmp, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some wrappers
|
||||||
|
*/
|
||||||
|
|
||||||
|
static u32
|
||||||
|
make_timestamp (void)
|
||||||
|
{
|
||||||
|
return time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef KEYBOX_WITH_OPENPGP
|
||||||
|
/*
|
||||||
|
OpenPGP specific stuff
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
We must store the keyid at some place because we can't calculate the
|
||||||
|
offset yet. This is only used for v3 keyIDs. Function returns an
|
||||||
|
index value for later fixup or -1 for out of core. The value must be
|
||||||
|
a non-zero value */
|
||||||
|
static int
|
||||||
|
pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
|
||||||
|
{
|
||||||
|
struct keyid_list *k, *r;
|
||||||
|
|
||||||
|
k = xtrymalloc (sizeof *k);
|
||||||
|
if (!k)
|
||||||
|
return -1;
|
||||||
|
k->kid[0] = pk->keyid[0] >> 24 ;
|
||||||
|
k->kid[1] = pk->keyid[0] >> 16 ;
|
||||||
|
k->kid[2] = pk->keyid[0] >> 8 ;
|
||||||
|
k->kid[3] = pk->keyid[0] ;
|
||||||
|
k->kid[4] = pk->keyid[0] >> 24 ;
|
||||||
|
k->kid[5] = pk->keyid[0] >> 16 ;
|
||||||
|
k->kid[6] = pk->keyid[0] >> 8 ;
|
||||||
|
k->kid[7] = pk->keyid[0] ;
|
||||||
|
k->seqno = 0;
|
||||||
|
k->next = blob->temp_kids;
|
||||||
|
blob->temp_kids = k;
|
||||||
|
for (r=k; r; r = r->next)
|
||||||
|
k->seqno++;
|
||||||
|
|
||||||
|
return k->seqno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
|
||||||
|
{
|
||||||
|
KBNODE node;
|
||||||
|
size_t fprlen;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n=0, node = keyblock; node; node = node->next)
|
||||||
|
{
|
||||||
|
if ( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||||
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||||
|
{
|
||||||
|
PKT_public_key *pk = node->pkt->pkt.public_key;
|
||||||
|
char tmp[20];
|
||||||
|
|
||||||
|
fingerprint_from_pk (pk, tmp , &fprlen);
|
||||||
|
memcpy (blob->keys[n].fpr, tmp, 20);
|
||||||
|
if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
|
||||||
|
{
|
||||||
|
assert (fprlen == 16);
|
||||||
|
memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
|
||||||
|
memset (blob->keys[n].fpr, 0, 4);
|
||||||
|
blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blob->keys[n].off_kid = 0; /* will be fixed up later */
|
||||||
|
}
|
||||||
|
blob->keys[n].flags = 0;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
else if ( node->pkt->pkttype == PKT_SECRET_KEY
|
||||||
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY )
|
||||||
|
{
|
||||||
|
never_reached (); /* actually not yet implemented */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (n == blob->nkeys);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
|
||||||
|
{
|
||||||
|
KBNODE node;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n=0, node = keyblock; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (node->pkt->pkttype == PKT_USER_ID)
|
||||||
|
{
|
||||||
|
PKT_user_id *u = node->pkt->pkt.user_id;
|
||||||
|
|
||||||
|
blob->uids[n].len = u->len;
|
||||||
|
blob->uids[n].flags = 0;
|
||||||
|
blob->uids[n].validity = 0;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (n == blob->nuids);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
|
||||||
|
{
|
||||||
|
KBNODE node;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n=0, node = keyblock; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (node->pkt->pkttype == PKT_SIGNATURE)
|
||||||
|
{
|
||||||
|
PKT_signature *sig = node->pkt->pkt.signature;
|
||||||
|
|
||||||
|
blob->sigs[n] = 0; /* FIXME: check the signature here */
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert( n == blob->nsigs );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
|
||||||
|
{
|
||||||
|
struct membuf *a = blob->buf;
|
||||||
|
KBNODE node;
|
||||||
|
int rc;
|
||||||
|
int n;
|
||||||
|
u32 kbstart = a->len;
|
||||||
|
|
||||||
|
{
|
||||||
|
struct fixup_list *fl = xtrycalloc(1, sizeof *fl );
|
||||||
|
|
||||||
|
if (!fl)
|
||||||
|
return KEYBOX_Out_Of_Core;
|
||||||
|
fl->off = 8;
|
||||||
|
fl->val = kbstart;
|
||||||
|
fl->next = blob->fixups;
|
||||||
|
blob->fixups = fl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0, node = keyblock; node; node = node->next)
|
||||||
|
{
|
||||||
|
rc = build_packet ( a, node->pkt );
|
||||||
|
if ( rc ) {
|
||||||
|
gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
|
||||||
|
node->pkt->pkttype, gpg_errstr(rc) );
|
||||||
|
return GPGERR_WRITE_FILE;
|
||||||
|
}
|
||||||
|
if ( node->pkt->pkttype == PKT_USER_ID )
|
||||||
|
{
|
||||||
|
PKT_user_id *u = node->pkt->pkt.user_id;
|
||||||
|
/* build_packet has set the offset of the name into u ;
|
||||||
|
* now we can do the fixup */
|
||||||
|
struct fixup_list *fl = xcalloc(1, sizeof *fl ); /* fixme */
|
||||||
|
fl->off = blob->uids[n].off_addr;
|
||||||
|
fl->val = u->stored_at;
|
||||||
|
fl->next = blob->fixups;
|
||||||
|
blob->fixups = fl;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (n == blob->nuids);
|
||||||
|
|
||||||
|
{
|
||||||
|
struct fixup_list *fl = xcalloc(1, sizeof *fl ); /* fixme */
|
||||||
|
|
||||||
|
fl->off = 12;
|
||||||
|
fl->val = a->len - kbstart;
|
||||||
|
fl->next = blob->fixups;
|
||||||
|
blob->fixups = fl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*KEYBOX_WITH_OPENPGP*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef KEYBOX_WITH_X509
|
||||||
|
/*
|
||||||
|
X.509 specific stuff
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /*KEYBOX_WITH_X509*/
|
||||||
|
|
||||||
|
/* Write a stored keyID out to the buffer */
|
||||||
|
static void
|
||||||
|
write_stored_kid (KEYBOXBLOB blob, int seqno)
|
||||||
|
{
|
||||||
|
struct keyid_list *r;
|
||||||
|
|
||||||
|
for ( r = blob->temp_kids; r; r = r->next )
|
||||||
|
{
|
||||||
|
if (r->seqno == seqno )
|
||||||
|
{
|
||||||
|
put_membuf (blob->buf, r->kid, 8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
never_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release a list of key IDs */
|
||||||
|
static void
|
||||||
|
release_kid_list (struct keyid_list *kl)
|
||||||
|
{
|
||||||
|
struct keyid_list *r, *r2;
|
||||||
|
|
||||||
|
for ( r = kl; r; r = r2 )
|
||||||
|
{
|
||||||
|
r2 = r->next;
|
||||||
|
xfree (r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_blob_header (KEYBOXBLOB blob, int blobtype)
|
||||||
|
{
|
||||||
|
struct membuf *a = blob->buf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
put32 ( a, 0 ); /* blob length, needs fixup */
|
||||||
|
put8 ( a, blobtype);
|
||||||
|
put8 ( a, 1 ); /* blob type version */
|
||||||
|
put16 ( a, 0 ); /* blob flags */
|
||||||
|
|
||||||
|
put32 ( a, 0 ); /* offset to the raw data, needs fixup */
|
||||||
|
put32 ( a, 0 ); /* length of the raw data, needs fixup */
|
||||||
|
|
||||||
|
put16 ( a, blob->nkeys );
|
||||||
|
put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */
|
||||||
|
for ( i=0; i < blob->nkeys; i++ )
|
||||||
|
{
|
||||||
|
put_membuf (a, blob->keys[i].fpr, 20);
|
||||||
|
blob->keys[i].off_kid_addr = a->len;
|
||||||
|
put32 ( a, 0 ); /* offset to keyid, fixed up later */
|
||||||
|
put16 ( a, blob->keys[i].flags );
|
||||||
|
put16 ( a, 0 ); /* reserved */
|
||||||
|
}
|
||||||
|
|
||||||
|
put16 ( a, blob->nuids );
|
||||||
|
put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
|
||||||
|
for (i=0; i < blob->nuids; i++)
|
||||||
|
{
|
||||||
|
blob->uids[i].off_addr = a->len;
|
||||||
|
put32 ( a, 0 ); /* offset to userid, fixed up later */
|
||||||
|
put32 ( a, blob->uids[i].len );
|
||||||
|
put16 ( a, blob->uids[i].flags );
|
||||||
|
put8 ( a, 0 ); /* validity */
|
||||||
|
put8 ( a, 0 ); /* reserved */
|
||||||
|
}
|
||||||
|
|
||||||
|
put16 ( a, blob->nsigs );
|
||||||
|
put16 ( a, 4 ); /* size of sig info */
|
||||||
|
for (i=0; i < blob->nsigs; i++)
|
||||||
|
{
|
||||||
|
put32 ( a, blob->sigs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
put8 ( a, 0 ); /* assigned ownertrust */
|
||||||
|
put8 ( a, 0 ); /* validity of all user IDs */
|
||||||
|
put16 ( a, 0 ); /* reserved */
|
||||||
|
put32 ( a, 0 ); /* time of next recheck */
|
||||||
|
put32 ( a, 0 ); /* newest timestamp (none) */
|
||||||
|
put32 ( a, make_timestamp() ); /* creation time */
|
||||||
|
put32 ( a, 0 ); /* size of reserved space */
|
||||||
|
/* reserved space (which is currently of size 0) */
|
||||||
|
|
||||||
|
/* We need to store the keyids for all pgp v3 keys because those key
|
||||||
|
IDs are not part of the fingerprint. While we are doing that, we
|
||||||
|
fixup all the keyID offsets */
|
||||||
|
for (i=0; i < blob->nkeys; i++ )
|
||||||
|
{
|
||||||
|
struct fixup_list *fl = xtrycalloc(1, sizeof *fl );
|
||||||
|
|
||||||
|
if (!fl)
|
||||||
|
return KEYBOX_Out_Of_Core;
|
||||||
|
|
||||||
|
fl->off = blob->keys[i].off_kid_addr;
|
||||||
|
fl->next = blob->fixups;
|
||||||
|
blob->fixups = fl;
|
||||||
|
|
||||||
|
if (blob->keys[i].off_kid)
|
||||||
|
{ /* this is a v3 one */
|
||||||
|
fl->val = a->len;
|
||||||
|
write_stored_kid (blob, blob->keys[i].off_kid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* the better v4 key IDs - just store an offset 8 bytes back */
|
||||||
|
fl->val = blob->keys[i].off_kid_addr - 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_blob_trailer (KEYBOXBLOB blob)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_blob_finish (KEYBOXBLOB blob)
|
||||||
|
{
|
||||||
|
struct membuf *a = blob->buf;
|
||||||
|
byte *p;
|
||||||
|
char *pp;
|
||||||
|
int i;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
/* write a placeholder for the checksum */
|
||||||
|
for (i = 0; i < 16; i++ )
|
||||||
|
put32 (a, 0);
|
||||||
|
|
||||||
|
/* get the memory area */
|
||||||
|
p = a->buf;
|
||||||
|
n = a->len;
|
||||||
|
assert (n >= 20);
|
||||||
|
|
||||||
|
/* fixup the length */
|
||||||
|
{
|
||||||
|
struct fixup_list *fl = xtrycalloc(1, sizeof *fl);
|
||||||
|
if (!fl)
|
||||||
|
return KEYBOX_Out_Of_Core;
|
||||||
|
fl->off = 0;
|
||||||
|
fl->val = n;
|
||||||
|
fl->next = blob->fixups;
|
||||||
|
blob->fixups = fl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do the fixups */
|
||||||
|
{
|
||||||
|
struct fixup_list *fl;
|
||||||
|
for (fl = blob->fixups; fl; fl = fl->next)
|
||||||
|
{
|
||||||
|
assert (fl->off+4 <= n);
|
||||||
|
p[fl->off+0] = fl->val >> 24;
|
||||||
|
p[fl->off+1] = fl->val >> 16;
|
||||||
|
p[fl->off+2] = fl->val >> 8;
|
||||||
|
p[fl->off+3] = fl->val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate and store the MD5 checksum */
|
||||||
|
gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
|
||||||
|
|
||||||
|
pp = xtrymalloc (n);
|
||||||
|
if ( !pp )
|
||||||
|
return KEYBOX_Out_Of_Core;
|
||||||
|
memcpy (pp , p, n);
|
||||||
|
blob->blob = pp;
|
||||||
|
blob->bloblen = n;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef KEYBOX_WITH_OPENPGP
|
||||||
|
|
||||||
|
int
|
||||||
|
_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
KBNODE node;
|
||||||
|
KEYBOXBLOB blob;
|
||||||
|
|
||||||
|
*r_blob = NULL;
|
||||||
|
blob = xtrycalloc (1, sizeof *blob);
|
||||||
|
if( !blob )
|
||||||
|
return KEYBOX_Out_Of_Core;
|
||||||
|
|
||||||
|
/* fixme: Do some sanity checks on the keyblock */
|
||||||
|
|
||||||
|
/* count userids and keys so that we can allocate the arrays */
|
||||||
|
for (node = keyblock; node; node = node->next)
|
||||||
|
{
|
||||||
|
switch (node->pkt->pkttype)
|
||||||
|
{
|
||||||
|
case PKT_PUBLIC_KEY:
|
||||||
|
case PKT_SECRET_KEY:
|
||||||
|
case PKT_PUBLIC_SUBKEY:
|
||||||
|
case PKT_SECRET_SUBKEY: blob->nkeys++; break;
|
||||||
|
case PKT_USER_ID: blob->nuids++; break;
|
||||||
|
case PKT_SIGNATURE: blob->nsigs++; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
|
||||||
|
blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
|
||||||
|
blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
|
||||||
|
if (!blob->keys || !blob->uids || !blob->sigs)
|
||||||
|
{
|
||||||
|
rc = KEYBOX_Out_Of_Core;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = pgp_create_key_part ( blob, keyblock );
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
rc = pgp_create_uid_part ( blob, keyblock );
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
rc = pgp_create_sig_part ( blob, keyblock );
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
init_membuf (blob->buf, 1024);
|
||||||
|
rc = create_blob_header (blob, BLOBTYPE_OPENPGP);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
rc = pgp_create_blob_keyblock (blob, keyblock);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
rc = create_blob_trailer (blob);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
rc = create_blob_finish ( blob );
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
|
||||||
|
leave:
|
||||||
|
release_kid_list (blob->temp_kids);
|
||||||
|
blob->temp_kids = NULL;
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
keybox_release_blob (blob);
|
||||||
|
*r_blob = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*r_blob = blob;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#endif /*KEYBOX_WITH_OPENPGP*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen)
|
||||||
|
{
|
||||||
|
KEYBOXBLOB blob;
|
||||||
|
|
||||||
|
*r_blob = NULL;
|
||||||
|
blob = xtrycalloc (1, sizeof *blob);
|
||||||
|
if (!blob)
|
||||||
|
return KEYBOX_Out_Of_Core;
|
||||||
|
|
||||||
|
blob->blob = image;
|
||||||
|
blob->bloblen = imagelen;
|
||||||
|
*r_blob = blob;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_keybox_release_blob (KEYBOXBLOB blob)
|
||||||
|
{
|
||||||
|
if (!blob)
|
||||||
|
return;
|
||||||
|
/* if (blob->buf) */
|
||||||
|
/* iobuf_cancel( blob->buf ); */
|
||||||
|
xfree (blob->keys );
|
||||||
|
xfree (blob->uids );
|
||||||
|
xfree (blob->sigs );
|
||||||
|
xfree (blob->blob );
|
||||||
|
xfree (blob );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
|
||||||
|
{
|
||||||
|
*n = blob->bloblen;
|
||||||
|
return blob->blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
147
kbx/keybox-defs.h
Normal file
147
kbx/keybox-defs.h
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/* 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_HEADER = 1,
|
||||||
|
BLOBTYPE_PGP = 2,
|
||||||
|
BLOBTYPE_X509 = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 resource;
|
||||||
|
int secret; /* this is for a secret keybox */
|
||||||
|
struct {
|
||||||
|
CONST_KB_NAME kb;
|
||||||
|
/*IOBUF iobuf;*/
|
||||||
|
int eof;
|
||||||
|
int error;
|
||||||
|
} current;
|
||||||
|
struct {
|
||||||
|
CONST_KB_NAME kb;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct keyboxblob *KEYBOXBLOB;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-- keybox-blob.c --*/
|
||||||
|
int _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen);
|
||||||
|
void _keybox_release_blob (KEYBOXBLOB blob);
|
||||||
|
const char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n);
|
||||||
|
|
||||||
|
/*-- keybox-file.c --*/
|
||||||
|
int _keybox_read_blob (KEYBOXBLOB *r_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)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*KEYBOX_DEFS_H*/
|
||||||
|
|
||||||
|
|
250
kbx/keybox-dump.c
Normal file
250
kbx/keybox-dump.c
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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_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", n);
|
||||||
|
|
||||||
|
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-%lu-Fpr: ", n );
|
||||||
|
for (i=0; i < 20; i++ )
|
||||||
|
fprintf (fp, "%02X", p[i]);
|
||||||
|
kidoff = get32 (p + 20);
|
||||||
|
fprintf (fp, "\nKey-%lu-Kid-Off: %lu\n", n, kidoff );
|
||||||
|
fprintf (fp, "Key-%lu-Kid: ", n );
|
||||||
|
/* fixme: check bounds */
|
||||||
|
for (i=0; i < 8; i++ )
|
||||||
|
fprintf (fp, "%02X", buffer[kidoff+i] );
|
||||||
|
kflags = get16 (p + 24 );
|
||||||
|
fprintf( fp, "\nKey-%lu-Flags: %04lX\n", n, kflags);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
fprintf (fp, "Uid-%lu-Off: %lu\n", n, uidoff );
|
||||||
|
fprintf (fp, "Uid-%lu-Len: %lu\n", n, uidlen );
|
||||||
|
fprintf (fp, "Uid-%lu: \"", n );
|
||||||
|
/*print_string (fp, buffer+uidoff, uidlen, '\"');*/
|
||||||
|
fputs ("\"\n", fp);
|
||||||
|
uflags = get16 (p + 8);
|
||||||
|
fprintf (fp, "Uid-%lu-Flags: %04lX\n", n, uflags );
|
||||||
|
fprintf (fp, "Uid-%lu-Validity: %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-%lu-Expire: ", 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;
|
||||||
|
}
|
40
kbx/keybox-errors.c
Normal file
40
kbx/keybox-errors.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Generated automatically by mkerrors */
|
||||||
|
/* Do not edit! */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "keybox-defs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keybox_strerror:
|
||||||
|
* @err: Error code
|
||||||
|
*
|
||||||
|
* This function returns a textual representaion of the given
|
||||||
|
* errorcode. If this is an unknown value, a string with the value
|
||||||
|
* is returned (Beware: it is hold in a static buffer).
|
||||||
|
*
|
||||||
|
* Return value: String with the error description.
|
||||||
|
**/
|
||||||
|
const char *
|
||||||
|
keybox_strerror (KeyboxError err)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
static char buf[25];
|
||||||
|
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case KEYBOX_No_Error: s="no error"; break;
|
||||||
|
case KEYBOX_General_Error: s="general error"; break;
|
||||||
|
case KEYBOX_Out_Of_Core: s="out of core"; break;
|
||||||
|
case KEYBOX_Invalid_Value: s="invalid value"; break;
|
||||||
|
case KEYBOX_Timeout: s="timeout"; break;
|
||||||
|
case KEYBOX_Read_Error: s="read error"; break;
|
||||||
|
case KEYBOX_Write_Error: s="write error"; break;
|
||||||
|
case KEYBOX_File_Error: s="file error"; break;
|
||||||
|
case KEYBOX_Blob_Too_Short: s="blob too short"; break;
|
||||||
|
case KEYBOX_Blob_Too_Large: s="blob too large"; break;
|
||||||
|
default: sprintf (buf, "ec=%d", err ); s=buf; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
113
kbx/keybox-file.c
Normal file
113
kbx/keybox-file.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/* 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"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp)
|
||||||
|
{
|
||||||
|
char *image;
|
||||||
|
size_t imagelen = 0;
|
||||||
|
int c1, c2, c3, c4;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
*r_blob = NULL;
|
||||||
|
if ((c1 = getc (fp)) == EOF
|
||||||
|
|| (c2 = getc (fp)) == EOF
|
||||||
|
|| (c3 = getc (fp)) == EOF
|
||||||
|
|| (c4 = 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 < 4)
|
||||||
|
return KEYBOX_Blob_Too_Short;
|
||||||
|
|
||||||
|
image = xtrymalloc (imagelen);
|
||||||
|
if (!image)
|
||||||
|
return KEYBOX_Out_Of_Core;
|
||||||
|
|
||||||
|
image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4;
|
||||||
|
if (fread (image+4, imagelen-4, 1, fp) != 1)
|
||||||
|
{
|
||||||
|
return KEYBOX_Read_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = _keybox_new_blob (r_blob, image, imagelen);
|
||||||
|
if (rc)
|
||||||
|
xfree (image);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
export_as_kbxfile(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
KBPOS kbpos;
|
||||||
|
KBNODE keyblock = NULL;
|
||||||
|
int rc=0;
|
||||||
|
|
||||||
|
rc = enum_keyblocks_begin( &kbpos, 0 );
|
||||||
|
if( rc ) {
|
||||||
|
if( rc != -1 )
|
||||||
|
log_error("enum_keyblocks(open) failed: %s\n", gpg_errstr(rc) );
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( !(rc = enum_keyblocks_next( kbpos, 1, &keyblock )) ) {
|
||||||
|
KBXBLOB blob;
|
||||||
|
const char *p;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
merge_keys_and_selfsig( keyblock );
|
||||||
|
rc = kbx_create_blob ( &blob, keyblock );
|
||||||
|
if( rc ) {
|
||||||
|
log_error("kbx_create_blob failed: %s\n", gpg_errstr(rc) );
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
p = kbx_get_blob_image ( blob, &n );
|
||||||
|
fwrite( p, n, 1, stdout );
|
||||||
|
kbx_release_blob ( blob );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc && rc != -1 )
|
||||||
|
log_error("enum_keyblocks(read) failed: %s\n", gpg_errstr(rc));
|
||||||
|
|
||||||
|
leave:
|
||||||
|
enum_keyblocks_end( kbpos );
|
||||||
|
release_kbnode( keyblock );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
73
kbx/keybox-init.c
Normal file
73
kbx/keybox-init.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* 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 "keybox-defs.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
#if 0
|
||||||
|
KB_NAME kr;
|
||||||
|
|
||||||
|
if (active_handles)
|
||||||
|
BUG (); /* We don't allow that */
|
||||||
|
|
||||||
|
for (kr=kb_names; kr; kr = kr->next) {
|
||||||
|
if ( !compare_filenames (kr->fname, fname) )
|
||||||
|
return NULL; /* already registered */
|
||||||
|
}
|
||||||
|
|
||||||
|
kr = m_alloc (sizeof *kr + strlen (fname));
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
keybox_is_writable (void *token)
|
||||||
|
{
|
||||||
|
KB_NAME r = token;
|
||||||
|
|
||||||
|
return r? !access (r->fname, W_OK) : 0;
|
||||||
|
}
|
||||||
|
|
158
kbx/keybox-search.c
Normal file
158
kbx/keybox-search.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/* keybox-search.c - Search 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 "keybox-defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Check whether the given fingerprint (20 bytes) is in the
|
||||||
|
* given keyblob. fpr is always 20 bytes.
|
||||||
|
* Return: 0 = found
|
||||||
|
* -1 = not found
|
||||||
|
other = error (fixme: do not always reurn gpgerr_general)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keybox_blob_has_fpr ( KEYBOXBLOB blob, const byte *fpr )
|
||||||
|
{
|
||||||
|
ulong n, nkeys, keyinfolen;
|
||||||
|
const byte *p, *pend;
|
||||||
|
byte *buffer = blob->blob;
|
||||||
|
size_t buflen = blob->bloblen;
|
||||||
|
|
||||||
|
if ( buflen < 40 )
|
||||||
|
return GPGERR_GENERAL; /* blob too short */
|
||||||
|
n = get32( buffer );
|
||||||
|
if ( n > buflen )
|
||||||
|
return GPGERR_GENERAL; /* blob larger than announced length */
|
||||||
|
buflen = n; /* ignore trailing stuff */
|
||||||
|
pend = buffer + n - 1;
|
||||||
|
|
||||||
|
if ( buffer[4] != 2 )
|
||||||
|
return GPGERR_GENERAL; /* invalid blob type */
|
||||||
|
if ( buffer[5] != 1 )
|
||||||
|
return GPGERR_GENERAL; /* invalid blob format version */
|
||||||
|
|
||||||
|
nkeys = get16( buffer + 16 );
|
||||||
|
keyinfolen = get16( buffer + 18 );
|
||||||
|
p = buffer + 20;
|
||||||
|
for(n=0; n < nkeys; n++, p += keyinfolen ) {
|
||||||
|
if ( p+20 > pend )
|
||||||
|
return GPGERR_GENERAL; /* blob shorter than required */
|
||||||
|
if (!memcmp ( p, fpr, 20 ) )
|
||||||
|
return 0; /* found */
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Check whether the given keyID (20 bytes) is in the
|
||||||
|
* given keyblob.
|
||||||
|
* Return: 0 = found
|
||||||
|
* -1 = not found
|
||||||
|
other = error (fixme: do not always return gpgerr_general)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keybox_blob_has_kid ( KEYBOXBLOB blob, const byte *keyidbuf, size_t keyidlen )
|
||||||
|
{
|
||||||
|
ulong n, nkeys, keyinfolen, off;
|
||||||
|
const byte *p, *pend;
|
||||||
|
byte *buffer = blob->blob;
|
||||||
|
size_t buflen = blob->bloblen;
|
||||||
|
|
||||||
|
if ( buflen < 40 )
|
||||||
|
return GPGERR_GENERAL; /* blob too short */
|
||||||
|
n = get32( buffer );
|
||||||
|
if ( n > buflen )
|
||||||
|
return GPGERR_GENERAL; /* blob larger than announced length */
|
||||||
|
buflen = n; /* ignore trailing stuff */
|
||||||
|
pend = buffer + n - 1;
|
||||||
|
|
||||||
|
if ( buffer[4] != 2 )
|
||||||
|
return GPGERR_GENERAL; /* invalid blob type */
|
||||||
|
if ( buffer[5] != 1 )
|
||||||
|
return GPGERR_GENERAL; /* invalid blob format version */
|
||||||
|
|
||||||
|
nkeys = get16( buffer + 16 );
|
||||||
|
keyinfolen = get16( buffer + 18 );
|
||||||
|
p = buffer + 20;
|
||||||
|
for(n=0; n < nkeys; n++, p += keyinfolen ) {
|
||||||
|
if ( p+24 > pend )
|
||||||
|
return GPGERR_GENERAL; /* blob shorter than required */
|
||||||
|
off = get32 ( p + 20 );
|
||||||
|
if (keyidlen < 8 ) /* actually keyidlen may either be 4 or 8 */
|
||||||
|
off +=4;
|
||||||
|
if ( off+keyidlen > buflen )
|
||||||
|
return GPGERR_GENERAL; /* offset out of bounds */
|
||||||
|
if ( !memcmp ( buffer+off, keyidbuf, keyidlen ) )
|
||||||
|
return 0; /* found */
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
keybox_blob_has_uid ( KEYBOXBLOB blob,
|
||||||
|
int (*cmp)(const byte *, size_t, void *), void *opaque )
|
||||||
|
{
|
||||||
|
ulong n, nuids, uidinfolen, off, len;
|
||||||
|
const byte *p, *pend;
|
||||||
|
byte *buffer = blob->blob;
|
||||||
|
size_t buflen = blob->bloblen;
|
||||||
|
|
||||||
|
if ( buflen < 40 )
|
||||||
|
return GPGERR_GENERAL; /* blob too short */
|
||||||
|
n = get32( buffer );
|
||||||
|
if ( n > buflen )
|
||||||
|
return GPGERR_GENERAL; /* blob larger than announced length */
|
||||||
|
buflen = n; /* ignore trailing stuff */
|
||||||
|
pend = buffer + n - 1;
|
||||||
|
|
||||||
|
if ( buffer[4] != 2 )
|
||||||
|
return GPGERR_GENERAL; /* invalid blob type */
|
||||||
|
if ( buffer[5] != 1 )
|
||||||
|
return GPGERR_GENERAL; /* invalid blob format version */
|
||||||
|
|
||||||
|
p = buffer + 20 + get16( buffer + 16 ) * get16( buffer + 18 );
|
||||||
|
if ( p+4 > pend )
|
||||||
|
return GPGERR_GENERAL; /* blob shorter than required */
|
||||||
|
|
||||||
|
nuids = get16( p ); p+= 2;
|
||||||
|
uidinfolen = get16( p ); p+=2;
|
||||||
|
for(n=0; n < nuids; n++, p += uidinfolen ) {
|
||||||
|
if ( p+8 > pend )
|
||||||
|
return GPGERR_GENERAL; /* blob shorter than required */
|
||||||
|
off = get32 ( p );
|
||||||
|
len = get32 ( p + 4 );
|
||||||
|
if ( off+len > buflen )
|
||||||
|
return GPGERR_GENERAL; /* offset out of bounds */
|
||||||
|
if ( (*cmp) ( buffer+off, len, opaque ) )
|
||||||
|
return 0; /* found */
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
72
kbx/keybox-util.c
Normal file
72
kbx/keybox-util.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* keybox-util.c - Utility functions for Keybox
|
||||||
|
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 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"
|
||||||
|
|
||||||
|
|
||||||
|
static void *(*alloc_func)(size_t n) = malloc;
|
||||||
|
static void *(*realloc_func)(void *p, size_t n) = realloc;
|
||||||
|
static void (*free_func)(void*) = free;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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*) )
|
||||||
|
{
|
||||||
|
alloc_func = new_alloc_func;
|
||||||
|
realloc_func = new_realloc_func;
|
||||||
|
free_func = new_free_func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
_keybox_malloc (size_t n)
|
||||||
|
{
|
||||||
|
return alloc_func (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
_keybox_realloc (void *a, size_t n)
|
||||||
|
{
|
||||||
|
return realloc_func (a, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
_keybox_calloc (size_t n, size_t m)
|
||||||
|
{
|
||||||
|
void *p = _keybox_malloc (n*m);
|
||||||
|
if (p)
|
||||||
|
memset (p, 0, n* m);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_keybox_free (void *p)
|
||||||
|
{
|
||||||
|
if (p)
|
||||||
|
free_func (p);
|
||||||
|
}
|
||||||
|
|
99
kbx/keybox.h
Normal file
99
kbx/keybox.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/* 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
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
} 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_lock (KEYBOX_HANDLE hd, int yes);
|
||||||
|
#if 0
|
||||||
|
int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb);
|
||||||
|
int keybox_update_keyblock (KEYBOX_HANDLE hd, KBNODE kb);
|
||||||
|
int keybox_insert_keyblock (KEYBOX_HANDLE hd, KBNODE kb);
|
||||||
|
int keybox_locate_writable (KEYBOX_HANDLE hd);
|
||||||
|
int keybox_delete_keyblock (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*/
|
71
kbx/mkerrors
Executable file
71
kbx/mkerrors
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# mkerrors - Extract error strings from assuan.h
|
||||||
|
# and create C source for assuan_strerror
|
||||||
|
# Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of GnuPG.
|
||||||
|
#
|
||||||
|
# GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 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
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
/* Generated automatically by mkerrors */
|
||||||
|
/* Do not edit! */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "keybox-defs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keybox_strerror:
|
||||||
|
* @err: Error code
|
||||||
|
*
|
||||||
|
* This function returns a textual representaion of the given
|
||||||
|
* errorcode. If this is an unknown value, a string with the value
|
||||||
|
* is returned (Beware: it is hold in a static buffer).
|
||||||
|
*
|
||||||
|
* Return value: String with the error description.
|
||||||
|
**/
|
||||||
|
const char *
|
||||||
|
keybox_strerror (KeyboxError err)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
static char buf[25];
|
||||||
|
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
EOF
|
||||||
|
|
||||||
|
awk '
|
||||||
|
/KEYBOX_No_Error/ { okay=1 }
|
||||||
|
!okay {next}
|
||||||
|
/}/ { exit 0 }
|
||||||
|
/KEYBOX_[A-Za-z_]*/ { print_code($1) }
|
||||||
|
|
||||||
|
|
||||||
|
function print_code( s )
|
||||||
|
{
|
||||||
|
printf " case %s: s=\"", s ;
|
||||||
|
gsub(/_/, " ", s );
|
||||||
|
printf "%s\"; break;\n", tolower(substr(s,8));
|
||||||
|
}
|
||||||
|
'
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
default: sprintf (buf, "ec=%d", err ); s=buf; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOF
|
Loading…
x
Reference in New Issue
Block a user