gpg: Cache keybox searches.
[gnupg.git] / kbx / keybox-blob.c
1 /* keybox-blob.c - KBX Blob handling
2  * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 /* The keybox data formats
22
23 The KeyBox uses an augmented OpenPGP/X.509 key format.  This makes
24 random access to a keyblock/certificate easier and also gives the
25 opportunity to store additional information (e.g. the fingerprint)
26 along with the key.  All integers are stored in network byte order,
27 offsets are counted from the beginning of the Blob.
28
29 The first record of a plain KBX file has a special format:
30
31  u32  length of the first record
32  byte Blob type (1)
33  byte version number (1)
34  byte reserved
35  byte reserved
36  u32  magic 'KBXf'
37  u32  reserved
38  u32  file_created_at
39  u32  last_maintenance_run
40  u32  reserved
41  u32  reserved
42
43 The OpenPGP and X.509 blob are very similiar, things which are
44 X.509 specific are noted like [X.509: xxx]
45
46  u32  length of this blob (including these 4 bytes)
47  byte Blob type (2) [X509: 3]
48  byte version number of this blob type (1)
49  u16  Blob flags
50         bit 0 = contains secret key material (not used)
51         bit 1 = ephemeral blob (e.g. used while quering external resources)
52
53  u32  offset to the OpenPGP keyblock or X509 DER encoded certificate
54  u32  and its length
55  u16  number of keys (at least 1!) [X509: always 1]
56  u16  size of additional key information
57  n times:
58    b20  The keys fingerprint
59         (fingerprints are always 20 bytes, MD5 left padded with zeroes)
60    u32  offset to the n-th key's keyID (a keyID is always 8 byte)
61         or 0 if not known which is the case only for X509.
62    u16  special key flags
63          bit 0 = qualified signature (not yet implemented}
64    u16  reserved
65  u16  size of serialnumber(may be zero)
66    n  u16 (see above) bytes of serial number
67  u16  number of user IDs
68  u16  size of additional user ID information
69  n times:
70    u32  offset to the n-th user ID
71    u32  length of this user ID.
72    u16  special user ID flags.
73          bit 0 =
74    byte validity
75    byte reserved
76    [For X509, the first user ID is the Issuer, the second the Subject
77    and the others are subjectAltNames]
78  u16  number of signatures
79  u16  size of signature information (4)
80    u32  expiration time of signature with some special values:
81         0x00000000 = not checked
82         0x00000001 = missing key
83         0x00000002 = bad signature
84         0x10000000 = valid and expires at some date in 1978.
85         0xffffffff = valid and does not expire
86  u8     assigned ownertrust [X509: not used]
87  u8     all_validity
88            OpenPGP:  see ../g10/trustdb/TRUST_* [not yet used]
89            X509: Bit 4 set := key has been revoked.  Note that this value
90                               matches TRUST_FLAG_REVOKED
91  u16    reserved
92  u32    recheck_after
93  u32    Newest timestamp in the keyblock (useful for KS syncronsiation?)
94  u32    Blob created at
95  u32    size of reserved space (not including this field)
96       reserved space
97
98     Here we might want to put other data
99
100     Here comes the keyblock
101
102     maybe we put a signature here later.
103
104  b16    MD5 checksum  (useful for KS syncronisation), we might also want to use
105     a mac here.
106  b4    reserved
107
108 */
109
110
111 #include <config.h>
112 #include <stdio.h>
113 #include <stdlib.h>
114 #include <string.h>
115 #include <errno.h>
116 #include <assert.h>
117 #include <time.h>
118
119 #include "keybox-defs.h"
120 #include <gcrypt.h>
121
122 #ifdef KEYBOX_WITH_X509
123 #include <ksba.h>
124 #endif
125
126
127 #include "../common/gettime.h"
128
129
130 /* special values of the signature status */
131 #define SF_NONE(a)  ( !(a) )
132 #define SF_NOKEY(a) ((a) & (1<<0))
133 #define SF_BAD(a)   ((a) & (1<<1))
134 #define SF_VALID(a) ((a) & (1<<29))
135
136
137 struct membuf {
138   size_t len;
139   size_t size;
140   char *buf;
141   int out_of_core;
142 };
143
144
145 /*  #if MAX_FINGERPRINT_LEN < 20 */
146 /*    #error fingerprints are 20 bytes */
147 /*  #endif */
148
149 struct keyboxblob_key {
150   char   fpr[20];
151   u32    off_kid;
152   ulong  off_kid_addr;
153   u16    flags;
154 };
155 struct keyboxblob_uid {
156   u32    off;
157   ulong  off_addr;
158   char   *name;     /* used only with x509 */
159   u32    len;
160   u16    flags;
161   byte   validity;
162 };
163
164 struct keyid_list {
165     struct keyid_list *next;
166     int seqno;
167     byte kid[8];
168 };
169
170 struct fixup_list {
171     struct fixup_list *next;
172     u32 off;
173     u32 val;
174 };
175
176
177 struct keyboxblob {
178   byte *blob;
179   size_t bloblen;
180   off_t fileoffset;
181
182   /* stuff used only by keybox_create_blob */
183   unsigned char *serialbuf;
184   const unsigned char *serial;
185   size_t seriallen;
186   int nkeys;
187   struct keyboxblob_key *keys;
188   int nuids;
189   struct keyboxblob_uid *uids;
190   int nsigs;
191   u32  *sigs;
192   struct fixup_list *fixups;
193   int fixup_out_of_core;
194
195   struct keyid_list *temp_kids;
196   struct membuf bufbuf; /* temporary store for the blob */
197   struct membuf *buf;
198 };
199
200
201 \f
202 /* A simple implemention of a dynamic buffer.  Use init_membuf() to
203    create a buffer, put_membuf to append bytes and get_membuf to
204    release and return the buffer.  Allocation errors are detected but
205    only returned at the final get_membuf(), this helps not to clutter
206    the code with out of core checks.  */
207
208 static void
209 init_membuf (struct membuf *mb, int initiallen)
210 {
211   mb->len = 0;
212   mb->size = initiallen;
213   mb->out_of_core = 0;
214   mb->buf = xtrymalloc (initiallen);
215   if (!mb->buf)
216       mb->out_of_core = 1;
217 }
218
219 static void
220 put_membuf (struct membuf *mb, const void *buf, size_t len)
221 {
222   if (mb->out_of_core)
223     return;
224
225   if (mb->len + len >= mb->size)
226     {
227       char *p;
228
229       mb->size += len + 1024;
230       p = xtryrealloc (mb->buf, mb->size);
231       if (!p)
232         {
233           mb->out_of_core = 1;
234           return;
235         }
236       mb->buf = p;
237     }
238   memcpy (mb->buf + mb->len, buf, len);
239   mb->len += len;
240 }
241
242 static void *
243 get_membuf (struct membuf *mb, size_t *len)
244 {
245   char *p;
246
247   if (mb->out_of_core)
248     {
249       xfree (mb->buf);
250       mb->buf = NULL;
251       return NULL;
252     }
253
254   p = mb->buf;
255   *len = mb->len;
256   mb->buf = NULL;
257   mb->out_of_core = 1; /* don't allow a reuse */
258   return p;
259 }
260
261
262 static void
263 put8 (struct membuf *mb, byte a )
264 {
265   put_membuf (mb, &a, 1);
266 }
267
268 static void
269 put16 (struct membuf *mb, u16 a )
270 {
271   unsigned char tmp[2];
272   tmp[0] = a>>8;
273   tmp[1] = a;
274   put_membuf (mb, tmp, 2);
275 }
276
277 static void
278 put32 (struct membuf *mb, u32 a )
279 {
280   unsigned char tmp[4];
281   tmp[0] = a>>24;
282   tmp[1] = a>>16;
283   tmp[2] = a>>8;
284   tmp[3] = a;
285   put_membuf (mb, tmp, 4);
286 }
287
288 \f
289 /* Store a value in the fixup list */
290 static void
291 add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
292 {
293   struct fixup_list *fl;
294
295   if (blob->fixup_out_of_core)
296     return;
297
298   fl = xtrycalloc(1, sizeof *fl);
299   if (!fl)
300     blob->fixup_out_of_core = 1;
301   else
302     {
303       fl->off = off;
304       fl->val = val;
305       fl->next = blob->fixups;
306       blob->fixups = fl;
307     }
308 }
309
310
311 \f
312 /*
313   OpenPGP specific stuff
314 */
315
316
317 /* We must store the keyid at some place because we can't calculate
318    the offset yet. This is only used for v3 keyIDs.  Function returns
319    an index value for later fixup or -1 for out of core.  The value
320    must be a non-zero value. */
321 static int
322 pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo)
323 {
324   struct keyid_list *k, *r;
325
326   k = xtrymalloc (sizeof *k);
327   if (!k)
328     return -1;
329   memcpy (k->kid, kinfo->keyid, 8);
330   k->seqno = 0;
331   k->next = blob->temp_kids;
332   blob->temp_kids = k;
333   for (r=k; r; r = r->next)
334     k->seqno++;
335
336   return k->seqno;
337 }
338
339
340 /* Helper for pgp_create_key_part.  */
341 static gpg_error_t
342 pgp_create_key_part_single (KEYBOXBLOB blob, int n,
343                             struct _keybox_openpgp_key_info *kinfo)
344 {
345   size_t fprlen;
346   int off;
347
348   fprlen = kinfo->fprlen;
349   if (fprlen > 20)
350     fprlen = 20;
351   memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
352   if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */
353     {
354       memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen);
355       memset (blob->keys[n].fpr, 0, 20 - fprlen);
356       off = pgp_temp_store_kid (blob, kinfo);
357       if (off == -1)
358         return gpg_error_from_syserror ();
359       blob->keys[n].off_kid = off;
360     }
361   else
362     blob->keys[n].off_kid = 0; /* Will be fixed up later */
363   blob->keys[n].flags = 0;
364   return 0;
365 }
366
367
368 static gpg_error_t
369 pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
370 {
371   gpg_error_t err;
372   int n = 0;
373   struct _keybox_openpgp_key_info *kinfo;
374
375   err = pgp_create_key_part_single (blob, n++, &info->primary);
376   if (err)
377     return err;
378   if (info->nsubkeys)
379     for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
380       if ((err=pgp_create_key_part_single (blob, n++, kinfo)))
381         return err;
382
383   assert (n == blob->nkeys);
384   return 0;
385 }
386
387
388 static void
389 pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
390 {
391   int n = 0;
392   struct _keybox_openpgp_uid_info *u;
393
394   if (info->nuids)
395     {
396       for (u = &info->uids; u; u = u->next)
397         {
398           blob->uids[n].off = u->off;
399           blob->uids[n].len = u->len;
400           blob->uids[n].flags = 0;
401           blob->uids[n].validity = 0;
402           n++;
403         }
404     }
405
406   assert (n == blob->nuids);
407 }
408
409
410 static void
411 pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus)
412 {
413   int n;
414
415   for (n=0; n < blob->nsigs; n++)
416     {
417       blob->sigs[n] = sigstatus? sigstatus[n+1] : 0;
418     }
419 }
420
421
422 static int
423 pgp_create_blob_keyblock (KEYBOXBLOB blob,
424                           const unsigned char *image, size_t imagelen)
425 {
426   struct membuf *a = blob->buf;
427   int n;
428   u32 kbstart = a->len;
429
430   add_fixup (blob, 8, kbstart);
431
432   for (n = 0; n < blob->nuids; n++)
433     add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off);
434
435   put_membuf (a, image, imagelen);
436
437   add_fixup (blob, 12, a->len - kbstart);
438   return 0;
439 }
440
441
442 \f
443 #ifdef KEYBOX_WITH_X509
444 /*
445    X.509 specific stuff
446  */
447
448 /* Write the raw certificate out */
449 static int
450 x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
451 {
452   struct membuf *a = blob->buf;
453   const unsigned char *image;
454   size_t length;
455   u32 kbstart = a->len;
456
457   /* Store our offset for later fixup */
458   add_fixup (blob, 8, kbstart);
459
460   image = ksba_cert_get_image (cert, &length);
461   if (!image)
462     return gpg_error (GPG_ERR_GENERAL);
463   put_membuf (a, image, length);
464
465   add_fixup (blob, 12, a->len - kbstart);
466   return 0;
467 }
468
469 #endif /*KEYBOX_WITH_X509*/
470
471 /* Write a stored keyID out to the buffer */
472 static void
473 write_stored_kid (KEYBOXBLOB blob, int seqno)
474 {
475   struct keyid_list *r;
476
477   for ( r = blob->temp_kids; r; r = r->next )
478     {
479       if (r->seqno == seqno )
480         {
481           put_membuf (blob->buf, r->kid, 8);
482           return;
483         }
484     }
485   never_reached ();
486 }
487
488 /* Release a list of key IDs */
489 static void
490 release_kid_list (struct keyid_list *kl)
491 {
492   struct keyid_list *r, *r2;
493
494   for ( r = kl; r; r = r2 )
495     {
496       r2 = r->next;
497       xfree (r);
498     }
499 }
500
501
502
503 static int
504 create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
505 {
506   struct membuf *a = blob->buf;
507   int i;
508
509   put32 ( a, 0 ); /* blob length, needs fixup */
510   put8 ( a, blobtype);
511   put8 ( a, 1 );  /* blob type version */
512   put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
513
514   put32 ( a, 0 ); /* offset to the raw data, needs fixup */
515   put32 ( a, 0 ); /* length of the raw data, needs fixup */
516
517   put16 ( a, blob->nkeys );
518   put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
519   for ( i=0; i < blob->nkeys; i++ )
520     {
521       put_membuf (a, blob->keys[i].fpr, 20);
522       blob->keys[i].off_kid_addr = a->len;
523       put32 ( a, 0 ); /* offset to keyid, fixed up later */
524       put16 ( a, blob->keys[i].flags );
525       put16 ( a, 0 ); /* reserved */
526     }
527
528   put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
529   if (blob->serial)
530     put_membuf (a, blob->serial, blob->seriallen);
531
532   put16 ( a, blob->nuids );
533   put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
534   for (i=0; i < blob->nuids; i++)
535     {
536       blob->uids[i].off_addr = a->len;
537       put32 ( a, 0 ); /* offset to userid, fixed up later */
538       put32 ( a, blob->uids[i].len );
539       put16 ( a, blob->uids[i].flags );
540       put8  ( a, 0 ); /* validity */
541       put8  ( a, 0 ); /* reserved */
542     }
543
544   put16 ( a, blob->nsigs );
545   put16 ( a, 4 );  /* size of sig info */
546   for (i=0; i < blob->nsigs; i++)
547     {
548       put32 ( a, blob->sigs[i]);
549     }
550
551   put8 ( a, 0 );  /* assigned ownertrust */
552   put8 ( a, 0 );  /* validity of all user IDs */
553   put16 ( a, 0 );  /* reserved */
554   put32 ( a, 0 );  /* time of next recheck */
555   put32 ( a, 0 );  /* newest timestamp (none) */
556   put32 ( a, make_timestamp() );  /* creation time */
557   put32 ( a, 0 );  /* size of reserved space */
558   /* reserved space (which is currently of size 0) */
559
560   /* space where we write keyIDs and and other stuff so that the
561      pointers can actually point to somewhere */
562   if (blobtype == BLOBTYPE_PGP)
563     {
564       /* We need to store the keyids for all pgp v3 keys because those key
565          IDs are not part of the fingerprint.  While we are doing that, we
566          fixup all the keyID offsets */
567       for (i=0; i < blob->nkeys; i++ )
568         {
569           if (blob->keys[i].off_kid)
570             { /* this is a v3 one */
571               add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
572               write_stored_kid (blob, blob->keys[i].off_kid);
573             }
574           else
575             { /* the better v4 key IDs - just store an offset 8 bytes back */
576               add_fixup (blob, blob->keys[i].off_kid_addr,
577                          blob->keys[i].off_kid_addr - 8);
578             }
579         }
580     }
581
582   if (blobtype == BLOBTYPE_X509)
583     {
584       /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
585          the utf-8 string represenation of them */
586       for (i=0; i < blob->nuids; i++ )
587         {
588           if (blob->uids[i].name)
589             { /* this is a v3 one */
590               add_fixup (blob, blob->uids[i].off_addr, a->len);
591               put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
592             }
593         }
594     }
595
596     return 0;
597 }
598
599
600
601 static int
602 create_blob_trailer (KEYBOXBLOB blob)
603 {
604   (void)blob;
605   return 0;
606 }
607
608
609 static int
610 create_blob_finish (KEYBOXBLOB blob)
611 {
612   struct membuf *a = blob->buf;
613   unsigned char *p;
614   unsigned char *pp;
615   int i;
616   size_t n;
617
618   /* write a placeholder for the checksum */
619   for (i = 0; i < 16; i++ )
620     put32 (a, 0);  /* Hmmm: why put32() ?? */
621
622   /* get the memory area */
623   n = 0; /* (Just to avoid compiler warning.) */
624   p = get_membuf (a, &n);
625   if (!p)
626     return gpg_error (GPG_ERR_ENOMEM);
627   assert (n >= 20);
628
629   /* fixup the length */
630   add_fixup (blob, 0, n);
631
632   /* do the fixups */
633   if (blob->fixup_out_of_core)
634     return gpg_error (GPG_ERR_ENOMEM);
635
636   {
637     struct fixup_list *fl;
638     for (fl = blob->fixups; fl; fl = fl->next)
639       {
640         assert (fl->off+4 <= n);
641         p[fl->off+0] = fl->val >> 24;
642         p[fl->off+1] = fl->val >> 16;
643         p[fl->off+2] = fl->val >>  8;
644         p[fl->off+3] = fl->val;
645       }
646   }
647
648   /* calculate and store the MD5 checksum */
649   gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
650
651   pp = xtrymalloc (n);
652   if ( !pp )
653     return gpg_error_from_syserror ();
654   memcpy (pp , p, n);
655   blob->blob = pp;
656   blob->bloblen = n;
657
658   return 0;
659 }
660
661
662 \f
663 gpg_error_t
664 _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
665                              keybox_openpgp_info_t info,
666                              const unsigned char *image,
667                              size_t imagelen,
668                              u32 *sigstatus,
669                              int as_ephemeral)
670 {
671   gpg_error_t err;
672   KEYBOXBLOB blob;
673
674   *r_blob = NULL;
675
676   if (!info->nuids || !info->nsigs)
677     return gpg_error (GPG_ERR_BAD_PUBKEY);
678
679   /* If we have a signature status vector, check that the number of
680      elements matches the actual number of signatures.  */
681   if (sigstatus && sigstatus[0] != info->nsigs)
682     return gpg_error (GPG_ERR_INTERNAL);
683
684   blob = xtrycalloc (1, sizeof *blob);
685   if (!blob)
686     return gpg_error_from_syserror ();
687
688   blob->nkeys = 1 + info->nsubkeys;
689   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
690   if (!blob->keys)
691     {
692       err = gpg_error_from_syserror ();
693       goto leave;
694     }
695   blob->nuids = info->nuids;
696   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
697   if (!blob->uids)
698     {
699       err = gpg_error_from_syserror ();
700       goto leave;
701     }
702   blob->nsigs = info->nsigs;
703   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
704   if (!blob->sigs)
705     {
706       err = gpg_error_from_syserror ();
707       goto leave;
708     }
709
710   err = pgp_create_key_part (blob, info);
711   if (err)
712     goto leave;
713   pgp_create_uid_part (blob, info);
714   pgp_create_sig_part (blob, sigstatus);
715
716   init_membuf (&blob->bufbuf, 1024);
717   blob->buf = &blob->bufbuf;
718   err = create_blob_header (blob, BLOBTYPE_PGP, as_ephemeral);
719   if (err)
720     goto leave;
721   err = pgp_create_blob_keyblock (blob, image, imagelen);
722   if (err)
723     goto leave;
724   err = create_blob_trailer (blob);
725   if (err)
726     goto leave;
727   err = create_blob_finish (blob);
728   if (err)
729     goto leave;
730
731  leave:
732   release_kid_list (blob->temp_kids);
733   blob->temp_kids = NULL;
734   if (err)
735     _keybox_release_blob (blob);
736   else
737     *r_blob = blob;
738   return err;
739 }
740
741
742 #ifdef KEYBOX_WITH_X509
743
744 /* Return an allocated string with the email address extracted from a
745    DN.  Note hat we use this code also in ../sm/keylist.c.  */
746 static char *
747 x509_email_kludge (const char *name)
748 {
749   const char *p, *string;
750   unsigned char *buf;
751   int n;
752
753   string = name;
754   for (;;)
755     {
756       p = strstr (string, "1.2.840.113549.1.9.1=#");
757       if (!p)
758         return NULL;
759       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
760         {
761           name = p + 22;
762           break;
763         }
764       string = p + 22;
765     }
766
767
768   /* This looks pretty much like an email address in the subject's DN
769      we use this to add an additional user ID entry.  This way,
770      OpenSSL generated keys get a nicer and usable listing.  */
771   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
772     ;
773   if (!n)
774     return NULL;
775   buf = xtrymalloc (n+3);
776   if (!buf)
777     return NULL; /* oops, out of core */
778   *buf = '<';
779   for (n=1, p=name; hexdigitp (p); p +=2, n++)
780     buf[n] = xtoi_2 (p);
781   buf[n++] = '>';
782   buf[n] = 0;
783   return (char*)buf;
784 }
785
786
787
788 /* Note: We should move calculation of the digest into libksba and
789    remove that parameter */
790 int
791 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
792                           unsigned char *sha1_digest, int as_ephemeral)
793 {
794   int i, rc = 0;
795   KEYBOXBLOB blob;
796   unsigned char *sn;
797   char *p;
798   char **names = NULL;
799   size_t max_names;
800
801   *r_blob = NULL;
802   blob = xtrycalloc (1, sizeof *blob);
803   if( !blob )
804     return gpg_error_from_syserror ();
805
806   sn = ksba_cert_get_serial (cert);
807   if (sn)
808     {
809       size_t n, len;
810       n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
811       if (n < 2)
812         {
813           xfree (sn);
814           return gpg_error (GPG_ERR_GENERAL);
815         }
816       blob->serialbuf = sn;
817       sn++; n--; /* skip '(' */
818       for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
819         len = len*10 + atoi_1 (sn);
820       if (*sn != ':')
821         {
822           xfree (blob->serialbuf);
823           blob->serialbuf = NULL;
824           return gpg_error (GPG_ERR_GENERAL);
825         }
826       sn++;
827       blob->serial = sn;
828       blob->seriallen = len;
829     }
830
831   blob->nkeys = 1;
832
833   /* create list of names */
834   blob->nuids = 0;
835   max_names = 100;
836   names = xtrymalloc (max_names * sizeof *names);
837   if (!names)
838     {
839       rc = gpg_error_from_syserror ();
840       goto leave;
841     }
842
843   p = ksba_cert_get_issuer (cert, 0);
844   if (!p)
845     {
846       rc =  gpg_error (GPG_ERR_MISSING_VALUE);
847       goto leave;
848     }
849   names[blob->nuids++] = p;
850   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
851     {
852       if (blob->nuids >= max_names)
853         {
854           char **tmp;
855
856           max_names += 100;
857           tmp = xtryrealloc (names, max_names * sizeof *names);
858           if (!tmp)
859             {
860               rc = gpg_error_from_syserror ();
861               goto leave;
862             }
863           names = tmp;
864         }
865       names[blob->nuids++] = p;
866       if (!i && (p=x509_email_kludge (p)))
867         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
868     }
869
870   /* space for signature information */
871   blob->nsigs = 1;
872
873   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
874   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
875   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
876   if (!blob->keys || !blob->uids || !blob->sigs)
877     {
878       rc = gpg_error (GPG_ERR_ENOMEM);
879       goto leave;
880     }
881
882   memcpy (blob->keys[0].fpr, sha1_digest, 20);
883   blob->keys[0].off_kid = 0; /* We don't have keyids */
884   blob->keys[0].flags = 0;
885
886   /* issuer and subject names */
887   for (i=0; i < blob->nuids; i++)
888     {
889       blob->uids[i].name = names[i];
890       blob->uids[i].len = strlen(names[i]);
891       names[i] = NULL;
892       blob->uids[i].flags = 0;
893       blob->uids[i].validity = 0;
894     }
895   xfree (names);
896   names = NULL;
897
898   /* signatures */
899   blob->sigs[0] = 0;    /* not yet checked */
900
901   /* Create a temporary buffer for further processing */
902   init_membuf (&blob->bufbuf, 1024);
903   blob->buf = &blob->bufbuf;
904   /* write out what we already have */
905   rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
906   if (rc)
907     goto leave;
908   rc = x509_create_blob_cert (blob, cert);
909   if (rc)
910     goto leave;
911   rc = create_blob_trailer (blob);
912   if (rc)
913     goto leave;
914   rc = create_blob_finish ( blob );
915   if (rc)
916     goto leave;
917
918
919  leave:
920   release_kid_list (blob->temp_kids);
921   blob->temp_kids = NULL;
922   if (blob && names)
923     {
924       for (i=0; i < blob->nuids; i++)
925         xfree (names[i]);
926     }
927   xfree (names);
928   if (rc)
929     {
930       _keybox_release_blob (blob);
931       *r_blob = NULL;
932     }
933   else
934     {
935       *r_blob = blob;
936     }
937   return rc;
938 }
939 #endif /*KEYBOX_WITH_X509*/
940
941
942 \f
943 int
944 _keybox_new_blob (KEYBOXBLOB *r_blob,
945                   unsigned char *image, size_t imagelen, off_t off)
946 {
947   KEYBOXBLOB blob;
948
949   *r_blob = NULL;
950   blob = xtrycalloc (1, sizeof *blob);
951   if (!blob)
952     return gpg_error_from_syserror ();
953
954   blob->blob = image;
955   blob->bloblen = imagelen;
956   blob->fileoffset = off;
957   *r_blob = blob;
958   return 0;
959 }
960
961
962 void
963 _keybox_release_blob (KEYBOXBLOB blob)
964 {
965   int i;
966   if (!blob)
967     return;
968   /* hmmm: release membuf here?*/
969   xfree (blob->keys );
970   xfree (blob->serialbuf);
971   for (i=0; i < blob->nuids; i++)
972     xfree (blob->uids[i].name);
973   xfree (blob->uids );
974   xfree (blob->sigs );
975   xfree (blob->blob );
976   xfree (blob );
977 }
978
979
980
981 const unsigned char *
982 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
983 {
984   *n = blob->bloblen;
985   return blob->blob;
986 }
987
988 off_t
989 _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
990 {
991   return blob->fileoffset;
992 }
993
994
995
996 void
997 _keybox_update_header_blob (KEYBOXBLOB blob)
998 {
999   if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
1000     {
1001       u32 val = make_timestamp ();
1002
1003       /* Update the last maintenance run times tamp. */
1004       blob->blob[20]   = (val >> 24);
1005       blob->blob[20+1] = (val >> 16);
1006       blob->blob[20+2] = (val >>  8);
1007       blob->blob[20+3] = (val      );
1008     }
1009 }