gpg: Fix using --decrypt along with --use-embedded-filename.
[gnupg.git] / kbx / keybox-search.c
1 /* keybox-search.c - Search operations
2  * Copyright (C) 2001, 2002, 2003, 2004, 2012,
3  *               2013 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <errno.h>
27
28 #include "keybox-defs.h"
29 #include <gcrypt.h>
30 #include "../common/host2net.h"
31 #include "../common/mbox-util.h"
32
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))
36
37
38 struct sn_array_s {
39     int snlen;
40     unsigned char *sn;
41 };
42
43
44 #define get32(a) buf32_to_ulong ((a))
45 #define get16(a) buf16_to_ulong ((a))
46
47
48 static inline unsigned int
49 blob_get_blob_flags (KEYBOXBLOB blob)
50 {
51   const unsigned char *buffer;
52   size_t length;
53
54   buffer = _keybox_get_blob_image (blob, &length);
55   if (length < 8)
56     return 0; /* oops */
57
58   return get16 (buffer + 6);
59 }
60
61
62 /* Return the first keyid from the blob.  Returns true if
63    available.  */
64 static int
65 blob_get_first_keyid (KEYBOXBLOB blob, u32 *kid)
66 {
67   const unsigned char *buffer;
68   size_t length, nkeys, keyinfolen;
69   int fpr32;
70
71   buffer = _keybox_get_blob_image (blob, &length);
72   if (length < 48)
73     return 0; /* blob too short */
74   fpr32 = buffer[5] == 2;
75   if (fpr32 && length < 56)
76     return 0; /* blob to short */
77
78   nkeys = get16 (buffer + 16);
79   keyinfolen = get16 (buffer + 18);
80   if (!nkeys || keyinfolen < (fpr32?56:28))
81     return 0; /* invalid blob */
82
83   if (fpr32 && (get16 (buffer + 20 + 32) & 0x80))
84     {
85       /* 32 byte fingerprint.  */
86       kid[0] = get32 (buffer + 20);
87       kid[1] = get32 (buffer + 20 + 4);
88     }
89   else /* 20 byte fingerprint.  */
90     {
91       kid[0] = get32 (buffer + 20 + 12);
92       kid[1] = get32 (buffer + 20 + 16);
93     }
94
95   return 1;
96 }
97
98
99 /* Return information on the flag WHAT within the blob BUFFER,LENGTH.
100    Return the offset and the length (in bytes) of the flag in
101    FLAGOFF,FLAG_SIZE. */
102 gpg_err_code_t
103 _keybox_get_flag_location (const unsigned char *buffer, size_t length,
104                            int what, size_t *flag_off, size_t *flag_size)
105 {
106   size_t pos;
107   size_t nkeys, keyinfolen;
108   size_t nuids, uidinfolen;
109   size_t nserial;
110   size_t nsigs, siginfolen, siginfooff;
111
112   switch (what)
113     {
114     case KEYBOX_FLAG_BLOB:
115       if (length < 8)
116         return GPG_ERR_INV_OBJ;
117       *flag_off = 6;
118       *flag_size = 2;
119       break;
120
121     case KEYBOX_FLAG_OWNERTRUST:
122     case KEYBOX_FLAG_VALIDITY:
123     case KEYBOX_FLAG_CREATED_AT:
124     case KEYBOX_FLAG_SIG_INFO:
125       if (length < 20)
126         return GPG_ERR_INV_OBJ;
127       /* Key info. */
128       nkeys = get16 (buffer + 16);
129       keyinfolen = get16 (buffer + 18 );
130       if (keyinfolen < 28)
131         return GPG_ERR_INV_OBJ;
132       pos = 20 + keyinfolen*nkeys;
133       if (pos+2 > length)
134         return GPG_ERR_INV_OBJ; /* Out of bounds. */
135       /* Serial number. */
136       nserial = get16 (buffer+pos);
137       pos += 2 + nserial;
138       if (pos+4 > length)
139         return GPG_ERR_INV_OBJ; /* Out of bounds. */
140       /* User IDs. */
141       nuids = get16 (buffer + pos); pos += 2;
142       uidinfolen = get16 (buffer + pos); pos += 2;
143       if (uidinfolen < 12 )
144         return GPG_ERR_INV_OBJ;
145       pos += uidinfolen*nuids;
146       if (pos+4 > length)
147         return GPG_ERR_INV_OBJ ; /* Out of bounds. */
148       /* Signature info. */
149       siginfooff = pos;
150       nsigs = get16 (buffer + pos); pos += 2;
151       siginfolen = get16 (buffer + pos); pos += 2;
152       if (siginfolen < 4 )
153         return GPG_ERR_INV_OBJ;
154       pos += siginfolen*nsigs;
155       if (pos+1+1+2+4+4+4+4 > length)
156         return GPG_ERR_INV_OBJ ; /* Out of bounds. */
157       *flag_size = 1;
158       *flag_off = pos;
159       switch (what)
160         {
161         case KEYBOX_FLAG_VALIDITY:
162           *flag_off += 1;
163           break;
164         case KEYBOX_FLAG_CREATED_AT:
165           *flag_size = 4;
166           *flag_off += 1+2+4+4+4;
167           break;
168         case KEYBOX_FLAG_SIG_INFO:
169           *flag_size = siginfolen * nsigs;
170           *flag_off = siginfooff;
171           break;
172         default:
173           break;
174         }
175       break;
176
177     default:
178       return GPG_ERR_INV_FLAG;
179     }
180   return 0;
181 }
182
183
184
185 /* Return one of the flags WHAT in VALUE from the blob BUFFER of
186    LENGTH bytes.  Return 0 on success or an raw error code. */
187 static gpg_err_code_t
188 get_flag_from_image (const unsigned char *buffer, size_t length,
189                      int what, unsigned int *value)
190 {
191   gpg_err_code_t ec;
192   size_t pos, size;
193
194   *value = 0;
195   ec = _keybox_get_flag_location (buffer, length, what, &pos, &size);
196   if (!ec)
197     switch (size)
198       {
199       case 1: *value = buffer[pos]; break;
200       case 2: *value = get16 (buffer + pos); break;
201       case 4: *value = get32 (buffer + pos); break;
202       default: ec = GPG_ERR_BUG; break;
203       }
204
205   return ec;
206 }
207
208
209 static int
210 blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
211 {
212   const unsigned char *buffer;
213   size_t length;
214   size_t pos, off;
215   size_t nkeys, keyinfolen;
216   size_t nserial;
217
218   buffer = _keybox_get_blob_image (blob, &length);
219   if (length < 40)
220     return 0; /* blob too short */
221
222   /*keys*/
223   nkeys = get16 (buffer + 16);
224   keyinfolen = get16 (buffer + 18 );
225   if (keyinfolen < 28)
226     return 0; /* invalid blob */
227   pos = 20 + keyinfolen*nkeys;
228   if (pos+2 > length)
229     return 0; /* out of bounds */
230
231   /*serial*/
232   nserial = get16 (buffer+pos);
233   off = pos + 2;
234   if (off+nserial > length)
235     return 0; /* out of bounds */
236
237   return nserial == snlen && !memcmp (buffer+off, sn, snlen);
238 }
239
240
241 /* Returns 0 if not found or the number of the key which was found.
242    For X.509 this is always 1, for OpenPGP this is 1 for the primary
243    key and 2 and more for the subkeys.  */
244 static int
245 blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr, unsigned int fprlen)
246 {
247   const unsigned char *buffer;
248   size_t length;
249   size_t pos, off;
250   size_t nkeys, keyinfolen;
251   int idx, fpr32, storedfprlen;
252
253   buffer = _keybox_get_blob_image (blob, &length);
254   if (length < 40)
255     return 0; /* blob too short */
256   fpr32 = buffer[5] == 2;
257
258   /*keys*/
259   nkeys = get16 (buffer + 16);
260   keyinfolen = get16 (buffer + 18 );
261   if (keyinfolen < (fpr32?56:28))
262     return 0; /* invalid blob */
263   pos = 20;
264   if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length)
265     return 0; /* out of bounds */
266
267   for (idx=0; idx < nkeys; idx++)
268     {
269       off = pos + idx*keyinfolen;
270       if (fpr32)
271         storedfprlen = (get16 (buffer + off + 32) & 0x80)? 32:20;
272       else
273         storedfprlen = 20;
274       if (storedfprlen == fprlen
275           && !memcmp (buffer + off, fpr, storedfprlen))
276         return idx+1; /* found */
277     }
278   return 0; /* not found */
279 }
280
281
282 /* Helper for has_short_kid and has_long_kid.  */
283 static int
284 blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
285                    int fproff, int fprlen)
286 {
287   const unsigned char *buffer;
288   size_t length;
289   size_t pos, off;
290   size_t nkeys, keyinfolen;
291   int idx, fpr32, storedfprlen;
292
293   buffer = _keybox_get_blob_image (blob, &length);
294   if (length < 40)
295     return 0; /* blob too short */
296   fpr32 = buffer[5] == 2;
297
298   /*keys*/
299   nkeys = get16 (buffer + 16);
300   keyinfolen = get16 (buffer + 18 );
301   if (keyinfolen < (fpr32?56:28))
302     return 0; /* invalid blob */
303   pos = 20;
304   if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length)
305     return 0; /* out of bounds */
306
307   if (fpr32)
308     fproff = 0; /* keyid are the high-order bits.  */
309   for (idx=0; idx < nkeys; idx++)
310     {
311       off = pos + idx*keyinfolen;
312       if (fpr32)
313         storedfprlen = (get16 (buffer + off + 32) & 0x80)? 32:20;
314       else
315         storedfprlen = 20;
316       if (storedfprlen == fproff + fprlen
317           && !memcmp (buffer + off + fproff, fpr, fprlen))
318         return idx+1; /* found */
319     }
320   return 0; /* not found */
321 }
322
323
324 static int
325 blob_cmp_name (KEYBOXBLOB blob, int idx,
326                const char *name, size_t namelen, int substr, int x509)
327 {
328   const unsigned char *buffer;
329   size_t length;
330   size_t pos, off, len;
331   size_t nkeys, keyinfolen;
332   size_t nuids, uidinfolen;
333   size_t nserial;
334
335   buffer = _keybox_get_blob_image (blob, &length);
336   if (length < 40)
337     return 0; /* blob too short */
338
339   /*keys*/
340   nkeys = get16 (buffer + 16);
341   keyinfolen = get16 (buffer + 18 );
342   if (keyinfolen < 28)
343     return 0; /* invalid blob */
344   pos = 20 + keyinfolen*nkeys;
345   if ((uint64_t)pos+2 > (uint64_t)length)
346     return 0; /* out of bounds */
347
348   /*serial*/
349   nserial = get16 (buffer+pos);
350   pos += 2 + nserial;
351   if (pos+4 > length)
352     return 0; /* out of bounds */
353
354   /* user ids*/
355   nuids = get16 (buffer + pos);  pos += 2;
356   uidinfolen = get16 (buffer + pos);  pos += 2;
357   if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */)
358     return 0; /* invalid blob */
359   if (pos + uidinfolen*nuids > length)
360     return 0; /* out of bounds */
361
362   if (idx < 0)
363     { /* Compare all names.  Note that for X.509 we start with index 1
364          so to skip the issuer at index 0.  */
365       for (idx = !!x509; idx < nuids; idx++)
366         {
367           size_t mypos = pos;
368
369           mypos += idx*uidinfolen;
370           off = get32 (buffer+mypos);
371           len = get32 (buffer+mypos+4);
372           if ((uint64_t)off+(uint64_t)len > (uint64_t)length)
373             return 0; /* error: better stop here out of bounds */
374           if (len < 1)
375             continue; /* empty name */
376           if (substr)
377             {
378               if (ascii_memcasemem (buffer+off, len, name, namelen))
379                 return idx+1; /* found */
380             }
381           else
382             {
383               if (len == namelen && !memcmp (buffer+off, name, len))
384                 return idx+1; /* found */
385             }
386         }
387     }
388   else
389     {
390       if (idx > nuids)
391         return 0; /* no user ID with that idx */
392       pos += idx*uidinfolen;
393       off = get32 (buffer+pos);
394       len = get32 (buffer+pos+4);
395       if (off+len > length)
396         return 0; /* out of bounds */
397       if (len < 1)
398         return 0; /* empty name */
399
400       if (substr)
401         {
402           if (ascii_memcasemem (buffer+off, len, name, namelen))
403             return idx+1; /* found */
404         }
405       else
406         {
407           if (len == namelen && !memcmp (buffer+off, name, len))
408             return idx+1; /* found */
409         }
410     }
411   return 0; /* not found */
412 }
413
414
415 /* Compare all email addresses of the subject.  With SUBSTR given as
416    True a substring search is done in the mail address.  The X509 flag
417    indicated whether the search is done on an X.509 blob.  */
418 static int
419 blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr,
420                int x509)
421 {
422   const unsigned char *buffer;
423   size_t length;
424   size_t pos, off, len;
425   size_t nkeys, keyinfolen;
426   size_t nuids, uidinfolen;
427   size_t nserial;
428   int idx;
429
430   /* fixme: this code is common to blob_cmp_mail */
431   buffer = _keybox_get_blob_image (blob, &length);
432   if (length < 40)
433     return 0; /* blob too short */
434
435   /*keys*/
436   nkeys = get16 (buffer + 16);
437   keyinfolen = get16 (buffer + 18 );
438   if (keyinfolen < 28)
439     return 0; /* invalid blob */
440   pos = 20 + keyinfolen*nkeys;
441   if (pos+2 > length)
442     return 0; /* out of bounds */
443
444   /*serial*/
445   nserial = get16 (buffer+pos);
446   pos += 2 + nserial;
447   if (pos+4 > length)
448     return 0; /* out of bounds */
449
450   /* user ids*/
451   nuids = get16 (buffer + pos);  pos += 2;
452   uidinfolen = get16 (buffer + pos);  pos += 2;
453   if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */)
454     return 0; /* invalid blob */
455   if (pos + uidinfolen*nuids > length)
456     return 0; /* out of bounds */
457
458   if (namelen < 1)
459     return 0;
460
461   /* Note that for X.509 we start at index 1 because index 0 is used
462      for the issuer name.  */
463   for (idx=!!x509 ;idx < nuids; idx++)
464     {
465       size_t mypos = pos;
466       size_t mylen;
467
468       mypos += idx*uidinfolen;
469       off = get32 (buffer+mypos);
470       len = get32 (buffer+mypos+4);
471       if ((uint64_t)off+(uint64_t)len > (uint64_t)length)
472         return 0; /* error: better stop here - out of bounds */
473       if (x509)
474         {
475           if (len < 2 || buffer[off] != '<')
476             continue; /* empty name or trailing 0 not stored */
477           len--; /* one back */
478           if ( len < 3 || buffer[off+len] != '>')
479             continue; /* not a proper email address */
480           off++;
481           len--;
482         }
483       else /* OpenPGP.  */
484         {
485           /* We need to forward to the mailbox part.  */
486           mypos = off;
487           mylen = len;
488           for ( ; len && buffer[off] != '<'; len--, off++)
489             ;
490           if (len < 2 || buffer[off] != '<')
491             {
492               /* Mailbox not explicitly given or too short.  Restore
493                  OFF and LEN and check whether the entire string
494                  resembles a mailbox without the angle brackets.  */
495               off = mypos;
496               len = mylen;
497               if (!is_valid_mailbox_mem (buffer+off, len))
498                 continue; /* Not a mail address. */
499             }
500           else /* Seems to be standard user id with mail address.  */
501             {
502               off++; /* Point to first char of the mail address.  */
503               len--;
504               /* Search closing '>'.  */
505               for (mypos=off; len && buffer[mypos] != '>'; len--, mypos++)
506                 ;
507               if (!len || buffer[mypos] != '>' || off == mypos)
508                 continue; /* Not a proper mail address.  */
509               len = mypos - off;
510             }
511
512         }
513
514       if (substr)
515         {
516           if (ascii_memcasemem (buffer+off, len, name, namelen))
517             return idx+1; /* found */
518         }
519       else
520         {
521           if (len == namelen && !ascii_memcasecmp (buffer+off, name, len))
522             return idx+1; /* found */
523         }
524     }
525   return 0; /* not found */
526 }
527
528
529 /* Return true if the key in BLOB matches the 20 bytes keygrip GRIP.
530  * We don't have the keygrips as meta data, thus we need to parse the
531  * certificate. Fixme: We might want to return proper error codes
532  * instead of failing a search for invalid certificates etc.  */
533 static int
534 blob_openpgp_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
535 {
536   int rc = 0;
537   const unsigned char *buffer;
538   size_t length;
539   size_t cert_off, cert_len;
540   struct _keybox_openpgp_info info;
541   struct _keybox_openpgp_key_info *k;
542
543   buffer = _keybox_get_blob_image (blob, &length);
544   if (length < 40)
545     return 0; /* Too short. */
546   cert_off = get32 (buffer+8);
547   cert_len = get32 (buffer+12);
548   if ((uint64_t)cert_off+(uint64_t)cert_len > (uint64_t)length)
549     return 0; /* Too short.  */
550
551   if (_keybox_parse_openpgp (buffer + cert_off, cert_len, NULL, &info))
552     return 0; /* Parse error.  */
553
554   if (!memcmp (info.primary.grip, grip, 20))
555     {
556       rc = 1;
557       goto leave;
558     }
559
560   if (info.nsubkeys)
561     {
562       k = &info.subkeys;
563       do
564         {
565           if (!memcmp (k->grip, grip, 20))
566             {
567               rc = 1;
568               goto leave;
569             }
570           k = k->next;
571         }
572       while (k);
573     }
574
575  leave:
576   _keybox_destroy_openpgp_info (&info);
577   return rc;
578 }
579
580
581 #ifdef KEYBOX_WITH_X509
582 /* Return true if the key in BLOB matches the 20 bytes keygrip GRIP.
583    We don't have the keygrips as meta data, thus we need to parse the
584    certificate. Fixme: We might want to return proper error codes
585    instead of failing a search for invalid certificates etc.  */
586 static int
587 blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
588 {
589   int rc;
590   const unsigned char *buffer;
591   size_t length;
592   size_t cert_off, cert_len;
593   ksba_reader_t reader = NULL;
594   ksba_cert_t cert = NULL;
595   ksba_sexp_t p = NULL;
596   gcry_sexp_t s_pkey;
597   unsigned char array[20];
598   unsigned char *rcp;
599   size_t n;
600
601   buffer = _keybox_get_blob_image (blob, &length);
602   if (length < 40)
603     return 0; /* Too short. */
604   cert_off = get32 (buffer+8);
605   cert_len = get32 (buffer+12);
606   if ((uint64_t)cert_off+(uint64_t)cert_len > (uint64_t)length)
607     return 0; /* Too short.  */
608
609   rc = ksba_reader_new (&reader);
610   if (rc)
611     return 0; /* Problem with ksba. */
612   rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
613   if (rc)
614     goto failed;
615   rc = ksba_cert_new (&cert);
616   if (rc)
617     goto failed;
618   rc = ksba_cert_read_der (cert, reader);
619   if (rc)
620     goto failed;
621   p = ksba_cert_get_public_key (cert);
622   if (!p)
623     goto failed;
624   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
625   if (!n)
626     goto failed;
627   rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n);
628   if (rc)
629     {
630       gcry_sexp_release (s_pkey);
631       goto failed;
632     }
633   rcp = gcry_pk_get_keygrip (s_pkey, array);
634   gcry_sexp_release (s_pkey);
635   if (!rcp)
636     goto failed; /* Can't calculate keygrip. */
637
638   xfree (p);
639   ksba_cert_release (cert);
640   ksba_reader_release (reader);
641   return !memcmp (array, grip, 20);
642  failed:
643   xfree (p);
644   ksba_cert_release (cert);
645   ksba_reader_release (reader);
646   return 0;
647 }
648 #endif /*KEYBOX_WITH_X509*/
649
650
651 \f
652 /*
653   The has_foo functions are used as helpers for search
654 */
655 static inline int
656 has_short_kid (KEYBOXBLOB blob, u32 lkid)
657 {
658   unsigned char buf[4];
659   buf[0] = lkid >> 24;
660   buf[1] = lkid >> 16;
661   buf[2] = lkid >> 8;
662   buf[3] = lkid;
663   return blob_cmp_fpr_part (blob, buf, 16, 4);
664 }
665
666 static inline int
667 has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid)
668 {
669   unsigned char buf[8];
670   buf[0] = mkid >> 24;
671   buf[1] = mkid >> 16;
672   buf[2] = mkid >> 8;
673   buf[3] = mkid;
674   buf[4] = lkid >> 24;
675   buf[5] = lkid >> 16;
676   buf[6] = lkid >> 8;
677   buf[7] = lkid;
678   return blob_cmp_fpr_part (blob, buf, 12, 8);
679 }
680
681 static inline int
682 has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr, unsigned int fprlen)
683 {
684   return blob_cmp_fpr (blob, fpr, fprlen);
685 }
686
687 static inline int
688 has_keygrip (KEYBOXBLOB blob, const unsigned char *grip)
689 {
690   if (blob_get_type (blob) == KEYBOX_BLOBTYPE_PGP)
691     return blob_openpgp_has_grip (blob, grip);
692 #ifdef KEYBOX_WITH_X509
693   if (blob_get_type (blob) == KEYBOX_BLOBTYPE_X509)
694     return blob_x509_has_grip (blob, grip);
695 #endif
696   return 0;
697 }
698
699
700 static inline int
701 has_issuer (KEYBOXBLOB blob, const char *name)
702 {
703   size_t namelen;
704
705   return_val_if_fail (name, 0);
706
707   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
708     return 0;
709
710   namelen = strlen (name);
711   return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1);
712 }
713
714 static inline int
715 has_issuer_sn (KEYBOXBLOB blob, const char *name,
716                const unsigned char *sn, int snlen)
717 {
718   size_t namelen;
719
720   return_val_if_fail (name, 0);
721   return_val_if_fail (sn, 0);
722
723   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
724     return 0;
725
726   namelen = strlen (name);
727
728   return (blob_cmp_sn (blob, sn, snlen)
729           && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1));
730 }
731
732 static inline int
733 has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
734 {
735   return_val_if_fail (sn, 0);
736
737   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
738     return 0;
739   return blob_cmp_sn (blob, sn, snlen);
740 }
741
742 static inline int
743 has_subject (KEYBOXBLOB blob, const char *name)
744 {
745   size_t namelen;
746
747   return_val_if_fail (name, 0);
748
749   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
750     return 0;
751
752   namelen = strlen (name);
753   return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1);
754 }
755
756
757 static inline int
758 has_username (KEYBOXBLOB blob, const char *name, int substr)
759 {
760   size_t namelen;
761   int btype;
762
763   return_val_if_fail (name, 0);
764
765   btype = blob_get_type (blob);
766   if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
767     return 0;
768
769   namelen = strlen (name);
770   return blob_cmp_name (blob, -1 /* all subject/user names */, name,
771                         namelen, substr, (btype == KEYBOX_BLOBTYPE_X509));
772 }
773
774
775 static inline int
776 has_mail (KEYBOXBLOB blob, const char *name, int substr)
777 {
778   size_t namelen;
779   int btype;
780
781   return_val_if_fail (name, 0);
782
783   btype = blob_get_type (blob);
784   if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
785     return 0;
786
787   if (btype == KEYBOX_BLOBTYPE_PGP && *name == '<')
788     name++; /* Hack to remove the leading '<' for gpg.  */
789
790   namelen = strlen (name);
791   if (namelen && name[namelen-1] == '>')
792     namelen--;
793   return blob_cmp_mail (blob, name, namelen, substr,
794                         (btype == KEYBOX_BLOBTYPE_X509));
795 }
796
797
798 static void
799 release_sn_array (struct sn_array_s *array, size_t size)
800 {
801   size_t n;
802
803   for (n=0; n < size; n++)
804     xfree (array[n].sn);
805   xfree (array);
806 }
807
808
809 /* Helper to open the file.  */
810 static gpg_error_t
811 open_file (KEYBOX_HANDLE hd)
812 {
813
814   hd->fp = fopen (hd->kb->fname, "rb");
815   if (!hd->fp)
816     {
817       hd->error = gpg_error_from_syserror ();
818       return hd->error;
819     }
820
821   return 0;
822 }
823
824
825 \f
826 /*
827
828   The search API
829
830 */
831
832 gpg_error_t
833 keybox_search_reset (KEYBOX_HANDLE hd)
834 {
835   if (!hd)
836     return gpg_error (GPG_ERR_INV_VALUE);
837
838   if (hd->found.blob)
839     {
840       _keybox_release_blob (hd->found.blob);
841       hd->found.blob = NULL;
842     }
843
844   if (hd->fp)
845     {
846       if (fseeko (hd->fp, 0, SEEK_SET))
847         {
848           /* Ooops.  Seek did not work.  Close so that the search will
849            * open the file again.  */
850           fclose (hd->fp);
851           hd->fp = NULL;
852         }
853     }
854   hd->error = 0;
855   hd->eof = 0;
856   return 0;
857 }
858
859
860 /* Note: When in ephemeral mode the search function does visit all
861    blobs but in standard mode, blobs flagged as ephemeral are ignored.
862    If WANT_BLOBTYPE is not 0 only blobs of this type are considered.
863    The value at R_SKIPPED is updated by the number of skipped long
864    records (counts PGP and X.509). */
865 gpg_error_t
866 keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
867                keybox_blobtype_t want_blobtype,
868                size_t *r_descindex, unsigned long *r_skipped)
869 {
870   gpg_error_t rc;
871   size_t n;
872   int need_words, any_skip;
873   KEYBOXBLOB blob = NULL;
874   struct sn_array_s *sn_array = NULL;
875   int pk_no, uid_no;
876   off_t lastfoundoff;
877
878   if (!hd)
879     return gpg_error (GPG_ERR_INV_VALUE);
880
881   /* Clear last found result but reord the offset of the last found
882    * blob which we may need later. */
883   if (hd->found.blob)
884     {
885       lastfoundoff = _keybox_get_blob_fileoffset (hd->found.blob);
886       _keybox_release_blob (hd->found.blob);
887       hd->found.blob = NULL;
888     }
889   else
890     lastfoundoff = 0;
891
892   if (hd->error)
893     return hd->error; /* still in error state */
894   if (hd->eof)
895     return -1; /* still EOF */
896
897   /* figure out what information we need */
898   need_words = any_skip = 0;
899   for (n=0; n < ndesc; n++)
900     {
901       switch (desc[n].mode)
902         {
903         case KEYDB_SEARCH_MODE_WORDS:
904           need_words = 1;
905           break;
906         case KEYDB_SEARCH_MODE_FIRST:
907           /* always restart the search in this mode */
908           keybox_search_reset (hd);
909           lastfoundoff = 0;
910           break;
911         default:
912           break;
913         }
914       if (desc[n].skipfnc)
915         any_skip = 1;
916       if (desc[n].snlen == -1 && !sn_array)
917         {
918           sn_array = xtrycalloc (ndesc, sizeof *sn_array);
919           if (!sn_array)
920             return (hd->error = gpg_error_from_syserror ());
921         }
922     }
923
924   (void)need_words;  /* Not yet implemented.  */
925
926   if (!hd->fp)
927     {
928       rc = open_file (hd);
929       if (rc)
930         {
931           xfree (sn_array);
932           return rc;
933         }
934       /* log_debug ("%s: re-opened file\n", __func__); */
935       if (ndesc && desc[0].mode != KEYDB_SEARCH_MODE_FIRST && lastfoundoff)
936         {
937           /* Search mode is not first and the last search operation
938            * returned a blob which also was not the first one.  We now
939            * need to skip over that blob and hope that the file has
940            * not changed.  */
941           if (fseeko (hd->fp, lastfoundoff, SEEK_SET))
942             {
943               rc = gpg_error_from_syserror ();
944               log_debug ("%s: seeking to last found offset failed: %s\n",
945                          __func__, gpg_strerror (rc));
946               xfree (sn_array);
947               return gpg_error (GPG_ERR_NOTHING_FOUND);
948             }
949           /* log_debug ("%s: re-opened file and sought to last offset\n", */
950           /*            __func__); */
951           rc = _keybox_read_blob (NULL, hd->fp, NULL);
952           if (rc)
953             {
954               log_debug ("%s: skipping last found blob failed: %s\n",
955                          __func__, gpg_strerror (rc));
956               xfree (sn_array);
957               return gpg_error (GPG_ERR_NOTHING_FOUND);
958             }
959         }
960     }
961
962   /* Kludge: We need to convert an SN given as hexstring to its binary
963      representation - in some cases we are not able to store it in the
964      search descriptor, because due to the way we use it, it is not
965      possible to free allocated memory. */
966   if (sn_array)
967     {
968       const unsigned char *s;
969       int i, odd;
970       size_t snlen;
971
972       for (n=0; n < ndesc; n++)
973         {
974           if (!desc[n].sn)
975             ;
976           else if (desc[n].snlen == -1)
977             {
978               unsigned char *sn;
979
980               s = desc[n].sn;
981               for (i=0; *s && *s != '/'; s++, i++)
982                 ;
983               odd = (i & 1);
984               snlen = (i+1)/2;
985               sn_array[n].sn = xtrymalloc (snlen);
986               if (!sn_array[n].sn)
987                 {
988                   hd->error = gpg_error_from_syserror ();
989                   release_sn_array (sn_array, n);
990                   return hd->error;
991                 }
992               sn_array[n].snlen = snlen;
993               sn = sn_array[n].sn;
994               s = desc[n].sn;
995               if (odd)
996                 {
997                   *sn++ = xtoi_1 (s);
998                   s++;
999                 }
1000               for (; *s && *s != '/';  s += 2)
1001                 *sn++ = xtoi_2 (s);
1002             }
1003           else
1004             {
1005               const unsigned char *sn;
1006
1007               sn = desc[n].sn;
1008               snlen = desc[n].snlen;
1009               sn_array[n].sn = xtrymalloc (snlen);
1010               if (!sn_array[n].sn)
1011                 {
1012                   hd->error = gpg_error_from_syserror ();
1013                   release_sn_array (sn_array, n);
1014                   return hd->error;
1015                 }
1016               sn_array[n].snlen = snlen;
1017               memcpy (sn_array[n].sn, sn, snlen);
1018             }
1019         }
1020     }
1021
1022
1023   pk_no = uid_no = 0;
1024   for (;;)
1025     {
1026       unsigned int blobflags;
1027       int blobtype;
1028
1029       _keybox_release_blob (blob); blob = NULL;
1030       rc = _keybox_read_blob (&blob, hd->fp, NULL);
1031       if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
1032           && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
1033         {
1034           ++*r_skipped;
1035           continue; /* Skip too large records.  */
1036         }
1037
1038       if (rc)
1039         break;
1040
1041       blobtype = blob_get_type (blob);
1042       if (blobtype == KEYBOX_BLOBTYPE_HEADER)
1043         continue;
1044       if (want_blobtype && blobtype != want_blobtype)
1045         continue;
1046
1047       blobflags = blob_get_blob_flags (blob);
1048       if (!hd->ephemeral && (blobflags & 2))
1049         continue; /* Not in ephemeral mode but blob is flagged ephemeral.  */
1050
1051       for (n=0; n < ndesc; n++)
1052         {
1053           switch (desc[n].mode)
1054             {
1055             case KEYDB_SEARCH_MODE_NONE:
1056               never_reached ();
1057               break;
1058             case KEYDB_SEARCH_MODE_EXACT:
1059               uid_no = has_username (blob, desc[n].u.name, 0);
1060               if (uid_no)
1061                 goto found;
1062               break;
1063             case KEYDB_SEARCH_MODE_MAIL:
1064               uid_no = has_mail (blob, desc[n].u.name, 0);
1065               if (uid_no)
1066                 goto found;
1067               break;
1068             case KEYDB_SEARCH_MODE_MAILSUB:
1069               uid_no = has_mail (blob, desc[n].u.name, 1);
1070               if (uid_no)
1071                 goto found;
1072               break;
1073             case KEYDB_SEARCH_MODE_SUBSTR:
1074               uid_no =  has_username (blob, desc[n].u.name, 1);
1075               if (uid_no)
1076                 goto found;
1077               break;
1078             case KEYDB_SEARCH_MODE_MAILEND:
1079             case KEYDB_SEARCH_MODE_WORDS:
1080               /* not yet implemented */
1081               break;
1082             case KEYDB_SEARCH_MODE_ISSUER:
1083               if (has_issuer (blob, desc[n].u.name))
1084                 goto found;
1085               break;
1086             case KEYDB_SEARCH_MODE_ISSUER_SN:
1087               if (has_issuer_sn (blob, desc[n].u.name,
1088                                  sn_array? sn_array[n].sn : desc[n].sn,
1089                                  sn_array? sn_array[n].snlen : desc[n].snlen))
1090                 goto found;
1091               break;
1092             case KEYDB_SEARCH_MODE_SN:
1093               if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn,
1094                                 sn_array? sn_array[n].snlen : desc[n].snlen))
1095                 goto found;
1096               break;
1097             case KEYDB_SEARCH_MODE_SUBJECT:
1098               if (has_subject (blob, desc[n].u.name))
1099                 goto found;
1100               break;
1101             case KEYDB_SEARCH_MODE_SHORT_KID:
1102               pk_no = has_short_kid (blob, desc[n].u.kid[1]);
1103               if (pk_no)
1104                 goto found;
1105               break;
1106             case KEYDB_SEARCH_MODE_LONG_KID:
1107               pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]);
1108               if (pk_no)
1109                 goto found;
1110               break;
1111
1112             case KEYDB_SEARCH_MODE_FPR:
1113               pk_no = has_fingerprint (blob, desc[n].u.fpr, desc[n].fprlen);
1114               if (pk_no)
1115                 goto found;
1116               break;
1117
1118             case KEYDB_SEARCH_MODE_KEYGRIP:
1119               if (has_keygrip (blob, desc[n].u.grip))
1120                 goto found;
1121               break;
1122             case KEYDB_SEARCH_MODE_FIRST:
1123               goto found;
1124               break;
1125             case KEYDB_SEARCH_MODE_NEXT:
1126               goto found;
1127               break;
1128             default:
1129               rc = gpg_error (GPG_ERR_INV_VALUE);
1130               goto found;
1131             }
1132         }
1133       continue;
1134     found:
1135       /* Record which DESC we matched on.  Note this value is only
1136          meaningful if this function returns with no errors. */
1137       if(r_descindex)
1138         *r_descindex = n;
1139       for (n=any_skip?0:ndesc; n < ndesc; n++)
1140         {
1141           u32 kid[2];
1142
1143           if (desc[n].skipfnc
1144               && blob_get_first_keyid (blob, kid)
1145               && desc[n].skipfnc (desc[n].skipfncvalue, kid, uid_no))
1146                 break;
1147         }
1148       if (n == ndesc)
1149         break; /* got it */
1150     }
1151
1152   if (!rc)
1153     {
1154       hd->found.blob = blob;
1155       hd->found.pk_no = pk_no;
1156       hd->found.uid_no = uid_no;
1157     }
1158   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1159     {
1160       _keybox_release_blob (blob);
1161       hd->eof = 1;
1162     }
1163   else
1164     {
1165       _keybox_release_blob (blob);
1166       hd->error = rc;
1167     }
1168
1169   if (sn_array)
1170     release_sn_array (sn_array, ndesc);
1171
1172   return rc;
1173 }
1174
1175
1176
1177 \f
1178 /*
1179    Functions to return a certificate or a keyblock.  To be used after
1180    a successful search operation.
1181 */
1182
1183
1184 /* Return the last found keyblock.  Returns 0 on success and stores a
1185  * new iobuf at R_IOBUF.  R_UID_NO and R_PK_NO are used to return the
1186  * number of the key or user id which was matched the search criteria;
1187  * if not known they are set to 0. */
1188 gpg_error_t
1189 keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
1190                      int *r_pk_no, int *r_uid_no)
1191 {
1192   gpg_error_t err;
1193   const unsigned char *buffer;
1194   size_t length;
1195   size_t image_off, image_len;
1196   size_t siginfo_off, siginfo_len;
1197
1198   *r_iobuf = NULL;
1199
1200   if (!hd)
1201     return gpg_error (GPG_ERR_INV_VALUE);
1202   if (!hd->found.blob)
1203     return gpg_error (GPG_ERR_NOTHING_FOUND);
1204
1205   if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP)
1206     return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1207
1208   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1209   if (length < 40)
1210     return gpg_error (GPG_ERR_TOO_SHORT);
1211   image_off = get32 (buffer+8);
1212   image_len = get32 (buffer+12);
1213   if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length)
1214     return gpg_error (GPG_ERR_TOO_SHORT);
1215
1216   err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO,
1217                                    &siginfo_off, &siginfo_len);
1218   if (err)
1219     return err;
1220
1221   *r_pk_no  = hd->found.pk_no;
1222   *r_uid_no = hd->found.uid_no;
1223   *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len);
1224   return 0;
1225 }
1226
1227
1228 #ifdef KEYBOX_WITH_X509
1229 /*
1230   Return the last found cert.  Caller must free it.
1231  */
1232 int
1233 keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert)
1234 {
1235   const unsigned char *buffer;
1236   size_t length;
1237   size_t cert_off, cert_len;
1238   ksba_reader_t reader = NULL;
1239   ksba_cert_t cert = NULL;
1240   int rc;
1241
1242   if (!hd)
1243     return gpg_error (GPG_ERR_INV_VALUE);
1244   if (!hd->found.blob)
1245     return gpg_error (GPG_ERR_NOTHING_FOUND);
1246
1247   if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_X509)
1248     return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1249
1250   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1251   if (length < 40)
1252     return gpg_error (GPG_ERR_TOO_SHORT);
1253   cert_off = get32 (buffer+8);
1254   cert_len = get32 (buffer+12);
1255   if ((uint64_t)cert_off+(uint64_t)cert_len > (uint64_t)length)
1256     return gpg_error (GPG_ERR_TOO_SHORT);
1257
1258   rc = ksba_reader_new (&reader);
1259   if (rc)
1260     return rc;
1261   rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
1262   if (rc)
1263     {
1264       ksba_reader_release (reader);
1265       /* fixme: need to map the error codes */
1266       return gpg_error (GPG_ERR_GENERAL);
1267     }
1268
1269   rc = ksba_cert_new (&cert);
1270   if (rc)
1271     {
1272       ksba_reader_release (reader);
1273       return rc;
1274     }
1275
1276   rc = ksba_cert_read_der (cert, reader);
1277   if (rc)
1278     {
1279       ksba_cert_release (cert);
1280       ksba_reader_release (reader);
1281       /* fixme: need to map the error codes */
1282       return gpg_error (GPG_ERR_GENERAL);
1283     }
1284
1285   *r_cert = cert;
1286   ksba_reader_release (reader);
1287   return 0;
1288 }
1289
1290 #endif /*KEYBOX_WITH_X509*/
1291
1292 /* Return the flags named WHAT at the address of VALUE. IDX is used
1293    only for certain flags and should be 0 if not required. */
1294 int
1295 keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value)
1296 {
1297   const unsigned char *buffer;
1298   size_t length;
1299   gpg_err_code_t ec;
1300
1301   (void)idx; /* Not yet used.  */
1302
1303   if (!hd)
1304     return gpg_error (GPG_ERR_INV_VALUE);
1305   if (!hd->found.blob)
1306     return gpg_error (GPG_ERR_NOTHING_FOUND);
1307
1308   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1309   ec = get_flag_from_image (buffer, length, what, value);
1310   return ec? gpg_error (ec):0;
1311 }
1312
1313 off_t
1314 keybox_offset (KEYBOX_HANDLE hd)
1315 {
1316   if (!hd->fp)
1317     return 0;
1318   return ftello (hd->fp);
1319 }
1320
1321 gpg_error_t
1322 keybox_seek (KEYBOX_HANDLE hd, off_t offset)
1323 {
1324   gpg_error_t err;
1325
1326   if (hd->error)
1327     return hd->error; /* still in error state */
1328
1329   if (! hd->fp)
1330     {
1331       if (!offset)
1332         {
1333           /* No need to open the file.  An unopened file is effectively at
1334              offset 0.  */
1335           return 0;
1336         }
1337
1338       err = open_file (hd);
1339       if (err)
1340         return err;
1341     }
1342
1343   err = fseeko (hd->fp, offset, SEEK_SET);
1344   hd->error = gpg_error_from_errno (err);
1345
1346   return hd->error;
1347 }