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