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