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