mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
See ChangeLog: Thu May 25 18:39:11 CEST 2000 Werner Koch
This commit is contained in:
parent
da129a5124
commit
d1648b4d7a
@ -65,7 +65,10 @@
|
||||
</indexterm>
|
||||
<function>gcry_md_open</function> creates the context required for
|
||||
the message digest functions. The hash algorithm may optionally be
|
||||
specified.
|
||||
specified. It is possible to use these functions as MAC functons; therefore
|
||||
the flag <literal/GCRY_MD_FLAG_HMAC/ must be given along with the
|
||||
hash functions. Other MAC algorithms than HMAC are currently not
|
||||
supported. The key for the MAC must be set using the gcry_md_setkey macro.
|
||||
<function>gcry_md_close</function> releases all resources associated
|
||||
with the context.
|
||||
<function>gcry_md_enable</function> may be used to enable hash
|
||||
@ -149,6 +152,7 @@
|
||||
<refnamediv>
|
||||
<refname>gcry_md_ctl</refname>
|
||||
<refname>gcry_md_final</refname>
|
||||
<refname>gcry_md_setkey</refname>
|
||||
<refpurpose>perform special operations on a digest context</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
@ -179,9 +183,18 @@
|
||||
</para>
|
||||
<para>
|
||||
Currently defined values for <parameter>cmd</> are:
|
||||
<literal>GCRYCTL_FINALIZE</> and the conevnience macro
|
||||
</para>
|
||||
<para>
|
||||
<literal>GCRYCTL_FINALIZE</> and the convenience macro
|
||||
<function>gcry_md_final(a)</>
|
||||
</para>
|
||||
<para>
|
||||
<literal>GCRYCTL_SET_KEY</> and the convenience macro
|
||||
<function>gcry_md_setkey(a)</>. This is used to turn these
|
||||
hash functions into MAC functions. The key may be any string
|
||||
of the speicified length. The type of the MAC is determined
|
||||
by special flags set with the open function.
|
||||
</para>
|
||||
</refentry>
|
||||
|
||||
<!--**********************************************
|
||||
|
@ -1,3 +1,10 @@
|
||||
Thu May 25 18:39:11 CEST 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* kbxio.c: New.
|
||||
|
||||
* kbxfile.c (print_kbxfile): Add a loop
|
||||
(do_print_kbxfile): Fixed passing to kbx_dump_blob.
|
||||
|
||||
Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
|
||||
|
||||
* gpg.c (print_mds): Add arg keys as a kludge to print hmacs
|
||||
|
@ -9,7 +9,7 @@ LDFLAGS = -static @LDFLAGS@ @DYNLINK_LDFLAGS@
|
||||
needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la ../jnlib/libjnlib.la ../util/libutil.la
|
||||
|
||||
#noinst_PROGRAMS = gpgd
|
||||
bin_PROGRAMS = gpg
|
||||
bin_PROGRAMS = gpg kbxutil
|
||||
|
||||
common_source = \
|
||||
build-packet.c \
|
||||
@ -26,6 +26,7 @@ common_source = \
|
||||
kbnode.c \
|
||||
kbx.h \
|
||||
kbxblob.c \
|
||||
kbxio.c \
|
||||
kbxfile.c \
|
||||
main.h \
|
||||
mainproc.c \
|
||||
@ -73,6 +74,11 @@ gpg_SOURCES = gpg.c \
|
||||
dearmor.c \
|
||||
keygen.c
|
||||
|
||||
# fixme: remove unused sources from kbxutil
|
||||
kbxutil_SOURCES = kbxutil.c \
|
||||
$(common_source)
|
||||
|
||||
|
||||
#gpgd_SOURCES = gpgd.c \
|
||||
# ks-proto.h \
|
||||
# ks-proto.c \
|
||||
|
@ -196,7 +196,8 @@ static int
|
||||
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
|
||||
{
|
||||
write_header(out, ctb, uid->len);
|
||||
uid->stored_at = iobuf_tell( out ); /* what a hack */
|
||||
uid->stored_at = iobuf_get_temp_length ( out ); /* what a hack ... */
|
||||
/* ... and it does only work when used with a temp iobuf */
|
||||
if( iobuf_write( out, uid->name, uid->len ) )
|
||||
return GPGERR_WRITE_FILE;
|
||||
return 0;
|
||||
|
@ -1461,9 +1461,11 @@ main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
case aFixTrustDB:
|
||||
log_error("this command ist not yet implemented.\"\n");
|
||||
log_error("this command is not yet implemented.\"\n");
|
||||
log_error("A workaround is to use \"--export-ownertrust\", remove\n");
|
||||
log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
|
||||
#warning removed the next line
|
||||
export_as_kbxfile();
|
||||
break;
|
||||
|
||||
case aListTrustPath:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* ggpd.c - The GnuPG daemon (keyserver)
|
||||
/* gpg.c - The GnuPG daemon (keyserver)
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
|
21
g10/kbx.h
21
g10/kbx.h
@ -23,10 +23,29 @@
|
||||
|
||||
#include "keydb.h"
|
||||
|
||||
/*-- kbxblob.c */
|
||||
struct kbxblob;
|
||||
typedef struct kbxblob *KBXBLOB;
|
||||
|
||||
int kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock );
|
||||
int kbx_new_blob ( KBXBLOB *r_blob, char *image, size_t imagelen );
|
||||
int kbx_create_blob ( KBXBLOB *r_blob, KBNODE keyblock );
|
||||
void kbx_release_blob ( KBXBLOB blob );
|
||||
const char *kbx_get_blob_image ( KBXBLOB blob, size_t *n );
|
||||
|
||||
int kbx_dump_blob ( FILE *fp, KBXBLOB blob );
|
||||
int kbx_blob_has_fpr ( KBXBLOB blob, const byte *fpr );
|
||||
int kbx_blob_has_kid ( KBXBLOB blob, const byte *keyidbuf, size_t keyidlen );
|
||||
int kbx_blob_has_uid ( KBXBLOB blob,
|
||||
int (*cmp)(const byte *, size_t, void *), void *opaque );
|
||||
|
||||
/*-- kbxio.c --*/
|
||||
int kbx_read_blob ( KBXBLOB *r_blob, FILE *a );
|
||||
|
||||
/*-- kbxfile.c --*/
|
||||
int kbxfile_search_by_fpr( const char *filename, const byte *fpr );
|
||||
int kbxfile_search_by_kid ( const char *filename, u32 *kid, int mode );
|
||||
int kbxfile_search_by_uid ( const char *filename, const char *name );
|
||||
void print_kbxfile( const char *filename );
|
||||
|
||||
|
||||
#endif /*GPG_KBX_H*/
|
||||
|
397
g10/kbxblob.c
397
g10/kbxblob.c
@ -88,7 +88,7 @@ The standard KBX Blob looks like this:
|
||||
|
||||
Here comes the keyblock
|
||||
|
||||
maybe we put a sigture here later.
|
||||
maybe we put a signature here later.
|
||||
|
||||
b16 MD5 checksum (useful for KS syncronisation)
|
||||
*
|
||||
@ -136,20 +136,31 @@ struct keyid_list {
|
||||
byte kid[8];
|
||||
};
|
||||
|
||||
struct fixup_list {
|
||||
struct fixup_list *next;
|
||||
u32 off;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
|
||||
struct kbxblob {
|
||||
byte *blob;
|
||||
size_t bloblen;
|
||||
|
||||
/* stuff used only by kbx_create_blob */
|
||||
int nkeys;
|
||||
struct kbxblob_key *keys;
|
||||
int nuids;
|
||||
struct kbxblob_uid *uids;
|
||||
int nsigs;
|
||||
u32 *sigs;
|
||||
struct fixup_list *fixups;
|
||||
|
||||
struct keyid_list *temp_kids;
|
||||
IOBUF buf; /* the KBX is stored here */
|
||||
IOBUF buf; /* the KBX is temporarly stored here */
|
||||
};
|
||||
|
||||
|
||||
|
||||
void kbx_release_blob ( KBXBLOB blob );
|
||||
|
||||
/* Note: this functions are only used for temportay iobufs and therefore
|
||||
* they can't fail */
|
||||
@ -183,28 +194,9 @@ putn ( IOBUF out, const byte *p, size_t n )
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* special version of put 32, which is used to fixup a value at file offset OFF
|
||||
*/
|
||||
static void
|
||||
put32at ( IOBUF out, u32 a, size_t pos )
|
||||
{
|
||||
size_t n;
|
||||
byte *p;
|
||||
|
||||
iobuf_flush_temp ( out );
|
||||
p = iobuf_get_temp_buffer( out );
|
||||
n = iobuf_get_temp_length( out );
|
||||
assert( n >= pos+4 );
|
||||
p[0] = a >> 24 ;
|
||||
p[1] = a >> 16 ;
|
||||
p[2] = a >> 8 ;
|
||||
p[3] = a ;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* We must store the keyid at some place becuase we can't calculate the
|
||||
* 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 fixupd; this must be a non-zero value
|
||||
*/
|
||||
@ -269,8 +261,10 @@ create_key_part( KBXBLOB blob, KBNODE keyblock )
|
||||
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, blob->keys[n].fpr, &fprlen );
|
||||
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);
|
||||
@ -346,10 +340,10 @@ create_blob_header( KBXBLOB blob )
|
||||
put32 ( a, 0 ); /* length of the keyblock, needs fixup */
|
||||
|
||||
put16 ( a, blob->nkeys );
|
||||
put16 ( a, 20 + 8 + 2 + 2 ); /* size of key info */
|
||||
put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */
|
||||
for ( i=0; i < blob->nkeys; i++ ) {
|
||||
putn ( a, blob->keys[i].fpr, 20 );
|
||||
blob->keys[i].off_kid_addr = iobuf_tell ( a );
|
||||
blob->keys[i].off_kid_addr = iobuf_get_temp_length (a);
|
||||
put32 ( a, 0 ); /* offset to keyid, fixed up later */
|
||||
put16 ( a, blob->keys[i].flags );
|
||||
put16 ( a, 0 ); /* reserved */
|
||||
@ -358,7 +352,7 @@ create_blob_header( KBXBLOB blob )
|
||||
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 = iobuf_tell ( a );
|
||||
blob->uids[i].off_addr = iobuf_get_temp_length ( a );
|
||||
put32 ( a, 0 ); /* offset to userid, fixed up later */
|
||||
put32 ( a, blob->uids[i].len );
|
||||
put16 ( a, blob->uids[i].flags );
|
||||
@ -385,13 +379,17 @@ create_blob_header( KBXBLOB blob )
|
||||
* 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 = gcry_xcalloc(1, sizeof *fl );
|
||||
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 */
|
||||
put32at ( a, iobuf_tell(a), blob->keys[i].off_kid_addr );
|
||||
fl->val = iobuf_get_temp_length (a);
|
||||
put_stored_kid ( blob, blob->keys[i].off_kid );
|
||||
}
|
||||
else { /* the better v4 key IDs - just store an offset 8 bytes back */
|
||||
put32at ( a, blob->keys[i].off_kid_addr-8,
|
||||
blob->keys[i].off_kid_addr );
|
||||
fl->val = blob->keys[i].off_kid_addr-8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,9 +403,17 @@ create_blob_keyblock( KBXBLOB blob, KBNODE keyblock )
|
||||
IOBUF a = blob->buf;
|
||||
KBNODE node;
|
||||
int rc;
|
||||
int nsig;
|
||||
int n;
|
||||
u32 kbstart = iobuf_get_temp_length ( a );
|
||||
|
||||
for ( nsig = 0, node = keyblock; node; node = node->next ) {
|
||||
{
|
||||
struct fixup_list *fl = gcry_xcalloc(1, sizeof *fl );
|
||||
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 kbxblob failed: %s\n",
|
||||
@ -418,11 +424,22 @@ create_blob_keyblock( KBXBLOB blob, KBNODE keyblock )
|
||||
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 */
|
||||
put32at ( a, u->stored_at, blob->uids[nsig].off_addr );
|
||||
nsig++;
|
||||
struct fixup_list *fl = gcry_xcalloc(1, sizeof *fl );
|
||||
fl->off = blob->uids[n].off_addr;
|
||||
fl->val = u->stored_at;
|
||||
fl->next = blob->fixups;
|
||||
blob->fixups = fl;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
assert( nsig == blob->nsigs );
|
||||
assert( n == blob->nuids );
|
||||
{
|
||||
struct fixup_list *fl = gcry_xcalloc(1, sizeof *fl );
|
||||
fl->off = 12;
|
||||
fl->val = iobuf_get_temp_length (a) - kbstart;
|
||||
fl->next = blob->fixups;
|
||||
blob->fixups = fl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -438,10 +455,13 @@ create_blob_finish( KBXBLOB blob )
|
||||
{
|
||||
IOBUF a = blob->buf;
|
||||
byte *p;
|
||||
char *pp;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
/* write a placeholder for the checksum */
|
||||
put32( a, 0 ); put32( a, 0 ); put32( a, 0 ); put32( a, 0 );
|
||||
for ( i = 0; i < 16; i++ )
|
||||
put32( a, 0 );
|
||||
/* get the memory area */
|
||||
iobuf_flush_temp ( a );
|
||||
p = iobuf_get_temp_buffer ( a );
|
||||
@ -449,23 +469,48 @@ create_blob_finish( KBXBLOB blob )
|
||||
assert( n >= 20 );
|
||||
|
||||
/* fixup the length */
|
||||
put32at ( a, 0, n );
|
||||
{
|
||||
struct fixup_list *fl = gcry_xcalloc(1, sizeof *fl );
|
||||
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 = gcry_malloc ( n );
|
||||
if ( !pp )
|
||||
return GCRYERR_NO_MEM;
|
||||
memcpy ( pp , p, n );
|
||||
blob->blob = pp;
|
||||
blob->bloblen = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
|
||||
kbx_create_blob ( KBXBLOB *r_blob, KBNODE keyblock )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE node;
|
||||
KBXBLOB blob;
|
||||
|
||||
*retkbx = NULL;
|
||||
*r_blob = NULL;
|
||||
blob = gcry_calloc (1, sizeof *blob );
|
||||
if( !blob )
|
||||
return GCRYERR_NO_MEM;
|
||||
@ -484,9 +529,9 @@ kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
blob->keys = gcry_calloc ( blob->nkeys, sizeof ( blob->keys ) );
|
||||
blob->uids = gcry_calloc ( blob->nuids, sizeof ( blob->uids ) );
|
||||
blob->sigs = gcry_calloc ( blob->nsigs, sizeof ( blob->sigs ) );
|
||||
blob->keys = gcry_calloc ( blob->nkeys, sizeof ( *blob->keys ) );
|
||||
blob->uids = gcry_calloc ( blob->nuids, sizeof ( *blob->uids ) );
|
||||
blob->sigs = gcry_calloc ( blob->nsigs, sizeof ( *blob->sigs ) );
|
||||
if ( !blob->keys || !blob->uids || !blob->sigs ) {
|
||||
rc = GCRYERR_NO_MEM;
|
||||
goto leave;
|
||||
@ -516,17 +561,44 @@ kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
|
||||
if( rc )
|
||||
goto leave;
|
||||
|
||||
*retkbx = blob;
|
||||
|
||||
leave:
|
||||
release_kid_list( blob->temp_kids );
|
||||
blob->temp_kids = NULL;
|
||||
if ( rc ) {
|
||||
kbx_release_blob ( blob );
|
||||
*r_blob = NULL;
|
||||
}
|
||||
else {
|
||||
*r_blob = blob;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
kbx_new_blob ( KBXBLOB *r_blob, char *image, size_t imagelen )
|
||||
{
|
||||
KBXBLOB blob;
|
||||
|
||||
*r_blob = NULL;
|
||||
blob = gcry_calloc (1, sizeof *blob );
|
||||
if( !blob )
|
||||
return GCRYERR_NO_MEM;
|
||||
blob->blob = image;
|
||||
blob->bloblen = imagelen;
|
||||
*r_blob = blob;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
kbx_get_blob_image ( KBXBLOB blob, size_t *n )
|
||||
{
|
||||
*n = blob->bloblen;
|
||||
return blob->blob;
|
||||
}
|
||||
|
||||
void
|
||||
kbx_release_blob ( KBXBLOB blob )
|
||||
{
|
||||
@ -537,6 +609,9 @@ kbx_release_blob ( KBXBLOB blob )
|
||||
gcry_free( blob->keys );
|
||||
gcry_free( blob->uids );
|
||||
gcry_free( blob->sigs );
|
||||
|
||||
gcry_free ( blob->blob );
|
||||
|
||||
gcry_free( blob );
|
||||
}
|
||||
|
||||
@ -556,17 +631,21 @@ get16( const byte *buffer )
|
||||
{
|
||||
ulong a;
|
||||
a = *buffer << 8;
|
||||
a |= buffer[0];
|
||||
a |= buffer[1];
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
kbx_dump_blob ( FILE *fp, const byte* buffer, size_t length )
|
||||
kbx_dump_blob ( FILE *fp, KBXBLOB blob )
|
||||
{
|
||||
#if 0
|
||||
ulong n;
|
||||
const byte *buffer = blob->blob;
|
||||
size_t length = blob->bloblen;
|
||||
ulong n, nkeys, keyinfolen;
|
||||
ulong nuids, uidinfolen;
|
||||
ulong nsigs, siginfolen;
|
||||
ulong keyblock_off, keyblock_len;
|
||||
const byte *p;
|
||||
|
||||
if( length < 40 ) {
|
||||
fprintf( fp, "blob too short\n");
|
||||
@ -579,8 +658,8 @@ kbx_dump_blob ( FILE *fp, const byte* buffer, size_t length )
|
||||
else
|
||||
length = n; /* ignore the rest */
|
||||
fprintf( fp, "Length: %lu\n", n );
|
||||
fprintf( fp, "Type: %d\n", buffer[4] ),
|
||||
fprintf( fp, "Version: %d\n", buffer[5] ),
|
||||
fprintf( fp, "Type: %d\n", buffer[4] );
|
||||
fprintf( fp, "Version: %d\n", buffer[5] );
|
||||
if( buffer[4] != 2 ) {
|
||||
fprintf( fp, "can't dump this blob type\n" );
|
||||
return 0;
|
||||
@ -593,8 +672,224 @@ kbx_dump_blob ( FILE *fp, const byte* buffer, size_t length )
|
||||
fprintf( fp, "Keyblock-Offset: %lu\n", keyblock_off );
|
||||
fprintf( fp, "Keyblock-Length: %lu\n", keyblock_len );
|
||||
|
||||
#endif
|
||||
nkeys = get16( buffer + 16 );
|
||||
fprintf( fp, "Key-Count: %lu\n", nkeys );
|
||||
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( 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", strtimestamp(n) );
|
||||
n = get32( p ); p += 4;
|
||||
fprintf( fp, "Created-At: %s\n", 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;
|
||||
}
|
||||
|
||||
/****************
|
||||
* 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
|
||||
kbx_blob_has_fpr ( KBXBLOB 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
|
||||
kbx_blob_has_kid ( KBXBLOB 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
|
||||
kbx_blob_has_uid ( KBXBLOB 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;
|
||||
}
|
||||
|
||||
|
||||
|
291
g10/kbxfile.c
291
g10/kbxfile.c
@ -22,7 +22,7 @@
|
||||
* We will change the whole system to use only KBX. This file here
|
||||
* will implement the methods needed to operate on plain KBXfiles.
|
||||
* Most stuff from getkey and ringedit will be replaced by stuff here.
|
||||
* To make things even mor easier we will only allow one updateable kbxfile
|
||||
* To make things even more easier we will only allow one updateable kbxfile
|
||||
* and optionally some read-only files.
|
||||
*/
|
||||
|
||||
@ -35,11 +35,298 @@
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include "kbx.h"
|
||||
#include "options.h"
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
#include "main.h"
|
||||
|
||||
/****************
|
||||
* Read the blob at the current fileposition and return an allocated
|
||||
* pointer nto the blob if it was found.
|
||||
* Fixme: return a blob object.
|
||||
*/
|
||||
static int
|
||||
do_search_by_fpr ( const char *filename, FILE *a, const char *fpr,
|
||||
KBXBLOB *r_blob )
|
||||
{
|
||||
KBXBLOB blob;
|
||||
int rc;
|
||||
|
||||
*r_blob = NULL;
|
||||
rc = kbx_read_blob ( &blob, a );
|
||||
if ( rc && rc != -1 ) {
|
||||
log_error (_("file `%s': error reading blob\n"), filename );
|
||||
}
|
||||
else if ( !rc ) {
|
||||
rc = kbx_blob_has_fpr ( blob, fpr );
|
||||
}
|
||||
else
|
||||
log_info ("eof\n");
|
||||
|
||||
if ( !rc ) {
|
||||
*r_blob = blob;
|
||||
}
|
||||
else {
|
||||
kbx_release_blob ( blob );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
kbxfile_search_by_fpr( void )
|
||||
kbxfile_search_by_fpr( const char *filename, const byte *fpr )
|
||||
{
|
||||
FILE *fp;
|
||||
KBXBLOB blob;
|
||||
int rc;
|
||||
|
||||
fp = fopen ( filename, "rb" );
|
||||
if( !fp ) {
|
||||
log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ( (rc=do_search_by_fpr ( filename, fp, fpr, &blob )) == -1 )
|
||||
;
|
||||
if ( !rc ) {
|
||||
fputs ("FOUND\n", stderr );
|
||||
kbx_dump_blob ( stderr, blob );
|
||||
kbx_release_blob ( blob );
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Read the blob at the current fileposition and return an allocated
|
||||
* pointer nto the blob if it was found.
|
||||
* Fixme: return a blob object.
|
||||
*/
|
||||
static int
|
||||
do_search_by_keyid ( const char *filename, FILE *a,
|
||||
const byte *keyidbuf, size_t keyidlen, KBXBLOB *r_blob )
|
||||
{
|
||||
KBXBLOB blob;
|
||||
int rc;
|
||||
|
||||
*r_blob = NULL;
|
||||
rc = kbx_read_blob ( &blob, a );
|
||||
if ( rc && rc != -1 ) {
|
||||
log_error (_("file `%s': error reading blob\n"), filename );
|
||||
}
|
||||
else if ( !rc ) {
|
||||
rc = kbx_blob_has_kid ( blob, keyidbuf, keyidlen );
|
||||
}
|
||||
else
|
||||
rc = GPGERR_GENERAL; /* eof */
|
||||
|
||||
if ( !rc ) {
|
||||
*r_blob = blob;
|
||||
}
|
||||
else {
|
||||
kbx_release_blob ( blob );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Look for a KBX described by an keyid. This function will in
|
||||
* turn return each matching keyid because there may me duplicates
|
||||
* (which can't happen for fingerprints)
|
||||
* mode 10 = short keyid
|
||||
* 11 = long keyid
|
||||
*/
|
||||
int
|
||||
kbxfile_search_by_kid ( const char *filename, u32 *kid, int mode )
|
||||
{
|
||||
FILE *fp;
|
||||
KBXBLOB blob;
|
||||
int rc;
|
||||
byte kbuf[8], *kbufptr;
|
||||
int kbuflen;
|
||||
|
||||
fp = fopen ( filename, "rb" );
|
||||
if( !fp ) {
|
||||
log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
kbuf[0] = kid[0] >> 24;
|
||||
kbuf[1] = kid[0] >> 16;
|
||||
kbuf[2] = kid[0] >> 8;
|
||||
kbuf[3] = kid[0];
|
||||
kbuf[4] = kid[1] >> 24;
|
||||
kbuf[5] = kid[1] >> 16;
|
||||
kbuf[6] = kid[1] >> 8;
|
||||
kbuf[7] = kid[1];
|
||||
if ( mode == 10 ) {
|
||||
kbufptr=kbuf+4;
|
||||
kbuflen = 4;
|
||||
}
|
||||
else if (mode == 11 ) {
|
||||
kbufptr=kbuf;
|
||||
kbuflen = 8;
|
||||
}
|
||||
else {
|
||||
BUG();
|
||||
}
|
||||
|
||||
do {
|
||||
while ( (rc=do_search_by_keyid ( filename, fp,
|
||||
kbufptr, kbuflen, &blob )) == -1 )
|
||||
;
|
||||
if ( !rc ) {
|
||||
fputs ("FOUND:\n", stderr );
|
||||
kbx_dump_blob ( stderr, blob );
|
||||
kbx_release_blob ( blob );
|
||||
}
|
||||
} while ( !rc );
|
||||
|
||||
fclose (fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_search_by_uid ( const char *filename, FILE *a,
|
||||
int (*cmpfnc)(const byte*,size_t,void*), void *cmpdata,
|
||||
KBXBLOB *r_blob )
|
||||
{
|
||||
KBXBLOB blob;
|
||||
int rc;
|
||||
|
||||
*r_blob = NULL;
|
||||
rc = kbx_read_blob ( &blob, a );
|
||||
if ( rc && rc != -1 ) {
|
||||
log_error (_("file `%s': error reading blob\n"), filename );
|
||||
}
|
||||
else if ( !rc ) {
|
||||
rc = kbx_blob_has_uid ( blob, cmpfnc, cmpdata );
|
||||
}
|
||||
else
|
||||
rc = GPGERR_GENERAL; /* eof */
|
||||
|
||||
if ( !rc ) {
|
||||
*r_blob = blob;
|
||||
}
|
||||
else {
|
||||
kbx_release_blob ( blob );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
substr_compare ( const byte *buf, size_t buflen, void *opaque )
|
||||
{
|
||||
return !!memistr ( buf, buflen, opaque );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
kbxfile_search_by_uid ( const char *filename, const char *name )
|
||||
{
|
||||
FILE *fp;
|
||||
KBXBLOB blob;
|
||||
int rc;
|
||||
byte kbuf[8], *kbufptr;
|
||||
int kbuflen;
|
||||
|
||||
fp = fopen ( filename, "rb" );
|
||||
if( !fp ) {
|
||||
log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
while ( (rc=do_search_by_uid ( filename, fp,
|
||||
substr_compare, name, &blob )) == -1 )
|
||||
;
|
||||
if ( !rc ) {
|
||||
fputs ("FOUND:\n", stderr );
|
||||
kbx_dump_blob ( stderr, blob );
|
||||
kbx_release_blob ( blob );
|
||||
}
|
||||
} while ( !rc );
|
||||
|
||||
fclose ( fp );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
export_as_kbxfile(void)
|
||||
{
|
||||
|
||||
KBPOS kbpos;
|
||||
KBNODE keyblock = NULL;
|
||||
int rc=0;
|
||||
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
if( rc != -1 )
|
||||
log_error("enum_keyblocks(open) failed: %s\n", gpg_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &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( 2, &kbpos, &keyblock ); /* close */
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_print_kbxfile( const char *filename, FILE *a )
|
||||
{
|
||||
KBXBLOB blob;
|
||||
int rc;
|
||||
|
||||
rc = kbx_read_blob ( &blob, a );
|
||||
if ( rc && rc != -1 ) {
|
||||
log_error (_("file `%s': error reading blob\n"), filename );
|
||||
}
|
||||
else if ( ! rc )
|
||||
kbx_dump_blob ( stdout, blob );
|
||||
kbx_release_blob ( blob );
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
print_kbxfile( const char *filename )
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen ( filename, "rb" );
|
||||
if( !fp ) {
|
||||
log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ( !do_print_kbxfile( filename, fp ) )
|
||||
;
|
||||
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
|
75
g10/kbxio.c
Normal file
75
g10/kbxio.c
Normal file
@ -0,0 +1,75 @@
|
||||
/* kbxio.c - KBX I/O handling
|
||||
* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include "kbx.h"
|
||||
|
||||
|
||||
int
|
||||
kbx_read_blob ( KBXBLOB *r_blob, FILE *a )
|
||||
{
|
||||
char *image;
|
||||
size_t imagelen = 0;
|
||||
int c1, c2, c3, c4;
|
||||
int rc;
|
||||
|
||||
*r_blob = NULL;
|
||||
if ( (c1 = getc ( a )) == EOF
|
||||
|| (c2 = getc ( a )) == EOF
|
||||
|| (c3 = getc ( a )) == EOF
|
||||
|| (c4 = getc ( a )) == EOF ) {
|
||||
if ( c1 == EOF && !ferror ( a ) )
|
||||
return -1;
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4;
|
||||
if ( imagelen > 500000 ) { /* sanity check:blob too large */
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
else if ( imagelen < 4 ) { /* blobtoo short */
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
image = gcry_malloc ( imagelen );
|
||||
if ( !image ) {
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
|
||||
image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4;
|
||||
if ( fread ( image+4, imagelen-4, 1, a ) != 1 ) {
|
||||
gcry_free ( image );
|
||||
return GPGERR_GENERAL;
|
||||
}
|
||||
|
||||
rc = kbx_new_blob ( r_blob, image, imagelen );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
442
g10/kbxutil.c
Normal file
442
g10/kbxutil.c
Normal file
@ -0,0 +1,442 @@
|
||||
/* gpg.c - The GnuPG utility (main for gpg)
|
||||
* Copyright (C) 1998, 1999, 2000 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 "packet.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "keydb.h"
|
||||
#include "filter.h"
|
||||
#include "ttyio.h"
|
||||
#include "i18n.h"
|
||||
#include "gnupg-defs.h"
|
||||
#include "kbx.h"
|
||||
|
||||
|
||||
enum cmd_and_opt_values { aNull = 0,
|
||||
oArmor = 'a',
|
||||
aDetachedSign = 'b',
|
||||
aSym = 'c',
|
||||
aDecrypt = 'd',
|
||||
aEncr = 'e',
|
||||
oInteractive = 'i',
|
||||
oKOption = 'k',
|
||||
oDryRun = 'n',
|
||||
oOutput = 'o',
|
||||
oQuiet = 'q',
|
||||
oRecipient = 'r',
|
||||
aSign = 's',
|
||||
oTextmodeShort= 't',
|
||||
oUser = 'u',
|
||||
oVerbose = 'v',
|
||||
oCompress = 'z',
|
||||
oNotation = 'N',
|
||||
oBatch = 500,
|
||||
aClearsign,
|
||||
aStore,
|
||||
aKeygen,
|
||||
aSignEncr,
|
||||
aSignKey,
|
||||
aLSignKey,
|
||||
aListPackets,
|
||||
aEditKey,
|
||||
aDeleteKey,
|
||||
aDeleteSecretKey,
|
||||
aKMode,
|
||||
aKModeC,
|
||||
aImport,
|
||||
aFastImport,
|
||||
aVerify,
|
||||
aListKeys,
|
||||
aListSigs,
|
||||
aListSecretKeys,
|
||||
aSendKeys,
|
||||
aRecvKeys,
|
||||
aExport,
|
||||
aExportAll,
|
||||
aExportSecret,
|
||||
aCheckKeys,
|
||||
aGenRevoke,
|
||||
aPrimegen,
|
||||
aPrintMD,
|
||||
aPrintHMAC,
|
||||
aPrintMDs,
|
||||
aCheckTrustDB,
|
||||
aUpdateTrustDB,
|
||||
aFixTrustDB,
|
||||
aListTrustDB,
|
||||
aListTrustPath,
|
||||
aExportOwnerTrust,
|
||||
aImportOwnerTrust,
|
||||
aDeArmor,
|
||||
aEnArmor,
|
||||
aGenRandom,
|
||||
|
||||
oTextmode,
|
||||
oFingerprint,
|
||||
oWithFingerprint,
|
||||
oAnswerYes,
|
||||
oAnswerNo,
|
||||
oKeyring,
|
||||
oSecretKeyring,
|
||||
oDefaultKey,
|
||||
oDefRecipient,
|
||||
oDefRecipientSelf,
|
||||
oNoDefRecipient,
|
||||
oOptions,
|
||||
oDebug,
|
||||
oDebugAll,
|
||||
oStatusFD,
|
||||
oNoComment,
|
||||
oNoVersion,
|
||||
oEmitVersion,
|
||||
oCompletesNeeded,
|
||||
oMarginalsNeeded,
|
||||
oMaxCertDepth,
|
||||
oLoadExtension,
|
||||
oRFC1991,
|
||||
oOpenPGP,
|
||||
oCipherAlgo,
|
||||
oDigestAlgo,
|
||||
oCompressAlgo,
|
||||
oPasswdFD,
|
||||
oNoVerbose,
|
||||
oTrustDBName,
|
||||
oNoSecmemWarn,
|
||||
oNoArmor,
|
||||
oNoDefKeyring,
|
||||
oNoGreeting,
|
||||
oNoTTY,
|
||||
oNoOptions,
|
||||
oNoBatch,
|
||||
oHomedir,
|
||||
oWithColons,
|
||||
oWithKeyData,
|
||||
oSkipVerify,
|
||||
oCompressKeys,
|
||||
oCompressSigs,
|
||||
oAlwaysTrust,
|
||||
oEmuChecksumBug,
|
||||
oRunAsShmCP,
|
||||
oSetFilename,
|
||||
oSetPolicyURL,
|
||||
oUseEmbeddedFilename,
|
||||
oComment,
|
||||
oDefaultComment,
|
||||
oThrowKeyid,
|
||||
oForceV3Sigs,
|
||||
oForceMDC,
|
||||
oS2KMode,
|
||||
oS2KDigest,
|
||||
oS2KCipher,
|
||||
oCharset,
|
||||
oNotDashEscaped,
|
||||
oEscapeFrom,
|
||||
oLockOnce,
|
||||
oLockMultiple,
|
||||
oKeyServer,
|
||||
oEncryptTo,
|
||||
oNoEncryptTo,
|
||||
oLoggerFD,
|
||||
oUtf8Strings,
|
||||
oNoUtf8Strings,
|
||||
oDisableCipherAlgo,
|
||||
oDisablePubkeyAlgo,
|
||||
oAllowNonSelfsignedUID,
|
||||
oNoLiteral,
|
||||
oSetFilesize,
|
||||
oEntropyDLLName,
|
||||
|
||||
aFindByFpr,
|
||||
aFindByKid,
|
||||
aFindByUid,
|
||||
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, "@" },
|
||||
{ oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
|
||||
{ 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") },
|
||||
{ oOptions, "options" , 2, N_("read options from file")},
|
||||
|
||||
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
|
||||
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
|
||||
|
||||
|
||||
{0} };
|
||||
|
||||
|
||||
|
||||
int gpg_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 <gnupg-bugs@gnu.org>.\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 KBX 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);
|
||||
gpg_exit ( 1 );
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
ARGPARSE_ARGS pargs;
|
||||
enum cmd_and_opt_values cmd = 0;
|
||||
|
||||
set_strusage( my_strusage );
|
||||
log_set_name("kbxutil");
|
||||
/* 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.0a" ) ) {
|
||||
log_fatal(_("libgcrypt is too old (need %s, have %s)\n"),
|
||||
VERSION, gcry_check_version(NULL) );
|
||||
}
|
||||
|
||||
create_dotlock(NULL); /* register locking cleanup */
|
||||
i18n_init();
|
||||
|
||||
|
||||
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) )
|
||||
gpg_exit(2);
|
||||
|
||||
if ( !cmd ) { /* default is to list a KBX file */
|
||||
if( !argc ) {
|
||||
print_kbxfile( NULL );
|
||||
}
|
||||
else {
|
||||
for ( ; argc; argc--, argv++ ) {
|
||||
print_kbxfile( *argv );
|
||||
}
|
||||
}
|
||||
}
|
||||
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] );
|
||||
}
|
||||
else
|
||||
log_error ("unsupported action\n");
|
||||
|
||||
gpg_exit(0);
|
||||
return 8; /*NEVER REACHED*/
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gpg_exit( 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 :
|
||||
gpg_errors_seen? 1 : 0;
|
||||
exit(rc );
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user