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