kbx: Switch from MD5 to SHA-1 for the checksum.
[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 format
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 ** Overview of blob types
30
31    | Byte 4 | Blob type    |
32    |--------+--------------|
33    |      0 | Empty blob   |
34    |      1 | First blob   |
35    |      2 | OpenPGP blob |
36    |      3 | X.509 blob   |
37
38 ** The First blob
39
40    The first blob of a plain KBX file has a special format:
41
42    - u32  Length of this blob
43    - byte Blob type (1)
44    - byte Version number (1)
45    - byte RFU
46    - byte RFU
47    - b4   Magic 'KBXf'
48    - u32  RFU
49    - u32  file_created_at
50    - u32  last_maintenance_run
51    - u32  RFU
52    - u32  RFU
53
54 ** The OpenPGP and X.509 blobs
55
56    The OpenPGP and X.509 blobs are very similiar, things which are
57    X.509 specific are noted like [X.509: xxx]
58
59    - u32  Length of this blob (including these 4 bytes)
60    - byte Blob type
61            2 = OpenPGP
62            3 = X509
63    - byte Version number of this blob type
64            1 = The only defined value
65    - u16  Blob flags
66           bit 0 = contains secret key material (not used)
67           bit 1 = ephemeral blob (e.g. used while quering external resources)
68    - u32  Offset to the OpenPGP keyblock or the X.509 DER encoded
69           certificate
70    - u32  The length of the keyblock or certificate
71    - u16  [NKEYS] Number of keys (at least 1!) [X509: always 1]
72    - u16  Size of the key information structure (at least 28).
73    - NKEYS times:
74       - b20  The fingerprint of the key.
75              Fingerprints are always 20 bytes, MD5 left padded with zeroes.
76       - u32  Offset to the n-th key's keyID (a keyID is always 8 byte)
77              or 0 if not known which is the case only for X.509.
78       - u16  Key flags
79              bit 0 = qualified signature (not yet implemented}
80       - u16  RFU
81       - bN   Optional filler up to the specified length of this
82              structure.
83    - u16  Size of the serial number (may be zero)
84       -  bN  The serial number. N as giiven above.
85    - u16  Number of user IDs
86    - u16  [NUIDS] Size of user ID information structure
87    - NUIDS times:
88
89       For X509, the first user ID is the Issuer, the second the
90       Subject and the others are subjectAltNames.  For OpenPGP we only
91       store the information from UserID packets here.
92
93       - u32  Blob offset to the n-th user ID
94       - u32  Length of this user ID.
95       - u16  User ID flags.
96              (not yet used)
97       - byte Validity
98       - byte RFU
99
100    - u16  [NSIGS] Number of signatures
101    - u16  Size of signature information (4)
102    - NSIGS times:
103       - u32  Expiration time of signature with some special values:
104              - 0x00000000 = not checked
105              - 0x00000001 = missing key
106              - 0x00000002 = bad signature
107              - 0x10000000 = valid and expires at some date in 1978.
108              - 0xffffffff = valid and does not expire
109    - u8 Assigned ownertrust [X509: not used]
110    - u8 All_Validity
111         OpenPGP: See ../g10/trustdb/TRUST_* [not yet used]
112         X509: Bit 4 set := key has been revoked.
113                            Note that this value matches TRUST_FLAG_REVOKED
114    - u16  RFU
115    - u32  Recheck_after
116    - u32  Latest timestamp in the keyblock (useful for KS syncronsiation?)
117    - u32  Blob created at
118    - u32  [NRES] Size of reserved space (not including this field)
119    - bN   Reserved space of size NRES for future use.
120    - bN   Arbitrary space for example used to store data which is not
121           part of the keyblock or certificate.  For example the v3 key
122           IDs go here.
123    - bN   Space for the keyblock or certifciate.
124    - bN   RFU
125    - b20  SHA-1 checksum (useful for KS syncronisation?)
126           Note, that KBX versions before GnuPG 2.1 used an MD5
127           checksum.  However it was only created but never checked.
128           Thus we do not expect problems if we switch to SHA-1.  If
129           the checksum fails and the first 4 bytes are zero, we can
130           try again with MD5.  SHA-1 has the advantage that it is
131           faster on CPUs with dedicated SHA-1 support.
132
133
134 */
135
136
137 #include <config.h>
138 #include <stdio.h>
139 #include <stdlib.h>
140 #include <string.h>
141 #include <errno.h>
142 #include <assert.h>
143 #include <time.h>
144
145 #include "keybox-defs.h"
146 #include <gcrypt.h>
147
148 #ifdef KEYBOX_WITH_X509
149 #include <ksba.h>
150 #endif
151
152
153 #include "../common/gettime.h"
154
155
156 /* special values of the signature status */
157 #define SF_NONE(a)  ( !(a) )
158 #define SF_NOKEY(a) ((a) & (1<<0))
159 #define SF_BAD(a)   ((a) & (1<<1))
160 #define SF_VALID(a) ((a) & (1<<29))
161
162
163 struct membuf {
164   size_t len;
165   size_t size;
166   char *buf;
167   int out_of_core;
168 };
169
170
171 /*  #if MAX_FINGERPRINT_LEN < 20 */
172 /*    #error fingerprints are 20 bytes */
173 /*  #endif */
174
175 struct keyboxblob_key {
176   char   fpr[20];
177   u32    off_kid;
178   ulong  off_kid_addr;
179   u16    flags;
180 };
181 struct keyboxblob_uid {
182   u32    off;
183   ulong  off_addr;
184   char   *name;     /* used only with x509 */
185   u32    len;
186   u16    flags;
187   byte   validity;
188 };
189
190 struct keyid_list {
191     struct keyid_list *next;
192     int seqno;
193     byte kid[8];
194 };
195
196 struct fixup_list {
197     struct fixup_list *next;
198     u32 off;
199     u32 val;
200 };
201
202
203 struct keyboxblob {
204   byte *blob;
205   size_t bloblen;
206   off_t fileoffset;
207
208   /* stuff used only by keybox_create_blob */
209   unsigned char *serialbuf;
210   const unsigned char *serial;
211   size_t seriallen;
212   int nkeys;
213   struct keyboxblob_key *keys;
214   int nuids;
215   struct keyboxblob_uid *uids;
216   int nsigs;
217   u32  *sigs;
218   struct fixup_list *fixups;
219   int fixup_out_of_core;
220
221   struct keyid_list *temp_kids;
222   struct membuf bufbuf; /* temporary store for the blob */
223   struct membuf *buf;
224 };
225
226
227 \f
228 /* A simple implemention of a dynamic buffer.  Use init_membuf() to
229    create a buffer, put_membuf to append bytes and get_membuf to
230    release and return the buffer.  Allocation errors are detected but
231    only returned at the final get_membuf(), this helps not to clutter
232    the code with out of core checks.  */
233
234 static void
235 init_membuf (struct membuf *mb, int initiallen)
236 {
237   mb->len = 0;
238   mb->size = initiallen;
239   mb->out_of_core = 0;
240   mb->buf = xtrymalloc (initiallen);
241   if (!mb->buf)
242       mb->out_of_core = 1;
243 }
244
245 static void
246 put_membuf (struct membuf *mb, const void *buf, size_t len)
247 {
248   if (mb->out_of_core)
249     return;
250
251   if (mb->len + len >= mb->size)
252     {
253       char *p;
254
255       mb->size += len + 1024;
256       p = xtryrealloc (mb->buf, mb->size);
257       if (!p)
258         {
259           mb->out_of_core = 1;
260           return;
261         }
262       mb->buf = p;
263     }
264   if (buf)
265     memcpy (mb->buf + mb->len, buf, len);
266   else
267     memset (mb->buf + mb->len, 0, len);
268   mb->len += len;
269 }
270
271 static void *
272 get_membuf (struct membuf *mb, size_t *len)
273 {
274   char *p;
275
276   if (mb->out_of_core)
277     {
278       xfree (mb->buf);
279       mb->buf = NULL;
280       return NULL;
281     }
282
283   p = mb->buf;
284   *len = mb->len;
285   mb->buf = NULL;
286   mb->out_of_core = 1; /* don't allow a reuse */
287   return p;
288 }
289
290
291 static void
292 put8 (struct membuf *mb, byte a )
293 {
294   put_membuf (mb, &a, 1);
295 }
296
297 static void
298 put16 (struct membuf *mb, u16 a )
299 {
300   unsigned char tmp[2];
301   tmp[0] = a>>8;
302   tmp[1] = a;
303   put_membuf (mb, tmp, 2);
304 }
305
306 static void
307 put32 (struct membuf *mb, u32 a )
308 {
309   unsigned char tmp[4];
310   tmp[0] = a>>24;
311   tmp[1] = a>>16;
312   tmp[2] = a>>8;
313   tmp[3] = a;
314   put_membuf (mb, tmp, 4);
315 }
316
317
318 \f
319 /* Store a value in the fixup list */
320 static void
321 add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
322 {
323   struct fixup_list *fl;
324
325   if (blob->fixup_out_of_core)
326     return;
327
328   fl = xtrycalloc(1, sizeof *fl);
329   if (!fl)
330     blob->fixup_out_of_core = 1;
331   else
332     {
333       fl->off = off;
334       fl->val = val;
335       fl->next = blob->fixups;
336       blob->fixups = fl;
337     }
338 }
339
340
341 \f
342 /*
343   OpenPGP specific stuff
344 */
345
346
347 /* We must store the keyid at some place because we can't calculate
348    the offset yet. This is only used for v3 keyIDs.  Function returns
349    an index value for later fixup or -1 for out of core.  The value
350    must be a non-zero value. */
351 static int
352 pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo)
353 {
354   struct keyid_list *k, *r;
355
356   k = xtrymalloc (sizeof *k);
357   if (!k)
358     return -1;
359   memcpy (k->kid, kinfo->keyid, 8);
360   k->seqno = 0;
361   k->next = blob->temp_kids;
362   blob->temp_kids = k;
363   for (r=k; r; r = r->next)
364     k->seqno++;
365
366   return k->seqno;
367 }
368
369
370 /* Helper for pgp_create_key_part.  */
371 static gpg_error_t
372 pgp_create_key_part_single (KEYBOXBLOB blob, int n,
373                             struct _keybox_openpgp_key_info *kinfo)
374 {
375   size_t fprlen;
376   int off;
377
378   fprlen = kinfo->fprlen;
379   if (fprlen > 20)
380     fprlen = 20;
381   memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
382   if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */
383     {
384       memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen);
385       memset (blob->keys[n].fpr, 0, 20 - fprlen);
386       off = pgp_temp_store_kid (blob, kinfo);
387       if (off == -1)
388         return gpg_error_from_syserror ();
389       blob->keys[n].off_kid = off;
390     }
391   else
392     blob->keys[n].off_kid = 0; /* Will be fixed up later */
393   blob->keys[n].flags = 0;
394   return 0;
395 }
396
397
398 static gpg_error_t
399 pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
400 {
401   gpg_error_t err;
402   int n = 0;
403   struct _keybox_openpgp_key_info *kinfo;
404
405   err = pgp_create_key_part_single (blob, n++, &info->primary);
406   if (err)
407     return err;
408   if (info->nsubkeys)
409     for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
410       if ((err=pgp_create_key_part_single (blob, n++, kinfo)))
411         return err;
412
413   assert (n == blob->nkeys);
414   return 0;
415 }
416
417
418 static void
419 pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
420 {
421   int n = 0;
422   struct _keybox_openpgp_uid_info *u;
423
424   if (info->nuids)
425     {
426       for (u = &info->uids; u; u = u->next)
427         {
428           blob->uids[n].off = u->off;
429           blob->uids[n].len = u->len;
430           blob->uids[n].flags = 0;
431           blob->uids[n].validity = 0;
432           n++;
433         }
434     }
435
436   assert (n == blob->nuids);
437 }
438
439
440 static void
441 pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus)
442 {
443   int n;
444
445   for (n=0; n < blob->nsigs; n++)
446     {
447       blob->sigs[n] = sigstatus? sigstatus[n+1] : 0;
448     }
449 }
450
451
452 static int
453 pgp_create_blob_keyblock (KEYBOXBLOB blob,
454                           const unsigned char *image, size_t imagelen)
455 {
456   struct membuf *a = blob->buf;
457   int n;
458   u32 kbstart = a->len;
459
460   add_fixup (blob, 8, kbstart);
461
462   for (n = 0; n < blob->nuids; n++)
463     add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off);
464
465   put_membuf (a, image, imagelen);
466
467   add_fixup (blob, 12, a->len - kbstart);
468   return 0;
469 }
470
471
472 \f
473 #ifdef KEYBOX_WITH_X509
474 /*
475    X.509 specific stuff
476  */
477
478 /* Write the raw certificate out */
479 static int
480 x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
481 {
482   struct membuf *a = blob->buf;
483   const unsigned char *image;
484   size_t length;
485   u32 kbstart = a->len;
486
487   /* Store our offset for later fixup */
488   add_fixup (blob, 8, kbstart);
489
490   image = ksba_cert_get_image (cert, &length);
491   if (!image)
492     return gpg_error (GPG_ERR_GENERAL);
493   put_membuf (a, image, length);
494
495   add_fixup (blob, 12, a->len - kbstart);
496   return 0;
497 }
498
499 #endif /*KEYBOX_WITH_X509*/
500
501 /* Write a stored keyID out to the buffer */
502 static void
503 write_stored_kid (KEYBOXBLOB blob, int seqno)
504 {
505   struct keyid_list *r;
506
507   for ( r = blob->temp_kids; r; r = r->next )
508     {
509       if (r->seqno == seqno )
510         {
511           put_membuf (blob->buf, r->kid, 8);
512           return;
513         }
514     }
515   never_reached ();
516 }
517
518 /* Release a list of key IDs */
519 static void
520 release_kid_list (struct keyid_list *kl)
521 {
522   struct keyid_list *r, *r2;
523
524   for ( r = kl; r; r = r2 )
525     {
526       r2 = r->next;
527       xfree (r);
528     }
529 }
530
531
532
533 static int
534 create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
535 {
536   struct membuf *a = blob->buf;
537   int i;
538
539   put32 ( a, 0 ); /* blob length, needs fixup */
540   put8 ( a, blobtype);
541   put8 ( a, 1 );  /* blob type version */
542   put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
543
544   put32 ( a, 0 ); /* offset to the raw data, needs fixup */
545   put32 ( a, 0 ); /* length of the raw data, needs fixup */
546
547   put16 ( a, blob->nkeys );
548   put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
549   for ( i=0; i < blob->nkeys; i++ )
550     {
551       put_membuf (a, blob->keys[i].fpr, 20);
552       blob->keys[i].off_kid_addr = a->len;
553       put32 ( a, 0 ); /* offset to keyid, fixed up later */
554       put16 ( a, blob->keys[i].flags );
555       put16 ( a, 0 ); /* reserved */
556     }
557
558   put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
559   if (blob->serial)
560     put_membuf (a, blob->serial, blob->seriallen);
561
562   put16 ( a, blob->nuids );
563   put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
564   for (i=0; i < blob->nuids; i++)
565     {
566       blob->uids[i].off_addr = a->len;
567       put32 ( a, 0 ); /* offset to userid, fixed up later */
568       put32 ( a, blob->uids[i].len );
569       put16 ( a, blob->uids[i].flags );
570       put8  ( a, 0 ); /* validity */
571       put8  ( a, 0 ); /* reserved */
572     }
573
574   put16 ( a, blob->nsigs );
575   put16 ( a, 4 );  /* size of sig info */
576   for (i=0; i < blob->nsigs; i++)
577     {
578       put32 ( a, blob->sigs[i]);
579     }
580
581   put8 ( a, 0 );  /* assigned ownertrust */
582   put8 ( a, 0 );  /* validity of all user IDs */
583   put16 ( a, 0 );  /* reserved */
584   put32 ( a, 0 );  /* time of next recheck */
585   put32 ( a, 0 );  /* newest timestamp (none) */
586   put32 ( a, make_timestamp() );  /* creation time */
587   put32 ( a, 0 );  /* size of reserved space */
588   /* reserved space (which is currently of size 0) */
589
590   /* space where we write keyIDs and and other stuff so that the
591      pointers can actually point to somewhere */
592   if (blobtype == BLOBTYPE_PGP)
593     {
594       /* We need to store the keyids for all pgp v3 keys because those key
595          IDs are not part of the fingerprint.  While we are doing that, we
596          fixup all the keyID offsets */
597       for (i=0; i < blob->nkeys; i++ )
598         {
599           if (blob->keys[i].off_kid)
600             { /* this is a v3 one */
601               add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
602               write_stored_kid (blob, blob->keys[i].off_kid);
603             }
604           else
605             { /* the better v4 key IDs - just store an offset 8 bytes back */
606               add_fixup (blob, blob->keys[i].off_kid_addr,
607                          blob->keys[i].off_kid_addr - 8);
608             }
609         }
610     }
611
612   if (blobtype == BLOBTYPE_X509)
613     {
614       /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
615          the utf-8 string represenation of them */
616       for (i=0; i < blob->nuids; i++ )
617         {
618           if (blob->uids[i].name)
619             { /* this is a v3 one */
620               add_fixup (blob, blob->uids[i].off_addr, a->len);
621               put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
622             }
623         }
624     }
625
626     return 0;
627 }
628
629
630
631 static int
632 create_blob_trailer (KEYBOXBLOB blob)
633 {
634   (void)blob;
635   return 0;
636 }
637
638
639 static int
640 create_blob_finish (KEYBOXBLOB blob)
641 {
642   struct membuf *a = blob->buf;
643   unsigned char *p;
644   unsigned char *pp;
645   size_t n;
646
647   /* Write a placeholder for the checksum */
648   put_membuf (a, NULL, 20);
649
650   /* get the memory area */
651   n = 0; /* (Just to avoid compiler warning.) */
652   p = get_membuf (a, &n);
653   if (!p)
654     return gpg_error (GPG_ERR_ENOMEM);
655   assert (n >= 20);
656
657   /* fixup the length */
658   add_fixup (blob, 0, n);
659
660   /* do the fixups */
661   if (blob->fixup_out_of_core)
662     return gpg_error (GPG_ERR_ENOMEM);
663
664   {
665     struct fixup_list *fl;
666     for (fl = blob->fixups; fl; fl = fl->next)
667       {
668         assert (fl->off+4 <= n);
669         p[fl->off+0] = fl->val >> 24;
670         p[fl->off+1] = fl->val >> 16;
671         p[fl->off+2] = fl->val >>  8;
672         p[fl->off+3] = fl->val;
673       }
674   }
675
676   /* Compute and store the SHA-1 checksum. */
677   gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20);
678
679   pp = xtrymalloc (n);
680   if ( !pp )
681     return gpg_error_from_syserror ();
682   memcpy (pp , p, n);
683   blob->blob = pp;
684   blob->bloblen = n;
685
686   return 0;
687 }
688
689
690 \f
691 gpg_error_t
692 _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
693                              keybox_openpgp_info_t info,
694                              const unsigned char *image,
695                              size_t imagelen,
696                              u32 *sigstatus,
697                              int as_ephemeral)
698 {
699   gpg_error_t err;
700   KEYBOXBLOB blob;
701
702   *r_blob = NULL;
703
704   if (!info->nuids || !info->nsigs)
705     return gpg_error (GPG_ERR_BAD_PUBKEY);
706
707   /* If we have a signature status vector, check that the number of
708      elements matches the actual number of signatures.  */
709   if (sigstatus && sigstatus[0] != info->nsigs)
710     return gpg_error (GPG_ERR_INTERNAL);
711
712   blob = xtrycalloc (1, sizeof *blob);
713   if (!blob)
714     return gpg_error_from_syserror ();
715
716   blob->nkeys = 1 + info->nsubkeys;
717   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
718   if (!blob->keys)
719     {
720       err = gpg_error_from_syserror ();
721       goto leave;
722     }
723   blob->nuids = info->nuids;
724   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
725   if (!blob->uids)
726     {
727       err = gpg_error_from_syserror ();
728       goto leave;
729     }
730   blob->nsigs = info->nsigs;
731   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
732   if (!blob->sigs)
733     {
734       err = gpg_error_from_syserror ();
735       goto leave;
736     }
737
738   err = pgp_create_key_part (blob, info);
739   if (err)
740     goto leave;
741   pgp_create_uid_part (blob, info);
742   pgp_create_sig_part (blob, sigstatus);
743
744   init_membuf (&blob->bufbuf, 1024);
745   blob->buf = &blob->bufbuf;
746   err = create_blob_header (blob, BLOBTYPE_PGP, as_ephemeral);
747   if (err)
748     goto leave;
749   err = pgp_create_blob_keyblock (blob, image, imagelen);
750   if (err)
751     goto leave;
752   err = create_blob_trailer (blob);
753   if (err)
754     goto leave;
755   err = create_blob_finish (blob);
756   if (err)
757     goto leave;
758
759  leave:
760   release_kid_list (blob->temp_kids);
761   blob->temp_kids = NULL;
762   if (err)
763     _keybox_release_blob (blob);
764   else
765     *r_blob = blob;
766   return err;
767 }
768
769
770 #ifdef KEYBOX_WITH_X509
771
772 /* Return an allocated string with the email address extracted from a
773    DN.  Note hat we use this code also in ../sm/keylist.c.  */
774 static char *
775 x509_email_kludge (const char *name)
776 {
777   const char *p, *string;
778   unsigned char *buf;
779   int n;
780
781   string = name;
782   for (;;)
783     {
784       p = strstr (string, "1.2.840.113549.1.9.1=#");
785       if (!p)
786         return NULL;
787       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
788         {
789           name = p + 22;
790           break;
791         }
792       string = p + 22;
793     }
794
795
796   /* This looks pretty much like an email address in the subject's DN
797      we use this to add an additional user ID entry.  This way,
798      OpenSSL generated keys get a nicer and usable listing.  */
799   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
800     ;
801   if (!n)
802     return NULL;
803   buf = xtrymalloc (n+3);
804   if (!buf)
805     return NULL; /* oops, out of core */
806   *buf = '<';
807   for (n=1, p=name; hexdigitp (p); p +=2, n++)
808     buf[n] = xtoi_2 (p);
809   buf[n++] = '>';
810   buf[n] = 0;
811   return (char*)buf;
812 }
813
814
815
816 /* Note: We should move calculation of the digest into libksba and
817    remove that parameter */
818 int
819 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
820                           unsigned char *sha1_digest, int as_ephemeral)
821 {
822   int i, rc = 0;
823   KEYBOXBLOB blob;
824   unsigned char *sn;
825   char *p;
826   char **names = NULL;
827   size_t max_names;
828
829   *r_blob = NULL;
830   blob = xtrycalloc (1, sizeof *blob);
831   if( !blob )
832     return gpg_error_from_syserror ();
833
834   sn = ksba_cert_get_serial (cert);
835   if (sn)
836     {
837       size_t n, len;
838       n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
839       if (n < 2)
840         {
841           xfree (sn);
842           return gpg_error (GPG_ERR_GENERAL);
843         }
844       blob->serialbuf = sn;
845       sn++; n--; /* skip '(' */
846       for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
847         len = len*10 + atoi_1 (sn);
848       if (*sn != ':')
849         {
850           xfree (blob->serialbuf);
851           blob->serialbuf = NULL;
852           return gpg_error (GPG_ERR_GENERAL);
853         }
854       sn++;
855       blob->serial = sn;
856       blob->seriallen = len;
857     }
858
859   blob->nkeys = 1;
860
861   /* create list of names */
862   blob->nuids = 0;
863   max_names = 100;
864   names = xtrymalloc (max_names * sizeof *names);
865   if (!names)
866     {
867       rc = gpg_error_from_syserror ();
868       goto leave;
869     }
870
871   p = ksba_cert_get_issuer (cert, 0);
872   if (!p)
873     {
874       rc =  gpg_error (GPG_ERR_MISSING_VALUE);
875       goto leave;
876     }
877   names[blob->nuids++] = p;
878   for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
879     {
880       if (blob->nuids >= max_names)
881         {
882           char **tmp;
883
884           max_names += 100;
885           tmp = xtryrealloc (names, max_names * sizeof *names);
886           if (!tmp)
887             {
888               rc = gpg_error_from_syserror ();
889               goto leave;
890             }
891           names = tmp;
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 }