mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02: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>
|
</indexterm>
|
||||||
<function>gcry_md_open</function> creates the context required for
|
<function>gcry_md_open</function> creates the context required for
|
||||||
the message digest functions. The hash algorithm may optionally be
|
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
|
<function>gcry_md_close</function> releases all resources associated
|
||||||
with the context.
|
with the context.
|
||||||
<function>gcry_md_enable</function> may be used to enable hash
|
<function>gcry_md_enable</function> may be used to enable hash
|
||||||
@ -149,6 +152,7 @@
|
|||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>gcry_md_ctl</refname>
|
<refname>gcry_md_ctl</refname>
|
||||||
<refname>gcry_md_final</refname>
|
<refname>gcry_md_final</refname>
|
||||||
|
<refname>gcry_md_setkey</refname>
|
||||||
<refpurpose>perform special operations on a digest context</refpurpose>
|
<refpurpose>perform special operations on a digest context</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
@ -179,9 +183,18 @@
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Currently defined values for <parameter>cmd</> are:
|
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)</>
|
<function>gcry_md_final(a)</>
|
||||||
</para>
|
</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>
|
</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>
|
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
|
* 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
|
needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la ../jnlib/libjnlib.la ../util/libutil.la
|
||||||
|
|
||||||
#noinst_PROGRAMS = gpgd
|
#noinst_PROGRAMS = gpgd
|
||||||
bin_PROGRAMS = gpg
|
bin_PROGRAMS = gpg kbxutil
|
||||||
|
|
||||||
common_source = \
|
common_source = \
|
||||||
build-packet.c \
|
build-packet.c \
|
||||||
@ -26,6 +26,7 @@ common_source = \
|
|||||||
kbnode.c \
|
kbnode.c \
|
||||||
kbx.h \
|
kbx.h \
|
||||||
kbxblob.c \
|
kbxblob.c \
|
||||||
|
kbxio.c \
|
||||||
kbxfile.c \
|
kbxfile.c \
|
||||||
main.h \
|
main.h \
|
||||||
mainproc.c \
|
mainproc.c \
|
||||||
@ -73,6 +74,11 @@ gpg_SOURCES = gpg.c \
|
|||||||
dearmor.c \
|
dearmor.c \
|
||||||
keygen.c
|
keygen.c
|
||||||
|
|
||||||
|
# fixme: remove unused sources from kbxutil
|
||||||
|
kbxutil_SOURCES = kbxutil.c \
|
||||||
|
$(common_source)
|
||||||
|
|
||||||
|
|
||||||
#gpgd_SOURCES = gpgd.c \
|
#gpgd_SOURCES = gpgd.c \
|
||||||
# ks-proto.h \
|
# ks-proto.h \
|
||||||
# ks-proto.c \
|
# ks-proto.c \
|
||||||
|
@ -196,7 +196,8 @@ static int
|
|||||||
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
|
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
|
||||||
{
|
{
|
||||||
write_header(out, ctb, uid->len);
|
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 ) )
|
if( iobuf_write( out, uid->name, uid->len ) )
|
||||||
return GPGERR_WRITE_FILE;
|
return GPGERR_WRITE_FILE;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1461,9 +1461,11 @@ main( int argc, char **argv )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case aFixTrustDB:
|
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("A workaround is to use \"--export-ownertrust\", remove\n");
|
||||||
log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
|
log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
|
||||||
|
#warning removed the next line
|
||||||
|
export_as_kbxfile();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aListTrustPath:
|
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.
|
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
|
21
g10/kbx.h
21
g10/kbx.h
@ -23,10 +23,29 @@
|
|||||||
|
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
|
||||||
|
/*-- kbxblob.c */
|
||||||
|
struct kbxblob;
|
||||||
typedef struct kbxblob *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 );
|
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*/
|
#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
|
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)
|
b16 MD5 checksum (useful for KS syncronisation)
|
||||||
*
|
*
|
||||||
@ -136,20 +136,31 @@ struct keyid_list {
|
|||||||
byte kid[8];
|
byte kid[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fixup_list {
|
||||||
|
struct fixup_list *next;
|
||||||
|
u32 off;
|
||||||
|
u32 val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct kbxblob {
|
struct kbxblob {
|
||||||
|
byte *blob;
|
||||||
|
size_t bloblen;
|
||||||
|
|
||||||
|
/* stuff used only by kbx_create_blob */
|
||||||
int nkeys;
|
int nkeys;
|
||||||
struct kbxblob_key *keys;
|
struct kbxblob_key *keys;
|
||||||
int nuids;
|
int nuids;
|
||||||
struct kbxblob_uid *uids;
|
struct kbxblob_uid *uids;
|
||||||
int nsigs;
|
int nsigs;
|
||||||
u32 *sigs;
|
u32 *sigs;
|
||||||
|
struct fixup_list *fixups;
|
||||||
|
|
||||||
struct keyid_list *temp_kids;
|
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
|
/* Note: this functions are only used for temportay iobufs and therefore
|
||||||
* they can't fail */
|
* 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
|
* offset yet. This is only used for v3 keyIDs. Function returns an index
|
||||||
* value for later fixupd; this must be a non-zero value
|
* 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
|
if ( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||||
PKT_public_key *pk = node->pkt->pkt.public_key;
|
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*/
|
if ( fprlen != 20 ) { /*v3 fpr - shift right and fill with zeroes*/
|
||||||
assert( fprlen == 16 );
|
assert( fprlen == 16 );
|
||||||
memmove( blob->keys[n].fpr+4, blob->keys[n].fpr, 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 */
|
put32 ( a, 0 ); /* length of the keyblock, needs fixup */
|
||||||
|
|
||||||
put16 ( a, blob->nkeys );
|
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++ ) {
|
for ( i=0; i < blob->nkeys; i++ ) {
|
||||||
putn ( a, blob->keys[i].fpr, 20 );
|
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 */
|
put32 ( a, 0 ); /* offset to keyid, fixed up later */
|
||||||
put16 ( a, blob->keys[i].flags );
|
put16 ( a, blob->keys[i].flags );
|
||||||
put16 ( a, 0 ); /* reserved */
|
put16 ( a, 0 ); /* reserved */
|
||||||
@ -358,7 +352,7 @@ create_blob_header( KBXBLOB blob )
|
|||||||
put16 ( a, blob->nuids );
|
put16 ( a, blob->nuids );
|
||||||
put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
|
put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
|
||||||
for ( i=0; i < blob->nuids; i++ ) {
|
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, 0 ); /* offset to userid, fixed up later */
|
||||||
put32 ( a, blob->uids[i].len );
|
put32 ( a, blob->uids[i].len );
|
||||||
put16 ( a, blob->uids[i].flags );
|
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
|
* not part of the fingerprint. While we are doing that, we fixup all
|
||||||
* the keyID offsets */
|
* the keyID offsets */
|
||||||
for ( i=0; i < blob->nkeys; i++ ) {
|
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 */
|
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 );
|
put_stored_kid ( blob, blob->keys[i].off_kid );
|
||||||
}
|
}
|
||||||
else { /* the better v4 key IDs - just store an offset 8 bytes back */
|
else { /* the better v4 key IDs - just store an offset 8 bytes back */
|
||||||
put32at ( a, blob->keys[i].off_kid_addr-8,
|
fl->val = blob->keys[i].off_kid_addr-8;
|
||||||
blob->keys[i].off_kid_addr );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,9 +403,17 @@ create_blob_keyblock( KBXBLOB blob, KBNODE keyblock )
|
|||||||
IOBUF a = blob->buf;
|
IOBUF a = blob->buf;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
int rc;
|
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 );
|
rc = build_packet ( a, node->pkt );
|
||||||
if ( rc ) {
|
if ( rc ) {
|
||||||
gpg_log_error("build_packet(%d) for kbxblob failed: %s\n",
|
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;
|
PKT_user_id *u = node->pkt->pkt.user_id;
|
||||||
/* build_packet has set the offset of the name into u ;
|
/* build_packet has set the offset of the name into u ;
|
||||||
* now we can do the fixup */
|
* now we can do the fixup */
|
||||||
put32at ( a, u->stored_at, blob->uids[nsig].off_addr );
|
struct fixup_list *fl = gcry_xcalloc(1, sizeof *fl );
|
||||||
nsig++;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,10 +455,13 @@ create_blob_finish( KBXBLOB blob )
|
|||||||
{
|
{
|
||||||
IOBUF a = blob->buf;
|
IOBUF a = blob->buf;
|
||||||
byte *p;
|
byte *p;
|
||||||
|
char *pp;
|
||||||
|
int i;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
/* write a placeholder for the checksum */
|
/* 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 */
|
/* get the memory area */
|
||||||
iobuf_flush_temp ( a );
|
iobuf_flush_temp ( a );
|
||||||
p = iobuf_get_temp_buffer ( a );
|
p = iobuf_get_temp_buffer ( a );
|
||||||
@ -449,23 +469,48 @@ create_blob_finish( KBXBLOB blob )
|
|||||||
assert( n >= 20 );
|
assert( n >= 20 );
|
||||||
|
|
||||||
/* fixup the length */
|
/* 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 */
|
/* calculate and store the MD5 checksum */
|
||||||
gcry_md_hash_buffer( GCRY_MD_MD5, p + n - 16, p, n - 16 );
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
|
kbx_create_blob ( KBXBLOB *r_blob, KBNODE keyblock )
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
KBXBLOB blob;
|
KBXBLOB blob;
|
||||||
|
|
||||||
*retkbx = NULL;
|
*r_blob = NULL;
|
||||||
blob = gcry_calloc (1, sizeof *blob );
|
blob = gcry_calloc (1, sizeof *blob );
|
||||||
if( !blob )
|
if( !blob )
|
||||||
return GCRYERR_NO_MEM;
|
return GCRYERR_NO_MEM;
|
||||||
@ -484,9 +529,9 @@ kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blob->keys = gcry_calloc ( blob->nkeys, sizeof ( blob->keys ) );
|
blob->keys = gcry_calloc ( blob->nkeys, sizeof ( *blob->keys ) );
|
||||||
blob->uids = gcry_calloc ( blob->nuids, sizeof ( blob->uids ) );
|
blob->uids = gcry_calloc ( blob->nuids, sizeof ( *blob->uids ) );
|
||||||
blob->sigs = gcry_calloc ( blob->nsigs, sizeof ( blob->sigs ) );
|
blob->sigs = gcry_calloc ( blob->nsigs, sizeof ( *blob->sigs ) );
|
||||||
if ( !blob->keys || !blob->uids || !blob->sigs ) {
|
if ( !blob->keys || !blob->uids || !blob->sigs ) {
|
||||||
rc = GCRYERR_NO_MEM;
|
rc = GCRYERR_NO_MEM;
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -516,17 +561,44 @@ kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
|
|||||||
if( rc )
|
if( rc )
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
*retkbx = blob;
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
release_kid_list( blob->temp_kids );
|
release_kid_list( blob->temp_kids );
|
||||||
blob->temp_kids = NULL;
|
blob->temp_kids = NULL;
|
||||||
if ( rc ) {
|
if ( rc ) {
|
||||||
kbx_release_blob ( blob );
|
kbx_release_blob ( blob );
|
||||||
|
*r_blob = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*r_blob = blob;
|
||||||
}
|
}
|
||||||
return rc;
|
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
|
void
|
||||||
kbx_release_blob ( KBXBLOB blob )
|
kbx_release_blob ( KBXBLOB blob )
|
||||||
{
|
{
|
||||||
@ -537,6 +609,9 @@ kbx_release_blob ( KBXBLOB blob )
|
|||||||
gcry_free( blob->keys );
|
gcry_free( blob->keys );
|
||||||
gcry_free( blob->uids );
|
gcry_free( blob->uids );
|
||||||
gcry_free( blob->sigs );
|
gcry_free( blob->sigs );
|
||||||
|
|
||||||
|
gcry_free ( blob->blob );
|
||||||
|
|
||||||
gcry_free( blob );
|
gcry_free( blob );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,17 +631,21 @@ get16( const byte *buffer )
|
|||||||
{
|
{
|
||||||
ulong a;
|
ulong a;
|
||||||
a = *buffer << 8;
|
a = *buffer << 8;
|
||||||
a |= buffer[0];
|
a |= buffer[1];
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
kbx_dump_blob ( FILE *fp, const byte* buffer, size_t length )
|
kbx_dump_blob ( FILE *fp, KBXBLOB blob )
|
||||||
{
|
{
|
||||||
#if 0
|
const byte *buffer = blob->blob;
|
||||||
ulong n;
|
size_t length = blob->bloblen;
|
||||||
|
ulong n, nkeys, keyinfolen;
|
||||||
|
ulong nuids, uidinfolen;
|
||||||
|
ulong nsigs, siginfolen;
|
||||||
ulong keyblock_off, keyblock_len;
|
ulong keyblock_off, keyblock_len;
|
||||||
|
const byte *p;
|
||||||
|
|
||||||
if( length < 40 ) {
|
if( length < 40 ) {
|
||||||
fprintf( fp, "blob too short\n");
|
fprintf( fp, "blob too short\n");
|
||||||
@ -579,8 +658,8 @@ kbx_dump_blob ( FILE *fp, const byte* buffer, size_t length )
|
|||||||
else
|
else
|
||||||
length = n; /* ignore the rest */
|
length = n; /* ignore the rest */
|
||||||
fprintf( fp, "Length: %lu\n", n );
|
fprintf( fp, "Length: %lu\n", n );
|
||||||
fprintf( fp, "Type: %d\n", buffer[4] ),
|
fprintf( fp, "Type: %d\n", buffer[4] );
|
||||||
fprintf( fp, "Version: %d\n", buffer[5] ),
|
fprintf( fp, "Version: %d\n", buffer[5] );
|
||||||
if( buffer[4] != 2 ) {
|
if( buffer[4] != 2 ) {
|
||||||
fprintf( fp, "can't dump this blob type\n" );
|
fprintf( fp, "can't dump this blob type\n" );
|
||||||
return 0;
|
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-Offset: %lu\n", keyblock_off );
|
||||||
fprintf( fp, "Keyblock-Length: %lu\n", keyblock_len );
|
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
|
* We will change the whole system to use only KBX. This file here
|
||||||
* will implement the methods needed to operate on plain KBXfiles.
|
* will implement the methods needed to operate on plain KBXfiles.
|
||||||
* Most stuff from getkey and ringedit will be replaced by stuff here.
|
* 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.
|
* and optionally some read-only files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -35,11 +35,298 @@
|
|||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
|
|
||||||
#include "kbx.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
|
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;
|
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