Fix regression in gpg's mail address parsing.
[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           names = tmp;
893         }
894       names[blob->nuids++] = p;
895       if (!i && (p=x509_email_kludge (p)))
896         names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
897     }
898
899   /* space for signature information */
900   blob->nsigs = 1;
901
902   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
903   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
904   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
905   if (!blob->keys || !blob->uids || !blob->sigs)
906     {
907       rc = gpg_error (GPG_ERR_ENOMEM);
908       goto leave;
909     }
910
911   memcpy (blob->keys[0].fpr, sha1_digest, 20);
912   blob->keys[0].off_kid = 0; /* We don't have keyids */
913   blob->keys[0].flags = 0;
914
915   /* issuer and subject names */
916   for (i=0; i < blob->nuids; i++)
917     {
918       blob->uids[i].name = names[i];
919       blob->uids[i].len = strlen(names[i]);
920       names[i] = NULL;
921       blob->uids[i].flags = 0;
922       blob->uids[i].validity = 0;
923     }
924   xfree (names);
925   names = NULL;
926
927   /* signatures */
928   blob->sigs[0] = 0;    /* not yet checked */
929
930   /* Create a temporary buffer for further processing */
931   init_membuf (&blob->bufbuf, 1024);
932   blob->buf = &blob->bufbuf;
933   /* write out what we already have */
934   rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
935   if (rc)
936     goto leave;
937   rc = x509_create_blob_cert (blob, cert);
938   if (rc)
939     goto leave;
940   rc = create_blob_trailer (blob);
941   if (rc)
942     goto leave;
943   rc = create_blob_finish ( blob );
944   if (rc)
945     goto leave;
946
947
948  leave:
949   release_kid_list (blob->temp_kids);
950   blob->temp_kids = NULL;
951   if (blob && names)
952     {
953       for (i=0; i < blob->nuids; i++)
954         xfree (names[i]);
955     }
956   xfree (names);
957   if (rc)
958     {
959       _keybox_release_blob (blob);
960       *r_blob = NULL;
961     }
962   else
963     {
964       *r_blob = blob;
965     }
966   return rc;
967 }
968 #endif /*KEYBOX_WITH_X509*/
969
970
971 \f
972 int
973 _keybox_new_blob (KEYBOXBLOB *r_blob,
974                   unsigned char *image, size_t imagelen, off_t off)
975 {
976   KEYBOXBLOB blob;
977
978   *r_blob = NULL;
979   blob = xtrycalloc (1, sizeof *blob);
980   if (!blob)
981     return gpg_error_from_syserror ();
982
983   blob->blob = image;
984   blob->bloblen = imagelen;
985   blob->fileoffset = off;
986   *r_blob = blob;
987   return 0;
988 }
989
990
991 void
992 _keybox_release_blob (KEYBOXBLOB blob)
993 {
994   int i;
995   if (!blob)
996     return;
997   /* hmmm: release membuf here?*/
998   xfree (blob->keys );
999   xfree (blob->serialbuf);
1000   for (i=0; i < blob->nuids; i++)
1001     xfree (blob->uids[i].name);
1002   xfree (blob->uids );
1003   xfree (blob->sigs );
1004   xfree (blob->blob );
1005   xfree (blob );
1006 }
1007
1008
1009
1010 const unsigned char *
1011 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
1012 {
1013   *n = blob->bloblen;
1014   return blob->blob;
1015 }
1016
1017 off_t
1018 _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
1019 {
1020   return blob->fileoffset;
1021 }
1022
1023
1024
1025 void
1026 _keybox_update_header_blob (KEYBOXBLOB blob)
1027 {
1028   if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
1029     {
1030       u32 val = make_timestamp ();
1031
1032       /* Update the last maintenance run times tamp. */
1033       blob->blob[20]   = (val >> 24);
1034       blob->blob[20+1] = (val >> 16);
1035       blob->blob[20+2] = (val >>  8);
1036       blob->blob[20+3] = (val      );
1037     }
1038 }