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