Started with keybox implementation by basing it on code from the GnuPG
[gnupg.git] / kbx / keybox-blob.c
1 /* keybox-blob.c - KBX Blob handling
2  *      Copyright (C) 2000, 2001 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 2 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21
22 /* The keybox data formats
23
24 The KeyBox uses an augmented OpenPGP/X.509 key format.  This makes
25 random access to a keyblock/Certificate easier and also gives the
26 opportunity to store additional information (e.g. the fingerprint)
27 along with the key.  All integers are stored in network byte order,
28 offsets are counted from the beginning of the Blob.
29
30 The first record of a plain KBX file has a special format:
31
32  u32  length of the first record
33  byte Blob type (1)
34  byte version number (1)
35  byte reserved
36  byte reserved
37  u32  magic 'KBXf'
38  byte pgp_marginals  used for validity calculation of this file
39  byte pgp_completes  ditto.
40  byte pgp_cert_depth ditto.
41
42 The OpenPGP KBX Blob looks like this:
43
44  u32  length of this blob (including these 4 bytes)
45  byte Blob type (2)
46  byte version number of this blob type (1)
47  u16  Blob flags
48         bit 0 = contains secret key material
49
50  u32  offset to the OpenPGP keyblock
51  u32  length of the keyblock
52  u16  number of keys (at least 1!)
53  u16  size of additional key information
54  n times:
55    b20  The keys fingerprint
56         (fingerprints are always 20 bytes, MD5 left padded with zeroes)
57    u32  offset to the n-th key's keyID (a keyID is always 8 byte)
58    u16  special key flags
59          bit 0 =
60    u16  reserved
61  u16  number of user IDs
62  u16  size of additional user ID information
63  n times:
64    u32  offset to the n-th user ID
65    u32  length of this user ID.
66    u16  special user ID flags.
67          bit 0 =
68    byte validity
69    byte reserved
70  u16  number of signatures
71  u16  size of signature information (4)
72    u32  expiration time of signature with some special values:
73         0x00000000 = not checked
74         0x00000001 = missing key
75         0x00000002 = bad signature
76         0x10000000 = valid and expires at some date in 1978.
77         0xffffffff = valid and does not expire
78  u8     assigned ownertrust
79  u8     all_validity
80  u16    reserved
81  u32    recheck_after
82  u32    Newest timestamp in the keyblock (useful for KS syncronsiation?)
83  u32    Blob created at
84  u32    size of reserved space (not including this field)
85       reserved space
86
87     Here we might want to put other data
88
89     Here comes the keyblock
90
91     maybe we put a signature here later.
92
93  b16    MD5 checksum  (useful for KS syncronisation)
94
95 */
96
97
98 #include <config.h>
99 #include <stdio.h>
100 #include <stdlib.h>
101 #include <string.h>
102 #include <errno.h>
103 #include <assert.h>
104 #include <gcrypt.h>
105
106 #include "keybox-defs.h"
107
108 /* special values of the signature status */
109 #define SF_NONE(a)  ( !(a) )
110 #define SF_NOKEY(a) ((a) & (1<<0))
111 #define SF_BAD(a)   ((a) & (1<<1))
112 #define SF_VALID(a) ((a) & (1<<29))
113
114
115 struct membuf {
116   size_t len;
117   size_t size;
118   char *buf;
119   int out_of_core;
120 };
121
122
123 /*  #if MAX_FINGERPRINT_LEN < 20 */
124 /*    #error fingerprints are 20 bytes */
125 /*  #endif */
126
127 struct keyboxblob_key {
128     char   fpr[20];
129     u32    off_kid;
130     ulong  off_kid_addr;
131     u16    flags;
132 };
133 struct keyboxblob_uid {
134     ulong  off_addr;
135     u32    len;
136     u16    flags;
137     byte   validity;
138 };
139
140 struct keyid_list {
141     struct keyid_list *next;
142     int seqno;
143     byte kid[8];
144 };
145
146 struct fixup_list {
147     struct fixup_list *next;
148     u32 off;
149     u32 val;
150 };
151
152
153 struct keyboxblob {
154   byte *blob;
155   size_t bloblen;
156   
157   /* stuff used only by keybox_create_blob */
158   int nkeys;
159   struct keyboxblob_key *keys;
160   int nuids;
161   struct keyboxblob_uid *uids;
162   int nsigs;
163   u32  *sigs;
164   struct fixup_list *fixups;
165   
166   struct keyid_list *temp_kids;
167   struct membuf *buf; /* temporary store for the blob */
168 };
169
170
171 \f
172 /* A simple implemnation of a dynamic buffer.  Use init_membuf() to
173    create a buffer, put_membuf to append bytes and get_membuf to
174    release and return the buffer.  Allocation errors are detected but
175    only returned at the final get_membuf(), this helps not to clutter
176    the code with out of core checks.  */
177
178 static void
179 init_membuf (struct membuf *mb, int initiallen)
180 {
181   mb->len = 0;
182   mb->size = initiallen;
183   mb->out_of_core = 0;
184   mb->buf = xtrymalloc (initiallen);
185   if (!mb->buf)
186       mb->out_of_core = 1;
187 }
188
189 static void
190 put_membuf (struct membuf *mb, const void *buf, size_t len)
191 {
192   if (mb->out_of_core)
193     return;
194
195   if (mb->len + len >= mb->size)
196     {
197       char *p;
198       
199       mb->size += len + 1024;
200       p = xtryrealloc (mb->buf, mb->size);
201       if (!p)
202         {
203           mb->out_of_core = 1;
204           return;
205         }
206       mb->buf = p;
207     }
208   memcpy (mb->buf + mb->len, buf, len);
209   mb->len += len;
210 }
211
212 static void *
213 get_membuf (struct membuf *mb, size_t *len)
214 {
215   char *p;
216
217   if (mb->out_of_core)
218     {
219       xfree (mb->buf);
220       mb->buf = NULL;
221       return NULL;
222     }
223
224   p = mb->buf;
225   *len = mb->len;
226   mb->buf = NULL;
227   mb->out_of_core = 1; /* don't allow a reuse */
228   return p;
229 }
230
231
232 static void
233 put8 (struct membuf *mb, byte a )
234 {
235   put_membuf (mb, &a, 1);
236 }
237
238 static void
239 put16 (struct membuf *mb, u16 a )
240 {
241   unsigned char tmp[2];
242   tmp[0] = a>>8;
243   tmp[1] = a;
244   put_membuf (mb, tmp, 2);
245 }
246
247 static void
248 put32 (struct membuf *mb, u32 a )
249 {
250   unsigned char tmp[4];
251   tmp[0] = a>>24;
252   tmp[1] = a>>16;
253   tmp[2] = a>>8;
254   tmp[3] = a;
255   put_membuf (mb, tmp, 4);
256 }
257
258 \f
259 /*
260  Some wrappers
261 */
262
263 static u32
264 make_timestamp (void)
265 {
266   return time(NULL);
267 }
268
269
270 \f
271 #ifdef KEYBOX_WITH_OPENPGP
272 /*
273   OpenPGP specific stuff 
274 */
275
276
277 /*
278   We must store the keyid at some place because we can't calculate the
279   offset yet. This is only used for v3 keyIDs.  Function returns an
280   index value for later fixup or -1 for out of core. The value must be
281   a non-zero value */
282 static int
283 pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
284 {
285   struct keyid_list *k, *r;
286   
287   k = xtrymalloc (sizeof *k); 
288   if (!k)
289     return -1;
290   k->kid[0] = pk->keyid[0] >> 24 ;
291   k->kid[1] = pk->keyid[0] >> 16 ;
292   k->kid[2] = pk->keyid[0] >>  8 ;
293   k->kid[3] = pk->keyid[0]         ;
294   k->kid[4] = pk->keyid[0] >> 24 ;
295   k->kid[5] = pk->keyid[0] >> 16 ;
296   k->kid[6] = pk->keyid[0] >>  8 ;
297   k->kid[7] = pk->keyid[0]         ;
298   k->seqno = 0;
299   k->next = blob->temp_kids;
300   blob->temp_kids = k;
301   for (r=k; r; r = r->next) 
302     k->seqno++;
303   
304   return k->seqno;
305 }
306
307 static int
308 pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
309 {
310   KBNODE node;
311   size_t fprlen;
312   int n;
313
314   for (n=0, node = keyblock; node; node = node->next)
315     {
316       if ( node->pkt->pkttype == PKT_PUBLIC_KEY
317            || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) 
318         {
319           PKT_public_key *pk = node->pkt->pkt.public_key;
320           char tmp[20];
321
322           fingerprint_from_pk (pk, tmp , &fprlen);
323           memcpy (blob->keys[n].fpr, tmp, 20);
324           if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
325             {
326               assert (fprlen == 16);
327               memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
328               memset (blob->keys[n].fpr, 0, 4);
329               blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
330             }
331           else
332             {
333               blob->keys[n].off_kid = 0; /* will be fixed up later */
334             }
335           blob->keys[n].flags = 0;
336           n++;
337         }
338       else if ( node->pkt->pkttype == PKT_SECRET_KEY
339                   || node->pkt->pkttype == PKT_SECRET_SUBKEY ) 
340         {
341           never_reached (); /* actually not yet implemented */
342         }
343     }
344   assert (n == blob->nkeys);
345   return 0;
346 }
347
348 static int
349 pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
350 {
351   KBNODE node;
352   int n;
353
354   for (n=0, node = keyblock; node; node = node->next)
355     {
356       if (node->pkt->pkttype == PKT_USER_ID)
357         {
358           PKT_user_id *u = node->pkt->pkt.user_id;
359           
360           blob->uids[n].len = u->len;
361           blob->uids[n].flags = 0;
362           blob->uids[n].validity = 0;
363           n++;
364         }
365     }
366   assert (n == blob->nuids);
367   return 0;
368 }
369
370 static int
371 pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
372 {
373   KBNODE node;
374   int n;
375   
376   for (n=0, node = keyblock; node; node = node->next)
377     {
378       if (node->pkt->pkttype == PKT_SIGNATURE)
379         {
380           PKT_signature *sig = node->pkt->pkt.signature;
381           
382           blob->sigs[n] = 0;    /* FIXME: check the signature here */
383           n++;
384         }
385     }
386   assert( n == blob->nsigs );
387   return 0;
388 }
389
390 static int
391 pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
392 {
393   struct membuf *a = blob->buf;
394   KBNODE node;
395   int rc;
396   int n;
397   u32 kbstart = a->len;
398
399   {
400     struct fixup_list *fl = xtrycalloc(1, sizeof *fl ); 
401     
402     if (!fl)
403       return KEYBOX_Out_Of_Core;
404     fl->off = 8;
405     fl->val = kbstart;
406     fl->next = blob->fixups;
407     blob->fixups = fl;
408   }
409
410   for (n = 0, node = keyblock; node; node = node->next)
411     {
412       rc = build_packet ( a, node->pkt );
413       if ( rc ) {
414         gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
415                       node->pkt->pkttype, gpg_errstr(rc) );
416         return GPGERR_WRITE_FILE;
417       }
418       if ( node->pkt->pkttype == PKT_USER_ID ) 
419         {
420           PKT_user_id *u = node->pkt->pkt.user_id;
421           /* build_packet has set the offset of the name into u ;
422            * now we can do the fixup */
423           struct fixup_list *fl = xcalloc(1, sizeof *fl ); /* fixme */
424           fl->off = blob->uids[n].off_addr;
425           fl->val = u->stored_at;
426           fl->next = blob->fixups;
427           blob->fixups = fl;
428           n++;
429         }
430     }
431   assert (n == blob->nuids);
432
433   {
434     struct fixup_list *fl = xcalloc(1, sizeof *fl ); /* fixme */
435
436     fl->off = 12;
437     fl->val = a->len - kbstart;
438     fl->next = blob->fixups;
439     blob->fixups = fl;
440   }
441
442   return 0;
443 }
444
445 #endif /*KEYBOX_WITH_OPENPGP*/
446
447 \f
448 #ifdef KEYBOX_WITH_X509
449 /* 
450    X.509 specific stuff
451  */
452
453 #endif /*KEYBOX_WITH_X509*/
454
455 /* Write a stored keyID out to the buffer */
456 static void
457 write_stored_kid (KEYBOXBLOB blob, int seqno)
458 {
459   struct keyid_list *r;
460   
461   for ( r = blob->temp_kids; r; r = r->next ) 
462     {
463       if (r->seqno == seqno )
464         {
465           put_membuf (blob->buf, r->kid, 8);
466           return;
467         }
468     }
469   never_reached ();
470 }
471
472 /* Release a list of key IDs */
473 static void
474 release_kid_list (struct keyid_list *kl)
475 {
476   struct keyid_list *r, *r2;
477   
478   for ( r = kl; r; r = r2 ) 
479     {
480       r2 = r->next;
481       xfree (r);
482     }
483 }
484
485
486
487 static int
488 create_blob_header (KEYBOXBLOB blob, int blobtype)
489 {
490   struct membuf *a = blob->buf;
491   int i;
492
493   put32 ( a, 0 ); /* blob length, needs fixup */
494   put8 ( a, blobtype);  
495   put8 ( a, 1 );  /* blob type version */
496   put16 ( a, 0 ); /* blob flags */
497
498   put32 ( a, 0 ); /* offset to the raw data, needs fixup */
499   put32 ( a, 0 ); /* length of the raw data, needs fixup */
500
501   put16 ( a, blob->nkeys );
502   put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
503   for ( i=0; i < blob->nkeys; i++ )
504     {
505       put_membuf (a, blob->keys[i].fpr, 20);
506       blob->keys[i].off_kid_addr = a->len;
507       put32 ( a, 0 ); /* offset to keyid, fixed up later */
508       put16 ( a, blob->keys[i].flags );
509       put16 ( a, 0 ); /* reserved */
510     }
511
512   put16 ( a, blob->nuids );
513   put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
514   for (i=0; i < blob->nuids; i++)
515     {
516       blob->uids[i].off_addr = a->len;
517       put32 ( a, 0 ); /* offset to userid, fixed up later */
518       put32 ( a, blob->uids[i].len );
519       put16 ( a, blob->uids[i].flags );
520       put8  ( a, 0 ); /* validity */
521       put8  ( a, 0 ); /* reserved */
522     }
523
524   put16 ( a, blob->nsigs );
525   put16 ( a, 4 );  /* size of sig info */
526   for (i=0; i < blob->nsigs; i++)
527     {
528       put32 ( a, blob->sigs[i]);
529     }
530
531   put8 ( a, 0 );  /* assigned ownertrust */
532   put8 ( a, 0 );  /* validity of all user IDs */
533   put16 ( a, 0 );  /* reserved */
534   put32 ( a, 0 );  /* time of next recheck */
535   put32 ( a, 0 );  /* newest timestamp (none) */
536   put32 ( a, make_timestamp() );  /* creation time */
537   put32 ( a, 0 );  /* size of reserved space */
538   /* reserved space (which is currently of size 0) */
539
540   /* We need to store the keyids for all pgp v3 keys because those key
541      IDs are not part of the fingerprint.  While we are doing that, we
542      fixup all the keyID offsets */
543   for (i=0; i < blob->nkeys; i++ )
544     {
545       struct fixup_list *fl = xtrycalloc(1, sizeof *fl ); 
546       
547       if (!fl)
548         return KEYBOX_Out_Of_Core;
549
550       fl->off = blob->keys[i].off_kid_addr;
551       fl->next = blob->fixups;
552       blob->fixups = fl;
553
554       if (blob->keys[i].off_kid) 
555         { /* this is a v3 one */
556           fl->val = a->len;
557           write_stored_kid (blob, blob->keys[i].off_kid);
558         }
559       else
560         { /* the better v4 key IDs - just store an offset 8 bytes back */
561           fl->val = blob->keys[i].off_kid_addr - 8;
562         }
563     }
564   
565     return 0;
566 }
567
568
569
570 static int
571 create_blob_trailer (KEYBOXBLOB blob)
572 {
573     return 0;
574 }
575
576
577 static int
578 create_blob_finish (KEYBOXBLOB blob)
579 {
580   struct membuf *a = blob->buf;
581   byte *p;
582   char *pp;
583   int i;
584   size_t n;
585
586   /* write a placeholder for the checksum */
587   for (i = 0; i < 16; i++ )
588     put32 (a, 0);
589   
590   /* get the memory area */
591   p = a->buf;
592   n = a->len;
593   assert (n >= 20);
594
595   /* fixup the length */
596   {
597     struct fixup_list *fl = xtrycalloc(1, sizeof *fl);
598     if (!fl)
599       return KEYBOX_Out_Of_Core;
600     fl->off = 0;
601     fl->val = n;
602     fl->next = blob->fixups;
603     blob->fixups = fl;
604   }
605
606   /* do the fixups */
607   {
608     struct fixup_list *fl;
609     for (fl = blob->fixups; fl; fl = fl->next)
610       {
611         assert (fl->off+4 <= n);
612         p[fl->off+0] = fl->val >> 24;
613         p[fl->off+1] = fl->val >> 16;
614         p[fl->off+2] = fl->val >>  8;
615         p[fl->off+3] = fl->val;
616       }
617   }
618
619   /* calculate and store the MD5 checksum */
620   gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
621
622   pp = xtrymalloc (n);
623   if ( !pp )
624     return KEYBOX_Out_Of_Core;
625   memcpy (pp , p, n);
626   blob->blob = pp;
627   blob->bloblen = n;
628   
629   return 0;
630 }
631
632 \f
633 #ifdef KEYBOX_WITH_OPENPGP
634
635 int
636 _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock)
637 {
638   int rc = 0;
639   KBNODE node;
640   KEYBOXBLOB blob;
641
642   *r_blob = NULL;
643   blob = xtrycalloc (1, sizeof *blob);
644   if( !blob )
645     return KEYBOX_Out_Of_Core;
646
647   /* fixme: Do some sanity checks on the keyblock */
648
649   /* count userids and keys so that we can allocate the arrays */
650   for (node = keyblock; node; node = node->next) 
651     {
652       switch (node->pkt->pkttype)
653         {
654         case PKT_PUBLIC_KEY:
655         case PKT_SECRET_KEY:
656         case PKT_PUBLIC_SUBKEY:
657         case PKT_SECRET_SUBKEY: blob->nkeys++; break;
658         case PKT_USER_ID:  blob->nuids++; break;
659         case PKT_SIGNATURE: blob->nsigs++; break;
660         default: break;
661         }
662     }
663
664   blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
665   blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
666   blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
667   if (!blob->keys || !blob->uids || !blob->sigs)
668     {
669       rc = KEYBOX_Out_Of_Core;
670       goto leave;
671     }
672
673   rc = pgp_create_key_part ( blob, keyblock );
674   if (rc)
675     goto leave;
676   rc = pgp_create_uid_part ( blob, keyblock );
677   if (rc)
678     goto leave;
679   rc = pgp_create_sig_part ( blob, keyblock );
680   if (rc)
681     goto leave;
682   
683   init_membuf (blob->buf, 1024);
684   rc = create_blob_header (blob, BLOBTYPE_OPENPGP);
685   if (rc)
686     goto leave;
687   rc = pgp_create_blob_keyblock (blob, keyblock);
688   if (rc)
689     goto leave;
690   rc = create_blob_trailer (blob);
691   if (rc)
692     goto leave;
693   rc = create_blob_finish ( blob );
694   if (rc)
695     goto leave;
696
697   
698  leave:
699   release_kid_list (blob->temp_kids);
700   blob->temp_kids = NULL;
701   if (rc)
702     {
703       keybox_release_blob (blob);
704       *r_blob = NULL;
705     }
706   else
707     {
708       *r_blob = blob;
709     }
710   return rc;
711 }
712 #endif /*KEYBOX_WITH_OPENPGP*/
713
714
715 \f
716 int
717 _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen)
718 {
719   KEYBOXBLOB blob;
720   
721   *r_blob = NULL;
722   blob = xtrycalloc (1, sizeof *blob);
723   if (!blob)
724     return KEYBOX_Out_Of_Core;
725
726   blob->blob = image;
727   blob->bloblen = imagelen;
728   *r_blob = blob;
729   return 0;
730 }
731
732 void
733 _keybox_release_blob (KEYBOXBLOB blob)
734 {
735   if (!blob)
736     return;
737 /*    if (blob->buf) */
738 /*      iobuf_cancel( blob->buf ); */
739   xfree (blob->keys );
740   xfree (blob->uids );
741   xfree (blob->sigs );
742   xfree (blob->blob );
743   xfree (blob );
744 }
745
746
747
748 const char *
749 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
750 {
751     *n = blob->bloblen;
752     return blob->blob;
753 }
754
755