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