gpg: More fix of get_best_pubkey_byname.
[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 static inline int
700 has_ubid (KEYBOXBLOB blob, const unsigned char *ubid)
701 {
702   size_t length;
703   const unsigned char *buffer;
704   size_t image_off, image_len;
705   unsigned char ubid_blob[20];
706
707   buffer = _keybox_get_blob_image (blob, &length);
708   if (length < 40)
709     return 0; /*GPG_ERR_TOO_SHORT*/
710
711   if ((get16 (buffer + 6) & 4))
712     {
713       /* The blob has a stored UBID.  */
714       return !memcmp (ubid, buffer + length - 40, 20);
715     }
716   else
717     {
718       /* Need to compute the UBID.  */
719       image_off = get32 (buffer+8);
720       image_len = get32 (buffer+12);
721       if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length)
722         return 0; /*GPG_ERR_TOO_SHORT*/
723
724       gcry_md_hash_buffer (GCRY_MD_SHA1, ubid_blob, buffer+image_off,image_len);
725       return !memcmp (ubid, ubid_blob, 20);
726     }
727 }
728
729 static inline int
730 has_issuer (KEYBOXBLOB blob, const char *name)
731 {
732   size_t namelen;
733
734   return_val_if_fail (name, 0);
735
736   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
737     return 0;
738
739   namelen = strlen (name);
740   return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1);
741 }
742
743 static inline int
744 has_issuer_sn (KEYBOXBLOB blob, const char *name,
745                const unsigned char *sn, int snlen)
746 {
747   size_t namelen;
748
749   return_val_if_fail (name, 0);
750   return_val_if_fail (sn, 0);
751
752   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
753     return 0;
754
755   namelen = strlen (name);
756
757   return (blob_cmp_sn (blob, sn, snlen)
758           && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1));
759 }
760
761 static inline int
762 has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
763 {
764   return_val_if_fail (sn, 0);
765
766   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
767     return 0;
768   return blob_cmp_sn (blob, sn, snlen);
769 }
770
771 static inline int
772 has_subject (KEYBOXBLOB blob, const char *name)
773 {
774   size_t namelen;
775
776   return_val_if_fail (name, 0);
777
778   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
779     return 0;
780
781   namelen = strlen (name);
782   return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1);
783 }
784
785
786 static inline int
787 has_username (KEYBOXBLOB blob, const char *name, int substr)
788 {
789   size_t namelen;
790   int btype;
791
792   return_val_if_fail (name, 0);
793
794   btype = blob_get_type (blob);
795   if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
796     return 0;
797
798   namelen = strlen (name);
799   return blob_cmp_name (blob, -1 /* all subject/user names */, name,
800                         namelen, substr, (btype == KEYBOX_BLOBTYPE_X509));
801 }
802
803
804 static inline int
805 has_mail (KEYBOXBLOB blob, const char *name, int substr)
806 {
807   size_t namelen;
808   int btype;
809
810   return_val_if_fail (name, 0);
811
812   btype = blob_get_type (blob);
813   if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
814     return 0;
815
816   if (btype == KEYBOX_BLOBTYPE_PGP && *name == '<')
817     name++; /* Hack to remove the leading '<' for gpg.  */
818
819   namelen = strlen (name);
820   if (namelen && name[namelen-1] == '>')
821     namelen--;
822   return blob_cmp_mail (blob, name, namelen, substr,
823                         (btype == KEYBOX_BLOBTYPE_X509));
824 }
825
826
827 static void
828 release_sn_array (struct sn_array_s *array, size_t size)
829 {
830   size_t n;
831
832   for (n=0; n < size; n++)
833     xfree (array[n].sn);
834   xfree (array);
835 }
836
837
838 /* Helper to open the file.  */
839 static gpg_error_t
840 open_file (KEYBOX_HANDLE hd)
841 {
842
843   hd->fp = fopen (hd->kb->fname, "rb");
844   if (!hd->fp)
845     {
846       hd->error = gpg_error_from_syserror ();
847       return hd->error;
848     }
849
850   return 0;
851 }
852
853
854 \f
855 /*
856
857   The search API
858
859 */
860
861 gpg_error_t
862 keybox_search_reset (KEYBOX_HANDLE hd)
863 {
864   if (!hd)
865     return gpg_error (GPG_ERR_INV_VALUE);
866
867   if (hd->found.blob)
868     {
869       _keybox_release_blob (hd->found.blob);
870       hd->found.blob = NULL;
871     }
872
873   if (hd->fp)
874     {
875       if (fseeko (hd->fp, 0, SEEK_SET))
876         {
877           /* Ooops.  Seek did not work.  Close so that the search will
878            * open the file again.  */
879           fclose (hd->fp);
880           hd->fp = NULL;
881         }
882     }
883   hd->error = 0;
884   hd->eof = 0;
885   return 0;
886 }
887
888
889 /* Note: When in ephemeral mode the search function does visit all
890    blobs but in standard mode, blobs flagged as ephemeral are ignored.
891    If WANT_BLOBTYPE is not 0 only blobs of this type are considered.
892    The value at R_SKIPPED is updated by the number of skipped long
893    records (counts PGP and X.509). */
894 gpg_error_t
895 keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
896                keybox_blobtype_t want_blobtype,
897                size_t *r_descindex, unsigned long *r_skipped)
898 {
899   gpg_error_t rc;
900   size_t n;
901   int need_words, any_skip;
902   KEYBOXBLOB blob = NULL;
903   struct sn_array_s *sn_array = NULL;
904   int pk_no, uid_no;
905   off_t lastfoundoff;
906
907   if (!hd)
908     return gpg_error (GPG_ERR_INV_VALUE);
909
910   /* Clear last found result but reord the offset of the last found
911    * blob which we may need later. */
912   if (hd->found.blob)
913     {
914       lastfoundoff = _keybox_get_blob_fileoffset (hd->found.blob);
915       _keybox_release_blob (hd->found.blob);
916       hd->found.blob = NULL;
917     }
918   else
919     lastfoundoff = 0;
920
921   if (hd->error)
922     return hd->error; /* still in error state */
923   if (hd->eof)
924     return -1; /* still EOF */
925
926   /* figure out what information we need */
927   need_words = any_skip = 0;
928   for (n=0; n < ndesc; n++)
929     {
930       switch (desc[n].mode)
931         {
932         case KEYDB_SEARCH_MODE_WORDS:
933           need_words = 1;
934           break;
935         case KEYDB_SEARCH_MODE_FIRST:
936           /* always restart the search in this mode */
937           keybox_search_reset (hd);
938           lastfoundoff = 0;
939           break;
940         default:
941           break;
942         }
943       if (desc[n].skipfnc)
944         any_skip = 1;
945       if (desc[n].snlen == -1 && !sn_array)
946         {
947           sn_array = xtrycalloc (ndesc, sizeof *sn_array);
948           if (!sn_array)
949             return (hd->error = gpg_error_from_syserror ());
950         }
951     }
952
953   (void)need_words;  /* Not yet implemented.  */
954
955   if (!hd->fp)
956     {
957       rc = open_file (hd);
958       if (rc)
959         {
960           xfree (sn_array);
961           return rc;
962         }
963       /* log_debug ("%s: re-opened file\n", __func__); */
964       if (ndesc && desc[0].mode != KEYDB_SEARCH_MODE_FIRST && lastfoundoff)
965         {
966           /* Search mode is not first and the last search operation
967            * returned a blob which also was not the first one.  We now
968            * need to skip over that blob and hope that the file has
969            * not changed.  */
970           if (fseeko (hd->fp, lastfoundoff, SEEK_SET))
971             {
972               rc = gpg_error_from_syserror ();
973               log_debug ("%s: seeking to last found offset failed: %s\n",
974                          __func__, gpg_strerror (rc));
975               xfree (sn_array);
976               return gpg_error (GPG_ERR_NOTHING_FOUND);
977             }
978           /* log_debug ("%s: re-opened file and sought to last offset\n", */
979           /*            __func__); */
980           rc = _keybox_read_blob (NULL, hd->fp, NULL);
981           if (rc)
982             {
983               log_debug ("%s: skipping last found blob failed: %s\n",
984                          __func__, gpg_strerror (rc));
985               xfree (sn_array);
986               return gpg_error (GPG_ERR_NOTHING_FOUND);
987             }
988         }
989     }
990
991   /* Kludge: We need to convert an SN given as hexstring to its binary
992      representation - in some cases we are not able to store it in the
993      search descriptor, because due to the way we use it, it is not
994      possible to free allocated memory. */
995   if (sn_array)
996     {
997       const unsigned char *s;
998       int i, odd;
999       size_t snlen;
1000
1001       for (n=0; n < ndesc; n++)
1002         {
1003           if (!desc[n].sn)
1004             ;
1005           else if (desc[n].snlen == -1)
1006             {
1007               unsigned char *sn;
1008
1009               s = desc[n].sn;
1010               for (i=0; *s && *s != '/'; s++, i++)
1011                 ;
1012               odd = (i & 1);
1013               snlen = (i+1)/2;
1014               sn_array[n].sn = xtrymalloc (snlen);
1015               if (!sn_array[n].sn)
1016                 {
1017                   hd->error = gpg_error_from_syserror ();
1018                   release_sn_array (sn_array, n);
1019                   return hd->error;
1020                 }
1021               sn_array[n].snlen = snlen;
1022               sn = sn_array[n].sn;
1023               s = desc[n].sn;
1024               if (odd)
1025                 {
1026                   *sn++ = xtoi_1 (s);
1027                   s++;
1028                 }
1029               for (; *s && *s != '/';  s += 2)
1030                 *sn++ = xtoi_2 (s);
1031             }
1032           else
1033             {
1034               const unsigned char *sn;
1035
1036               sn = desc[n].sn;
1037               snlen = desc[n].snlen;
1038               sn_array[n].sn = xtrymalloc (snlen);
1039               if (!sn_array[n].sn)
1040                 {
1041                   hd->error = gpg_error_from_syserror ();
1042                   release_sn_array (sn_array, n);
1043                   return hd->error;
1044                 }
1045               sn_array[n].snlen = snlen;
1046               memcpy (sn_array[n].sn, sn, snlen);
1047             }
1048         }
1049     }
1050
1051
1052   pk_no = uid_no = 0;
1053   for (;;)
1054     {
1055       unsigned int blobflags;
1056       int blobtype;
1057
1058       _keybox_release_blob (blob); blob = NULL;
1059       rc = _keybox_read_blob (&blob, hd->fp, NULL);
1060       if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
1061           && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
1062         {
1063           ++*r_skipped;
1064           continue; /* Skip too large records.  */
1065         }
1066
1067       if (rc)
1068         break;
1069
1070       blobtype = blob_get_type (blob);
1071       if (blobtype == KEYBOX_BLOBTYPE_HEADER)
1072         continue;
1073       if (want_blobtype && blobtype != want_blobtype)
1074         continue;
1075
1076       blobflags = blob_get_blob_flags (blob);
1077       if (!hd->ephemeral && (blobflags & 2))
1078         continue; /* Not in ephemeral mode but blob is flagged ephemeral.  */
1079
1080       for (n=0; n < ndesc; n++)
1081         {
1082           switch (desc[n].mode)
1083             {
1084             case KEYDB_SEARCH_MODE_NONE:
1085               never_reached ();
1086               break;
1087             case KEYDB_SEARCH_MODE_EXACT:
1088               uid_no = has_username (blob, desc[n].u.name, 0);
1089               if (uid_no)
1090                 goto found;
1091               break;
1092             case KEYDB_SEARCH_MODE_MAIL:
1093               uid_no = has_mail (blob, desc[n].u.name, 0);
1094               if (uid_no)
1095                 goto found;
1096               break;
1097             case KEYDB_SEARCH_MODE_MAILSUB:
1098               uid_no = has_mail (blob, desc[n].u.name, 1);
1099               if (uid_no)
1100                 goto found;
1101               break;
1102             case KEYDB_SEARCH_MODE_SUBSTR:
1103               uid_no =  has_username (blob, desc[n].u.name, 1);
1104               if (uid_no)
1105                 goto found;
1106               break;
1107             case KEYDB_SEARCH_MODE_MAILEND:
1108             case KEYDB_SEARCH_MODE_WORDS:
1109               /* not yet implemented */
1110               break;
1111             case KEYDB_SEARCH_MODE_ISSUER:
1112               if (has_issuer (blob, desc[n].u.name))
1113                 goto found;
1114               break;
1115             case KEYDB_SEARCH_MODE_ISSUER_SN:
1116               if (has_issuer_sn (blob, desc[n].u.name,
1117                                  sn_array? sn_array[n].sn : desc[n].sn,
1118                                  sn_array? sn_array[n].snlen : desc[n].snlen))
1119                 goto found;
1120               break;
1121             case KEYDB_SEARCH_MODE_SN:
1122               if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn,
1123                                 sn_array? sn_array[n].snlen : desc[n].snlen))
1124                 goto found;
1125               break;
1126             case KEYDB_SEARCH_MODE_SUBJECT:
1127               if (has_subject (blob, desc[n].u.name))
1128                 goto found;
1129               break;
1130             case KEYDB_SEARCH_MODE_SHORT_KID:
1131               pk_no = has_short_kid (blob, desc[n].u.kid[1]);
1132               if (pk_no)
1133                 goto found;
1134               break;
1135             case KEYDB_SEARCH_MODE_LONG_KID:
1136               pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]);
1137               if (pk_no)
1138                 goto found;
1139               break;
1140
1141             case KEYDB_SEARCH_MODE_FPR:
1142               pk_no = has_fingerprint (blob, desc[n].u.fpr, desc[n].fprlen);
1143               if (pk_no)
1144                 goto found;
1145               break;
1146
1147             case KEYDB_SEARCH_MODE_KEYGRIP:
1148               if (has_keygrip (blob, desc[n].u.grip))
1149                 goto found;
1150               break;
1151             case KEYDB_SEARCH_MODE_UBID:
1152               if (has_ubid (blob, desc[n].u.ubid))
1153                 goto found;
1154               break;
1155             case KEYDB_SEARCH_MODE_FIRST:
1156               goto found;
1157               break;
1158             case KEYDB_SEARCH_MODE_NEXT:
1159               goto found;
1160               break;
1161             default:
1162               rc = gpg_error (GPG_ERR_INV_VALUE);
1163               goto found;
1164             }
1165         }
1166       continue;
1167     found:
1168       /* Record which DESC we matched on.  Note this value is only
1169          meaningful if this function returns with no errors. */
1170       if(r_descindex)
1171         *r_descindex = n;
1172       for (n=any_skip?0:ndesc; n < ndesc; n++)
1173         {
1174           u32 kid[2];
1175
1176           if (desc[n].skipfnc
1177               && blob_get_first_keyid (blob, kid)
1178               && desc[n].skipfnc (desc[n].skipfncvalue, kid, uid_no))
1179                 break;
1180         }
1181       if (n == ndesc)
1182         break; /* got it */
1183     }
1184
1185   if (!rc)
1186     {
1187       hd->found.blob = blob;
1188       hd->found.pk_no = pk_no;
1189       hd->found.uid_no = uid_no;
1190     }
1191   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1192     {
1193       _keybox_release_blob (blob);
1194       hd->eof = 1;
1195     }
1196   else
1197     {
1198       _keybox_release_blob (blob);
1199       hd->error = rc;
1200     }
1201
1202   if (sn_array)
1203     release_sn_array (sn_array, ndesc);
1204
1205   return rc;
1206 }
1207
1208
1209
1210 \f
1211 /*
1212    Functions to return a certificate or a keyblock.  To be used after
1213    a successful search operation.
1214 */
1215
1216 /* Return the raw data from the last found blob.  Caller must release
1217  * the value stored at R_BUFFER.  If called with NULL for R_BUFFER
1218  * only the needed length for the buffer and the public key type is
1219  * returned.  */
1220 gpg_error_t
1221 keybox_get_data (KEYBOX_HANDLE hd, void **r_buffer, size_t *r_length,
1222                  enum pubkey_types *r_pubkey_type)
1223 {
1224   const unsigned char *buffer;
1225   size_t length;
1226   size_t image_off, image_len;
1227
1228   if (r_buffer)
1229     *r_buffer = NULL;
1230   if (r_length)
1231     *r_length = 0;
1232   if (r_pubkey_type)
1233     *r_pubkey_type = PUBKEY_TYPE_UNKNOWN;
1234
1235   if (!hd)
1236     return gpg_error (GPG_ERR_INV_VALUE);
1237   if (!hd->found.blob)
1238     return gpg_error (GPG_ERR_NOTHING_FOUND);
1239
1240   switch (blob_get_type (hd->found.blob))
1241     {
1242     case KEYBOX_BLOBTYPE_PGP:
1243       if (r_pubkey_type)
1244         *r_pubkey_type = PUBKEY_TYPE_OPGP;
1245       break;
1246     case KEYBOX_BLOBTYPE_X509:
1247       if (r_pubkey_type)
1248         *r_pubkey_type = PUBKEY_TYPE_X509;
1249       break;
1250     default:
1251       return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1252     }
1253
1254   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1255   if (length < 40)
1256     return gpg_error (GPG_ERR_TOO_SHORT);
1257   image_off = get32 (buffer+8);
1258   image_len = get32 (buffer+12);
1259   if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length)
1260     return gpg_error (GPG_ERR_TOO_SHORT);
1261
1262   if (r_length)
1263     *r_length = image_len;
1264   if (r_buffer)
1265     {
1266       *r_buffer = xtrymalloc (image_len);
1267       if (!*r_buffer)
1268         return gpg_error_from_syserror ();
1269       memcpy (*r_buffer, buffer + image_off, image_len);
1270     }
1271
1272   return 0;
1273 }
1274
1275
1276 /* Return the last found keyblock.  Returns 0 on success and stores a
1277  * new iobuf at R_IOBUF.  R_UID_NO and R_PK_NO are used to return the
1278  * index of the key or user id which matched the search criteria; if
1279  * not known they are set to 0. */
1280 gpg_error_t
1281 keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
1282                      int *r_pk_no, int *r_uid_no)
1283 {
1284   gpg_error_t err;
1285   const unsigned char *buffer;
1286   size_t length;
1287   size_t image_off, image_len;
1288   size_t siginfo_off, siginfo_len;
1289
1290   *r_iobuf = NULL;
1291
1292   if (!hd)
1293     return gpg_error (GPG_ERR_INV_VALUE);
1294   if (!hd->found.blob)
1295     return gpg_error (GPG_ERR_NOTHING_FOUND);
1296
1297   if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP)
1298     return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1299
1300   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1301   if (length < 40)
1302     return gpg_error (GPG_ERR_TOO_SHORT);
1303   image_off = get32 (buffer+8);
1304   image_len = get32 (buffer+12);
1305   if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length)
1306     return gpg_error (GPG_ERR_TOO_SHORT);
1307
1308   err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO,
1309                                    &siginfo_off, &siginfo_len);
1310   if (err)
1311     return err;
1312
1313   *r_pk_no  = hd->found.pk_no;
1314   *r_uid_no = hd->found.uid_no;
1315   *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len);
1316   return 0;
1317 }
1318
1319
1320 #ifdef KEYBOX_WITH_X509
1321 /*
1322   Return the last found cert.  Caller must free it.
1323  */
1324 int
1325 keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert)
1326 {
1327   const unsigned char *buffer;
1328   size_t length;
1329   size_t cert_off, cert_len;
1330   ksba_reader_t reader = NULL;
1331   ksba_cert_t cert = NULL;
1332   int rc;
1333
1334   if (!hd)
1335     return gpg_error (GPG_ERR_INV_VALUE);
1336   if (!hd->found.blob)
1337     return gpg_error (GPG_ERR_NOTHING_FOUND);
1338
1339   if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_X509)
1340     return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1341
1342   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1343   if (length < 40)
1344     return gpg_error (GPG_ERR_TOO_SHORT);
1345   cert_off = get32 (buffer+8);
1346   cert_len = get32 (buffer+12);
1347   if ((uint64_t)cert_off+(uint64_t)cert_len > (uint64_t)length)
1348     return gpg_error (GPG_ERR_TOO_SHORT);
1349
1350   rc = ksba_reader_new (&reader);
1351   if (rc)
1352     return rc;
1353   rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
1354   if (rc)
1355     {
1356       ksba_reader_release (reader);
1357       /* fixme: need to map the error codes */
1358       return gpg_error (GPG_ERR_GENERAL);
1359     }
1360
1361   rc = ksba_cert_new (&cert);
1362   if (rc)
1363     {
1364       ksba_reader_release (reader);
1365       return rc;
1366     }
1367
1368   rc = ksba_cert_read_der (cert, reader);
1369   if (rc)
1370     {
1371       ksba_cert_release (cert);
1372       ksba_reader_release (reader);
1373       /* fixme: need to map the error codes */
1374       return gpg_error (GPG_ERR_GENERAL);
1375     }
1376
1377   *r_cert = cert;
1378   ksba_reader_release (reader);
1379   return 0;
1380 }
1381
1382 #endif /*KEYBOX_WITH_X509*/
1383
1384 /* Return the flags named WHAT at the address of VALUE. IDX is used
1385    only for certain flags and should be 0 if not required. */
1386 int
1387 keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value)
1388 {
1389   const unsigned char *buffer;
1390   size_t length;
1391   gpg_err_code_t ec;
1392
1393   (void)idx; /* Not yet used.  */
1394
1395   if (!hd)
1396     return gpg_error (GPG_ERR_INV_VALUE);
1397   if (!hd->found.blob)
1398     return gpg_error (GPG_ERR_NOTHING_FOUND);
1399
1400   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1401   ec = get_flag_from_image (buffer, length, what, value);
1402   return ec? gpg_error (ec):0;
1403 }
1404
1405 off_t
1406 keybox_offset (KEYBOX_HANDLE hd)
1407 {
1408   if (!hd->fp)
1409     return 0;
1410   return ftello (hd->fp);
1411 }
1412
1413 gpg_error_t
1414 keybox_seek (KEYBOX_HANDLE hd, off_t offset)
1415 {
1416   gpg_error_t err;
1417
1418   if (hd->error)
1419     return hd->error; /* still in error state */
1420
1421   if (! hd->fp)
1422     {
1423       if (!offset)
1424         {
1425           /* No need to open the file.  An unopened file is effectively at
1426              offset 0.  */
1427           return 0;
1428         }
1429
1430       err = open_file (hd);
1431       if (err)
1432         return err;
1433     }
1434
1435   err = fseeko (hd->fp, offset, SEEK_SET);
1436   hd->error = gpg_error_from_errno (err);
1437
1438   return hd->error;
1439 }