1 /* keybox-search.c - Search operations
2 * Copyright (C) 2001, 2002, 2003, 2004, 2012,
3 * 2013 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
28 #include "keybox-defs.h"
31 #include "mbox-util.h"
33 #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
34 *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
35 #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
44 #define get32(a) buf32_to_ulong ((a))
45 #define get16(a) buf16_to_ulong ((a))
48 static inline unsigned int
49 blob_get_blob_flags (KEYBOXBLOB blob)
51 const unsigned char *buffer;
54 buffer = _keybox_get_blob_image (blob, &length);
58 return get16 (buffer + 6);
62 /* Return the first keyid from the blob. Returns true if
65 blob_get_first_keyid (KEYBOXBLOB blob, u32 *kid)
67 const unsigned char *buffer;
68 size_t length, nkeys, keyinfolen;
70 buffer = _keybox_get_blob_image (blob, &length);
72 return 0; /* blob too short */
74 nkeys = get16 (buffer + 16);
75 keyinfolen = get16 (buffer + 18);
76 if (!nkeys || keyinfolen < 28)
77 return 0; /* invalid blob */
79 kid[0] = get32 (buffer + 32);
80 kid[1] = get32 (buffer + 36);
86 /* Return information on the flag WHAT within the blob BUFFER,LENGTH.
87 Return the offset and the length (in bytes) of the flag in
90 _keybox_get_flag_location (const unsigned char *buffer, size_t length,
91 int what, size_t *flag_off, size_t *flag_size)
94 size_t nkeys, keyinfolen;
95 size_t nuids, uidinfolen;
97 size_t nsigs, siginfolen, siginfooff;
101 case KEYBOX_FLAG_BLOB:
103 return GPG_ERR_INV_OBJ;
108 case KEYBOX_FLAG_OWNERTRUST:
109 case KEYBOX_FLAG_VALIDITY:
110 case KEYBOX_FLAG_CREATED_AT:
111 case KEYBOX_FLAG_SIG_INFO:
113 return GPG_ERR_INV_OBJ;
115 nkeys = get16 (buffer + 16);
116 keyinfolen = get16 (buffer + 18 );
118 return GPG_ERR_INV_OBJ;
119 pos = 20 + keyinfolen*nkeys;
121 return GPG_ERR_INV_OBJ; /* Out of bounds. */
123 nserial = get16 (buffer+pos);
126 return GPG_ERR_INV_OBJ; /* Out of bounds. */
128 nuids = get16 (buffer + pos); pos += 2;
129 uidinfolen = get16 (buffer + pos); pos += 2;
130 if (uidinfolen < 12 )
131 return GPG_ERR_INV_OBJ;
132 pos += uidinfolen*nuids;
134 return GPG_ERR_INV_OBJ ; /* Out of bounds. */
135 /* Signature info. */
137 nsigs = get16 (buffer + pos); pos += 2;
138 siginfolen = get16 (buffer + pos); pos += 2;
140 return GPG_ERR_INV_OBJ;
141 pos += siginfolen*nsigs;
142 if (pos+1+1+2+4+4+4+4 > length)
143 return GPG_ERR_INV_OBJ ; /* Out of bounds. */
148 case KEYBOX_FLAG_VALIDITY:
151 case KEYBOX_FLAG_CREATED_AT:
153 *flag_off += 1+2+4+4+4;
155 case KEYBOX_FLAG_SIG_INFO:
156 *flag_size = siginfolen * nsigs;
157 *flag_off = siginfooff;
165 return GPG_ERR_INV_FLAG;
172 /* Return one of the flags WHAT in VALUE from the blob BUFFER of
173 LENGTH bytes. Return 0 on success or an raw error code. */
174 static gpg_err_code_t
175 get_flag_from_image (const unsigned char *buffer, size_t length,
176 int what, unsigned int *value)
182 ec = _keybox_get_flag_location (buffer, length, what, &pos, &size);
186 case 1: *value = buffer[pos]; break;
187 case 2: *value = get16 (buffer + pos); break;
188 case 4: *value = get32 (buffer + pos); break;
189 default: ec = GPG_ERR_BUG; break;
197 blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
199 const unsigned char *buffer;
202 size_t nkeys, keyinfolen;
205 buffer = _keybox_get_blob_image (blob, &length);
207 return 0; /* blob too short */
210 nkeys = get16 (buffer + 16);
211 keyinfolen = get16 (buffer + 18 );
213 return 0; /* invalid blob */
214 pos = 20 + keyinfolen*nkeys;
216 return 0; /* out of bounds */
219 nserial = get16 (buffer+pos);
221 if (off+nserial > length)
222 return 0; /* out of bounds */
224 return nserial == snlen && !memcmp (buffer+off, sn, snlen);
228 /* Returns 0 if not found or the number of the key which was found.
229 For X.509 this is always 1, for OpenPGP this is 1 for the primary
230 key and 2 and more for the subkeys. */
232 blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
234 const unsigned char *buffer;
237 size_t nkeys, keyinfolen;
240 buffer = _keybox_get_blob_image (blob, &length);
242 return 0; /* blob too short */
245 nkeys = get16 (buffer + 16);
246 keyinfolen = get16 (buffer + 18 );
248 return 0; /* invalid blob */
250 if (pos + keyinfolen*nkeys > length)
251 return 0; /* out of bounds */
253 for (idx=0; idx < nkeys; idx++)
255 off = pos + idx*keyinfolen;
256 if (!memcmp (buffer + off, fpr, 20))
257 return idx+1; /* found */
259 return 0; /* not found */
263 blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
264 int fproff, int fprlen)
266 const unsigned char *buffer;
269 size_t nkeys, keyinfolen;
272 buffer = _keybox_get_blob_image (blob, &length);
274 return 0; /* blob too short */
277 nkeys = get16 (buffer + 16);
278 keyinfolen = get16 (buffer + 18 );
280 return 0; /* invalid blob */
282 if (pos + keyinfolen*nkeys > length)
283 return 0; /* out of bounds */
285 for (idx=0; idx < nkeys; idx++)
287 off = pos + idx*keyinfolen;
288 if (!memcmp (buffer + off + fproff, fpr, fprlen))
289 return idx+1; /* found */
291 return 0; /* not found */
296 blob_cmp_name (KEYBOXBLOB blob, int idx,
297 const char *name, size_t namelen, int substr, int x509)
299 const unsigned char *buffer;
301 size_t pos, off, len;
302 size_t nkeys, keyinfolen;
303 size_t nuids, uidinfolen;
306 buffer = _keybox_get_blob_image (blob, &length);
308 return 0; /* blob too short */
311 nkeys = get16 (buffer + 16);
312 keyinfolen = get16 (buffer + 18 );
314 return 0; /* invalid blob */
315 pos = 20 + keyinfolen*nkeys;
317 return 0; /* out of bounds */
320 nserial = get16 (buffer+pos);
323 return 0; /* out of bounds */
326 nuids = get16 (buffer + pos); pos += 2;
327 uidinfolen = get16 (buffer + pos); pos += 2;
328 if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */)
329 return 0; /* invalid blob */
330 if (pos + uidinfolen*nuids > length)
331 return 0; /* out of bounds */
334 { /* Compare all names. Note that for X.509 we start with index 1
335 so to skip the issuer at index 0. */
336 for (idx = !!x509; idx < nuids; idx++)
340 mypos += idx*uidinfolen;
341 off = get32 (buffer+mypos);
342 len = get32 (buffer+mypos+4);
343 if (off+len > length)
344 return 0; /* error: better stop here out of bounds */
346 continue; /* empty name */
349 if (ascii_memcasemem (buffer+off, len, name, namelen))
350 return idx+1; /* found */
354 if (len == namelen && !memcmp (buffer+off, name, len))
355 return idx+1; /* found */
362 return 0; /* no user ID with that idx */
363 pos += idx*uidinfolen;
364 off = get32 (buffer+pos);
365 len = get32 (buffer+pos+4);
366 if (off+len > length)
367 return 0; /* out of bounds */
369 return 0; /* empty name */
373 if (ascii_memcasemem (buffer+off, len, name, namelen))
374 return idx+1; /* found */
378 if (len == namelen && !memcmp (buffer+off, name, len))
379 return idx+1; /* found */
382 return 0; /* not found */
386 /* Compare all email addresses of the subject. With SUBSTR given as
387 True a substring search is done in the mail address. The X509 flag
388 indicated whether the search is done on an X.509 blob. */
390 blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr,
393 const unsigned char *buffer;
395 size_t pos, off, len;
396 size_t nkeys, keyinfolen;
397 size_t nuids, uidinfolen;
401 /* fixme: this code is common to blob_cmp_mail */
402 buffer = _keybox_get_blob_image (blob, &length);
404 return 0; /* blob too short */
407 nkeys = get16 (buffer + 16);
408 keyinfolen = get16 (buffer + 18 );
410 return 0; /* invalid blob */
411 pos = 20 + keyinfolen*nkeys;
413 return 0; /* out of bounds */
416 nserial = get16 (buffer+pos);
419 return 0; /* out of bounds */
422 nuids = get16 (buffer + pos); pos += 2;
423 uidinfolen = get16 (buffer + pos); pos += 2;
424 if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */)
425 return 0; /* invalid blob */
426 if (pos + uidinfolen*nuids > length)
427 return 0; /* out of bounds */
432 /* Note that for X.509 we start at index 1 because index 0 is used
433 for the issuer name. */
434 for (idx=!!x509 ;idx < nuids; idx++)
439 mypos += idx*uidinfolen;
440 off = get32 (buffer+mypos);
441 len = get32 (buffer+mypos+4);
442 if (off+len > length)
443 return 0; /* error: better stop here - out of bounds */
446 if (len < 2 || buffer[off] != '<')
447 continue; /* empty name or trailing 0 not stored */
448 len--; /* one back */
449 if ( len < 3 || buffer[off+len] != '>')
450 continue; /* not a proper email address */
456 /* We need to forward to the mailbox part. */
459 for ( ; len && buffer[off] != '<'; len--, off++)
461 if (len < 2 || buffer[off] != '<')
463 /* Mailbox not explicitly given or too short. Restore
464 OFF and LEN and check whether the entire string
465 resembles a mailbox without the angle brackets. */
468 if (!is_valid_mailbox_mem (buffer+off, len))
469 continue; /* Not a mail address. */
471 else /* Seems to be standard user id with mail address. */
473 off++; /* Point to first char of the mail address. */
475 /* Search closing '>'. */
476 for (mypos=off; len && buffer[mypos] != '>'; len--, mypos++)
478 if (!len || buffer[mypos] != '>' || off == mypos)
479 continue; /* Not a proper mail address. */
487 if (ascii_memcasemem (buffer+off, len, name, namelen))
488 return idx+1; /* found */
492 if (len == namelen && !ascii_memcasecmp (buffer+off, name, len))
493 return idx+1; /* found */
496 return 0; /* not found */
500 #ifdef KEYBOX_WITH_X509
501 /* Return true if the key in BLOB matches the 20 bytes keygrip GRIP.
502 We don't have the keygrips as meta data, thus we need to parse the
503 certificate. Fixme: We might want to return proper error codes
504 instead of failing a search for invalid certificates etc. */
506 blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
509 const unsigned char *buffer;
511 size_t cert_off, cert_len;
512 ksba_reader_t reader = NULL;
513 ksba_cert_t cert = NULL;
514 ksba_sexp_t p = NULL;
516 unsigned char array[20];
520 buffer = _keybox_get_blob_image (blob, &length);
522 return 0; /* Too short. */
523 cert_off = get32 (buffer+8);
524 cert_len = get32 (buffer+12);
525 if (cert_off+cert_len > length)
526 return 0; /* Too short. */
528 rc = ksba_reader_new (&reader);
530 return 0; /* Problem with ksba. */
531 rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
534 rc = ksba_cert_new (&cert);
537 rc = ksba_cert_read_der (cert, reader);
540 p = ksba_cert_get_public_key (cert);
543 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
546 rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n);
549 gcry_sexp_release (s_pkey);
552 rcp = gcry_pk_get_keygrip (s_pkey, array);
553 gcry_sexp_release (s_pkey);
555 goto failed; /* Can't calculate keygrip. */
558 ksba_cert_release (cert);
559 ksba_reader_release (reader);
560 return !memcmp (array, grip, 20);
563 ksba_cert_release (cert);
564 ksba_reader_release (reader);
567 #endif /*KEYBOX_WITH_X509*/
572 The has_foo functions are used as helpers for search
575 has_short_kid (KEYBOXBLOB blob, u32 lkid)
577 unsigned char buf[4];
582 return blob_cmp_fpr_part (blob, buf, 16, 4);
586 has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid)
588 unsigned char buf[8];
597 return blob_cmp_fpr_part (blob, buf, 12, 8);
601 has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr)
603 return blob_cmp_fpr (blob, fpr);
607 has_keygrip (KEYBOXBLOB blob, const unsigned char *grip)
609 #ifdef KEYBOX_WITH_X509
610 if (blob_get_type (blob) == KEYBOX_BLOBTYPE_X509)
611 return blob_x509_has_grip (blob, grip);
621 has_issuer (KEYBOXBLOB blob, const char *name)
625 return_val_if_fail (name, 0);
627 if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
630 namelen = strlen (name);
631 return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1);
635 has_issuer_sn (KEYBOXBLOB blob, const char *name,
636 const unsigned char *sn, int snlen)
640 return_val_if_fail (name, 0);
641 return_val_if_fail (sn, 0);
643 if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
646 namelen = strlen (name);
648 return (blob_cmp_sn (blob, sn, snlen)
649 && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1));
653 has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
655 return_val_if_fail (sn, 0);
657 if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
659 return blob_cmp_sn (blob, sn, snlen);
663 has_subject (KEYBOXBLOB blob, const char *name)
667 return_val_if_fail (name, 0);
669 if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
672 namelen = strlen (name);
673 return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1);
678 has_username (KEYBOXBLOB blob, const char *name, int substr)
683 return_val_if_fail (name, 0);
685 btype = blob_get_type (blob);
686 if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
689 namelen = strlen (name);
690 return blob_cmp_name (blob, -1 /* all subject/user names */, name,
691 namelen, substr, (btype == KEYBOX_BLOBTYPE_X509));
696 has_mail (KEYBOXBLOB blob, const char *name, int substr)
701 return_val_if_fail (name, 0);
703 btype = blob_get_type (blob);
704 if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
707 if (btype == KEYBOX_BLOBTYPE_PGP && *name == '<')
708 name++; /* Hack to remove the leading '<' for gpg. */
710 namelen = strlen (name);
711 if (namelen && name[namelen-1] == '>')
713 return blob_cmp_mail (blob, name, namelen, substr,
714 (btype == KEYBOX_BLOBTYPE_X509));
719 release_sn_array (struct sn_array_s *array, size_t size)
723 for (n=0; n < size; n++)
736 keybox_search_reset (KEYBOX_HANDLE hd)
739 return gpg_error (GPG_ERR_INV_VALUE);
743 _keybox_release_blob (hd->found.blob);
744 hd->found.blob = NULL;
758 /* Note: When in ephemeral mode the search function does visit all
759 blobs but in standard mode, blobs flagged as ephemeral are ignored.
760 If WANT_BLOBTYPE is not 0 only blobs of this type are considered.
761 The value at R_SKIPPED is updated by the number of skipped long
762 records (counts PGP and X.509). */
764 keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
765 keybox_blobtype_t want_blobtype,
766 size_t *r_descindex, unsigned long *r_skipped)
770 int need_words, any_skip;
771 KEYBOXBLOB blob = NULL;
772 struct sn_array_s *sn_array = NULL;
776 return gpg_error (GPG_ERR_INV_VALUE);
778 /* clear last found result */
781 _keybox_release_blob (hd->found.blob);
782 hd->found.blob = NULL;
786 return hd->error; /* still in error state */
788 return -1; /* still EOF */
790 /* figure out what information we need */
791 need_words = any_skip = 0;
792 for (n=0; n < ndesc; n++)
794 switch (desc[n].mode)
796 case KEYDB_SEARCH_MODE_WORDS:
799 case KEYDB_SEARCH_MODE_FIRST:
800 /* always restart the search in this mode */
801 keybox_search_reset (hd);
808 if (desc[n].snlen == -1 && !sn_array)
810 sn_array = xtrycalloc (ndesc, sizeof *sn_array);
812 return (hd->error = gpg_error_from_syserror ());
816 (void)need_words; /* Not yet implemented. */
820 hd->fp = fopen (hd->kb->fname, "rb");
823 hd->error = gpg_error_from_syserror ();
829 /* Kludge: We need to convert an SN given as hexstring to its binary
830 representation - in some cases we are not able to store it in the
831 search descriptor, because due to the way we use it, it is not
832 possible to free allocated memory. */
835 const unsigned char *s;
839 for (n=0; n < ndesc; n++)
843 else if (desc[n].snlen == -1)
848 for (i=0; *s && *s != '/'; s++, i++)
852 sn_array[n].sn = xtrymalloc (snlen);
855 hd->error = gpg_error_from_syserror ();
856 release_sn_array (sn_array, n);
859 sn_array[n].snlen = snlen;
867 for (; *s && *s != '/'; s += 2)
872 const unsigned char *sn;
875 snlen = desc[n].snlen;
876 sn_array[n].sn = xtrymalloc (snlen);
879 hd->error = gpg_error_from_syserror ();
880 release_sn_array (sn_array, n);
883 sn_array[n].snlen = snlen;
884 memcpy (sn_array[n].sn, sn, snlen);
893 unsigned int blobflags;
896 _keybox_release_blob (blob); blob = NULL;
897 rc = _keybox_read_blob (&blob, hd->fp);
898 if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
899 && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
902 continue; /* Skip too large records. */
908 blobtype = blob_get_type (blob);
909 if (blobtype == KEYBOX_BLOBTYPE_HEADER)
911 if (want_blobtype && blobtype != want_blobtype)
914 blobflags = blob_get_blob_flags (blob);
915 if (!hd->ephemeral && (blobflags & 2))
916 continue; /* Not in ephemeral mode but blob is flagged ephemeral. */
918 for (n=0; n < ndesc; n++)
920 switch (desc[n].mode)
922 case KEYDB_SEARCH_MODE_NONE:
925 case KEYDB_SEARCH_MODE_EXACT:
926 uid_no = has_username (blob, desc[n].u.name, 0);
930 case KEYDB_SEARCH_MODE_MAIL:
931 uid_no = has_mail (blob, desc[n].u.name, 0);
935 case KEYDB_SEARCH_MODE_MAILSUB:
936 uid_no = has_mail (blob, desc[n].u.name, 1);
940 case KEYDB_SEARCH_MODE_SUBSTR:
941 uid_no = has_username (blob, desc[n].u.name, 1);
945 case KEYDB_SEARCH_MODE_MAILEND:
946 case KEYDB_SEARCH_MODE_WORDS:
947 /* not yet implemented */
949 case KEYDB_SEARCH_MODE_ISSUER:
950 if (has_issuer (blob, desc[n].u.name))
953 case KEYDB_SEARCH_MODE_ISSUER_SN:
954 if (has_issuer_sn (blob, desc[n].u.name,
955 sn_array? sn_array[n].sn : desc[n].sn,
956 sn_array? sn_array[n].snlen : desc[n].snlen))
959 case KEYDB_SEARCH_MODE_SN:
960 if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn,
961 sn_array? sn_array[n].snlen : desc[n].snlen))
964 case KEYDB_SEARCH_MODE_SUBJECT:
965 if (has_subject (blob, desc[n].u.name))
968 case KEYDB_SEARCH_MODE_SHORT_KID:
969 pk_no = has_short_kid (blob, desc[n].u.kid[1]);
973 case KEYDB_SEARCH_MODE_LONG_KID:
974 pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]);
978 case KEYDB_SEARCH_MODE_FPR:
979 case KEYDB_SEARCH_MODE_FPR20:
980 pk_no = has_fingerprint (blob, desc[n].u.fpr);
984 case KEYDB_SEARCH_MODE_KEYGRIP:
985 if (has_keygrip (blob, desc[n].u.grip))
988 case KEYDB_SEARCH_MODE_FIRST:
991 case KEYDB_SEARCH_MODE_NEXT:
995 rc = gpg_error (GPG_ERR_INV_VALUE);
1001 /* Record which DESC we matched on. Note this value is only
1002 meaningful if this function returns with no errors. */
1005 for (n=any_skip?0:ndesc; n < ndesc; n++)
1010 && blob_get_first_keyid (blob, kid)
1011 && desc[n].skipfnc (desc[n].skipfncvalue, kid, uid_no))
1020 hd->found.blob = blob;
1021 hd->found.pk_no = pk_no;
1022 hd->found.uid_no = uid_no;
1024 else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1026 _keybox_release_blob (blob);
1031 _keybox_release_blob (blob);
1036 release_sn_array (sn_array, ndesc);
1045 Functions to return a certificate or a keyblock. To be used after
1046 a successful search operation.
1050 /* Return the last found keyblock. Returns 0 on success and stores a
1051 new iobuf at R_IOBUF and a signature status vector at R_SIGSTATUS
1052 in that case. R_UID_NO and R_PK_NO are used to retun the number of
1053 the key or user id which was matched the search criteria; if not
1054 known they are set to 0. */
1056 keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
1057 int *r_pk_no, int *r_uid_no, u32 **r_sigstatus)
1060 const unsigned char *buffer, *p;
1062 size_t image_off, image_len;
1063 size_t siginfo_off, siginfo_len;
1064 u32 *sigstatus, n, n_sigs, sigilen;
1067 *r_sigstatus = NULL;
1070 return gpg_error (GPG_ERR_INV_VALUE);
1071 if (!hd->found.blob)
1072 return gpg_error (GPG_ERR_NOTHING_FOUND);
1074 if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP)
1075 return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1077 buffer = _keybox_get_blob_image (hd->found.blob, &length);
1079 return gpg_error (GPG_ERR_TOO_SHORT);
1080 image_off = get32 (buffer+8);
1081 image_len = get32 (buffer+12);
1082 if (image_off+image_len > length)
1083 return gpg_error (GPG_ERR_TOO_SHORT);
1085 err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO,
1086 &siginfo_off, &siginfo_len);
1089 n_sigs = get16 (buffer + siginfo_off);
1090 sigilen = get16 (buffer + siginfo_off + 2);
1091 p = buffer + siginfo_off + 4;
1092 sigstatus = xtrymalloc ((1+n_sigs) * sizeof *sigstatus);
1094 return gpg_error_from_syserror ();
1095 sigstatus[0] = n_sigs;
1096 for (n=1; n <= n_sigs; n++, p += sigilen)
1097 sigstatus[n] = get32 (p);
1099 *r_pk_no = hd->found.pk_no;
1100 *r_uid_no = hd->found.uid_no;
1101 *r_sigstatus = sigstatus;
1102 *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len);
1107 #ifdef KEYBOX_WITH_X509
1109 Return the last found cert. Caller must free it.
1112 keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert)
1114 const unsigned char *buffer;
1116 size_t cert_off, cert_len;
1117 ksba_reader_t reader = NULL;
1118 ksba_cert_t cert = NULL;
1122 return gpg_error (GPG_ERR_INV_VALUE);
1123 if (!hd->found.blob)
1124 return gpg_error (GPG_ERR_NOTHING_FOUND);
1126 if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_X509)
1127 return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1129 buffer = _keybox_get_blob_image (hd->found.blob, &length);
1131 return gpg_error (GPG_ERR_TOO_SHORT);
1132 cert_off = get32 (buffer+8);
1133 cert_len = get32 (buffer+12);
1134 if (cert_off+cert_len > length)
1135 return gpg_error (GPG_ERR_TOO_SHORT);
1137 rc = ksba_reader_new (&reader);
1140 rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
1143 ksba_reader_release (reader);
1144 /* fixme: need to map the error codes */
1145 return gpg_error (GPG_ERR_GENERAL);
1148 rc = ksba_cert_new (&cert);
1151 ksba_reader_release (reader);
1155 rc = ksba_cert_read_der (cert, reader);
1158 ksba_cert_release (cert);
1159 ksba_reader_release (reader);
1160 /* fixme: need to map the error codes */
1161 return gpg_error (GPG_ERR_GENERAL);
1165 ksba_reader_release (reader);
1169 #endif /*KEYBOX_WITH_X509*/
1171 /* Return the flags named WHAT at the address of VALUE. IDX is used
1172 only for certain flags and should be 0 if not required. */
1174 keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value)
1176 const unsigned char *buffer;
1180 (void)idx; /* Not yet used. */
1183 return gpg_error (GPG_ERR_INV_VALUE);
1184 if (!hd->found.blob)
1185 return gpg_error (GPG_ERR_NOTHING_FOUND);
1187 buffer = _keybox_get_blob_image (hd->found.blob, &length);
1188 ec = get_flag_from_image (buffer, length, what, value);
1189 return ec? gpg_error (ec):0;
1193 keybox_offset (KEYBOX_HANDLE hd)
1197 return ftello (hd->fp);
1201 keybox_seek (KEYBOX_HANDLE hd, off_t offset)
1206 return hd->error; /* still in error state */
1211 /* No need to open the file. An unopened file is effectively at
1215 hd->fp = fopen (hd->kb->fname, "rb");
1218 hd->error = gpg_error_from_syserror ();
1223 err = fseeko (hd->fp, offset, SEEK_SET);
1224 hd->error = gpg_error_from_errno (err);