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