2000-03-13 18:19:12 +00:00
|
|
|
/* kbxfile.c - KBX file 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
/****************
|
|
|
|
* We will change the whole system to use only KBX. This file here
|
2000-03-24 10:19:50 +00:00
|
|
|
* will implement the methods needed to operate on plain KBXfiles.
|
2000-03-13 18:19:12 +00:00
|
|
|
* Most stuff from getkey and ringedit will be replaced by stuff here.
|
2000-05-25 16:28:04 +00:00
|
|
|
* To make things even more easier we will only allow one updateable kbxfile
|
2000-03-13 18:19:12 +00:00
|
|
|
* and optionally some read-only files.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <gcrypt.h>
|
|
|
|
|
|
|
|
#include "kbx.h"
|
2000-05-25 16:28:04 +00:00
|
|
|
#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( 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 );
|
|
|
|
}
|
2000-03-13 18:19:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
int
|
2000-05-25 16:28:04 +00:00
|
|
|
kbxfile_search_by_uid ( const char *filename, const char *name )
|
2000-03-13 18:19:12 +00:00
|
|
|
{
|
2000-05-25 16:28:04 +00:00
|
|
|
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 );
|
2000-03-13 18:19:12 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2000-05-25 16:28:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
export_as_kbxfile(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
KBPOS kbpos;
|
|
|
|
KBNODE keyblock = NULL;
|
|
|
|
int rc=0;
|
|
|
|
|
2000-10-10 12:58:43 +00:00
|
|
|
rc = enum_keyblocks_begin( &kbpos, 0 );
|
2000-05-25 16:28:04 +00:00
|
|
|
if( rc ) {
|
|
|
|
if( rc != -1 )
|
|
|
|
log_error("enum_keyblocks(open) failed: %s\n", gpg_errstr(rc) );
|
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
|
2000-10-10 12:58:43 +00:00
|
|
|
while( !(rc = enum_keyblocks_next( kbpos, 1, &keyblock )) ) {
|
2000-05-25 16:28:04 +00:00
|
|
|
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:
|
2000-10-10 12:58:43 +00:00
|
|
|
enum_keyblocks_end( kbpos );
|
2000-05-25 16:28:04 +00:00
|
|
|
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) );
|
2000-07-14 17:34:53 +00:00
|
|
|
return;
|
2000-05-25 16:28:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
while ( !do_print_kbxfile( filename, fp ) )
|
|
|
|
;
|
|
|
|
|
|
|
|
fclose (fp);
|
|
|
|
}
|
|
|
|
|