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