gpgscm: Make it possible to set the logfile name.
[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
70   buffer = _keybox_get_blob_image (blob, &length);
71   if (length < 48)
72     return 0; /* blob too short */
73
74   nkeys = get16 (buffer + 16);
75   keyinfolen = get16 (buffer + 18);
76   if (!nkeys || keyinfolen < 28)
77     return 0; /* invalid blob */
78
79   kid[0] = get32 (buffer + 32);
80   kid[1] = get32 (buffer + 36);
81
82   return 1;
83 }
84
85
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
88    FLAGOFF,FLAG_SIZE. */
89 gpg_err_code_t
90 _keybox_get_flag_location (const unsigned char *buffer, size_t length,
91                            int what, size_t *flag_off, size_t *flag_size)
92 {
93   size_t pos;
94   size_t nkeys, keyinfolen;
95   size_t nuids, uidinfolen;
96   size_t nserial;
97   size_t nsigs, siginfolen, siginfooff;
98
99   switch (what)
100     {
101     case KEYBOX_FLAG_BLOB:
102       if (length < 8)
103         return GPG_ERR_INV_OBJ;
104       *flag_off = 6;
105       *flag_size = 2;
106       break;
107
108     case KEYBOX_FLAG_OWNERTRUST:
109     case KEYBOX_FLAG_VALIDITY:
110     case KEYBOX_FLAG_CREATED_AT:
111     case KEYBOX_FLAG_SIG_INFO:
112       if (length < 20)
113         return GPG_ERR_INV_OBJ;
114       /* Key info. */
115       nkeys = get16 (buffer + 16);
116       keyinfolen = get16 (buffer + 18 );
117       if (keyinfolen < 28)
118         return GPG_ERR_INV_OBJ;
119       pos = 20 + keyinfolen*nkeys;
120       if (pos+2 > length)
121         return GPG_ERR_INV_OBJ; /* Out of bounds. */
122       /* Serial number. */
123       nserial = get16 (buffer+pos);
124       pos += 2 + nserial;
125       if (pos+4 > length)
126         return GPG_ERR_INV_OBJ; /* Out of bounds. */
127       /* User IDs. */
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;
133       if (pos+4 > length)
134         return GPG_ERR_INV_OBJ ; /* Out of bounds. */
135       /* Signature info. */
136       siginfooff = pos;
137       nsigs = get16 (buffer + pos); pos += 2;
138       siginfolen = get16 (buffer + pos); pos += 2;
139       if (siginfolen < 4 )
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. */
144       *flag_size = 1;
145       *flag_off = pos;
146       switch (what)
147         {
148         case KEYBOX_FLAG_VALIDITY:
149           *flag_off += 1;
150           break;
151         case KEYBOX_FLAG_CREATED_AT:
152           *flag_size = 4;
153           *flag_off += 1+2+4+4+4;
154           break;
155         case KEYBOX_FLAG_SIG_INFO:
156           *flag_size = siginfolen * nsigs;
157           *flag_off = siginfooff;
158           break;
159         default:
160           break;
161         }
162       break;
163
164     default:
165       return GPG_ERR_INV_FLAG;
166     }
167   return 0;
168 }
169
170
171
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)
177 {
178   gpg_err_code_t ec;
179   size_t pos, size;
180
181   *value = 0;
182   ec = _keybox_get_flag_location (buffer, length, what, &pos, &size);
183   if (!ec)
184     switch (size)
185       {
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;
190       }
191
192   return ec;
193 }
194
195
196 static int
197 blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
198 {
199   const unsigned char *buffer;
200   size_t length;
201   size_t pos, off;
202   size_t nkeys, keyinfolen;
203   size_t nserial;
204
205   buffer = _keybox_get_blob_image (blob, &length);
206   if (length < 40)
207     return 0; /* blob too short */
208
209   /*keys*/
210   nkeys = get16 (buffer + 16);
211   keyinfolen = get16 (buffer + 18 );
212   if (keyinfolen < 28)
213     return 0; /* invalid blob */
214   pos = 20 + keyinfolen*nkeys;
215   if (pos+2 > length)
216     return 0; /* out of bounds */
217
218   /*serial*/
219   nserial = get16 (buffer+pos);
220   off = pos + 2;
221   if (off+nserial > length)
222     return 0; /* out of bounds */
223
224   return nserial == snlen && !memcmp (buffer+off, sn, snlen);
225 }
226
227
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.  */
231 static int
232 blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
233 {
234   const unsigned char *buffer;
235   size_t length;
236   size_t pos, off;
237   size_t nkeys, keyinfolen;
238   int idx;
239
240   buffer = _keybox_get_blob_image (blob, &length);
241   if (length < 40)
242     return 0; /* blob too short */
243
244   /*keys*/
245   nkeys = get16 (buffer + 16);
246   keyinfolen = get16 (buffer + 18 );
247   if (keyinfolen < 28)
248     return 0; /* invalid blob */
249   pos = 20;
250   if (pos + keyinfolen*nkeys > length)
251     return 0; /* out of bounds */
252
253   for (idx=0; idx < nkeys; idx++)
254     {
255       off = pos + idx*keyinfolen;
256       if (!memcmp (buffer + off, fpr, 20))
257         return idx+1; /* found */
258     }
259   return 0; /* not found */
260 }
261
262 static int
263 blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
264                    int fproff, int fprlen)
265 {
266   const unsigned char *buffer;
267   size_t length;
268   size_t pos, off;
269   size_t nkeys, keyinfolen;
270   int idx;
271
272   buffer = _keybox_get_blob_image (blob, &length);
273   if (length < 40)
274     return 0; /* blob too short */
275
276   /*keys*/
277   nkeys = get16 (buffer + 16);
278   keyinfolen = get16 (buffer + 18 );
279   if (keyinfolen < 28)
280     return 0; /* invalid blob */
281   pos = 20;
282   if (pos + keyinfolen*nkeys > length)
283     return 0; /* out of bounds */
284
285   for (idx=0; idx < nkeys; idx++)
286     {
287       off = pos + idx*keyinfolen;
288       if (!memcmp (buffer + off + fproff, fpr, fprlen))
289         return idx+1; /* found */
290     }
291   return 0; /* not found */
292 }
293
294
295 static int
296 blob_cmp_name (KEYBOXBLOB blob, int idx,
297                const char *name, size_t namelen, int substr, int x509)
298 {
299   const unsigned char *buffer;
300   size_t length;
301   size_t pos, off, len;
302   size_t nkeys, keyinfolen;
303   size_t nuids, uidinfolen;
304   size_t nserial;
305
306   buffer = _keybox_get_blob_image (blob, &length);
307   if (length < 40)
308     return 0; /* blob too short */
309
310   /*keys*/
311   nkeys = get16 (buffer + 16);
312   keyinfolen = get16 (buffer + 18 );
313   if (keyinfolen < 28)
314     return 0; /* invalid blob */
315   pos = 20 + keyinfolen*nkeys;
316   if (pos+2 > length)
317     return 0; /* out of bounds */
318
319   /*serial*/
320   nserial = get16 (buffer+pos);
321   pos += 2 + nserial;
322   if (pos+4 > length)
323     return 0; /* out of bounds */
324
325   /* user ids*/
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 */
332
333   if (idx < 0)
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++)
337         {
338           size_t mypos = pos;
339
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 */
345           if (len < 1)
346             continue; /* empty name */
347           if (substr)
348             {
349               if (ascii_memcasemem (buffer+off, len, name, namelen))
350                 return idx+1; /* found */
351             }
352           else
353             {
354               if (len == namelen && !memcmp (buffer+off, name, len))
355                 return idx+1; /* found */
356             }
357         }
358     }
359   else
360     {
361       if (idx > nuids)
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 */
368       if (len < 1)
369         return 0; /* empty name */
370
371       if (substr)
372         {
373           if (ascii_memcasemem (buffer+off, len, name, namelen))
374             return idx+1; /* found */
375         }
376       else
377         {
378           if (len == namelen && !memcmp (buffer+off, name, len))
379             return idx+1; /* found */
380         }
381     }
382   return 0; /* not found */
383 }
384
385
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.  */
389 static int
390 blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr,
391                int x509)
392 {
393   const unsigned char *buffer;
394   size_t length;
395   size_t pos, off, len;
396   size_t nkeys, keyinfolen;
397   size_t nuids, uidinfolen;
398   size_t nserial;
399   int idx;
400
401   /* fixme: this code is common to blob_cmp_mail */
402   buffer = _keybox_get_blob_image (blob, &length);
403   if (length < 40)
404     return 0; /* blob too short */
405
406   /*keys*/
407   nkeys = get16 (buffer + 16);
408   keyinfolen = get16 (buffer + 18 );
409   if (keyinfolen < 28)
410     return 0; /* invalid blob */
411   pos = 20 + keyinfolen*nkeys;
412   if (pos+2 > length)
413     return 0; /* out of bounds */
414
415   /*serial*/
416   nserial = get16 (buffer+pos);
417   pos += 2 + nserial;
418   if (pos+4 > length)
419     return 0; /* out of bounds */
420
421   /* user ids*/
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 */
428
429   if (namelen < 1)
430     return 0;
431
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++)
435     {
436       size_t mypos = pos;
437       size_t mylen;
438
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 */
444       if (x509)
445         {
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 */
451           off++;
452           len--;
453         }
454       else /* OpenPGP.  */
455         {
456           /* We need to forward to the mailbox part.  */
457           mypos = off;
458           mylen = len;
459           for ( ; len && buffer[off] != '<'; len--, off++)
460             ;
461           if (len < 2 || buffer[off] != '<')
462             {
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.  */
466               off = mypos;
467               len = mylen;
468               if (!is_valid_mailbox_mem (buffer+off, len))
469                 continue; /* Not a mail address. */
470             }
471           else /* Seems to be standard user id with mail address.  */
472             {
473               off++; /* Point to first char of the mail address.  */
474               len--;
475               /* Search closing '>'.  */
476               for (mypos=off; len && buffer[mypos] != '>'; len--, mypos++)
477                 ;
478               if (!len || buffer[mypos] != '>' || off == mypos)
479                 continue; /* Not a proper mail address.  */
480               len = mypos - off;
481             }
482
483         }
484
485       if (substr)
486         {
487           if (ascii_memcasemem (buffer+off, len, name, namelen))
488             return idx+1; /* found */
489         }
490       else
491         {
492           if (len == namelen && !ascii_memcasecmp (buffer+off, name, len))
493             return idx+1; /* found */
494         }
495     }
496   return 0; /* not found */
497 }
498
499
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.  */
505 static int
506 blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip)
507 {
508   int rc;
509   const unsigned char *buffer;
510   size_t length;
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;
515   gcry_sexp_t s_pkey;
516   unsigned char array[20];
517   unsigned char *rcp;
518   size_t n;
519
520   buffer = _keybox_get_blob_image (blob, &length);
521   if (length < 40)
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.  */
527
528   rc = ksba_reader_new (&reader);
529   if (rc)
530     return 0; /* Problem with ksba. */
531   rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
532   if (rc)
533     goto failed;
534   rc = ksba_cert_new (&cert);
535   if (rc)
536     goto failed;
537   rc = ksba_cert_read_der (cert, reader);
538   if (rc)
539     goto failed;
540   p = ksba_cert_get_public_key (cert);
541   if (!p)
542     goto failed;
543   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
544   if (!n)
545     goto failed;
546   rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n);
547   if (rc)
548     {
549       gcry_sexp_release (s_pkey);
550       goto failed;
551     }
552   rcp = gcry_pk_get_keygrip (s_pkey, array);
553   gcry_sexp_release (s_pkey);
554   if (!rcp)
555     goto failed; /* Can't calculate keygrip. */
556
557   xfree (p);
558   ksba_cert_release (cert);
559   ksba_reader_release (reader);
560   return !memcmp (array, grip, 20);
561  failed:
562   xfree (p);
563   ksba_cert_release (cert);
564   ksba_reader_release (reader);
565   return 0;
566 }
567 #endif /*KEYBOX_WITH_X509*/
568
569
570 \f
571 /*
572   The has_foo functions are used as helpers for search
573 */
574 static inline int
575 has_short_kid (KEYBOXBLOB blob, u32 lkid)
576 {
577   unsigned char buf[4];
578   buf[0] = lkid >> 24;
579   buf[1] = lkid >> 16;
580   buf[2] = lkid >> 8;
581   buf[3] = lkid;
582   return blob_cmp_fpr_part (blob, buf, 16, 4);
583 }
584
585 static inline int
586 has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid)
587 {
588   unsigned char buf[8];
589   buf[0] = mkid >> 24;
590   buf[1] = mkid >> 16;
591   buf[2] = mkid >> 8;
592   buf[3] = mkid;
593   buf[4] = lkid >> 24;
594   buf[5] = lkid >> 16;
595   buf[6] = lkid >> 8;
596   buf[7] = lkid;
597   return blob_cmp_fpr_part (blob, buf, 12, 8);
598 }
599
600 static inline int
601 has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr)
602 {
603   return blob_cmp_fpr (blob, fpr);
604 }
605
606 static inline int
607 has_keygrip (KEYBOXBLOB blob, const unsigned char *grip)
608 {
609 #ifdef KEYBOX_WITH_X509
610   if (blob_get_type (blob) == KEYBOX_BLOBTYPE_X509)
611     return blob_x509_has_grip (blob, grip);
612 #else
613   (void)blob;
614   (void)grip;
615 #endif
616   return 0;
617 }
618
619
620 static inline int
621 has_issuer (KEYBOXBLOB blob, const char *name)
622 {
623   size_t namelen;
624
625   return_val_if_fail (name, 0);
626
627   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
628     return 0;
629
630   namelen = strlen (name);
631   return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1);
632 }
633
634 static inline int
635 has_issuer_sn (KEYBOXBLOB blob, const char *name,
636                const unsigned char *sn, int snlen)
637 {
638   size_t namelen;
639
640   return_val_if_fail (name, 0);
641   return_val_if_fail (sn, 0);
642
643   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
644     return 0;
645
646   namelen = strlen (name);
647
648   return (blob_cmp_sn (blob, sn, snlen)
649           && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0, 1));
650 }
651
652 static inline int
653 has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
654 {
655   return_val_if_fail (sn, 0);
656
657   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
658     return 0;
659   return blob_cmp_sn (blob, sn, snlen);
660 }
661
662 static inline int
663 has_subject (KEYBOXBLOB blob, const char *name)
664 {
665   size_t namelen;
666
667   return_val_if_fail (name, 0);
668
669   if (blob_get_type (blob) != KEYBOX_BLOBTYPE_X509)
670     return 0;
671
672   namelen = strlen (name);
673   return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0, 1);
674 }
675
676
677 static inline int
678 has_username (KEYBOXBLOB blob, const char *name, int substr)
679 {
680   size_t namelen;
681   int btype;
682
683   return_val_if_fail (name, 0);
684
685   btype = blob_get_type (blob);
686   if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
687     return 0;
688
689   namelen = strlen (name);
690   return blob_cmp_name (blob, -1 /* all subject/user names */, name,
691                         namelen, substr, (btype == KEYBOX_BLOBTYPE_X509));
692 }
693
694
695 static inline int
696 has_mail (KEYBOXBLOB blob, const char *name, int substr)
697 {
698   size_t namelen;
699   int btype;
700
701   return_val_if_fail (name, 0);
702
703   btype = blob_get_type (blob);
704   if (btype != KEYBOX_BLOBTYPE_PGP && btype != KEYBOX_BLOBTYPE_X509)
705     return 0;
706
707   if (btype == KEYBOX_BLOBTYPE_PGP && *name == '<')
708     name++; /* Hack to remove the leading '<' for gpg.  */
709
710   namelen = strlen (name);
711   if (namelen && name[namelen-1] == '>')
712     namelen--;
713   return blob_cmp_mail (blob, name, namelen, substr,
714                         (btype == KEYBOX_BLOBTYPE_X509));
715 }
716
717
718 static void
719 release_sn_array (struct sn_array_s *array, size_t size)
720 {
721   size_t n;
722
723   for (n=0; n < size; n++)
724     xfree (array[n].sn);
725   xfree (array);
726 }
727
728
729 /* Helper to open the file.  */
730 static gpg_error_t
731 open_file (KEYBOX_HANDLE hd)
732 {
733
734   hd->fp = fopen (hd->kb->fname, "rb");
735   if (!hd->fp)
736     {
737       hd->error = gpg_error_from_syserror ();
738       return hd->error;
739     }
740
741   return 0;
742 }
743
744
745 \f
746 /*
747
748   The search API
749
750 */
751
752 gpg_error_t
753 keybox_search_reset (KEYBOX_HANDLE hd)
754 {
755   if (!hd)
756     return gpg_error (GPG_ERR_INV_VALUE);
757
758   if (hd->found.blob)
759     {
760       _keybox_release_blob (hd->found.blob);
761       hd->found.blob = NULL;
762     }
763
764   if (hd->fp)
765     {
766       if (fseeko (hd->fp, 0, SEEK_SET))
767         {
768           /* Ooops.  Seek did not work.  Close so that the search will
769            * open the file again.  */
770           fclose (hd->fp);
771           hd->fp = NULL;
772         }
773     }
774   hd->error = 0;
775   hd->eof = 0;
776   return 0;
777 }
778
779
780 /* Note: When in ephemeral mode the search function does visit all
781    blobs but in standard mode, blobs flagged as ephemeral are ignored.
782    If WANT_BLOBTYPE is not 0 only blobs of this type are considered.
783    The value at R_SKIPPED is updated by the number of skipped long
784    records (counts PGP and X.509). */
785 gpg_error_t
786 keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
787                keybox_blobtype_t want_blobtype,
788                size_t *r_descindex, unsigned long *r_skipped)
789 {
790   gpg_error_t rc;
791   size_t n;
792   int need_words, any_skip;
793   KEYBOXBLOB blob = NULL;
794   struct sn_array_s *sn_array = NULL;
795   int pk_no, uid_no;
796
797   if (!hd)
798     return gpg_error (GPG_ERR_INV_VALUE);
799
800   /* clear last found result */
801   if (hd->found.blob)
802     {
803       _keybox_release_blob (hd->found.blob);
804       hd->found.blob = NULL;
805     }
806
807   if (hd->error)
808     return hd->error; /* still in error state */
809   if (hd->eof)
810     return -1; /* still EOF */
811
812   /* figure out what information we need */
813   need_words = any_skip = 0;
814   for (n=0; n < ndesc; n++)
815     {
816       switch (desc[n].mode)
817         {
818         case KEYDB_SEARCH_MODE_WORDS:
819           need_words = 1;
820           break;
821         case KEYDB_SEARCH_MODE_FIRST:
822           /* always restart the search in this mode */
823           keybox_search_reset (hd);
824           break;
825         default:
826           break;
827         }
828       if (desc[n].skipfnc)
829         any_skip = 1;
830       if (desc[n].snlen == -1 && !sn_array)
831         {
832           sn_array = xtrycalloc (ndesc, sizeof *sn_array);
833           if (!sn_array)
834             return (hd->error = gpg_error_from_syserror ());
835         }
836     }
837
838   (void)need_words;  /* Not yet implemented.  */
839
840   if (!hd->fp)
841     {
842       rc = open_file (hd);
843       if (rc)
844         {
845           xfree (sn_array);
846           return rc;
847         }
848     }
849
850   /* Kludge: We need to convert an SN given as hexstring to its binary
851      representation - in some cases we are not able to store it in the
852      search descriptor, because due to the way we use it, it is not
853      possible to free allocated memory. */
854   if (sn_array)
855     {
856       const unsigned char *s;
857       int i, odd;
858       size_t snlen;
859
860       for (n=0; n < ndesc; n++)
861         {
862           if (!desc[n].sn)
863             ;
864           else if (desc[n].snlen == -1)
865             {
866               unsigned char *sn;
867
868               s = desc[n].sn;
869               for (i=0; *s && *s != '/'; s++, i++)
870                 ;
871               odd = (i & 1);
872               snlen = (i+1)/2;
873               sn_array[n].sn = xtrymalloc (snlen);
874               if (!sn_array[n].sn)
875                 {
876                   hd->error = gpg_error_from_syserror ();
877                   release_sn_array (sn_array, n);
878                   return hd->error;
879                 }
880               sn_array[n].snlen = snlen;
881               sn = sn_array[n].sn;
882               s = desc[n].sn;
883               if (odd)
884                 {
885                   *sn++ = xtoi_1 (s);
886                   s++;
887                 }
888               for (; *s && *s != '/';  s += 2)
889                 *sn++ = xtoi_2 (s);
890             }
891           else
892             {
893               const unsigned char *sn;
894
895               sn = desc[n].sn;
896               snlen = desc[n].snlen;
897               sn_array[n].sn = xtrymalloc (snlen);
898               if (!sn_array[n].sn)
899                 {
900                   hd->error = gpg_error_from_syserror ();
901                   release_sn_array (sn_array, n);
902                   return hd->error;
903                 }
904               sn_array[n].snlen = snlen;
905               memcpy (sn_array[n].sn, sn, snlen);
906             }
907         }
908     }
909
910
911   pk_no = uid_no = 0;
912   for (;;)
913     {
914       unsigned int blobflags;
915       int blobtype;
916
917       _keybox_release_blob (blob); blob = NULL;
918       rc = _keybox_read_blob (&blob, hd->fp, NULL);
919       if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
920           && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
921         {
922           ++*r_skipped;
923           continue; /* Skip too large records.  */
924         }
925
926       if (rc)
927         break;
928
929       blobtype = blob_get_type (blob);
930       if (blobtype == KEYBOX_BLOBTYPE_HEADER)
931         continue;
932       if (want_blobtype && blobtype != want_blobtype)
933         continue;
934
935       blobflags = blob_get_blob_flags (blob);
936       if (!hd->ephemeral && (blobflags & 2))
937         continue; /* Not in ephemeral mode but blob is flagged ephemeral.  */
938
939       for (n=0; n < ndesc; n++)
940         {
941           switch (desc[n].mode)
942             {
943             case KEYDB_SEARCH_MODE_NONE:
944               never_reached ();
945               break;
946             case KEYDB_SEARCH_MODE_EXACT:
947               uid_no = has_username (blob, desc[n].u.name, 0);
948               if (uid_no)
949                 goto found;
950               break;
951             case KEYDB_SEARCH_MODE_MAIL:
952               uid_no = has_mail (blob, desc[n].u.name, 0);
953               if (uid_no)
954                 goto found;
955               break;
956             case KEYDB_SEARCH_MODE_MAILSUB:
957               uid_no = has_mail (blob, desc[n].u.name, 1);
958               if (uid_no)
959                 goto found;
960               break;
961             case KEYDB_SEARCH_MODE_SUBSTR:
962               uid_no =  has_username (blob, desc[n].u.name, 1);
963               if (uid_no)
964                 goto found;
965               break;
966             case KEYDB_SEARCH_MODE_MAILEND:
967             case KEYDB_SEARCH_MODE_WORDS:
968               /* not yet implemented */
969               break;
970             case KEYDB_SEARCH_MODE_ISSUER:
971               if (has_issuer (blob, desc[n].u.name))
972                 goto found;
973               break;
974             case KEYDB_SEARCH_MODE_ISSUER_SN:
975               if (has_issuer_sn (blob, desc[n].u.name,
976                                  sn_array? sn_array[n].sn : desc[n].sn,
977                                  sn_array? sn_array[n].snlen : desc[n].snlen))
978                 goto found;
979               break;
980             case KEYDB_SEARCH_MODE_SN:
981               if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn,
982                                 sn_array? sn_array[n].snlen : desc[n].snlen))
983                 goto found;
984               break;
985             case KEYDB_SEARCH_MODE_SUBJECT:
986               if (has_subject (blob, desc[n].u.name))
987                 goto found;
988               break;
989             case KEYDB_SEARCH_MODE_SHORT_KID:
990               pk_no = has_short_kid (blob, desc[n].u.kid[1]);
991               if (pk_no)
992                 goto found;
993               break;
994             case KEYDB_SEARCH_MODE_LONG_KID:
995               pk_no = has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]);
996               if (pk_no)
997                 goto found;
998               break;
999             case KEYDB_SEARCH_MODE_FPR:
1000             case KEYDB_SEARCH_MODE_FPR20:
1001               pk_no = has_fingerprint (blob, desc[n].u.fpr);
1002               if (pk_no)
1003                 goto found;
1004               break;
1005             case KEYDB_SEARCH_MODE_KEYGRIP:
1006               if (has_keygrip (blob, desc[n].u.grip))
1007                 goto found;
1008               break;
1009             case KEYDB_SEARCH_MODE_FIRST:
1010               goto found;
1011               break;
1012             case KEYDB_SEARCH_MODE_NEXT:
1013               goto found;
1014               break;
1015             default:
1016               rc = gpg_error (GPG_ERR_INV_VALUE);
1017               goto found;
1018             }
1019         }
1020       continue;
1021     found:
1022       /* Record which DESC we matched on.  Note this value is only
1023          meaningful if this function returns with no errors. */
1024       if(r_descindex)
1025         *r_descindex = n;
1026       for (n=any_skip?0:ndesc; n < ndesc; n++)
1027         {
1028           u32 kid[2];
1029
1030           if (desc[n].skipfnc
1031               && blob_get_first_keyid (blob, kid)
1032               && desc[n].skipfnc (desc[n].skipfncvalue, kid, uid_no))
1033                 break;
1034         }
1035       if (n == ndesc)
1036         break; /* got it */
1037     }
1038
1039   if (!rc)
1040     {
1041       hd->found.blob = blob;
1042       hd->found.pk_no = pk_no;
1043       hd->found.uid_no = uid_no;
1044     }
1045   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF)
1046     {
1047       _keybox_release_blob (blob);
1048       hd->eof = 1;
1049     }
1050   else
1051     {
1052       _keybox_release_blob (blob);
1053       hd->error = rc;
1054     }
1055
1056   if (sn_array)
1057     release_sn_array (sn_array, ndesc);
1058
1059   return rc;
1060 }
1061
1062
1063
1064 \f
1065 /*
1066    Functions to return a certificate or a keyblock.  To be used after
1067    a successful search operation.
1068 */
1069
1070
1071 /* Return the last found keyblock.  Returns 0 on success and stores a
1072  * new iobuf at R_IOBUF.  R_UID_NO and R_PK_NO are used to retun the
1073  * number of the key or user id which was matched the search criteria;
1074  * if not known they are set to 0. */
1075 gpg_error_t
1076 keybox_get_keyblock (KEYBOX_HANDLE hd, iobuf_t *r_iobuf,
1077                      int *r_pk_no, int *r_uid_no)
1078 {
1079   gpg_error_t err;
1080   const unsigned char *buffer;
1081   size_t length;
1082   size_t image_off, image_len;
1083   size_t siginfo_off, siginfo_len;
1084
1085   *r_iobuf = NULL;
1086
1087   if (!hd)
1088     return gpg_error (GPG_ERR_INV_VALUE);
1089   if (!hd->found.blob)
1090     return gpg_error (GPG_ERR_NOTHING_FOUND);
1091
1092   if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_PGP)
1093     return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1094
1095   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1096   if (length < 40)
1097     return gpg_error (GPG_ERR_TOO_SHORT);
1098   image_off = get32 (buffer+8);
1099   image_len = get32 (buffer+12);
1100   if (image_off+image_len > length)
1101     return gpg_error (GPG_ERR_TOO_SHORT);
1102
1103   err = _keybox_get_flag_location (buffer, length, KEYBOX_FLAG_SIG_INFO,
1104                                    &siginfo_off, &siginfo_len);
1105   if (err)
1106     return err;
1107
1108   *r_pk_no  = hd->found.pk_no;
1109   *r_uid_no = hd->found.uid_no;
1110   *r_iobuf = iobuf_temp_with_content (buffer+image_off, image_len);
1111   return 0;
1112 }
1113
1114
1115 #ifdef KEYBOX_WITH_X509
1116 /*
1117   Return the last found cert.  Caller must free it.
1118  */
1119 int
1120 keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert)
1121 {
1122   const unsigned char *buffer;
1123   size_t length;
1124   size_t cert_off, cert_len;
1125   ksba_reader_t reader = NULL;
1126   ksba_cert_t cert = NULL;
1127   int rc;
1128
1129   if (!hd)
1130     return gpg_error (GPG_ERR_INV_VALUE);
1131   if (!hd->found.blob)
1132     return gpg_error (GPG_ERR_NOTHING_FOUND);
1133
1134   if (blob_get_type (hd->found.blob) != KEYBOX_BLOBTYPE_X509)
1135     return gpg_error (GPG_ERR_WRONG_BLOB_TYPE);
1136
1137   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1138   if (length < 40)
1139     return gpg_error (GPG_ERR_TOO_SHORT);
1140   cert_off = get32 (buffer+8);
1141   cert_len = get32 (buffer+12);
1142   if (cert_off+cert_len > length)
1143     return gpg_error (GPG_ERR_TOO_SHORT);
1144
1145   rc = ksba_reader_new (&reader);
1146   if (rc)
1147     return rc;
1148   rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len);
1149   if (rc)
1150     {
1151       ksba_reader_release (reader);
1152       /* fixme: need to map the error codes */
1153       return gpg_error (GPG_ERR_GENERAL);
1154     }
1155
1156   rc = ksba_cert_new (&cert);
1157   if (rc)
1158     {
1159       ksba_reader_release (reader);
1160       return rc;
1161     }
1162
1163   rc = ksba_cert_read_der (cert, reader);
1164   if (rc)
1165     {
1166       ksba_cert_release (cert);
1167       ksba_reader_release (reader);
1168       /* fixme: need to map the error codes */
1169       return gpg_error (GPG_ERR_GENERAL);
1170     }
1171
1172   *r_cert = cert;
1173   ksba_reader_release (reader);
1174   return 0;
1175 }
1176
1177 #endif /*KEYBOX_WITH_X509*/
1178
1179 /* Return the flags named WHAT at the address of VALUE. IDX is used
1180    only for certain flags and should be 0 if not required. */
1181 int
1182 keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value)
1183 {
1184   const unsigned char *buffer;
1185   size_t length;
1186   gpg_err_code_t ec;
1187
1188   (void)idx; /* Not yet used.  */
1189
1190   if (!hd)
1191     return gpg_error (GPG_ERR_INV_VALUE);
1192   if (!hd->found.blob)
1193     return gpg_error (GPG_ERR_NOTHING_FOUND);
1194
1195   buffer = _keybox_get_blob_image (hd->found.blob, &length);
1196   ec = get_flag_from_image (buffer, length, what, value);
1197   return ec? gpg_error (ec):0;
1198 }
1199
1200 off_t
1201 keybox_offset (KEYBOX_HANDLE hd)
1202 {
1203   if (!hd->fp)
1204     return 0;
1205   return ftello (hd->fp);
1206 }
1207
1208 gpg_error_t
1209 keybox_seek (KEYBOX_HANDLE hd, off_t offset)
1210 {
1211   gpg_error_t err;
1212
1213   if (hd->error)
1214     return hd->error; /* still in error state */
1215
1216   if (! hd->fp)
1217     {
1218       if (!offset)
1219         {
1220           /* No need to open the file.  An unopened file is effectively at
1221              offset 0.  */
1222           return 0;
1223         }
1224
1225       err = open_file (hd);
1226       if (err)
1227         return err;
1228     }
1229
1230   err = fseeko (hd->fp, offset, SEEK_SET);
1231   hd->error = gpg_error_from_errno (err);
1232
1233   return hd->error;
1234 }