a14499311e63a2a0ef040077a2bede4b8ba04d16
[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 #include "../common/gettime.h"
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
313 \f
314 #ifdef KEYBOX_WITH_OPENPGP
315 /*
316   OpenPGP specific stuff 
317 */
318
319
320 /*
321   We must store the keyid at some place because we can't calculate the
322   offset yet. This is only used for v3 keyIDs.  Function returns an
323   index value for later fixup or -1 for out of core. The value must be
324   a non-zero value */
325 static int
326 pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
327 {
328   struct keyid_list *k, *r;
329   
330   k = xtrymalloc (sizeof *k); 
331   if (!k)
332     return -1;
333   k->kid[0] = pk->keyid[0] >> 24 ;
334   k->kid[1] = pk->keyid[0] >> 16 ;
335   k->kid[2] = pk->keyid[0] >>  8 ;
336   k->kid[3] = pk->keyid[0]         ;
337   k->kid[4] = pk->keyid[0] >> 24 ;
338   k->kid[5] = pk->keyid[0] >> 16 ;
339   k->kid[6] = pk->keyid[0] >>  8 ;
340   k->kid[7] = pk->keyid[0]         ;
341   k->seqno = 0;
342   k->next = blob->temp_kids;
343   blob->temp_kids = k;
344   for (r=k; r; r = r->next) 
345     k->seqno++;
346   
347   return k->seqno;
348 }
349
350 static int
351 pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
352 {
353   KBNODE node;
354   size_t fprlen;
355   int n;
356
357   for (n=0, node = keyblock; node; node = node->next)
358     {
359       if ( node->pkt->pkttype == PKT_PUBLIC_KEY
360            || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) 
361         {
362           PKT_public_key *pk = node->pkt->pkt.public_key;
363           char tmp[20];
364
365           fingerprint_from_pk (pk, tmp , &fprlen);
366           memcpy (blob->keys[n].fpr, tmp, 20);
367           if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
368             {
369               assert (fprlen == 16);
370               memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
371               memset (blob->keys[n].fpr, 0, 4);
372               blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
373             }
374           else
375             {
376               blob->keys[n].off_kid = 0; /* will be fixed up later */
377             }
378           blob->keys[n].flags = 0;
379           n++;
380         }
381       else if ( node->pkt->pkttype == PKT_SECRET_KEY
382                   || node->pkt->pkttype == PKT_SECRET_SUBKEY ) 
383         {
384           never_reached (); /* actually not yet implemented */
385         }
386     }
387   assert (n == blob->nkeys);
388   return 0;
389 }
390
391 static int
392 pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
393 {
394   KBNODE node;
395   int n;
396
397   for (n=0, node = keyblock; node; node = node->next)
398     {
399       if (node->pkt->pkttype == PKT_USER_ID)
400         {
401           PKT_user_id *u = node->pkt->pkt.user_id;
402           
403           blob->uids[n].len = u->len;
404           blob->uids[n].flags = 0;
405           blob->uids[n].validity = 0;
406           n++;
407         }
408     }
409   assert (n == blob->nuids);
410   return 0;
411 }
412
413 static int
414 pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
415 {
416   KBNODE node;
417   int n;
418   
419   for (n=0, node = keyblock; node; node = node->next)
420     {
421       if (node->pkt->pkttype == PKT_SIGNATURE)
422         {
423           PKT_signature *sig = node->pkt->pkt.signature;
424           
425           blob->sigs[n] = 0;    /* FIXME: check the signature here */
426           n++;
427         }
428     }
429   assert( n == blob->nsigs );
430   return 0;
431 }
432
433 static int
434 pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
435 {
436   struct membuf *a = blob->buf;
437   KBNODE node;
438   int rc;
439   int n;
440   u32 kbstart = a->len;
441
442   add_fixup (blob, kbstart);
443
444   for (n = 0, node = keyblock; node; node = node->next)
445     {
446       rc = build_packet ( a, node->pkt );
447       if ( rc ) {
448         gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
449                       node->pkt->pkttype, gpg_errstr(rc) );
450         return GPGERR_WRITE_FILE;
451       }
452       if ( node->pkt->pkttype == PKT_USER_ID ) 
453         {
454           PKT_user_id *u = node->pkt->pkt.user_id;
455           /* build_packet has set the offset of the name into u ;
456            * now we can do the fixup */
457           add_fixup (blob, blob->uids[n].off_addr, u->stored_at);
458           n++;
459         }
460     }
461   assert (n == blob->nuids);
462
463   add_fixup (blob, a->len - kbstart);
464   return 0;
465 }
466  
467 #endif /*KEYBOX_WITH_OPENPGP*/
468
469 \f
470 #ifdef KEYBOX_WITH_X509
471 /* 
472    X.509 specific stuff
473  */
474
475 /* Write the raw certificate out */
476 static int
477 x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
478 {
479   struct membuf *a = blob->buf;
480   const unsigned char *image;
481   size_t length;
482   u32 kbstart = a->len;
483
484   /* Store our offset for later fixup */
485   add_fixup (blob, 8, kbstart);
486
487   image = ksba_cert_get_image (cert, &length);
488   if (!image)
489     return gpg_error (GPG_ERR_GENERAL);
490   put_membuf (a, image, length);
491
492   add_fixup (blob, 12, a->len - kbstart);
493   return 0;
494 }
495  
496 #endif /*KEYBOX_WITH_X509*/
497
498 /* Write a stored keyID out to the buffer */
499 static void
500 write_stored_kid (KEYBOXBLOB blob, int seqno)
501 {
502   struct keyid_list *r;
503   
504   for ( r = blob->temp_kids; r; r = r->next ) 
505     {
506       if (r->seqno == seqno )
507         {
508           put_membuf (blob->buf, r->kid, 8);
509           return;
510         }
511     }
512   never_reached ();
513 }
514
515 /* Release a list of key IDs */
516 static void
517 release_kid_list (struct keyid_list *kl)
518 {
519   struct keyid_list *r, *r2;
520   
521   for ( r = kl; r; r = r2 ) 
522     {
523       r2 = r->next;
524       xfree (r);
525     }
526 }
527
528
529
530 static int
531 create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
532 {
533   struct membuf *a = blob->buf;
534   int i;
535
536   put32 ( a, 0 ); /* blob length, needs fixup */
537   put8 ( a, blobtype);  
538   put8 ( a, 1 );  /* blob type version */
539   put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
540
541   put32 ( a, 0 ); /* offset to the raw data, needs fixup */
542   put32 ( a, 0 ); /* length of the raw data, needs fixup */
543
544   put16 ( a, blob->nkeys );
545   put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
546   for ( i=0; i < blob->nkeys; i++ )
547     {
548       put_membuf (a, blob->keys[i].fpr, 20);
549       blob->keys[i].off_kid_addr = a->len;
550       put32 ( a, 0 ); /* offset to keyid, fixed up later */
551       put16 ( a, blob->keys[i].flags );
552       put16 ( a, 0 ); /* reserved */
553     }
554
555   put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
556   if (blob->serial)
557     put_membuf (a, blob->serial, blob->seriallen);
558
559   put16 ( a, blob->nuids );
560   put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
561   for (i=0; i < blob->nuids; i++)
562     {
563       blob->uids[i].off_addr = a->len;
564       put32 ( a, 0 ); /* offset to userid, fixed up later */
565       put32 ( a, blob->uids[i].len );
566       put16 ( a, blob->uids[i].flags );
567       put8  ( a, 0 ); /* validity */
568       put8  ( a, 0 ); /* reserved */
569     }
570
571   put16 ( a, blob->nsigs );
572   put16 ( a, 4 );  /* size of sig info */
573   for (i=0; i < blob->nsigs; i++)
574     {
575       put32 ( a, blob->sigs[i]);
576     }
577
578   put8 ( a, 0 );  /* assigned ownertrust */
579   put8 ( a, 0 );  /* validity of all user IDs */
580   put16 ( a, 0 );  /* reserved */
581   put32 ( a, 0 );  /* time of next recheck */
582   put32 ( a, 0 );  /* newest timestamp (none) */
583   put32 ( a, make_timestamp() );  /* creation time */
584   put32 ( a, 0 );  /* size of reserved space */
585   /* reserved space (which is currently of size 0) */
586
587   /* space where we write keyIDs and and other stuff so that the
588      pointers can actually point to somewhere */
589   if (blobtype == BLOBTYPE_PGP)
590     {
591       /* We need to store the keyids for all pgp v3 keys because those key
592          IDs are not part of the fingerprint.  While we are doing that, we
593          fixup all the keyID offsets */
594       for (i=0; i < blob->nkeys; i++ )
595         {
596           if (blob->keys[i].off_kid) 
597             { /* this is a v3 one */
598               add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
599               write_stored_kid (blob, blob->keys[i].off_kid);
600             }
601           else
602             { /* the better v4 key IDs - just store an offset 8 bytes back */
603               add_fixup (blob, blob->keys[i].off_kid_addr,
604                          blob->keys[i].off_kid_addr - 8); 
605             }
606         }
607     }
608   
609   if (blobtype == BLOBTYPE_X509)
610     {
611       /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
612          the utf-8 string represenation of them */
613       for (i=0; i < blob->nuids; i++ )
614         {
615           if (blob->uids[i].name) 
616             { /* this is a v3 one */
617               add_fixup (blob, blob->uids[i].off_addr, a->len);
618               put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
619             }
620         }
621     }
622
623     return 0;
624 }
625
626
627
628 static int
629 create_blob_trailer (KEYBOXBLOB blob)
630 {
631   (void)blob;
632   return 0;
633 }
634
635
636 static int
637 create_blob_finish (KEYBOXBLOB blob)
638 {
639   struct membuf *a = blob->buf;
640   unsigned char *p;
641   unsigned char *pp;
642   int i;
643   size_t n;
644
645   /* write a placeholder for the checksum */
646   for (i = 0; i < 16; i++ )
647     put32 (a, 0);  /* Hmmm: why put32() ?? */
648   
649   /* get the memory area */
650   n = 0; /* (Just to avoid compiler warning.) */
651   p = get_membuf (a, &n);
652   if (!p)
653     return gpg_error (GPG_ERR_ENOMEM);
654   assert (n >= 20);
655
656   /* fixup the length */
657   add_fixup (blob, 0, n);
658
659   /* do the fixups */
660   if (blob->fixup_out_of_core)
661     return gpg_error (GPG_ERR_ENOMEM);
662
663   {
664     struct fixup_list *fl;
665     for (fl = blob->fixups; fl; fl = fl->next)
666       {
667         assert (fl->off+4 <= n);
668         p[fl->off+0] = fl->val >> 24;
669         p[fl->off+1] = fl->val >> 16;
670         p[fl->off+2] = fl->val >>  8;
671         p[fl->off+3] = fl->val;
672       }
673   }
674
675   /* calculate and store the MD5 checksum */
676   gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
677
678   pp = xtrymalloc (n);
679   if ( !pp )
680     return gpg_error_from_syserror ();
681   memcpy (pp , p, n);
682   blob->blob = pp;
683   blob->bloblen = n;
684   
685   return 0;
686 }
687
688 \f
689 #ifdef KEYBOX_WITH_OPENPGP
690
691 int
692 _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral)
693 {
694   int rc = 0;
695   KBNODE node;
696   KEYBOXBLOB blob;
697
698   *r_blob = NULL;
699   blob = xtrycalloc (1, sizeof *blob);
700   if (!blob)
701     return gpg_error_from_syserror ();
702
703   /* fixme: Do some sanity checks on the keyblock */
704
705   /* count userids and keys so that we can allocate the arrays */
706   for (node = keyblock; node; node = node->next) 
707     {
708       switch (node->pkt->pkttype)
709         {
710         case PKT_PUBLIC_KEY:
711         case PKT_SECRET_KEY:
712         case PKT_PUBLIC_SUBKEY:
713         case PKT_SECRET_SUBKEY: blob->nkeys++; break;
714         case PKT_USER_ID:  blob->nuids++; break;
715         case PKT_SIGNATURE: blob->nsigs++; break;
716         default: break;
717         }
718     }
719
720   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
721   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
722   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
723   if (!blob->keys || !blob->uids || !blob->sigs)
724     {
725       rc = gpg_error (GPG_ERR_ENOMEM);
726       goto leave;
727     }
728
729   rc = pgp_create_key_part ( blob, keyblock );
730   if (rc)
731     goto leave;
732   rc = pgp_create_uid_part ( blob, keyblock );
733   if (rc)
734     goto leave;
735   rc = pgp_create_sig_part ( blob, keyblock );
736   if (rc)
737     goto leave;
738   
739   init_membuf (&blob->bufbuf, 1024);
740   blob->buf = &blob->bufbuf;
741   rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral);
742   if (rc)
743     goto leave;
744   rc = pgp_create_blob_keyblock (blob, keyblock);
745   if (rc)
746     goto leave;
747   rc = create_blob_trailer (blob);
748   if (rc)
749     goto leave;
750   rc = create_blob_finish ( blob );
751   if (rc)
752     goto leave;
753
754   
755  leave:
756   release_kid_list (blob->temp_kids);
757   blob->temp_kids = NULL;
758   if (rc)
759     {
760       keybox_release_blob (blob);
761       *r_blob = NULL;
762     }
763   else
764     {
765       *r_blob = blob;
766     }
767   return rc;
768 }
769 #endif /*KEYBOX_WITH_OPENPGP*/
770
771 #ifdef KEYBOX_WITH_X509
772
773 /* Return an allocated string with the email address extracted from a
774    DN.  Note hat we use this code also in ../sm/keylist.c.  */
775 static char *
776 x509_email_kludge (const char *name)
777 {
778   const char *p, *string;
779   unsigned char *buf;
780   int n;
781
782   string = name;
783   for (;;)
784     {
785       p = strstr (string, "1.2.840.113549.1.9.1=#");
786       if (!p)
787         return NULL;
788       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
789         {
790           name = p + 22;
791           break;
792         }
793       string = p + 22;
794     }
795
796
797   /* This looks pretty much like an email address in the subject's DN
798      we use this to add an additional user ID entry.  This way,
799      OpenSSL generated keys get a nicer and usable listing.  */
800   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
801     ;
802   if (!n)
803     return NULL;
804   buf = xtrymalloc (n+3);
805   if (!buf)
806     return NULL; /* oops, out of core */
807   *buf = '<';
808   for (n=1, p=name; hexdigitp (p); p +=2, n++)
809     buf[n] = xtoi_2 (p);
810   buf[n++] = '>';
811   buf[n] = 0;
812   return (char*)buf;
813 }
814
815
816
817 /* Note: We should move calculation of the digest into libksba and
818    remove that parameter */
819 int
820 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
821                           unsigned char *sha1_digest, int as_ephemeral)
822 {
823   int i, rc = 0;
824   KEYBOXBLOB blob;
825   unsigned char *sn;
826   char *p;
827   char **names = NULL;
828   size_t max_names;
829
830   *r_blob = NULL;
831   blob = xtrycalloc (1, sizeof *blob);
832   if( !blob )
833     return gpg_error_from_syserror ();
834
835   sn = ksba_cert_get_serial (cert);
836   if (sn)
837     {
838       size_t n, len;
839       n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
840       if (n < 2)
841         {
842           xfree (sn);
843           return gpg_error (GPG_ERR_GENERAL);
844         }
845       blob->serialbuf = sn;
846       sn++; n--; /* skip '(' */
847       for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
848         len = len*10 + atoi_1 (sn);
849       if (*sn != ':')
850         {
851           xfree (blob->serialbuf);
852           blob->serialbuf = NULL;
853           return gpg_error (GPG_ERR_GENERAL);
854         }
855       sn++;
856       blob->serial = sn;
857       blob->seriallen = len;
858     }
859
860   blob->nkeys = 1;
861
862   /* create list of names */
863   blob->nuids = 0;
864   max_names = 100;
865   names = xtrymalloc (max_names * sizeof *names);
866   if (!names)
867     {
868       rc = gpg_error_from_syserror ();
869       goto leave;
870     }
871   
872   p = ksba_cert_get_issuer (cert, 0);
873   if (!p)
874     {
875       rc =  gpg_error (GPG_ERR_MISSING_VALUE);
876       goto leave;
877     }
878   names[blob->nuids++] = p;
879   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
880     {
881       if (blob->nuids >= max_names)
882         {
883           char **tmp;
884           
885           max_names += 100;
886           tmp = xtryrealloc (names, max_names * sizeof *names);
887           if (!tmp)
888             {
889               rc = gpg_error_from_syserror ();
890               goto leave;
891             }
892         }
893       names[blob->nuids++] = p;
894       if (!i && (p=x509_email_kludge (p)))
895         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
896     }
897   
898   /* space for signature information */
899   blob->nsigs = 1; 
900
901   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
902   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
903   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
904   if (!blob->keys || !blob->uids || !blob->sigs)
905     {
906       rc = gpg_error (GPG_ERR_ENOMEM);
907       goto leave;
908     }
909
910   memcpy (blob->keys[0].fpr, sha1_digest, 20);
911   blob->keys[0].off_kid = 0; /* We don't have keyids */
912   blob->keys[0].flags = 0;
913
914   /* issuer and subject names */
915   for (i=0; i < blob->nuids; i++)
916     {
917       blob->uids[i].name = names[i];
918       blob->uids[i].len = strlen(names[i]);
919       names[i] = NULL;
920       blob->uids[i].flags = 0;
921       blob->uids[i].validity = 0;
922     }
923   xfree (names);
924   names = NULL;
925
926   /* signatures */
927   blob->sigs[0] = 0;    /* not yet checked */
928
929   /* Create a temporary buffer for further processing */
930   init_membuf (&blob->bufbuf, 1024);
931   blob->buf = &blob->bufbuf;
932   /* write out what we already have */
933   rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
934   if (rc)
935     goto leave;
936   rc = x509_create_blob_cert (blob, cert);
937   if (rc)
938     goto leave;
939   rc = create_blob_trailer (blob);
940   if (rc)
941     goto leave;
942   rc = create_blob_finish ( blob );
943   if (rc)
944     goto leave;
945
946   
947  leave:
948   release_kid_list (blob->temp_kids);
949   blob->temp_kids = NULL;
950   if (blob && names)
951     {
952       for (i=0; i < blob->nuids; i++)
953         xfree (names[i]); 
954     }
955   xfree (names);
956   if (rc)
957     {
958       _keybox_release_blob (blob);
959       *r_blob = NULL;
960     }
961   else
962     {
963       *r_blob = blob;
964     }
965   return rc;
966 }
967 #endif /*KEYBOX_WITH_X509*/
968
969
970 \f
971 int
972 _keybox_new_blob (KEYBOXBLOB *r_blob,
973                   unsigned char *image, size_t imagelen, off_t off)
974 {
975   KEYBOXBLOB blob;
976   
977   *r_blob = NULL;
978   blob = xtrycalloc (1, sizeof *blob);
979   if (!blob)
980     return gpg_error_from_syserror ();
981
982   blob->blob = image;
983   blob->bloblen = imagelen;
984   blob->fileoffset = off;
985   *r_blob = blob;
986   return 0;
987 }
988
989
990 void
991 _keybox_release_blob (KEYBOXBLOB blob)
992 {
993   int i;
994   if (!blob)
995     return;
996   /* hmmm: release membuf here?*/
997   xfree (blob->keys );
998   xfree (blob->serialbuf);
999   for (i=0; i < blob->nuids; i++)
1000     xfree (blob->uids[i].name);
1001   xfree (blob->uids );
1002   xfree (blob->sigs );
1003   xfree (blob->blob );
1004   xfree (blob );
1005 }
1006
1007
1008
1009 const unsigned char *
1010 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
1011 {
1012   *n = blob->bloblen;
1013   return blob->blob;
1014 }
1015
1016 off_t
1017 _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
1018 {
1019   return blob->fileoffset;
1020 }
1021
1022
1023
1024 void
1025 _keybox_update_header_blob (KEYBOXBLOB blob)
1026 {
1027   if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
1028     {
1029       u32 val = make_timestamp ();
1030
1031       /* Update the last maintenance run times tamp. */
1032       blob->blob[20]   = (val >> 24);
1033       blob->blob[20+1] = (val >> 16);
1034       blob->blob[20+2] = (val >>  8);
1035       blob->blob[20+3] = (val      );
1036     }
1037 }