diff options
Diffstat (limited to 'kbx')
-rw-r--r-- | kbx/kbxutil.c | 42 | ||||
-rw-r--r-- | kbx/keybox-blob.c | 481 | ||||
-rw-r--r-- | kbx/keybox-defs.h | 11 | ||||
-rw-r--r-- | kbx/keybox-dump.c | 136 | ||||
-rw-r--r-- | kbx/keybox-file.c | 2 | ||||
-rw-r--r-- | kbx/keybox-init.c | 17 | ||||
-rw-r--r-- | kbx/keybox-openpgp.c | 2 | ||||
-rw-r--r-- | kbx/keybox-search.c | 171 | ||||
-rw-r--r-- | kbx/keybox-update.c | 62 | ||||
-rw-r--r-- | kbx/keybox.h | 28 |
10 files changed, 626 insertions, 326 deletions
diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 62e3dbe89..8b2b9000d 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -332,7 +332,8 @@ dump_fpr (const unsigned char *buffer, size_t len) static void dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) { - printf ("pub %02X%02X%02X%02X", + printf ("pub %2d %02X%02X%02X%02X", + info->primary.algo, info->primary.keyid[4], info->primary.keyid[5], info->primary.keyid[6], info->primary.keyid[7] ); dump_fpr (info->primary.fpr, info->primary.fprlen); @@ -344,7 +345,8 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) k = &info->subkeys; do { - printf ("sub %02X%02X%02X%02X", + printf ("sub %2d %02X%02X%02X%02X", + k->algo, k->keyid[4], k->keyid[5], k->keyid[6], k->keyid[7] ); dump_fpr (k->fpr, k->fprlen); @@ -369,13 +371,14 @@ dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) static void -import_openpgp (const char *filename) +import_openpgp (const char *filename, int dryrun) { gpg_error_t err; char *buffer; size_t buflen, nparsed; unsigned char *p; struct _keybox_openpgp_info info; + KEYBOXBLOB blob; buffer = read_file (filename, &buflen); if (!buffer) @@ -404,7 +407,31 @@ import_openpgp (const char *filename) } else { - dump_openpgp_key (&info, p); + if (dryrun) + dump_openpgp_key (&info, p); + else + { + err = _keybox_create_openpgp_blob (&blob, &info, p, nparsed, + NULL, 0); + if (err) + { + fflush (stdout); + log_error ("%s: failed to create OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + else + { + err = _keybox_write_blob (blob, stdout); + _keybox_release_blob (blob); + if (err) + { + fflush (stdout); + log_error ("%s: failed to write OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + } + } + _keybox_destroy_openpgp_info (&info); } p += nparsed; @@ -422,6 +449,7 @@ main( int argc, char **argv ) ARGPARSE_ARGS pargs; enum cmd_and_opt_values cmd = 0; unsigned long from = 0, to = ULONG_MAX; + int dry_run = 0; set_strusage( my_strusage ); gcry_control (GCRYCTL_DISABLE_SECMEM); @@ -479,6 +507,8 @@ main( int argc, char **argv ) case oFrom: from = pargs.r.ret_ulong; break; case oTo: to = pargs.r.ret_ulong; break; + case oDryRun: dry_run = 1; break; + default: pargs.err = 2; break; @@ -535,11 +565,11 @@ main( int argc, char **argv ) else if (cmd == aImportOpenPGP) { if (!argc) - import_openpgp ("-"); + import_openpgp ("-", dry_run); else { for (; argc; argc--, argv++) - import_openpgp (*argv); + import_openpgp (*argv, dry_run); } } #if 0 diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 998a77019..64935275e 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -17,93 +17,119 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +/* +* The keybox data format + + The KeyBox uses an augmented OpenPGP/X.509 key format. This makes + random access to a keyblock/certificate easier and also gives the + opportunity to store additional information (e.g. the fingerprint) + along with the key. All integers are stored in network byte order, + offsets are counted from the beginning of the Blob. + +** Overview of blob types + + | Byte 4 | Blob type | + |--------+--------------| + | 0 | Empty blob | + | 1 | First blob | + | 2 | OpenPGP blob | + | 3 | X.509 blob | + +** The First blob + + The first blob of a plain KBX file has a special format: + + - u32 Length of this blob + - byte Blob type (1) + - byte Version number (1) + - byte RFU + - byte RFU + - b4 Magic 'KBXf' + - u32 RFU + - u32 file_created_at + - u32 last_maintenance_run + - u32 RFU + - u32 RFU + +** The OpenPGP and X.509 blobs + + The OpenPGP and X.509 blobs are very similiar, things which are + X.509 specific are noted like [X.509: xxx] + + - u32 Length of this blob (including these 4 bytes) + - byte Blob type + 2 = OpenPGP + 3 = X509 + - byte Version number of this blob type + 1 = The only defined value + - u16 Blob flags + bit 0 = contains secret key material (not used) + bit 1 = ephemeral blob (e.g. used while quering external resources) + - u32 Offset to the OpenPGP keyblock or the X.509 DER encoded + certificate + - u32 The length of the keyblock or certificate + - u16 [NKEYS] Number of keys (at least 1!) [X509: always 1] + - u16 Size of the key information structure (at least 28). + - NKEYS times: + - b20 The fingerprint of the key. + 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) + or 0 if not known which is the case only for X.509. + - u16 Key flags + bit 0 = qualified signature (not yet implemented} + - u16 RFU + - bN Optional filler up to the specified length of this + structure. + - u16 Size of the serial number (may be zero) + - bN The serial number. N as giiven above. + - u16 Number of user IDs + - u16 [NUIDS] Size of user ID information structure + - NUIDS times: + + For X509, the first user ID is the Issuer, the second the + Subject and the others are subjectAltNames. For OpenPGP we only + store the information from UserID packets here. + + - u32 Blob offset to the n-th user ID + - u32 Length of this user ID. + - u16 User ID flags. + (not yet used) + - byte Validity + - byte RFU + + - u16 [NSIGS] Number of signatures + - u16 Size of signature information (4) + - NSIGS times: + - 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 [X509: not used] + - u8 All_Validity + OpenPGP: See ../g10/trustdb/TRUST_* [not yet used] + X509: Bit 4 set := key has been revoked. + Note that this value matches TRUST_FLAG_REVOKED + - u16 RFU + - u32 Recheck_after + - u32 Latest timestamp in the keyblock (useful for KS syncronsiation?) + - u32 Blob created at + - u32 [NRES] Size of reserved space (not including this field) + - bN Reserved space of size NRES for future use. + - bN Arbitrary space for example used to store data which is not + part of the keyblock or certificate. For example the v3 key + IDs go here. + - bN Space for the keyblock or certifciate. + - bN RFU + - b20 SHA-1 checksum (useful for KS syncronisation?) + Note, that KBX versions before GnuPG 2.1 used an MD5 + checksum. However it was only created but never checked. + Thus we do not expect problems if we switch to SHA-1. If + the checksum fails and the first 4 bytes are zero, we can + try again with MD5. SHA-1 has the advantage that it is + faster on CPUs with dedicated SHA-1 support. -/* The keybox data formats - -The KeyBox uses an augmented OpenPGP/X.509 key format. This makes -random access to a keyblock/certificate easier and also gives the -opportunity to store additional information (e.g. the fingerprint) -along with the key. All integers are stored in network byte order, -offsets are counted from the beginning of the Blob. - -The first record of a plain KBX file has a special format: - - u32 length of the first record - byte Blob type (1) - byte version number (1) - byte reserved - byte reserved - u32 magic 'KBXf' - u32 reserved - u32 file_created_at - u32 last_maintenance_run - u32 reserved - u32 reserved - -The OpenPGP and X.509 blob are very similiar, things which are -X.509 specific are noted like [X.509: xxx] - - u32 length of this blob (including these 4 bytes) - byte Blob type (2) [X509: 3] - byte version number of this blob type (1) - u16 Blob flags - bit 0 = contains secret key material - bit 1 = ephemeral blob (e.g. used while quering external resources) - - u32 offset to the OpenPGP keyblock or X509 DER encoded certificate - u32 and its length - u16 number of keys (at least 1!) [X509: always 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) - or 0 if not known which is the case only for X509. - u16 special key flags - bit 0 = qualified signature (not yet implemented} - u16 reserved - u16 size of serialnumber(may be zero) - n u16 (see above) bytes of serial number - 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 - [For X509, the first user ID is the Issuer, the second the Subject - and the others are subjectAltNames] - 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 [X509: not used] - u8 all_validity - OpenPGP: see ../g10/trustdb/TRUST_* [not yet used] - X509: Bit 4 set := key has been revoked. Note that this value - matches TRUST_FLAG_REVOKED - 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), we might also want to use - a mac here. - b4 reserved */ @@ -119,9 +145,6 @@ X.509 specific are noted like [X.509: xxx] #include "keybox-defs.h" #include <gcrypt.h> -#ifdef KEYBOX_WITH_OPENPGP -/* include stuff to parse the packets */ -#endif #ifdef KEYBOX_WITH_X509 #include <ksba.h> #endif @@ -156,6 +179,7 @@ struct keyboxblob_key { u16 flags; }; struct keyboxblob_uid { + u32 off; ulong off_addr; char *name; /* used only with x509 */ u32 len; @@ -237,7 +261,10 @@ put_membuf (struct membuf *mb, const void *buf, size_t len) } mb->buf = p; } - memcpy (mb->buf + mb->len, buf, len); + if (buf) + memcpy (mb->buf + mb->len, buf, len); + else + memset (mb->buf + mb->len, 0, len); mb->len += len; } @@ -287,6 +314,7 @@ put32 (struct membuf *mb, u32 a ) put_membuf (mb, tmp, 4); } + /* Store a value in the fixup list */ static void @@ -311,33 +339,24 @@ add_fixup (KEYBOXBLOB blob, u32 off, u32 val) -#ifdef KEYBOX_WITH_OPENPGP /* OpenPGP specific stuff */ -/* - We must store the keyid at some place because we can't calculate the - offset yet. This is only used for v3 keyIDs. Function returns an - index value for later fixup or -1 for out of core. The value must be - a non-zero value */ +/* We must store the keyid at some place because we can't calculate + the offset yet. This is only used for v3 keyIDs. Function returns + an index value for later fixup or -1 for out of core. The value + must be a non-zero value. */ static int -pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk) +pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo) { struct keyid_list *k, *r; k = xtrymalloc (sizeof *k); if (!k) return -1; - k->kid[0] = pk->keyid[0] >> 24 ; - k->kid[1] = pk->keyid[0] >> 16 ; - k->kid[2] = pk->keyid[0] >> 8 ; - k->kid[3] = pk->keyid[0] ; - k->kid[4] = pk->keyid[0] >> 24 ; - k->kid[5] = pk->keyid[0] >> 16 ; - k->kid[6] = pk->keyid[0] >> 8 ; - k->kid[7] = pk->keyid[0] ; + memcpy (k->kid, kinfo->keyid, 8); k->seqno = 0; k->next = blob->temp_kids; blob->temp_kids = k; @@ -347,124 +366,108 @@ pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk) return k->seqno; } -static int -pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock) + +/* Helper for pgp_create_key_part. */ +static gpg_error_t +pgp_create_key_part_single (KEYBOXBLOB blob, int n, + struct _keybox_openpgp_key_info *kinfo) { - KBNODE node; size_t fprlen; - int n; + int off; - for (n=0, node = keyblock; node; node = node->next) + fprlen = kinfo->fprlen; + if (fprlen > 20) + fprlen = 20; + memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen); + if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */ { - if ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - char tmp[20]; - - fingerprint_from_pk (pk, tmp , &fprlen); - memcpy (blob->keys[n].fpr, tmp, 20); - if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/ - { - assert (fprlen == 16); - memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16); - memset (blob->keys[n].fpr, 0, 4); - blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk); - } - else - { - blob->keys[n].off_kid = 0; /* will be fixed up later */ - } - blob->keys[n].flags = 0; - n++; - } - else if ( node->pkt->pkttype == PKT_SECRET_KEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - { - never_reached (); /* actually not yet implemented */ - } + memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen); + memset (blob->keys[n].fpr, 0, 20 - fprlen); + off = pgp_temp_store_kid (blob, kinfo); + if (off == -1) + return gpg_error_from_syserror (); + blob->keys[n].off_kid = off; } + else + blob->keys[n].off_kid = 0; /* Will be fixed up later */ + blob->keys[n].flags = 0; + return 0; +} + + +static gpg_error_t +pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info) +{ + gpg_error_t err; + int n = 0; + struct _keybox_openpgp_key_info *kinfo; + + err = pgp_create_key_part_single (blob, n++, &info->primary); + if (err) + return err; + if (info->nsubkeys) + for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next) + if ((err=pgp_create_key_part_single (blob, n++, kinfo))) + return err; + assert (n == blob->nkeys); return 0; } -static int -pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock) + +static void +pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info) { - KBNODE node; - int n; + int n = 0; + struct _keybox_openpgp_uid_info *u; - for (n=0, node = keyblock; node; node = node->next) + if (info->nuids) { - if (node->pkt->pkttype == PKT_USER_ID) + for (u = &info->uids; u; u = u->next) { - PKT_user_id *u = node->pkt->pkt.user_id; - + blob->uids[n].off = u->off; blob->uids[n].len = u->len; blob->uids[n].flags = 0; blob->uids[n].validity = 0; n++; - } + } } + assert (n == blob->nuids); - return 0; } -static int -pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock) + +static void +pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus) { - KBNODE node; int n; - for (n=0, node = keyblock; node; node = node->next) + for (n=0; n < blob->nsigs; n++) { - if (node->pkt->pkttype == PKT_SIGNATURE) - { - PKT_signature *sig = node->pkt->pkt.signature; - - blob->sigs[n] = 0; /* FIXME: check the signature here */ - n++; - } + blob->sigs[n] = sigstatus? sigstatus[n+1] : 0; } - assert( n == blob->nsigs ); - return 0; } + static int -pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock) +pgp_create_blob_keyblock (KEYBOXBLOB blob, + const unsigned char *image, size_t imagelen) { struct membuf *a = blob->buf; - KBNODE node; - int rc; int n; u32 kbstart = a->len; - add_fixup (blob, kbstart); + add_fixup (blob, 8, kbstart); - for (n = 0, node = keyblock; node; node = node->next) - { - rc = build_packet ( a, node->pkt ); - if ( rc ) { - gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n", - node->pkt->pkttype, gpg_errstr(rc) ); - return GPGERR_WRITE_FILE; - } - if ( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *u = node->pkt->pkt.user_id; - /* build_packet has set the offset of the name into u ; - * now we can do the fixup */ - add_fixup (blob, blob->uids[n].off_addr, u->stored_at); - n++; - } - } - assert (n == blob->nuids); + for (n = 0; n < blob->nuids; n++) + add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off); + + put_membuf (a, image, imagelen); - add_fixup (blob, a->len - kbstart); + add_fixup (blob, 12, a->len - kbstart); return 0; } -#endif /*KEYBOX_WITH_OPENPGP*/ #ifdef KEYBOX_WITH_X509 @@ -639,12 +642,10 @@ create_blob_finish (KEYBOXBLOB blob) struct membuf *a = blob->buf; unsigned char *p; unsigned char *pp; - int i; size_t n; - /* write a placeholder for the checksum */ - for (i = 0; i < 16; i++ ) - put32 (a, 0); /* Hmmm: why put32() ?? */ + /* Write a placeholder for the checksum */ + put_membuf (a, NULL, 20); /* get the memory area */ n = 0; /* (Just to avoid compiler warning.) */ @@ -672,8 +673,8 @@ create_blob_finish (KEYBOXBLOB blob) } } - /* calculate and store the MD5 checksum */ - gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16); + /* Compute and store the SHA-1 checksum. */ + gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20); pp = xtrymalloc (n); if ( !pp ) @@ -685,88 +686,86 @@ create_blob_finish (KEYBOXBLOB blob) return 0; } - -#ifdef KEYBOX_WITH_OPENPGP -int -_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral) + +gpg_error_t +_keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, + keybox_openpgp_info_t info, + const unsigned char *image, + size_t imagelen, + u32 *sigstatus, + int as_ephemeral) { - int rc = 0; - KBNODE node; + gpg_error_t err; KEYBOXBLOB blob; *r_blob = NULL; + + if (!info->nuids || !info->nsigs) + return gpg_error (GPG_ERR_BAD_PUBKEY); + + /* If we have a signature status vector, check that the number of + elements matches the actual number of signatures. */ + if (sigstatus && sigstatus[0] != info->nsigs) + return gpg_error (GPG_ERR_INTERNAL); + blob = xtrycalloc (1, sizeof *blob); if (!blob) return gpg_error_from_syserror (); - /* 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) + blob->nkeys = 1 + info->nsubkeys; + blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); + if (!blob->keys) { - 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; - } + err = gpg_error_from_syserror (); + goto leave; } - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); + blob->nuids = info->nuids; blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); + if (!blob->uids) + { + err = gpg_error_from_syserror (); + goto leave; + } + blob->nsigs = info->nsigs; blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) + if (!blob->sigs) { - rc = gpg_error (GPG_ERR_ENOMEM); + err = gpg_error_from_syserror (); goto leave; } - rc = pgp_create_key_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_uid_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_sig_part ( blob, keyblock ); - if (rc) + err = pgp_create_key_part (blob, info); + if (err) goto leave; + pgp_create_uid_part (blob, info); + pgp_create_sig_part (blob, sigstatus); init_membuf (&blob->bufbuf, 1024); blob->buf = &blob->bufbuf; - rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral); - if (rc) + err = create_blob_header (blob, BLOBTYPE_PGP, as_ephemeral); + if (err) goto leave; - rc = pgp_create_blob_keyblock (blob, keyblock); - if (rc) + err = pgp_create_blob_keyblock (blob, image, imagelen); + if (err) goto leave; - rc = create_blob_trailer (blob); - if (rc) + err = create_blob_trailer (blob); + if (err) goto leave; - rc = create_blob_finish ( blob ); - if (rc) + err = create_blob_finish (blob); + if (err) goto leave; - leave: release_kid_list (blob->temp_kids); blob->temp_kids = NULL; - if (rc) - { - keybox_release_blob (blob); - *r_blob = NULL; - } + if (err) + _keybox_release_blob (blob); else - { - *r_blob = blob; - } - return rc; + *r_blob = blob; + return err; } -#endif /*KEYBOX_WITH_OPENPGP*/ + #ifdef KEYBOX_WITH_X509 diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index ee48ca390..ad8e49d3f 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -111,6 +111,7 @@ struct keybox_handle { struct _keybox_openpgp_key_info { struct _keybox_openpgp_key_info *next; + int algo; unsigned char keyid[8]; int fprlen; /* Either 16 or 20 */ unsigned char fpr[20]; @@ -155,9 +156,12 @@ void _keybox_close_file (KEYBOX_HANDLE hd); /*-- keybox-blob.c --*/ -#ifdef KEYBOX_WITH_OPENPGP - /* fixme */ -#endif /*KEYBOX_WITH_OPENPGP*/ +gpg_error_t _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob, + keybox_openpgp_info_t info, + const unsigned char *image, + size_t imagelen, + u32 *sigstatus, + int as_ephemeral); #ifdef KEYBOX_WITH_X509 int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, unsigned char *sha1_digest, int as_ephemeral); @@ -182,7 +186,6 @@ void _keybox_destroy_openpgp_info (keybox_openpgp_info_t info); int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp); int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted); int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp); -int _keybox_write_header_blob (FILE *fp); /*-- keybox-search.c --*/ gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer, diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index c5f518e0f..c397f9c81 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -80,6 +80,57 @@ print_string (FILE *fp, const byte *p, size_t n, int delim) static int +print_checksum (const byte *buffer, size_t length, size_t unhashed, FILE *fp) +{ + const byte *p; + int i; + int hashlen; + unsigned char digest[20]; + + fprintf (fp, "Checksum: "); + if (unhashed && unhashed < 20) + { + fputs ("[specified unhashed sized too short]\n", fp); + return 0; + } + if (!unhashed) + { + unhashed = 16; + hashlen = 16; + } + else + hashlen = 20; + if (length < 5+unhashed) + { + fputs ("[blob too short for a checksum]\n", fp); + return 0; + } + + p = buffer + length - hashlen; + for (i=0; i < hashlen; p++, i++) + fprintf (fp, "%02x", *p); + + if (hashlen == 16) /* Compatibility method. */ + { + gcry_md_hash_buffer (GCRY_MD_MD5, digest, buffer, length - 16); + if (!memcmp (buffer + length - 16, digest, 16)) + fputs (" [valid]\n", fp); + else + fputs (" [bad]\n", fp); + } + else + { + gcry_md_hash_buffer (GCRY_MD_SHA1, digest, buffer, length - unhashed); + if (!memcmp (buffer + length - hashlen, digest, hashlen)) + fputs (" [valid]\n", fp); + else + fputs (" [bad]\n", fp); + } + return 0; +} + + +static int dump_header_blob (const byte *buffer, size_t length, FILE *fp) { unsigned long n; @@ -108,12 +159,13 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) { const byte *buffer; size_t length; - int type; + int type, i; ulong n, nkeys, keyinfolen; ulong nuids, uidinfolen; ulong nsigs, siginfolen; ulong rawdata_off, rawdata_len; ulong nserial; + ulong unhashed; const byte *p; buffer = _keybox_get_blob_image (blob, &length); @@ -189,8 +241,12 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) fprintf( fp, "Data-Offset: %lu\n", rawdata_off ); fprintf( fp, "Data-Length: %lu\n", rawdata_len ); if (rawdata_off > length || rawdata_len > length - || rawdata_off+rawdata_off > length) + || rawdata_off+rawdata_len > length + || rawdata_len + 4 > length + || rawdata_off+rawdata_len + 4 > length) fprintf (fp, "[Error: raw data larger than blob]\n"); + unhashed = get32 (buffer + rawdata_off + rawdata_len); + fprintf (fp, "Unhashed: %lu\n", unhashed); nkeys = get16 (buffer + 16); fprintf (fp, "Key-Count: %lu\n", nkeys ); @@ -205,7 +261,6 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) p = buffer + 20; for (n=0; n < nkeys; n++, p += keyinfolen) { - int i; ulong kidoff, kflags; fprintf (fp, "Key-Fpr[%lu]: ", n ); @@ -291,27 +346,50 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) 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-Expire[%lu]: ", n ); - if (!sflags) - fputs ("[not checked]", fp); - else if (sflags == 1 ) - fputs ("[missing key]", fp); - else if (sflags == 2 ) - fputs ("[bad signature]", fp); - else if (sflags < 0x10000000) - fprintf (fp, "[bad flag %0lx]", sflags); - else if (sflags == 0xffffffff) - fputs ("0", fp ); - else - fputs ("a time"/*strtimestamp( sflags )*/, fp ); - putc ('\n', fp ); - } - + { + int in_range = 0; + ulong first = 0; + + for (n=0; n < nsigs; n++, p += siginfolen) + { + ulong sflags; + + sflags = get32 (p); + if (!in_range && !sflags) + { + in_range = 1; + first = n; + continue; + } + if (in_range && !sflags) + continue; + if (in_range) + { + fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); + in_range = 0; + } + + fprintf (fp, "Sig-Expire[%lu]: ", 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 ("[good - does not expire]", fp ); + else + fprintf (fp, "[good - expires at %lu]", sflags); + putc ('\n', fp ); + } + if (in_range) + { + fprintf (fp, "Sig-Expire[%lu-%lu]: [not checked]\n", first, n-1); + in_range = 0; + } + } fprintf (fp, "Ownertrust: %d\n", p[0] ); fprintf (fp, "All-Validity: %d\n", p[1] ); p += 4; @@ -324,13 +402,17 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) 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");*/ + if (unhashed >= 24) + { + n = get32 ( buffer + length - unhashed); + fprintf (fp, "Storage-Flags: %08lx\n", n ); + } + print_checksum (buffer, length, unhashed, fp); return 0; } -/* Compute the SHA_1 checksum of teh rawdata in BLOB and aput it into +/* Compute the SHA-1 checksum of the rawdata in BLOB and put it into DIGEST. */ static int hash_blob_rawdata (KEYBOXBLOB blob, unsigned char *digest) diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c index ecfdfbe84..027bcf8d7 100644 --- a/kbx/keybox-file.c +++ b/kbx/keybox-file.c @@ -74,7 +74,7 @@ _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted) } imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4; - if (imagelen > 500000) /* Sanity check. */ + if (imagelen > 1000000) /* Sanity check. */ return gpg_error (GPG_ERR_TOO_LARGE); if (imagelen < 5) diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index 60594e313..d3299412a 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -200,3 +200,20 @@ _keybox_close_file (KEYBOX_HANDLE hd) } assert (!hd->fp); } + + +/* + * Lock the keybox at handle HD, or unlock if YES is false. Note that + * we currently ignore the handle and lock all registered keyboxes. + */ +int +keybox_lock (KEYBOX_HANDLE hd, int yes) +{ + /* FIXME: We need to implement it before we can use it with gpg. + gpgsm does the locking in its local keydb.c driver; this should + be changed as well. */ + + (void)hd; + (void)yes; + return 0; +} diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index 37e2771a8..82bc93479 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -223,6 +223,8 @@ parse_key (const unsigned char *data, size_t datalen, return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); } + ki->algo = algorithm; + for (i=0; i < npkey; i++ ) { unsigned int nbits, nbytes; diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index ef5cd953e..5e6432fa6 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -1,5 +1,6 @@ /* keybox-search.c - Search operations - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2012, + * 2013 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -102,7 +103,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, size_t nkeys, keyinfolen; size_t nuids, uidinfolen; size_t nserial; - size_t nsigs, siginfolen; + size_t nsigs, siginfolen, siginfooff; switch (what) { @@ -116,6 +117,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, case KEYBOX_FLAG_OWNERTRUST: case KEYBOX_FLAG_VALIDITY: case KEYBOX_FLAG_CREATED_AT: + case KEYBOX_FLAG_SIG_INFO: if (length < 20) return GPG_ERR_INV_OBJ; /* Key info. */ @@ -140,6 +142,7 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, if (pos+4 > length) return GPG_ERR_INV_OBJ ; /* Out of bounds. */ /* Signature info. */ + siginfooff = pos; nsigs = get16 (buffer + pos); pos += 2; siginfolen = get16 (buffer + pos); pos += 2; if (siginfolen < 4 ) @@ -158,6 +161,10 @@ _keybox_get_flag_location (const unsigned char *buffer, size_t length, *flag_size = 4; *flag_off += 1+2+4+4+4; break; + case KEYBOX_FLAG_SIG_INFO: + *flag_size = siginfolen * nsigs; + *flag_off = siginfooff; + break; default: break; } @@ -227,6 +234,9 @@ blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) } +/* Returns 0 if not found or the number of the key which was found. + For X.509 this is always 1, for OpenPGP this is 1 for the primary + key and 2 and more for the subkeys. */ static int blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) { @@ -253,7 +263,7 @@ blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) { off = pos + idx*keyinfolen; if (!memcmp (buffer + off, fpr, 20)) - return 1; /* found */ + return idx+1; /* found */ } return 0; /* not found */ } @@ -285,7 +295,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, { off = pos + idx*keyinfolen; if (!memcmp (buffer + off + fproff, fpr, fprlen)) - return 1; /* found */ + return idx+1; /* found */ } return 0; /* not found */ } @@ -293,7 +303,7 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, static int blob_cmp_name (KEYBOXBLOB blob, int idx, - const char *name, size_t namelen, int substr) + const char *name, size_t namelen, int substr, int x509) { const unsigned char *buffer; size_t length; @@ -330,10 +340,9 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, return 0; /* out of bounds */ if (idx < 0) - { /* compare all names starting with that (negated) index */ - idx = -idx; - - for ( ;idx < nuids; idx++) + { /* Compare all names. Note that for X.509 we start with index 1 + so to skip the issuer at index 0. */ + for (idx = !!x509; idx < nuids; idx++) { size_t mypos = pos; @@ -347,15 +356,14 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, if (substr) { if (ascii_memcasemem (buffer+off, len, name, namelen)) - return 1; /* found */ + return idx+1; /* found */ } else { if (len == namelen && !memcmp (buffer+off, name, len)) - return 1; /* found */ + return idx+1; /* found */ } } - return 0; /* not found */ } else { @@ -371,20 +379,25 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, if (substr) { - return !!ascii_memcasemem (buffer+off, len, name, namelen); + if (ascii_memcasemem (buffer+off, len, name, namelen)) + return idx+1; /* found */ } else { - return len == namelen && !memcmp (buffer+off, name, len); + if (len == namelen && !memcmp (buffer+off, name, len)) + return idx+1; /* found */ } } + return 0; /* not found */ } -/* compare all email addresses of the subject. With SUBSTR given as - True a substring search is done in the mail address */ +/* Compare all email addresses of the subject. With SUBSTR given as + True a substring search is done in the mail address. If X509 + states whether thr search is done on an X.509 blob. */ static int -blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) +blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr, + int x509) { const unsigned char *buffer; size_t length; @@ -425,7 +438,9 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) if (namelen < 1) return 0; - for (idx=1 ;idx < nuids; idx++) + /* Note that for X.509 we start at index 1 becuase index 0 is used + for the issuer name. */ + for (idx=!!x509 ;idx < nuids; idx++) { size_t mypos = pos; @@ -434,6 +449,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) len = get32 (buffer+mypos+4); if (off+len > length) return 0; /* error: better stop here out of bounds */ + if (!x509) + { + /* For OpenPGP we need to forward to the mailbox part. */ + for ( ;len && buffer[off] != '<'; len--, off++) + ; + } if (len < 2 || buffer[off] != '<') continue; /* empty name or trailing 0 not stored */ len--; /* one back */ @@ -443,12 +464,12 @@ blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) if (substr) { if (ascii_memcasemem (buffer+off+1, len, name, namelen)) - return 1; /* found */ + return idx+1; /* found */ } else { if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len)) - return 1; /* found */ + return idx+1; /* found */ } } return 0; /* not found */ @@ -583,7 +604,7 @@ has_issuer (KEYBOXBLOB blob, const char *name) return 0; namelen = strlen (name); - return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0); + return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1); } static inline int @@ -601,7 +622,7 @@ has_issuer_sn (KEYBOXBLOB blob, const char *name, namelen = strlen (name); return (blob_cmp_sn (blob, sn, snlen) - && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0)); + && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1)); } static inline int @@ -625,22 +646,25 @@ has_subject (KEYBOXBLOB blob, const char *name) return 0; namelen = strlen (name); - return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0); + return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1); } + static inline int -has_subject_or_alt (KEYBOXBLOB blob, const char *name, int substr) +has_username (KEYBOXBLOB blob, const char *name, int substr) { size_t namelen; + int btype; return_val_if_fail (name, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + btype = blob_get_type (blob); + if (btype != BLOBTYPE_PGP && btype != BLOBTYPE_X509) return 0; namelen = strlen (name); - return blob_cmp_name (blob, -1 /* all subject names*/, name, - namelen, substr); + return blob_cmp_name (blob, -1 /* all subject/user names */, name, + namelen, substr, (btype == BLOBTYPE_X509)); } @@ -648,16 +672,21 @@ static inline int has_mail (KEYBOXBLOB blob, const char *name, int substr) { size_t namelen; + int btype; return_val_if_fail (name, 0); - if (blob_get_type (blob) != BLOBTYPE_X509) + btype = blob_get_type (blob); + if (btype != BLOBTYPE_PGP && btype != BLOBTYPE_X509) return 0; + if (btype == BLOBTYPE_PGP && *name == '<') + name++; /* Hack to remove the leading '<' for gpg. */ + namelen = strlen (name); if (namelen && name[namelen-1] == '>') namelen--; - return blob_cmp_mail (blob, name, namelen, substr); + return blob_cmp_mail (blob, name, namelen, substr, (btype == BLOBTYPE_X509)); } @@ -711,6 +740,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) int need_words, any_skip; KEYBOXBLOB blob = NULL; struct sn_array_s *sn_array = NULL; + int pk_no, uid_no; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -827,6 +857,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) } + pk_no = uid_no = 0; for (;;) { unsigned int blobflags; @@ -852,19 +883,23 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) never_reached (); break; case KEYDB_SEARCH_MODE_EXACT: - if (has_subject_or_alt (blob, desc[n].u.name, 0)) + uid_no = has_username (blob, desc[n].u.name, 0); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_MAIL: - if (has_mail (blob, desc[n].u.name, 0)) + uid_no = has_mail (blob, desc[n].u.name, 0); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_MAILSUB: - if (has_mail (blob, desc[n].u.name, 1)) + uid_no = has_mail (blob, desc[n].u.name, 1); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_SUBSTR: - if (has_subject_or_alt (blob, desc[n].u.name, 1)) + uid_no = has_username (blob, desc[n].u.name, 1); + if (uid_no) goto found; break; case KEYDB_SEARCH_MODE_MAILEND: @@ -891,16 +926,19 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) goto found; break; case KEYDB_SEARCH_MODE_SHORT_KID: - if (has_short_kid (blob, desc[n].u.kid[1])) + pk_no = has_short_kid (blob, desc[n].u.kid[1]); + if (pk_no) goto found; break; case KEYDB_SEARCH_MODE_LONG_KID: - if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1])) + pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]); + if (pk_no) goto found; break; case KEYDB_SEARCH_MODE_FPR: case KEYDB_SEARCH_MODE_FPR20: - if (has_fingerprint (blob, desc[n].u.fpr)) + pk_no = has_fingerprint (blob, desc[n].u.fpr); + if (pk_no) goto found; break; case KEYDB_SEARCH_MODE_KEYGRIP: @@ -933,6 +971,8 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) if (!rc) { hd->found.blob = blob; + hd->found.pk_no = pk_no; + hd->found.uid_no = uid_no; } else if (rc == -1) { @@ -958,6 +998,65 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) Functions to return a certificate or a keyblock. To be used after a successful search operation. */ + + +/* Return the last found keyblock. Returns 0 on success and stores a + new iobuf at R_IOBUF and a signature status vector at R_SIGSTATUS + in that case. R_UID_NO and R_PK_NO are used to retun the number of + the key or user id which was matched the search criteria; if not + known they are set to 0. */ +gpg_error_t +keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, + int *r_pk_no, int *r_uid_no, u32 **r_sigstatus) +{ + gpg_error_t err; + const unsigned char *buffer, *p; + size_t length; + size_t image_off, image_len; + size_t siginfo_off, siginfo_len; + u32 *sigstatus, n, n_sigs, sigilen; + + *r_iobuf = NULL; + *r_sigstatus = NULL; + + if (!hd) + return gpg_error (GPG_ERR_INV_VALUE); + if (!hd->found.blob) + return gpg_error (GPG_ERR_NOTHING_FOUND); + + if (blob_get_type (hd->found.blob) != BLOBTYPE_PGP) + return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); + + buffer = _keybox_get_blob_image (hd->found.blob, &length); + if (length < 40) + return gpg_error (GPG_ERR_TOO_SHORT); + image_off = get32 (buffer+8); + image_len = get32 (buffer+12); + if (image_off+image_len > length) + return gpg_error (GPG_ERR_TOO_SHORT); + + err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO, + &siginfo_off, &siginfo_len); + if (err) + return err; + n_sigs = get16 (buffer + siginfo_off); + sigilen = get16 (buffer + siginfo_off + 2); + p = buffer + siginfo_off + 4; + sigstatus = xtrymalloc ((1+n_sigs) * sizeof *sigstatus); + if (!sigstatus) + return gpg_error_from_syserror (); + sigstatus[0] = n_sigs; + for (n=1; n <= n_sigs; n++, p += sigilen) + sigstatus[n] = get32 (p); + + *r_pk_no = hd->found.pk_no; + *r_uid_no = hd->found.uid_no; + *r_sigstatus = sigstatus; + *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len); + return 0; +} + + #ifdef KEYBOX_WITH_X509 /* Return the last found cert. Caller must free it. diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index 0d052c926..6428bb20a 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -1,5 +1,5 @@ /* keybox-update.c - keybox update operations - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -24,6 +24,7 @@ #include <errno.h> #include <time.h> #include <unistd.h> +#include <assert.h> #include "keybox-defs.h" #include "../common/sysutils.h" @@ -370,6 +371,65 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, } +/* Insert the OpenPGP keyblock {IMAGE,IMAGELEN} into HD. SIGSTATUS is + a vector describing the status of the signatures; its first element + gives the number of following elements. */ +gpg_error_t +keybox_insert_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen, + u32 *sigstatus) +{ + gpg_error_t err; + const char *fname; + KEYBOXBLOB blob; + size_t nparsed; + struct _keybox_openpgp_info info; + + if (!hd) + return gpg_error (GPG_ERR_INV_HANDLE); + if (!hd->kb) + return gpg_error (GPG_ERR_INV_HANDLE); + fname = hd->kb->fname; + if (!fname) + return gpg_error (GPG_ERR_INV_HANDLE); + + + /* Close this one otherwise we will mess up the position for a next + search. Fixme: it would be better to adjust the position after + the write operation. */ + _keybox_close_file (hd); + + err = _keybox_parse_openpgp (image, imagelen, &nparsed, &info); + if (err) + return err; + assert (nparsed <= imagelen); + err = _keybox_create_openpgp_blob (&blob, &info, image, imagelen, + sigstatus, hd->ephemeral); + _keybox_destroy_openpgp_info (&info); + if (!err) + { + err = blob_filecopy (1, fname, blob, hd->secret, 0); + _keybox_release_blob (blob); + /* if (!rc && !hd->secret && kb_offtbl) */ + /* { */ + /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */ + /* } */ + } + return err; +} + + +/* Update the current key at HD with the given OpenPGP keyblock in + {IMAGE,IMAGELEN}. */ +gpg_error_t +keybox_update_keyblock (KEYBOX_HANDLE hd, const void *image, size_t imagelen) +{ + (void)hd; + (void)image; + (void)imagelen; + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} + + #ifdef KEYBOX_WITH_X509 int diff --git a/kbx/keybox.h b/kbx/keybox.h index 52bbe21be..5b2943747 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -1,5 +1,5 @@ /* keybox.h - Keybox operations - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -26,17 +26,12 @@ extern "C" { #endif #endif +#include "../common/iobuf.h" #include "keybox-search-desc.h" -#define KEYBOX_WITH_OPENPGP 1 #define KEYBOX_WITH_X509 1 -#ifdef KEYBOX_WITH_OPENPGP -# undef KEYBOX_WITH_OPENPGP -/*#include <lib-to-handle-gpg-data-structs.h>*/ -#endif - #ifdef KEYBOX_WITH_X509 # include <ksba.h> #endif @@ -53,7 +48,8 @@ typedef enum KEYBOX_FLAG_UID, /* The user ID flags; requires an uid index. */ KEYBOX_FLAG_UID_VALIDITY,/* The validity of a specific uid, requires an uid index. */ - KEYBOX_FLAG_CREATED_AT /* The date the block was created. */ + KEYBOX_FLAG_CREATED_AT, /* The date the block was created. */ + KEYBOX_FLAG_SIG_INFO, /* The signature info block. */ } keybox_flag_t; /* Flag values used with KEYBOX_FLAG_BLOB. */ @@ -71,8 +67,16 @@ void keybox_release (KEYBOX_HANDLE hd); const char *keybox_get_resource_name (KEYBOX_HANDLE hd); int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); +int keybox_lock (KEYBOX_HANDLE hd, int yes); + +/*-- keybox-file.c --*/ +/* Fixme: This function does not belong here: Provide a better + interface to create a new keybox file. */ +int _keybox_write_header_blob (FILE *fp); /*-- keybox-search.c --*/ +gpg_error_t keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf, + int *r_uid_no, int *r_pk_no, u32 **sigstatus); #ifdef KEYBOX_WITH_X509 int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); #endif /*KEYBOX_WITH_X509*/ @@ -83,6 +87,12 @@ int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc); /*-- keybox-update.c --*/ +gpg_error_t keybox_insert_keyblock (KEYBOX_HANDLE hd, + const void *image, size_t imagelen, + u32 *sigstatus); +gpg_error_t keybox_update_keyblock (KEYBOX_HANDLE hd, + const void *image, size_t imagelen); + #ifdef KEYBOX_WITH_X509 int keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, unsigned char *sha1_digest); @@ -98,8 +108,6 @@ int keybox_compress (KEYBOX_HANDLE hd); /*-- --*/ #if 0 -int keybox_lock (KEYBOX_HANDLE hd, int yes); -int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb); int keybox_locate_writable (KEYBOX_HANDLE hd); int keybox_search_reset (KEYBOX_HANDLE hd); int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); |