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