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