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