aboutsummaryrefslogtreecommitdiffstats
path: root/g10/kbxblob.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/kbxblob.c')
-rw-r--r--g10/kbxblob.c895
1 files changed, 0 insertions, 895 deletions
diff --git a/g10/kbxblob.c b/g10/kbxblob.c
deleted file mode 100644
index 01d0dfe10..000000000
--- a/g10/kbxblob.c
+++ /dev/null
@@ -1,895 +0,0 @@
-/* kbxblob.c - KBX Blob 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
- */
-
-
-/* The keybox data formats
-
-The KeyBox uses an augmented OpenPGP key format. This makes random
-access to a keyblock easier and also gives the opportunity to store
-additional information (e.g. the fingerprint) along with the key.
-All integers are stored in network byte order, offsets are counted from
-the beginning of the Blob.
-
-The first record of a plain KBX file has a special format:
-
- u32 length of the first record
- byte Blob type (1)
- byte version number (1)
- byte reserved
- byte reserved
- u32 magic 'KBXf'
- byte marginals used for validity calculation of this file
- byte completes ditto.
- byte cert_depth ditto.
-
-The standard KBX Blob looks like this:
-
- u32 length of this blob (including these 4 bytes)
- byte Blob type (2)
- byte version number of this blob type (1)
- u16 Blob flags
- bit 0 = contains secret key material
-
- u32 offset to the OpenPGP keyblock
- u32 length of the keyblock
- u16 number of keys (at least 1!)
- u16 size of additional key information
- n times:
- b20 The keys fingerprint
- (fingerprints are always 20 bytes, MD5 left padded with zeroes)
- u32 offset to the n-th key's keyID (a keyID is always 8 byte)
- u16 special key flags
- bit 0 =
- u16 reserved
- u16 number of user IDs
- u16 size of additional user ID information
- n times:
- u32 offset to the n-th user ID
- u32 length of this user ID.
- u16 special user ID flags.
- bit 0 =
- byte validity
- byte reserved
- u16 number of signatures
- u16 size of signature information (4)
- u32 expiration time of signature with some special values:
- 0x00000000 = not checked
- 0x00000001 = missing key
- 0x00000002 = bad signature
- 0x10000000 = valid and expires at some date in 1978.
- 0xffffffff = valid and does not expire
- u8 assigned ownertrust
- u8 all_validity
- u16 reserved
- u32 recheck_after
- u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
- u32 Blob created at
- u32 size of reserved space (not including this field)
- reserved space
-
- Here we might want to put other data
-
- Here comes the keyblock
-
- maybe we put a signature here later.
-
- b16 MD5 checksum (useful for KS syncronisation)
- *
- */
-
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <gcrypt.h>
-
-#include "iobuf.h"
-#include "util.h"
-#include "kbx.h"
-
-/* special values of the signature status */
-#define SF_NONE(a) ( !(a) )
-#define SF_NOKEY(a) ((a) & (1<<0))
-#define SF_BAD(a) ((a) & (1<<1))
-#define SF_VALID(a) ((a) & (1<<29))
-
-#if MAX_FINGERPRINT_LEN < 20
- #error fingerprints are 20 bytes
-#endif
-
-struct kbxblob_key {
- char fpr[20];
- u32 off_kid;
- ulong off_kid_addr;
- u16 flags;
-};
-struct kbxblob_uid {
- ulong off_addr;
- u32 len;
- u16 flags;
- byte validity;
-};
-
-struct keyid_list {
- struct keyid_list *next;
- int seqno;
- byte kid[8];
-};
-
-struct fixup_list {
- struct fixup_list *next;
- u32 off;
- u32 val;
-};
-
-
-struct 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 temporarly stored here */
-};
-
-void kbx_release_blob ( KBXBLOB blob );
-
-/* Note: this functions are only used for temportay iobufs and therefore
- * they can't fail */
-static void
-put8 ( IOBUF out, byte a )
-{
- iobuf_put ( out, a );
-}
-
-static void
-put16 ( IOBUF out, u16 a )
-{
- iobuf_put ( out, a>>8 );
- iobuf_put ( out, a );
-}
-
-static void
-put32 ( IOBUF out, u32 a )
-{
- iobuf_put (out, a>> 24);
- iobuf_put (out, a>> 16);
- iobuf_put (out, a>> 8);
- iobuf_put (out, a );
-}
-
-static void
-putn ( IOBUF out, const byte *p, size_t n )
-{
- for ( ; n; p++, n-- ) {
- iobuf_put ( out, *p );
- }
-}
-
-
-/****************
- * 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
- */
-static int
-temp_store_kid ( KBXBLOB blob, PKT_public_key *pk )
-{
- struct keyid_list *k, *r;
-
- k = gcry_xmalloc ( sizeof *k );
- k->kid[0] = pk->keyid[0] >> 24 ;
- k->kid[1] = pk->keyid[0] >> 16 ;
- k->kid[2] = pk->keyid[0] >> 8 ;
- k->kid[3] = pk->keyid[0] ;
- k->kid[4] = pk->keyid[0] >> 24 ;
- k->kid[5] = pk->keyid[0] >> 16 ;
- k->kid[6] = pk->keyid[0] >> 8 ;
- k->kid[7] = pk->keyid[0] ;
- k->seqno = 0;
- k->next = blob->temp_kids;
- blob->temp_kids = k;
- for ( r=k; r; r = r->next ) {
- k->seqno++;
- }
-
- return k->seqno;
-}
-
-static void
-put_stored_kid( KBXBLOB blob, int seqno )
-{
- struct keyid_list *r;
-
- for ( r = blob->temp_kids; r; r = r->next ) {
- if( r->seqno == seqno ) {
- putn ( blob->buf, r->kid, 8 );
- return;
- }
- }
- BUG();
-}
-
-static void
-release_kid_list ( struct keyid_list *kl )
-{
- struct keyid_list *r, *r2;
-
- for ( r = kl; r; r = r2 ) {
- r2 = r->next;
- gcry_free( r );
- }
-}
-
-
-static int
-create_key_part( KBXBLOB blob, KBNODE keyblock )
-{
- KBNODE node;
- size_t fprlen;
- int n;
-
- for ( n=0, node = keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- PKT_public_key *pk = node->pkt->pkt.public_key;
- char tmp[20];
-
- fingerprint_from_pk( pk, tmp , &fprlen );
- memcpy(blob->keys[n].fpr,tmp,20);
- if ( fprlen != 20 ) { /*v3 fpr - shift right and fill with zeroes*/
- assert( fprlen == 16 );
- memmove( blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
- memset( blob->keys[n].fpr, 0, 4 );
- blob->keys[n].off_kid = temp_store_kid( blob, pk );
- }
- else {
- blob->keys[n].off_kid = 0; /* will be fixed up later */
- }
- blob->keys[n].flags = 0;
- n++;
- }
- else if ( node->pkt->pkttype == PKT_SECRET_KEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- BUG(); /* not yet implemented */
- }
- }
- assert( n == blob->nkeys );
- return 0;
-}
-
-static int
-create_uid_part( KBXBLOB blob, KBNODE keyblock )
-{
- KBNODE node;
- int n;
-
- for ( n=0, node = keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *u = node->pkt->pkt.user_id;
-
- blob->uids[n].len = u->len;
- blob->uids[n].flags = 0;
- blob->uids[n].validity = 0;
- n++;
- }
- }
- assert( n == blob->nuids );
- return 0;
-}
-
-static int
-create_sig_part( KBXBLOB blob, KBNODE keyblock )
-{
- KBNODE node;
- int n;
-
- for ( n=0, node = keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
-
- blob->sigs[n] = 0; /* FIXME: check the signature here */
- n++;
- }
- }
- assert( n == blob->nsigs );
- return 0;
-}
-
-
-static int
-create_blob_header( KBXBLOB blob )
-{
- IOBUF a = blob->buf;
- int i;
-
- put32 ( a, 0 ); /* blob length, needs fixup */
- put8 ( a, 2 ); /* blob type */
- put8 ( a, 1 ); /* blob type version */
- put16 ( a, 0 ); /* blob flags */
-
- put32 ( a, 0 ); /* offset to the keyblock, needs fixup */
- put32 ( a, 0 ); /* length of the keyblock, needs fixup */
-
- put16 ( a, blob->nkeys );
- 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_get_temp_length (a);
- put32 ( a, 0 ); /* offset to keyid, fixed up later */
- put16 ( a, blob->keys[i].flags );
- put16 ( a, 0 ); /* reserved */
- }
-
- put16 ( a, blob->nuids );
- put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
- for ( i=0; i < blob->nuids; i++ ) {
- blob->uids[i].off_addr = 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 );
- put8 ( a, 0 ); /* validity */
- put8 ( a, 0 ); /* reserved */
- }
-
- put16 ( a, blob->nsigs );
- put16 ( a, 4 ); /* size of sig info */
- for ( i=0; i < blob->nsigs; i++ ) {
- put32 ( a, blob->sigs[i] );
- }
-
- put8 ( a, 0 ); /* assigned ownertrust */
- put8 ( a, 0 ); /* validity of all user IDs */
- put16 ( a, 0 ); /* reserved */
- put32 ( a, 0 ); /* time of next recheck */
- put32 ( a, 0 ); /* newest timestamp (none) */
- put32 ( a, make_timestamp() ); /* creation time */
- put32 ( a, 0 ); /* size of reserved space */
- /* reserved space (which is currently of size 0) */
-
- /* We need to store the keyids for all v3 keys because those key IDs are
- * not part of the fingerprint. While we are doing that, we fixup all
- * the keyID offsets */
- for ( i=0; i < blob->nkeys; i++ ) {
- struct fixup_list *fl = 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 */
- 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 */
- fl->val = blob->keys[i].off_kid_addr-8;
- }
- }
-
-
- return 0;
-}
-
-static int
-create_blob_keyblock( KBXBLOB blob, KBNODE keyblock )
-{
- IOBUF a = blob->buf;
- KBNODE node;
- int rc;
- int n;
- u32 kbstart = iobuf_get_temp_length ( a );
-
- {
- 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",
- node->pkt->pkttype, gpg_errstr(rc) );
- return GPGERR_WRITE_FILE;
- }
- if ( node->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *u = node->pkt->pkt.user_id;
- /* build_packet has set the offset of the name into u ;
- * now we can do the fixup */
- struct fixup_list *fl = 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( 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;
-}
-
-static int
-create_blob_trailer( KBXBLOB blob )
-{
- IOBUF a = blob->buf;
- return 0;
-}
-
-static int
-create_blob_finish( KBXBLOB blob )
-{
- IOBUF a = blob->buf;
- byte *p;
- char *pp;
- int i;
- size_t n;
-
- /* write a placeholder for the checksum */
- for ( i = 0; i < 16; i++ )
- put32( a, 0 );
- /* get the memory area */
- iobuf_flush_temp ( a );
- p = iobuf_get_temp_buffer ( a );
- n = iobuf_get_temp_length ( a );
- assert( n >= 20 );
-
- /* fixup the length */
- {
- 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 *r_blob, KBNODE keyblock )
-{
- int rc = 0;
- KBNODE node;
- KBXBLOB blob;
-
- *r_blob = NULL;
- blob = gcry_xcalloc (1, sizeof *blob );
- if( !blob )
- return GCRYERR_NO_MEM;
-
- /* fixme: Do some sanity checks on the keyblock */
-
- /* count userids and keys so that we can allocate the arrays */
- for ( node = keyblock; node; node = node->next ) {
- switch ( node->pkt->pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- case PKT_PUBLIC_SUBKEY:
- case PKT_SECRET_SUBKEY: blob->nkeys++; break;
- case PKT_USER_ID: blob->nuids++; break;
- case PKT_SIGNATURE: blob->nsigs++; break;
- default: break;
- }
- }
- blob->keys = gcry_xcalloc ( blob->nkeys, sizeof ( *blob->keys ) );
- blob->uids = gcry_xcalloc ( blob->nuids, sizeof ( *blob->uids ) );
- blob->sigs = gcry_xcalloc ( blob->nsigs, sizeof ( *blob->sigs ) );
- if ( !blob->keys || !blob->uids || !blob->sigs ) {
- rc = GCRYERR_NO_MEM;
- goto leave;
- }
-
- rc = create_key_part ( blob, keyblock );
- if( rc )
- goto leave;
- rc = create_uid_part ( blob, keyblock );
- if( rc )
- goto leave;
- rc = create_sig_part ( blob, keyblock );
- if( rc )
- goto leave;
-
- blob->buf = iobuf_temp();
- rc = create_blob_header ( blob );
- if( rc )
- goto leave;
- rc = create_blob_keyblock ( blob, keyblock );
- if( rc )
- goto leave;
- rc = create_blob_trailer ( blob );
- if( rc )
- goto leave;
- rc = create_blob_finish ( blob );
- if( rc )
- goto leave;
-
-
- leave:
- release_kid_list( blob->temp_kids );
- blob->temp_kids = NULL;
- if ( rc ) {
- 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_xcalloc (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 )
-{
- if( !blob )
- return;
- if( blob->buf )
- iobuf_cancel( blob->buf );
- gcry_free( blob->keys );
- gcry_free( blob->uids );
- gcry_free( blob->sigs );
-
- gcry_free ( blob->blob );
-
- gcry_free( blob );
-}
-
-static ulong
-get32( const byte *buffer )
-{
- ulong a;
- a = *buffer << 24;
- a |= buffer[1] << 16;
- a |= buffer[2] << 8;
- a |= buffer[3];
- return a;
-}
-
-static ulong
-get16( const byte *buffer )
-{
- ulong a;
- a = *buffer << 8;
- a |= buffer[1];
- return a;
-}
-
-
-int
-kbx_dump_blob ( FILE *fp, KBXBLOB blob )
-{
- 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");
- return -1;
- }
- n = get32( buffer );
- if( n > length ) {
- fprintf( fp, "blob larger than length - output truncated\n");
- }
- else
- length = n; /* ignore the rest */
- fprintf( fp, "Length: %lu\n", n );
- 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;
- }
-
- n = get16( buffer + 6 );
- fprintf( fp, "Blob-Flags: %04lX\n", n );
- keyblock_off = get32( buffer + 8 );
- keyblock_len = get32( buffer + 12 );
- fprintf( fp, "Keyblock-Offset: %lu\n", keyblock_off );
- fprintf( fp, "Keyblock-Length: %lu\n", keyblock_len );
-
- 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;
-}
-
-