f3bc859b3fb83e867d3ab5131c24ce4f9d2c1c10
[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 *serialbuf;
176   const 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
772 /* return an allocated string with the email address extracted from a
773    DN */
774 static char *
775 x509_email_kludge (const char *name)
776 {
777   const unsigned char *p;
778   unsigned char *buf;
779   int n;
780
781   if (strncmp (name, "1.2.840.113549.1.9.1=#", 22))
782     return NULL;
783   /* This looks pretty much like an email address in the subject's DN
784      we use this to add an additional user ID entry.  This way,
785      openSSL generated keys get a nicer and usable listing */
786   name += 22;    
787   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
788     ;
789   if (*p != '#' || !n)
790     return NULL;
791   buf = xtrymalloc (n+3);
792   if (!buf)
793     return NULL; /* oops, out of core */
794   *buf = '<';
795   for (n=1, p=name; *p != '#'; p +=2, n++)
796     buf[n] = xtoi_2 (p);
797   buf[n++] = '>';
798   buf[n] = 0;
799   return buf;
800 }
801
802
803
804 /* Note: We should move calculation of the digest into libksba and
805    remove that parameter */
806 int
807 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
808                           unsigned char *sha1_digest)
809 {
810   int i, rc = 0;
811   KEYBOXBLOB blob;
812   unsigned char *p;
813   unsigned char **names = NULL;
814   size_t max_names;
815
816   *r_blob = NULL;
817   blob = xtrycalloc (1, sizeof *blob);
818   if( !blob )
819     return KEYBOX_Out_Of_Core;
820
821   p = ksba_cert_get_serial (cert);
822   if (p)
823     {
824       size_t n;
825       n = gcry_sexp_canon_len (p, 0, NULL, NULL);
826       if (!n)
827         return KEYBOX_General_Error;
828       blob->serialbuf = p;
829       for (; n && *p != ':'; n--, p++)
830         ;
831       p++;
832       blob->seriallen = n;
833       blob->serial = p;
834     }
835
836   blob->nkeys = 1;
837
838   /* create list of names */
839   blob->nuids = 0;
840   max_names = 100;
841   names = xtrymalloc (max_names * sizeof *names);
842   if (!names)
843     {
844       rc = KEYBOX_Out_Of_Core;
845       goto leave;
846     }
847   p = ksba_cert_get_issuer (cert, 0);
848   if (!p)
849     {
850       rc =  KEYBOX_Missing_Value;
851       goto leave;
852     }
853   names[blob->nuids++] = p;
854   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
855     {
856
857       if (blob->nuids >= max_names)
858         {
859           unsigned char **tmp;
860           
861           max_names += 100;
862           tmp = xtryrealloc (names, max_names * sizeof *names);
863           if (!tmp)
864             {
865               rc = KEYBOX_Out_Of_Core;
866               goto leave;
867             }
868         }
869       names[blob->nuids++] = p;
870       if (!i && (p=x509_email_kludge (p)))
871         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
872     }
873   
874   /* space for signature information */
875   blob->nsigs = 1; 
876
877   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
878   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
879   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
880   if (!blob->keys || !blob->uids || !blob->sigs)
881     {
882       rc = KEYBOX_Out_Of_Core;
883       goto leave;
884     }
885
886   memcpy (blob->keys[0].fpr, sha1_digest, 20);
887   blob->keys[0].off_kid = 0; /* We don't have keyids */
888   blob->keys[0].flags = 0;
889
890   /* issuer and subject names */
891   for (i=0; i < blob->nuids; i++)
892     {
893       blob->uids[i].name = names[i];
894       blob->uids[i].len = strlen(names[i]);
895       names[i] = NULL;
896       blob->uids[i].flags = 0;
897       blob->uids[i].validity = 0;
898     }
899   xfree (names);
900   names = NULL;
901
902   /* signatures */
903   blob->sigs[0] = 0;    /* not yet checked */
904
905   /* Create a temporary buffer for further processing */
906   init_membuf (&blob->bufbuf, 1024);
907   blob->buf = &blob->bufbuf;
908   /* write out what we already have */
909   rc = create_blob_header (blob, BLOBTYPE_X509);
910   if (rc)
911     goto leave;
912   rc = x509_create_blob_cert (blob, cert);
913   if (rc)
914     goto leave;
915   rc = create_blob_trailer (blob);
916   if (rc)
917     goto leave;
918   rc = create_blob_finish ( blob );
919   if (rc)
920     goto leave;
921
922   
923  leave:
924   release_kid_list (blob->temp_kids);
925   blob->temp_kids = NULL;
926   if (blob && names)
927     {
928       for (i=0; i < blob->nuids; i++)
929         xfree (names[i]); 
930     }
931   xfree (names);
932   if (rc)
933     {
934       _keybox_release_blob (blob);
935       *r_blob = NULL;
936     }
937   else
938     {
939       *r_blob = blob;
940     }
941   return rc;
942 }
943 #endif /*KEYBOX_WITH_X509*/
944
945
946 \f
947 int
948 _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen)
949 {
950   KEYBOXBLOB blob;
951   
952   *r_blob = NULL;
953   blob = xtrycalloc (1, sizeof *blob);
954   if (!blob)
955     return KEYBOX_Out_Of_Core;
956
957   blob->blob = image;
958   blob->bloblen = imagelen;
959   *r_blob = blob;
960   return 0;
961 }
962
963 void
964 _keybox_release_blob (KEYBOXBLOB blob)
965 {
966   int i;
967   if (!blob)
968     return;
969   /* hmmm: release membuf here?*/
970   xfree (blob->keys );
971   xfree (blob->serialbuf);
972   for (i=0; i < blob->nuids; i++)
973     xfree (blob->uids[i].name);
974   xfree (blob->uids );
975   xfree (blob->sigs );
976   xfree (blob->blob );
977   xfree (blob );
978 }
979
980
981
982 const char *
983 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
984 {
985     *n = blob->bloblen;
986     return blob->blob;
987 }