Fixed an email/DN bug.
[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
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_OPENPGP
123 /* include stuff to parse the packets */
124 #endif
125 #ifdef KEYBOX_WITH_X509
126 #include <ksba.h>
127 #endif
128
129
130
131 /* special values of the signature status */
132 #define SF_NONE(a)  ( !(a) )
133 #define SF_NOKEY(a) ((a) & (1<<0))
134 #define SF_BAD(a)   ((a) & (1<<1))
135 #define SF_VALID(a) ((a) & (1<<29))
136
137
138 struct membuf {
139   size_t len;
140   size_t size;
141   char *buf;
142   int out_of_core;
143 };
144
145
146 /*  #if MAX_FINGERPRINT_LEN < 20 */
147 /*    #error fingerprints are 20 bytes */
148 /*  #endif */
149
150 struct keyboxblob_key {
151   char   fpr[20];
152   u32    off_kid;
153   ulong  off_kid_addr;
154   u16    flags;
155 };
156 struct keyboxblob_uid {
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 \f
311 /*
312  Some wrappers
313 */
314
315 static u32
316 make_timestamp (void)
317 {
318   return time(NULL);
319 }
320
321
322 \f
323 #ifdef KEYBOX_WITH_OPENPGP
324 /*
325   OpenPGP specific stuff 
326 */
327
328
329 /*
330   We must store the keyid at some place because we can't calculate the
331   offset yet. This is only used for v3 keyIDs.  Function returns an
332   index value for later fixup or -1 for out of core. The value must be
333   a non-zero value */
334 static int
335 pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
336 {
337   struct keyid_list *k, *r;
338   
339   k = xtrymalloc (sizeof *k); 
340   if (!k)
341     return -1;
342   k->kid[0] = pk->keyid[0] >> 24 ;
343   k->kid[1] = pk->keyid[0] >> 16 ;
344   k->kid[2] = pk->keyid[0] >>  8 ;
345   k->kid[3] = pk->keyid[0]         ;
346   k->kid[4] = pk->keyid[0] >> 24 ;
347   k->kid[5] = pk->keyid[0] >> 16 ;
348   k->kid[6] = pk->keyid[0] >>  8 ;
349   k->kid[7] = pk->keyid[0]         ;
350   k->seqno = 0;
351   k->next = blob->temp_kids;
352   blob->temp_kids = k;
353   for (r=k; r; r = r->next) 
354     k->seqno++;
355   
356   return k->seqno;
357 }
358
359 static int
360 pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
361 {
362   KBNODE node;
363   size_t fprlen;
364   int n;
365
366   for (n=0, node = keyblock; node; node = node->next)
367     {
368       if ( node->pkt->pkttype == PKT_PUBLIC_KEY
369            || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) 
370         {
371           PKT_public_key *pk = node->pkt->pkt.public_key;
372           char tmp[20];
373
374           fingerprint_from_pk (pk, tmp , &fprlen);
375           memcpy (blob->keys[n].fpr, tmp, 20);
376           if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
377             {
378               assert (fprlen == 16);
379               memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
380               memset (blob->keys[n].fpr, 0, 4);
381               blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
382             }
383           else
384             {
385               blob->keys[n].off_kid = 0; /* will be fixed up later */
386             }
387           blob->keys[n].flags = 0;
388           n++;
389         }
390       else if ( node->pkt->pkttype == PKT_SECRET_KEY
391                   || node->pkt->pkttype == PKT_SECRET_SUBKEY ) 
392         {
393           never_reached (); /* actually not yet implemented */
394         }
395     }
396   assert (n == blob->nkeys);
397   return 0;
398 }
399
400 static int
401 pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
402 {
403   KBNODE node;
404   int n;
405
406   for (n=0, node = keyblock; node; node = node->next)
407     {
408       if (node->pkt->pkttype == PKT_USER_ID)
409         {
410           PKT_user_id *u = node->pkt->pkt.user_id;
411           
412           blob->uids[n].len = u->len;
413           blob->uids[n].flags = 0;
414           blob->uids[n].validity = 0;
415           n++;
416         }
417     }
418   assert (n == blob->nuids);
419   return 0;
420 }
421
422 static int
423 pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
424 {
425   KBNODE node;
426   int n;
427   
428   for (n=0, node = keyblock; node; node = node->next)
429     {
430       if (node->pkt->pkttype == PKT_SIGNATURE)
431         {
432           PKT_signature *sig = node->pkt->pkt.signature;
433           
434           blob->sigs[n] = 0;    /* FIXME: check the signature here */
435           n++;
436         }
437     }
438   assert( n == blob->nsigs );
439   return 0;
440 }
441
442 static int
443 pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
444 {
445   struct membuf *a = blob->buf;
446   KBNODE node;
447   int rc;
448   int n;
449   u32 kbstart = a->len;
450
451   add_fixup (blob, kbstart);
452
453   for (n = 0, node = keyblock; node; node = node->next)
454     {
455       rc = build_packet ( a, node->pkt );
456       if ( rc ) {
457         gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
458                       node->pkt->pkttype, gpg_errstr(rc) );
459         return GPGERR_WRITE_FILE;
460       }
461       if ( node->pkt->pkttype == PKT_USER_ID ) 
462         {
463           PKT_user_id *u = node->pkt->pkt.user_id;
464           /* build_packet has set the offset of the name into u ;
465            * now we can do the fixup */
466           add_fixup (blob, blob->uids[n].off_addr, u->stored_at);
467           n++;
468         }
469     }
470   assert (n == blob->nuids);
471
472   add_fixup (blob, a->len - kbstart);
473   return 0;
474 }
475  
476 #endif /*KEYBOX_WITH_OPENPGP*/
477
478 \f
479 #ifdef KEYBOX_WITH_X509
480 /* 
481    X.509 specific stuff
482  */
483
484 /* Write the raw certificate out */
485 static int
486 x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
487 {
488   struct membuf *a = blob->buf;
489   const unsigned char *image;
490   size_t length;
491   u32 kbstart = a->len;
492
493   /* Store our offset for later fixup */
494   add_fixup (blob, 8, kbstart);
495
496   image = ksba_cert_get_image (cert, &length);
497   if (!image)
498     return gpg_error (GPG_ERR_GENERAL);
499   put_membuf (a, image, length);
500
501   add_fixup (blob, 12, a->len - kbstart);
502   return 0;
503 }
504  
505 #endif /*KEYBOX_WITH_X509*/
506
507 /* Write a stored keyID out to the buffer */
508 static void
509 write_stored_kid (KEYBOXBLOB blob, int seqno)
510 {
511   struct keyid_list *r;
512   
513   for ( r = blob->temp_kids; r; r = r->next ) 
514     {
515       if (r->seqno == seqno )
516         {
517           put_membuf (blob->buf, r->kid, 8);
518           return;
519         }
520     }
521   never_reached ();
522 }
523
524 /* Release a list of key IDs */
525 static void
526 release_kid_list (struct keyid_list *kl)
527 {
528   struct keyid_list *r, *r2;
529   
530   for ( r = kl; r; r = r2 ) 
531     {
532       r2 = r->next;
533       xfree (r);
534     }
535 }
536
537
538
539 static int
540 create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
541 {
542   struct membuf *a = blob->buf;
543   int i;
544
545   put32 ( a, 0 ); /* blob length, needs fixup */
546   put8 ( a, blobtype);  
547   put8 ( a, 1 );  /* blob type version */
548   put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
549
550   put32 ( a, 0 ); /* offset to the raw data, needs fixup */
551   put32 ( a, 0 ); /* length of the raw data, needs fixup */
552
553   put16 ( a, blob->nkeys );
554   put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
555   for ( i=0; i < blob->nkeys; i++ )
556     {
557       put_membuf (a, blob->keys[i].fpr, 20);
558       blob->keys[i].off_kid_addr = a->len;
559       put32 ( a, 0 ); /* offset to keyid, fixed up later */
560       put16 ( a, blob->keys[i].flags );
561       put16 ( a, 0 ); /* reserved */
562     }
563
564   put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
565   if (blob->serial)
566     put_membuf (a, blob->serial, blob->seriallen);
567
568   put16 ( a, blob->nuids );
569   put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
570   for (i=0; i < blob->nuids; i++)
571     {
572       blob->uids[i].off_addr = a->len;
573       put32 ( a, 0 ); /* offset to userid, fixed up later */
574       put32 ( a, blob->uids[i].len );
575       put16 ( a, blob->uids[i].flags );
576       put8  ( a, 0 ); /* validity */
577       put8  ( a, 0 ); /* reserved */
578     }
579
580   put16 ( a, blob->nsigs );
581   put16 ( a, 4 );  /* size of sig info */
582   for (i=0; i < blob->nsigs; i++)
583     {
584       put32 ( a, blob->sigs[i]);
585     }
586
587   put8 ( a, 0 );  /* assigned ownertrust */
588   put8 ( a, 0 );  /* validity of all user IDs */
589   put16 ( a, 0 );  /* reserved */
590   put32 ( a, 0 );  /* time of next recheck */
591   put32 ( a, 0 );  /* newest timestamp (none) */
592   put32 ( a, make_timestamp() );  /* creation time */
593   put32 ( a, 0 );  /* size of reserved space */
594   /* reserved space (which is currently of size 0) */
595
596   /* space where we write keyIDs and and other stuff so that the
597      pointers can actually point to somewhere */
598   if (blobtype == BLOBTYPE_PGP)
599     {
600       /* We need to store the keyids for all pgp v3 keys because those key
601          IDs are not part of the fingerprint.  While we are doing that, we
602          fixup all the keyID offsets */
603       for (i=0; i < blob->nkeys; i++ )
604         {
605           if (blob->keys[i].off_kid) 
606             { /* this is a v3 one */
607               add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
608               write_stored_kid (blob, blob->keys[i].off_kid);
609             }
610           else
611             { /* the better v4 key IDs - just store an offset 8 bytes back */
612               add_fixup (blob, blob->keys[i].off_kid_addr,
613                          blob->keys[i].off_kid_addr - 8); 
614             }
615         }
616     }
617   
618   if (blobtype == BLOBTYPE_X509)
619     {
620       /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
621          the utf-8 string represenation of them */
622       for (i=0; i < blob->nuids; i++ )
623         {
624           if (blob->uids[i].name) 
625             { /* this is a v3 one */
626               add_fixup (blob, blob->uids[i].off_addr, a->len);
627               put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
628             }
629         }
630     }
631
632     return 0;
633 }
634
635
636
637 static int
638 create_blob_trailer (KEYBOXBLOB blob)
639 {
640     return 0;
641 }
642
643
644 static int
645 create_blob_finish (KEYBOXBLOB blob)
646 {
647   struct membuf *a = blob->buf;
648   unsigned char *p;
649   unsigned char *pp;
650   int i;
651   size_t n;
652
653   /* write a placeholder for the checksum */
654   for (i = 0; i < 16; i++ )
655     put32 (a, 0);  /* Hmmm: why put32() ?? */
656   
657   /* get the memory area */
658   n = 0; /* (Just to avoid compiler warning.) */
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.  Note hat we use this code also in ../sm/keylist.c.  */
783 static char *
784 x509_email_kludge (const char *name)
785 {
786   const char *p, *string;
787   unsigned char *buf;
788   int n;
789
790   string = name;
791   for (;;)
792     {
793       p = strstr (string, "1.2.840.113549.1.9.1=#");
794       if (!p)
795         return NULL;
796       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
797         {
798           name = p + 22;
799           break;
800         }
801       string = p + 22;
802     }
803
804
805   /* This looks pretty much like an email address in the subject's DN
806      we use this to add an additional user ID entry.  This way,
807      OpenSSL generated keys get a nicer and usable listing.  */
808   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
809     ;
810   if (!n)
811     return NULL;
812   buf = xtrymalloc (n+3);
813   if (!buf)
814     return NULL; /* oops, out of core */
815   *buf = '<';
816   for (n=1, p=name; hexdigitp (p); p +=2, n++)
817     buf[n] = xtoi_2 (p);
818   buf[n++] = '>';
819   buf[n] = 0;
820   return (char*)buf;
821 }
822
823
824
825 /* Note: We should move calculation of the digest into libksba and
826    remove that parameter */
827 int
828 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
829                           unsigned char *sha1_digest, int as_ephemeral)
830 {
831   int i, rc = 0;
832   KEYBOXBLOB blob;
833   unsigned char *sn;
834   char *p;
835   char **names = NULL;
836   size_t max_names;
837
838   *r_blob = NULL;
839   blob = xtrycalloc (1, sizeof *blob);
840   if( !blob )
841     return gpg_error (gpg_err_code_from_errno (errno));
842
843   sn = ksba_cert_get_serial (cert);
844   if (sn)
845     {
846       size_t n, len;
847       n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
848       if (n < 2)
849         {
850           xfree (sn);
851           return gpg_error (GPG_ERR_GENERAL);
852         }
853       blob->serialbuf = sn;
854       sn++; n--; /* skip '(' */
855       for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
856         len = len*10 + atoi_1 (sn);
857       if (*sn != ':')
858         {
859           xfree (blob->serialbuf);
860           blob->serialbuf = NULL;
861           return gpg_error (GPG_ERR_GENERAL);
862         }
863       sn++;
864       blob->serial = sn;
865       blob->seriallen = len;
866     }
867
868   blob->nkeys = 1;
869
870   /* create list of names */
871   blob->nuids = 0;
872   max_names = 100;
873   names = xtrymalloc (max_names * sizeof *names);
874   if (!names)
875     {
876       rc = gpg_error (gpg_err_code_from_errno (errno));
877       goto leave;
878     }
879   
880   p = ksba_cert_get_issuer (cert, 0);
881   if (!p)
882     {
883       rc =  gpg_error (GPG_ERR_MISSING_VALUE);
884       goto leave;
885     }
886   names[blob->nuids++] = p;
887   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
888     {
889       if (blob->nuids >= max_names)
890         {
891           char **tmp;
892           
893           max_names += 100;
894           tmp = xtryrealloc (names, max_names * sizeof *names);
895           if (!tmp)
896             {
897               rc = gpg_error (gpg_err_code_from_errno (errno));
898               goto leave;
899             }
900         }
901       names[blob->nuids++] = p;
902       if (!i && (p=x509_email_kludge (p)))
903         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
904     }
905   
906   /* space for signature information */
907   blob->nsigs = 1; 
908
909   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
910   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
911   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
912   if (!blob->keys || !blob->uids || !blob->sigs)
913     {
914       rc = gpg_error (GPG_ERR_ENOMEM);
915       goto leave;
916     }
917
918   memcpy (blob->keys[0].fpr, sha1_digest, 20);
919   blob->keys[0].off_kid = 0; /* We don't have keyids */
920   blob->keys[0].flags = 0;
921
922   /* issuer and subject names */
923   for (i=0; i < blob->nuids; i++)
924     {
925       blob->uids[i].name = names[i];
926       blob->uids[i].len = strlen(names[i]);
927       names[i] = NULL;
928       blob->uids[i].flags = 0;
929       blob->uids[i].validity = 0;
930     }
931   xfree (names);
932   names = NULL;
933
934   /* signatures */
935   blob->sigs[0] = 0;    /* not yet checked */
936
937   /* Create a temporary buffer for further processing */
938   init_membuf (&blob->bufbuf, 1024);
939   blob->buf = &blob->bufbuf;
940   /* write out what we already have */
941   rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
942   if (rc)
943     goto leave;
944   rc = x509_create_blob_cert (blob, cert);
945   if (rc)
946     goto leave;
947   rc = create_blob_trailer (blob);
948   if (rc)
949     goto leave;
950   rc = create_blob_finish ( blob );
951   if (rc)
952     goto leave;
953
954   
955  leave:
956   release_kid_list (blob->temp_kids);
957   blob->temp_kids = NULL;
958   if (blob && names)
959     {
960       for (i=0; i < blob->nuids; i++)
961         xfree (names[i]); 
962     }
963   xfree (names);
964   if (rc)
965     {
966       _keybox_release_blob (blob);
967       *r_blob = NULL;
968     }
969   else
970     {
971       *r_blob = blob;
972     }
973   return rc;
974 }
975 #endif /*KEYBOX_WITH_X509*/
976
977
978 \f
979 int
980 _keybox_new_blob (KEYBOXBLOB *r_blob,
981                   unsigned char *image, size_t imagelen, off_t off)
982 {
983   KEYBOXBLOB blob;
984   
985   *r_blob = NULL;
986   blob = xtrycalloc (1, sizeof *blob);
987   if (!blob)
988     return gpg_error (gpg_err_code_from_errno (errno));
989
990   blob->blob = image;
991   blob->bloblen = imagelen;
992   blob->fileoffset = off;
993   *r_blob = blob;
994   return 0;
995 }
996
997
998 void
999 _keybox_release_blob (KEYBOXBLOB blob)
1000 {
1001   int i;
1002   if (!blob)
1003     return;
1004   /* hmmm: release membuf here?*/
1005   xfree (blob->keys );
1006   xfree (blob->serialbuf);
1007   for (i=0; i < blob->nuids; i++)
1008     xfree (blob->uids[i].name);
1009   xfree (blob->uids );
1010   xfree (blob->sigs );
1011   xfree (blob->blob );
1012   xfree (blob );
1013 }
1014
1015
1016
1017 const unsigned char *
1018 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
1019 {
1020   *n = blob->bloblen;
1021   return blob->blob;
1022 }
1023
1024 off_t
1025 _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
1026 {
1027   return blob->fileoffset;
1028 }
1029
1030
1031
1032 void
1033 _keybox_update_header_blob (KEYBOXBLOB blob)
1034 {
1035   if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
1036     {
1037       u32 val = make_timestamp ();
1038
1039       /* Update the last maintenance run times tamp. */
1040       blob->blob[20]   = (val >> 24);
1041       blob->blob[20+1] = (val >> 16);
1042       blob->blob[20+2] = (val >>  8);
1043       blob->blob[20+3] = (val      );
1044     }
1045 }