gpg: First working support for keyboxes.
[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)
412 {
413   int n;
414
415   for (n=0; n < blob->nsigs; n++)
416     {
417       blob->sigs[n] = 0;  /* FIXME: check the signature here */
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 \f
662 gpg_error_t
663 _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
664                              keybox_openpgp_info_t info,
665                              const unsigned char *image,
666                              size_t imagelen,
667                              int as_ephemeral)
668 {
669   gpg_error_t err;
670   KEYBOXBLOB blob;
671
672   *r_blob = NULL;
673
674   if (!info->nuids || !info->nsigs)
675     return gpg_error (GPG_ERR_BAD_PUBKEY);
676
677   blob = xtrycalloc (1, sizeof *blob);
678   if (!blob)
679     return gpg_error_from_syserror ();
680
681   blob->nkeys = 1 + info->nsubkeys;
682   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
683   if (!blob->keys)
684     {
685       err = gpg_error_from_syserror ();
686       goto leave;
687     }
688   blob->nuids = info->nuids;
689   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
690   if (!blob->uids)
691     {
692       err = gpg_error_from_syserror ();
693       goto leave;
694     }
695   blob->nsigs = info->nsigs;
696   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
697   if (!blob->sigs)
698     {
699       err = gpg_error_from_syserror ();
700       goto leave;
701     }
702
703   err = pgp_create_key_part (blob, info);
704   if (err)
705     goto leave;
706   pgp_create_uid_part (blob, info);
707   pgp_create_sig_part (blob);
708
709   init_membuf (&blob->bufbuf, 1024);
710   blob->buf = &blob->bufbuf;
711   err = create_blob_header (blob, BLOBTYPE_PGP, as_ephemeral);
712   if (err)
713     goto leave;
714   err = pgp_create_blob_keyblock (blob, image, imagelen);
715   if (err)
716     goto leave;
717   err = create_blob_trailer (blob);
718   if (err)
719     goto leave;
720   err = create_blob_finish (blob);
721   if (err)
722     goto leave;
723
724  leave:
725   release_kid_list (blob->temp_kids);
726   blob->temp_kids = NULL;
727   if (err)
728     _keybox_release_blob (blob);
729   else
730     *r_blob = blob;
731   return err;
732 }
733
734
735 #ifdef KEYBOX_WITH_X509
736
737 /* Return an allocated string with the email address extracted from a
738    DN.  Note hat we use this code also in ../sm/keylist.c.  */
739 static char *
740 x509_email_kludge (const char *name)
741 {
742   const char *p, *string;
743   unsigned char *buf;
744   int n;
745
746   string = name;
747   for (;;)
748     {
749       p = strstr (string, "1.2.840.113549.1.9.1=#");
750       if (!p)
751         return NULL;
752       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
753         {
754           name = p + 22;
755           break;
756         }
757       string = p + 22;
758     }
759
760
761   /* This looks pretty much like an email address in the subject's DN
762      we use this to add an additional user ID entry.  This way,
763      OpenSSL generated keys get a nicer and usable listing.  */
764   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
765     ;
766   if (!n)
767     return NULL;
768   buf = xtrymalloc (n+3);
769   if (!buf)
770     return NULL; /* oops, out of core */
771   *buf = '<';
772   for (n=1, p=name; hexdigitp (p); p +=2, n++)
773     buf[n] = xtoi_2 (p);
774   buf[n++] = '>';
775   buf[n] = 0;
776   return (char*)buf;
777 }
778
779
780
781 /* Note: We should move calculation of the digest into libksba and
782    remove that parameter */
783 int
784 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
785                           unsigned char *sha1_digest, int as_ephemeral)
786 {
787   int i, rc = 0;
788   KEYBOXBLOB blob;
789   unsigned char *sn;
790   char *p;
791   char **names = NULL;
792   size_t max_names;
793
794   *r_blob = NULL;
795   blob = xtrycalloc (1, sizeof *blob);
796   if( !blob )
797     return gpg_error_from_syserror ();
798
799   sn = ksba_cert_get_serial (cert);
800   if (sn)
801     {
802       size_t n, len;
803       n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
804       if (n < 2)
805         {
806           xfree (sn);
807           return gpg_error (GPG_ERR_GENERAL);
808         }
809       blob->serialbuf = sn;
810       sn++; n--; /* skip '(' */
811       for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
812         len = len*10 + atoi_1 (sn);
813       if (*sn != ':')
814         {
815           xfree (blob->serialbuf);
816           blob->serialbuf = NULL;
817           return gpg_error (GPG_ERR_GENERAL);
818         }
819       sn++;
820       blob->serial = sn;
821       blob->seriallen = len;
822     }
823
824   blob->nkeys = 1;
825
826   /* create list of names */
827   blob->nuids = 0;
828   max_names = 100;
829   names = xtrymalloc (max_names * sizeof *names);
830   if (!names)
831     {
832       rc = gpg_error_from_syserror ();
833       goto leave;
834     }
835
836   p = ksba_cert_get_issuer (cert, 0);
837   if (!p)
838     {
839       rc =  gpg_error (GPG_ERR_MISSING_VALUE);
840       goto leave;
841     }
842   names[blob->nuids++] = p;
843   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
844     {
845       if (blob->nuids >= max_names)
846         {
847           char **tmp;
848
849           max_names += 100;
850           tmp = xtryrealloc (names, max_names * sizeof *names);
851           if (!tmp)
852             {
853               rc = gpg_error_from_syserror ();
854               goto leave;
855             }
856           names = tmp;
857         }
858       names[blob->nuids++] = p;
859       if (!i && (p=x509_email_kludge (p)))
860         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
861     }
862
863   /* space for signature information */
864   blob->nsigs = 1;
865
866   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
867   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
868   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
869   if (!blob->keys || !blob->uids || !blob->sigs)
870     {
871       rc = gpg_error (GPG_ERR_ENOMEM);
872       goto leave;
873     }
874
875   memcpy (blob->keys[0].fpr, sha1_digest, 20);
876   blob->keys[0].off_kid = 0; /* We don't have keyids */
877   blob->keys[0].flags = 0;
878
879   /* issuer and subject names */
880   for (i=0; i < blob->nuids; i++)
881     {
882       blob->uids[i].name = names[i];
883       blob->uids[i].len = strlen(names[i]);
884       names[i] = NULL;
885       blob->uids[i].flags = 0;
886       blob->uids[i].validity = 0;
887     }
888   xfree (names);
889   names = NULL;
890
891   /* signatures */
892   blob->sigs[0] = 0;    /* not yet checked */
893
894   /* Create a temporary buffer for further processing */
895   init_membuf (&blob->bufbuf, 1024);
896   blob->buf = &blob->bufbuf;
897   /* write out what we already have */
898   rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
899   if (rc)
900     goto leave;
901   rc = x509_create_blob_cert (blob, cert);
902   if (rc)
903     goto leave;
904   rc = create_blob_trailer (blob);
905   if (rc)
906     goto leave;
907   rc = create_blob_finish ( blob );
908   if (rc)
909     goto leave;
910
911
912  leave:
913   release_kid_list (blob->temp_kids);
914   blob->temp_kids = NULL;
915   if (blob && names)
916     {
917       for (i=0; i < blob->nuids; i++)
918         xfree (names[i]);
919     }
920   xfree (names);
921   if (rc)
922     {
923       _keybox_release_blob (blob);
924       *r_blob = NULL;
925     }
926   else
927     {
928       *r_blob = blob;
929     }
930   return rc;
931 }
932 #endif /*KEYBOX_WITH_X509*/
933
934
935 \f
936 int
937 _keybox_new_blob (KEYBOXBLOB *r_blob,
938                   unsigned char *image, size_t imagelen, off_t off)
939 {
940   KEYBOXBLOB blob;
941
942   *r_blob = NULL;
943   blob = xtrycalloc (1, sizeof *blob);
944   if (!blob)
945     return gpg_error_from_syserror ();
946
947   blob->blob = image;
948   blob->bloblen = imagelen;
949   blob->fileoffset = off;
950   *r_blob = blob;
951   return 0;
952 }
953
954
955 void
956 _keybox_release_blob (KEYBOXBLOB blob)
957 {
958   int i;
959   if (!blob)
960     return;
961   /* hmmm: release membuf here?*/
962   xfree (blob->keys );
963   xfree (blob->serialbuf);
964   for (i=0; i < blob->nuids; i++)
965     xfree (blob->uids[i].name);
966   xfree (blob->uids );
967   xfree (blob->sigs );
968   xfree (blob->blob );
969   xfree (blob );
970 }
971
972
973
974 const unsigned char *
975 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
976 {
977   *n = blob->bloblen;
978   return blob->blob;
979 }
980
981 off_t
982 _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
983 {
984   return blob->fileoffset;
985 }
986
987
988
989 void
990 _keybox_update_header_blob (KEYBOXBLOB blob)
991 {
992   if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
993     {
994       u32 val = make_timestamp ();
995
996       /* Update the last maintenance run times tamp. */
997       blob->blob[20]   = (val >> 24);
998       blob->blob[20+1] = (val >> 16);
999       blob->blob[20+2] = (val >>  8);
1000       blob->blob[20+3] = (val      );
1001     }
1002 }