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