~ubuntu-branches/ubuntu/quantal/gnupg2/quantal-updates

« back to all changes in this revision

Viewing changes to .pc/CVE-2010-2547.patch/kbx/keybox-blob.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2010-11-16 11:30:31 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20101116113031-3y0603x6m3bw78s1
Tags: 2.0.14-2ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Add udev rules to give gpg access to some smartcard readers;
    Debian #543217.
    . debian/gnupg2.dev: udev rules to set ACLs on SCM smartcard readers.
    . debian/rules: Call dh_installudev.
  - debian/control: Rename Vcs-* to XS-Debian-Vcs-*.
* debian/patches/CVE-2010-2547.patch: dropped, now in
  03-gpgsm-realloc.diff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* keybox-blob.c - KBX Blob handling
2
 
 * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
3
 
 *
4
 
 * This file is part of GnuPG.
5
 
 *
6
 
 * GnuPG is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 3 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * GnuPG is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
 
21
 
/* The keybox data formats
22
 
 
23
 
The KeyBox uses an augmented OpenPGP/X.509 key format.  This makes
24
 
random access to a keyblock/certificate easier and also gives the
25
 
opportunity to store additional information (e.g. the fingerprint)
26
 
along with the key.  All integers are stored in network byte order,
27
 
offsets are counted from the beginning of the Blob.
28
 
 
29
 
The first record of a plain KBX file has a special format:
30
 
 
31
 
 u32  length of the first record
32
 
 byte Blob type (1)
33
 
 byte version number (1)
34
 
 byte reserved
35
 
 byte reserved
36
 
 u32  magic 'KBXf'
37
 
 u32  reserved
38
 
 u32  file_created_at
39
 
 u32  last_maintenance_run
40
 
 u32  reserved
41
 
 u32  reserved
42
 
 
43
 
The OpenPGP and X.509 blob are very similiar, things which are
44
 
X.509 specific are noted like [X.509: xxx]
45
 
 
46
 
 u32  length of this blob (including these 4 bytes)
47
 
 byte Blob type (2) [X509: 3]
48
 
 byte version number of this blob type (1)
49
 
 u16  Blob flags
50
 
        bit 0 = contains secret key material
51
 
        bit 1 = ephemeral blob (e.g. used while quering external resources)
52
 
 
53
 
 u32  offset to the OpenPGP keyblock or X509 DER encoded certificate
54
 
 u32  and its length
55
 
 u16  number of keys (at least 1!) [X509: always 1]
56
 
 u16  size of additional key information
57
 
 n times:
58
 
   b20  The keys fingerprint
59
 
        (fingerprints are always 20 bytes, MD5 left padded with zeroes)
60
 
   u32  offset to the n-th key's keyID (a keyID is always 8 byte)
61
 
        or 0 if not known which is the case only for X509.
62
 
   u16  special key flags
63
 
         bit 0 = qualified signature (not yet implemented}
64
 
   u16  reserved
65
 
 u16  size of serialnumber(may be zero) 
66
 
   n  u16 (see above) bytes of serial number
67
 
 u16  number of user IDs
68
 
 u16  size of additional user ID information
69
 
 n times:
70
 
   u32  offset to the n-th user ID
71
 
   u32  length of this user ID.
72
 
   u16  special user ID flags.
73
 
         bit 0 =
74
 
   byte validity
75
 
   byte reserved
76
 
   [For X509, the first user ID is the Issuer, the second the Subject
77
 
   and the others are subjectAltNames]
78
 
 u16  number of signatures
79
 
 u16  size of signature information (4)
80
 
   u32  expiration time of signature with some special values:
81
 
        0x00000000 = not checked
82
 
        0x00000001 = missing key
83
 
        0x00000002 = bad signature
84
 
        0x10000000 = valid and expires at some date in 1978.
85
 
        0xffffffff = valid and does not expire
86
 
 u8     assigned ownertrust [X509: not used]
87
 
 u8     all_validity 
88
 
           OpenPGP:  see ../g10/trustdb/TRUST_* [not yet used]
89
 
           X509: Bit 4 set := key has been revoked.  Note that this value
90
 
                              matches TRUST_FLAG_REVOKED
91
 
 u16    reserved
92
 
 u32    recheck_after
93
 
 u32    Newest timestamp in the keyblock (useful for KS syncronsiation?)
94
 
 u32    Blob created at
95
 
 u32    size of reserved space (not including this field)
96
 
      reserved space
97
 
 
98
 
    Here we might want to put other data
99
 
 
100
 
    Here comes the keyblock
101
 
 
102
 
    maybe we put a signature here later.
103
 
 
104
 
 b16    MD5 checksum  (useful for KS syncronisation), we might also want to use
105
 
    a mac here.
106
 
 b4    reserved
107
 
 
108
 
*/
109
 
 
110
 
 
111
 
#include <config.h>
112
 
#include <stdio.h>
113
 
#include <stdlib.h>
114
 
#include <string.h>
115
 
#include <errno.h>
116
 
#include <assert.h>
117
 
#include <time.h>
118
 
 
119
 
#include "keybox-defs.h"
120
 
#include <gcrypt.h>
121
 
 
122
 
#ifdef KEYBOX_WITH_OPENPGP
123
 
/* include stuff to parse the packets */
124
 
#endif
125
 
#ifdef KEYBOX_WITH_X509
126
 
#include <ksba.h>
127
 
#endif
128
 
 
129
 
 
130
 
 
131
 
/* special values of the signature status */
132
 
#define SF_NONE(a)  ( !(a) )
133
 
#define SF_NOKEY(a) ((a) & (1<<0))
134
 
#define SF_BAD(a)   ((a) & (1<<1))
135
 
#define SF_VALID(a) ((a) & (1<<29))
136
 
 
137
 
 
138
 
struct membuf {
139
 
  size_t len;
140
 
  size_t size;
141
 
  char *buf;
142
 
  int out_of_core;
143
 
};
144
 
 
145
 
 
146
 
/*  #if MAX_FINGERPRINT_LEN < 20 */
147
 
/*    #error fingerprints are 20 bytes */
148
 
/*  #endif */
149
 
 
150
 
struct keyboxblob_key {
151
 
  char   fpr[20];
152
 
  u32    off_kid;
153
 
  ulong  off_kid_addr;
154
 
  u16    flags;
155
 
};
156
 
struct keyboxblob_uid {
157
 
  ulong  off_addr;
158
 
  char   *name;     /* used only with x509 */
159
 
  u32    len;
160
 
  u16    flags;
161
 
  byte   validity;
162
 
};
163
 
 
164
 
struct keyid_list {
165
 
    struct keyid_list *next;
166
 
    int seqno;
167
 
    byte kid[8];
168
 
};
169
 
 
170
 
struct fixup_list {
171
 
    struct fixup_list *next;
172
 
    u32 off;
173
 
    u32 val;
174
 
};
175
 
 
176
 
 
177
 
struct keyboxblob {
178
 
  byte *blob;
179
 
  size_t bloblen;
180
 
  off_t fileoffset;
181
 
  
182
 
  /* stuff used only by keybox_create_blob */
183
 
  unsigned char *serialbuf;
184
 
  const unsigned char *serial;
185
 
  size_t seriallen;
186
 
  int nkeys;
187
 
  struct keyboxblob_key *keys;
188
 
  int nuids;
189
 
  struct keyboxblob_uid *uids;
190
 
  int nsigs;
191
 
  u32  *sigs;
192
 
  struct fixup_list *fixups;
193
 
  int fixup_out_of_core;
194
 
  
195
 
  struct keyid_list *temp_kids;
196
 
  struct membuf bufbuf; /* temporary store for the blob */
197
 
  struct membuf *buf; 
198
 
};
199
 
 
200
 
 
201
 
 
202
 
/* A simple implemention of a dynamic buffer.  Use init_membuf() to
203
 
   create a buffer, put_membuf to append bytes and get_membuf to
204
 
   release and return the buffer.  Allocation errors are detected but
205
 
   only returned at the final get_membuf(), this helps not to clutter
206
 
   the code with out of core checks.  */
207
 
 
208
 
static void
209
 
init_membuf (struct membuf *mb, int initiallen)
210
 
{
211
 
  mb->len = 0;
212
 
  mb->size = initiallen;
213
 
  mb->out_of_core = 0;
214
 
  mb->buf = xtrymalloc (initiallen);
215
 
  if (!mb->buf)
216
 
      mb->out_of_core = 1;
217
 
}
218
 
 
219
 
static void
220
 
put_membuf (struct membuf *mb, const void *buf, size_t len)
221
 
{
222
 
  if (mb->out_of_core)
223
 
    return;
224
 
 
225
 
  if (mb->len + len >= mb->size)
226
 
    {
227
 
      char *p;
228
 
      
229
 
      mb->size += len + 1024;
230
 
      p = xtryrealloc (mb->buf, mb->size);
231
 
      if (!p)
232
 
        {
233
 
          mb->out_of_core = 1;
234
 
          return;
235
 
        }
236
 
      mb->buf = p;
237
 
    }
238
 
  memcpy (mb->buf + mb->len, buf, len);
239
 
  mb->len += len;
240
 
}
241
 
 
242
 
static void *
243
 
get_membuf (struct membuf *mb, size_t *len)
244
 
{
245
 
  char *p;
246
 
 
247
 
  if (mb->out_of_core)
248
 
    {
249
 
      xfree (mb->buf);
250
 
      mb->buf = NULL;
251
 
      return NULL;
252
 
    }
253
 
 
254
 
  p = mb->buf;
255
 
  *len = mb->len;
256
 
  mb->buf = NULL;
257
 
  mb->out_of_core = 1; /* don't allow a reuse */
258
 
  return p;
259
 
}
260
 
 
261
 
 
262
 
static void
263
 
put8 (struct membuf *mb, byte a )
264
 
{
265
 
  put_membuf (mb, &a, 1);
266
 
}
267
 
 
268
 
static void
269
 
put16 (struct membuf *mb, u16 a )
270
 
{
271
 
  unsigned char tmp[2];
272
 
  tmp[0] = a>>8;
273
 
  tmp[1] = a;
274
 
  put_membuf (mb, tmp, 2);
275
 
}
276
 
 
277
 
static void
278
 
put32 (struct membuf *mb, u32 a )
279
 
{
280
 
  unsigned char tmp[4];
281
 
  tmp[0] = a>>24;
282
 
  tmp[1] = a>>16;
283
 
  tmp[2] = a>>8;
284
 
  tmp[3] = a;
285
 
  put_membuf (mb, tmp, 4);
286
 
}
287
 
 
288
 
 
289
 
/* Store a value in the fixup list */
290
 
static void
291
 
add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
292
 
{
293
 
  struct fixup_list *fl;
294
 
  
295
 
  if (blob->fixup_out_of_core)
296
 
    return;
297
 
 
298
 
  fl = xtrycalloc(1, sizeof *fl);
299
 
  if (!fl)
300
 
    blob->fixup_out_of_core = 1;
301
 
  else 
302
 
    {
303
 
      fl->off = off;
304
 
      fl->val = val;
305
 
      fl->next = blob->fixups;
306
 
      blob->fixups = fl;
307
 
    }
308
 
}
309
 
 
310
 
 
311
 
/*
312
 
 Some wrappers
313
 
*/
314
 
 
315
 
static u32
316
 
make_timestamp (void)
317
 
{
318
 
  return time(NULL);
319
 
}
320
 
 
321
 
 
322
 
 
323
 
#ifdef KEYBOX_WITH_OPENPGP
324
 
/*
325
 
  OpenPGP specific stuff 
326
 
*/
327
 
 
328
 
 
329
 
/*
330
 
  We must store the keyid at some place because we can't calculate the
331
 
  offset yet. This is only used for v3 keyIDs.  Function returns an
332
 
  index value for later fixup or -1 for out of core. The value must be
333
 
  a non-zero value */
334
 
static int
335
 
pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
336
 
{
337
 
  struct keyid_list *k, *r;
338
 
  
339
 
  k = xtrymalloc (sizeof *k); 
340
 
  if (!k)
341
 
    return -1;
342
 
  k->kid[0] = pk->keyid[0] >> 24 ;
343
 
  k->kid[1] = pk->keyid[0] >> 16 ;
344
 
  k->kid[2] = pk->keyid[0] >>  8 ;
345
 
  k->kid[3] = pk->keyid[0]         ;
346
 
  k->kid[4] = pk->keyid[0] >> 24 ;
347
 
  k->kid[5] = pk->keyid[0] >> 16 ;
348
 
  k->kid[6] = pk->keyid[0] >>  8 ;
349
 
  k->kid[7] = pk->keyid[0]         ;
350
 
  k->seqno = 0;
351
 
  k->next = blob->temp_kids;
352
 
  blob->temp_kids = k;
353
 
  for (r=k; r; r = r->next) 
354
 
    k->seqno++;
355
 
  
356
 
  return k->seqno;
357
 
}
358
 
 
359
 
static int
360
 
pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
361
 
{
362
 
  KBNODE node;
363
 
  size_t fprlen;
364
 
  int n;
365
 
 
366
 
  for (n=0, node = keyblock; node; node = node->next)
367
 
    {
368
 
      if ( node->pkt->pkttype == PKT_PUBLIC_KEY
369
 
           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) 
370
 
        {
371
 
          PKT_public_key *pk = node->pkt->pkt.public_key;
372
 
          char tmp[20];
373
 
 
374
 
          fingerprint_from_pk (pk, tmp , &fprlen);
375
 
          memcpy (blob->keys[n].fpr, tmp, 20);
376
 
          if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
377
 
            {
378
 
              assert (fprlen == 16);
379
 
              memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
380
 
              memset (blob->keys[n].fpr, 0, 4);
381
 
              blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
382
 
            }
383
 
          else
384
 
            {
385
 
              blob->keys[n].off_kid = 0; /* will be fixed up later */
386
 
            }
387
 
          blob->keys[n].flags = 0;
388
 
          n++;
389
 
        }
390
 
      else if ( node->pkt->pkttype == PKT_SECRET_KEY
391
 
                  || node->pkt->pkttype == PKT_SECRET_SUBKEY ) 
392
 
        {
393
 
          never_reached (); /* actually not yet implemented */
394
 
        }
395
 
    }
396
 
  assert (n == blob->nkeys);
397
 
  return 0;
398
 
}
399
 
 
400
 
static int
401
 
pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
402
 
{
403
 
  KBNODE node;
404
 
  int n;
405
 
 
406
 
  for (n=0, node = keyblock; node; node = node->next)
407
 
    {
408
 
      if (node->pkt->pkttype == PKT_USER_ID)
409
 
        {
410
 
          PKT_user_id *u = node->pkt->pkt.user_id;
411
 
          
412
 
          blob->uids[n].len = u->len;
413
 
          blob->uids[n].flags = 0;
414
 
          blob->uids[n].validity = 0;
415
 
          n++;
416
 
        }
417
 
    }
418
 
  assert (n == blob->nuids);
419
 
  return 0;
420
 
}
421
 
 
422
 
static int
423
 
pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
424
 
{
425
 
  KBNODE node;
426
 
  int n;
427
 
  
428
 
  for (n=0, node = keyblock; node; node = node->next)
429
 
    {
430
 
      if (node->pkt->pkttype == PKT_SIGNATURE)
431
 
        {
432
 
          PKT_signature *sig = node->pkt->pkt.signature;
433
 
          
434
 
          blob->sigs[n] = 0;    /* FIXME: check the signature here */
435
 
          n++;
436
 
        }
437
 
    }
438
 
  assert( n == blob->nsigs );
439
 
  return 0;
440
 
}
441
 
 
442
 
static int
443
 
pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
444
 
{
445
 
  struct membuf *a = blob->buf;
446
 
  KBNODE node;
447
 
  int rc;
448
 
  int n;
449
 
  u32 kbstart = a->len;
450
 
 
451
 
  add_fixup (blob, kbstart);
452
 
 
453
 
  for (n = 0, node = keyblock; node; node = node->next)
454
 
    {
455
 
      rc = build_packet ( a, node->pkt );
456
 
      if ( rc ) {
457
 
        gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
458
 
                      node->pkt->pkttype, gpg_errstr(rc) );
459
 
        return GPGERR_WRITE_FILE;
460
 
      }
461
 
      if ( node->pkt->pkttype == PKT_USER_ID ) 
462
 
        {
463
 
          PKT_user_id *u = node->pkt->pkt.user_id;
464
 
          /* build_packet has set the offset of the name into u ;
465
 
           * now we can do the fixup */
466
 
          add_fixup (blob, blob->uids[n].off_addr, u->stored_at);
467
 
          n++;
468
 
        }
469
 
    }
470
 
  assert (n == blob->nuids);
471
 
 
472
 
  add_fixup (blob, a->len - kbstart);
473
 
  return 0;
474
 
}
475
 
 
476
 
#endif /*KEYBOX_WITH_OPENPGP*/
477
 
 
478
 
 
479
 
#ifdef KEYBOX_WITH_X509
480
 
/* 
481
 
   X.509 specific stuff
482
 
 */
483
 
 
484
 
/* Write the raw certificate out */
485
 
static int
486
 
x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
487
 
{
488
 
  struct membuf *a = blob->buf;
489
 
  const unsigned char *image;
490
 
  size_t length;
491
 
  u32 kbstart = a->len;
492
 
 
493
 
  /* Store our offset for later fixup */
494
 
  add_fixup (blob, 8, kbstart);
495
 
 
496
 
  image = ksba_cert_get_image (cert, &length);
497
 
  if (!image)
498
 
    return gpg_error (GPG_ERR_GENERAL);
499
 
  put_membuf (a, image, length);
500
 
 
501
 
  add_fixup (blob, 12, a->len - kbstart);
502
 
  return 0;
503
 
}
504
 
 
505
 
#endif /*KEYBOX_WITH_X509*/
506
 
 
507
 
/* Write a stored keyID out to the buffer */
508
 
static void
509
 
write_stored_kid (KEYBOXBLOB blob, int seqno)
510
 
{
511
 
  struct keyid_list *r;
512
 
  
513
 
  for ( r = blob->temp_kids; r; r = r->next ) 
514
 
    {
515
 
      if (r->seqno == seqno )
516
 
        {
517
 
          put_membuf (blob->buf, r->kid, 8);
518
 
          return;
519
 
        }
520
 
    }
521
 
  never_reached ();
522
 
}
523
 
 
524
 
/* Release a list of key IDs */
525
 
static void
526
 
release_kid_list (struct keyid_list *kl)
527
 
{
528
 
  struct keyid_list *r, *r2;
529
 
  
530
 
  for ( r = kl; r; r = r2 ) 
531
 
    {
532
 
      r2 = r->next;
533
 
      xfree (r);
534
 
    }
535
 
}
536
 
 
537
 
 
538
 
 
539
 
static int
540
 
create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
541
 
{
542
 
  struct membuf *a = blob->buf;
543
 
  int i;
544
 
 
545
 
  put32 ( a, 0 ); /* blob length, needs fixup */
546
 
  put8 ( a, blobtype);  
547
 
  put8 ( a, 1 );  /* blob type version */
548
 
  put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
549
 
 
550
 
  put32 ( a, 0 ); /* offset to the raw data, needs fixup */
551
 
  put32 ( a, 0 ); /* length of the raw data, needs fixup */
552
 
 
553
 
  put16 ( a, blob->nkeys );
554
 
  put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
555
 
  for ( i=0; i < blob->nkeys; i++ )
556
 
    {
557
 
      put_membuf (a, blob->keys[i].fpr, 20);
558
 
      blob->keys[i].off_kid_addr = a->len;
559
 
      put32 ( a, 0 ); /* offset to keyid, fixed up later */
560
 
      put16 ( a, blob->keys[i].flags );
561
 
      put16 ( a, 0 ); /* reserved */
562
 
    }
563
 
 
564
 
  put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
565
 
  if (blob->serial)
566
 
    put_membuf (a, blob->serial, blob->seriallen);
567
 
 
568
 
  put16 ( a, blob->nuids );
569
 
  put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
570
 
  for (i=0; i < blob->nuids; i++)
571
 
    {
572
 
      blob->uids[i].off_addr = a->len;
573
 
      put32 ( a, 0 ); /* offset to userid, fixed up later */
574
 
      put32 ( a, blob->uids[i].len );
575
 
      put16 ( a, blob->uids[i].flags );
576
 
      put8  ( a, 0 ); /* validity */
577
 
      put8  ( a, 0 ); /* reserved */
578
 
    }
579
 
 
580
 
  put16 ( a, blob->nsigs );
581
 
  put16 ( a, 4 );  /* size of sig info */
582
 
  for (i=0; i < blob->nsigs; i++)
583
 
    {
584
 
      put32 ( a, blob->sigs[i]);
585
 
    }
586
 
 
587
 
  put8 ( a, 0 );  /* assigned ownertrust */
588
 
  put8 ( a, 0 );  /* validity of all user IDs */
589
 
  put16 ( a, 0 );  /* reserved */
590
 
  put32 ( a, 0 );  /* time of next recheck */
591
 
  put32 ( a, 0 );  /* newest timestamp (none) */
592
 
  put32 ( a, make_timestamp() );  /* creation time */
593
 
  put32 ( a, 0 );  /* size of reserved space */
594
 
  /* reserved space (which is currently of size 0) */
595
 
 
596
 
  /* space where we write keyIDs and and other stuff so that the
597
 
     pointers can actually point to somewhere */
598
 
  if (blobtype == BLOBTYPE_PGP)
599
 
    {
600
 
      /* We need to store the keyids for all pgp v3 keys because those key
601
 
         IDs are not part of the fingerprint.  While we are doing that, we
602
 
         fixup all the keyID offsets */
603
 
      for (i=0; i < blob->nkeys; i++ )
604
 
        {
605
 
          if (blob->keys[i].off_kid) 
606
 
            { /* this is a v3 one */
607
 
              add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
608
 
              write_stored_kid (blob, blob->keys[i].off_kid);
609
 
            }
610
 
          else
611
 
            { /* the better v4 key IDs - just store an offset 8 bytes back */
612
 
              add_fixup (blob, blob->keys[i].off_kid_addr,
613
 
                         blob->keys[i].off_kid_addr - 8); 
614
 
            }
615
 
        }
616
 
    }
617
 
  
618
 
  if (blobtype == BLOBTYPE_X509)
619
 
    {
620
 
      /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
621
 
         the utf-8 string represenation of them */
622
 
      for (i=0; i < blob->nuids; i++ )
623
 
        {
624
 
          if (blob->uids[i].name) 
625
 
            { /* this is a v3 one */
626
 
              add_fixup (blob, blob->uids[i].off_addr, a->len);
627
 
              put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
628
 
            }
629
 
        }
630
 
    }
631
 
 
632
 
    return 0;
633
 
}
634
 
 
635
 
 
636
 
 
637
 
static int
638
 
create_blob_trailer (KEYBOXBLOB blob)
639
 
{
640
 
  (void)blob;
641
 
  return 0;
642
 
}
643
 
 
644
 
 
645
 
static int
646
 
create_blob_finish (KEYBOXBLOB blob)
647
 
{
648
 
  struct membuf *a = blob->buf;
649
 
  unsigned char *p;
650
 
  unsigned char *pp;
651
 
  int i;
652
 
  size_t n;
653
 
 
654
 
  /* write a placeholder for the checksum */
655
 
  for (i = 0; i < 16; i++ )
656
 
    put32 (a, 0);  /* Hmmm: why put32() ?? */
657
 
  
658
 
  /* get the memory area */
659
 
  n = 0; /* (Just to avoid compiler warning.) */
660
 
  p = get_membuf (a, &n);
661
 
  if (!p)
662
 
    return gpg_error (GPG_ERR_ENOMEM);
663
 
  assert (n >= 20);
664
 
 
665
 
  /* fixup the length */
666
 
  add_fixup (blob, 0, n);
667
 
 
668
 
  /* do the fixups */
669
 
  if (blob->fixup_out_of_core)
670
 
    return gpg_error (GPG_ERR_ENOMEM);
671
 
 
672
 
  {
673
 
    struct fixup_list *fl;
674
 
    for (fl = blob->fixups; fl; fl = fl->next)
675
 
      {
676
 
        assert (fl->off+4 <= n);
677
 
        p[fl->off+0] = fl->val >> 24;
678
 
        p[fl->off+1] = fl->val >> 16;
679
 
        p[fl->off+2] = fl->val >>  8;
680
 
        p[fl->off+3] = fl->val;
681
 
      }
682
 
  }
683
 
 
684
 
  /* calculate and store the MD5 checksum */
685
 
  gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
686
 
 
687
 
  pp = xtrymalloc (n);
688
 
  if ( !pp )
689
 
    return gpg_error_from_syserror ();
690
 
  memcpy (pp , p, n);
691
 
  blob->blob = pp;
692
 
  blob->bloblen = n;
693
 
  
694
 
  return 0;
695
 
}
696
 
 
697
 
 
698
 
#ifdef KEYBOX_WITH_OPENPGP
699
 
 
700
 
int
701
 
_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral)
702
 
{
703
 
  int rc = 0;
704
 
  KBNODE node;
705
 
  KEYBOXBLOB blob;
706
 
 
707
 
  *r_blob = NULL;
708
 
  blob = xtrycalloc (1, sizeof *blob);
709
 
  if (!blob)
710
 
    return gpg_error_from_syserror ();
711
 
 
712
 
  /* fixme: Do some sanity checks on the keyblock */
713
 
 
714
 
  /* count userids and keys so that we can allocate the arrays */
715
 
  for (node = keyblock; node; node = node->next) 
716
 
    {
717
 
      switch (node->pkt->pkttype)
718
 
        {
719
 
        case PKT_PUBLIC_KEY:
720
 
        case PKT_SECRET_KEY:
721
 
        case PKT_PUBLIC_SUBKEY:
722
 
        case PKT_SECRET_SUBKEY: blob->nkeys++; break;
723
 
        case PKT_USER_ID:  blob->nuids++; break;
724
 
        case PKT_SIGNATURE: blob->nsigs++; break;
725
 
        default: break;
726
 
        }
727
 
    }
728
 
 
729
 
  blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
730
 
  blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
731
 
  blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
732
 
  if (!blob->keys || !blob->uids || !blob->sigs)
733
 
    {
734
 
      rc = gpg_error (GPG_ERR_ENOMEM);
735
 
      goto leave;
736
 
    }
737
 
 
738
 
  rc = pgp_create_key_part ( blob, keyblock );
739
 
  if (rc)
740
 
    goto leave;
741
 
  rc = pgp_create_uid_part ( blob, keyblock );
742
 
  if (rc)
743
 
    goto leave;
744
 
  rc = pgp_create_sig_part ( blob, keyblock );
745
 
  if (rc)
746
 
    goto leave;
747
 
  
748
 
  init_membuf (&blob->bufbuf, 1024);
749
 
  blob->buf = &blob->bufbuf;
750
 
  rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral);
751
 
  if (rc)
752
 
    goto leave;
753
 
  rc = pgp_create_blob_keyblock (blob, keyblock);
754
 
  if (rc)
755
 
    goto leave;
756
 
  rc = create_blob_trailer (blob);
757
 
  if (rc)
758
 
    goto leave;
759
 
  rc = create_blob_finish ( blob );
760
 
  if (rc)
761
 
    goto leave;
762
 
 
763
 
  
764
 
 leave:
765
 
  release_kid_list (blob->temp_kids);
766
 
  blob->temp_kids = NULL;
767
 
  if (rc)
768
 
    {
769
 
      keybox_release_blob (blob);
770
 
      *r_blob = NULL;
771
 
    }
772
 
  else
773
 
    {
774
 
      *r_blob = blob;
775
 
    }
776
 
  return rc;
777
 
}
778
 
#endif /*KEYBOX_WITH_OPENPGP*/
779
 
 
780
 
#ifdef KEYBOX_WITH_X509
781
 
 
782
 
/* Return an allocated string with the email address extracted from a
783
 
   DN.  Note hat we use this code also in ../sm/keylist.c.  */
784
 
static char *
785
 
x509_email_kludge (const char *name)
786
 
{
787
 
  const char *p, *string;
788
 
  unsigned char *buf;
789
 
  int n;
790
 
 
791
 
  string = name;
792
 
  for (;;)
793
 
    {
794
 
      p = strstr (string, "1.2.840.113549.1.9.1=#");
795
 
      if (!p)
796
 
        return NULL;
797
 
      if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
798
 
        {
799
 
          name = p + 22;
800
 
          break;
801
 
        }
802
 
      string = p + 22;
803
 
    }
804
 
 
805
 
 
806
 
  /* This looks pretty much like an email address in the subject's DN
807
 
     we use this to add an additional user ID entry.  This way,
808
 
     OpenSSL generated keys get a nicer and usable listing.  */
809
 
  for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
810
 
    ;
811
 
  if (!n)
812
 
    return NULL;
813
 
  buf = xtrymalloc (n+3);
814
 
  if (!buf)
815
 
    return NULL; /* oops, out of core */
816
 
  *buf = '<';
817
 
  for (n=1, p=name; hexdigitp (p); p +=2, n++)
818
 
    buf[n] = xtoi_2 (p);
819
 
  buf[n++] = '>';
820
 
  buf[n] = 0;
821
 
  return (char*)buf;
822
 
}
823
 
 
824
 
 
825
 
 
826
 
/* Note: We should move calculation of the digest into libksba and
827
 
   remove that parameter */
828
 
int
829
 
_keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
830
 
                          unsigned char *sha1_digest, int as_ephemeral)
831
 
{
832
 
  int i, rc = 0;
833
 
  KEYBOXBLOB blob;
834
 
  unsigned char *sn;
835
 
  char *p;
836
 
  char **names = NULL;
837
 
  size_t max_names;
838
 
 
839
 
  *r_blob = NULL;
840
 
  blob = xtrycalloc (1, sizeof *blob);
841
 
  if( !blob )
842
 
    return gpg_error_from_syserror ();
843
 
 
844
 
  sn = ksba_cert_get_serial (cert);
845
 
  if (sn)
846
 
    {
847
 
      size_t n, len;
848
 
      n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
849
 
      if (n < 2)
850
 
        {
851
 
          xfree (sn);
852
 
          return gpg_error (GPG_ERR_GENERAL);
853
 
        }
854
 
      blob->serialbuf = sn;
855
 
      sn++; n--; /* skip '(' */
856
 
      for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
857
 
        len = len*10 + atoi_1 (sn);
858
 
      if (*sn != ':')
859
 
        {
860
 
          xfree (blob->serialbuf);
861
 
          blob->serialbuf = NULL;
862
 
          return gpg_error (GPG_ERR_GENERAL);
863
 
        }
864
 
      sn++;
865
 
      blob->serial = sn;
866
 
      blob->seriallen = len;
867
 
    }
868
 
 
869
 
  blob->nkeys = 1;
870
 
 
871
 
  /* create list of names */
872
 
  blob->nuids = 0;
873
 
  max_names = 100;
874
 
  names = xtrymalloc (max_names * sizeof *names);
875
 
  if (!names)
876
 
    {
877
 
      rc = gpg_error_from_syserror ();
878
 
      goto leave;
879
 
    }
880
 
  
881
 
  p = ksba_cert_get_issuer (cert, 0);
882
 
  if (!p)
883
 
    {
884
 
      rc =  gpg_error (GPG_ERR_MISSING_VALUE);
885
 
      goto leave;
886
 
    }
887
 
  names[blob->nuids++] = p;
888
 
  for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
889
 
    {
890
 
      if (blob->nuids >= max_names)
891
 
        {
892
 
          char **tmp;
893
 
          
894
 
          max_names += 100;
895
 
          tmp = xtryrealloc (names, max_names * sizeof *names);
896
 
          if (!tmp)
897
 
            {
898
 
              rc = gpg_error_from_syserror ();
899
 
              goto leave;
900
 
            }
901
 
        }
902
 
      names[blob->nuids++] = p;
903
 
      if (!i && (p=x509_email_kludge (p)))
904
 
        names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
905
 
    }
906
 
  
907
 
  /* space for signature information */
908
 
  blob->nsigs = 1; 
909
 
 
910
 
  blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
911
 
  blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
912
 
  blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
913
 
  if (!blob->keys || !blob->uids || !blob->sigs)
914
 
    {
915
 
      rc = gpg_error (GPG_ERR_ENOMEM);
916
 
      goto leave;
917
 
    }
918
 
 
919
 
  memcpy (blob->keys[0].fpr, sha1_digest, 20);
920
 
  blob->keys[0].off_kid = 0; /* We don't have keyids */
921
 
  blob->keys[0].flags = 0;
922
 
 
923
 
  /* issuer and subject names */
924
 
  for (i=0; i < blob->nuids; i++)
925
 
    {
926
 
      blob->uids[i].name = names[i];
927
 
      blob->uids[i].len = strlen(names[i]);
928
 
      names[i] = NULL;
929
 
      blob->uids[i].flags = 0;
930
 
      blob->uids[i].validity = 0;
931
 
    }
932
 
  xfree (names);
933
 
  names = NULL;
934
 
 
935
 
  /* signatures */
936
 
  blob->sigs[0] = 0;    /* not yet checked */
937
 
 
938
 
  /* Create a temporary buffer for further processing */
939
 
  init_membuf (&blob->bufbuf, 1024);
940
 
  blob->buf = &blob->bufbuf;
941
 
  /* write out what we already have */
942
 
  rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
943
 
  if (rc)
944
 
    goto leave;
945
 
  rc = x509_create_blob_cert (blob, cert);
946
 
  if (rc)
947
 
    goto leave;
948
 
  rc = create_blob_trailer (blob);
949
 
  if (rc)
950
 
    goto leave;
951
 
  rc = create_blob_finish ( blob );
952
 
  if (rc)
953
 
    goto leave;
954
 
 
955
 
  
956
 
 leave:
957
 
  release_kid_list (blob->temp_kids);
958
 
  blob->temp_kids = NULL;
959
 
  if (blob && names)
960
 
    {
961
 
      for (i=0; i < blob->nuids; i++)
962
 
        xfree (names[i]); 
963
 
    }
964
 
  xfree (names);
965
 
  if (rc)
966
 
    {
967
 
      _keybox_release_blob (blob);
968
 
      *r_blob = NULL;
969
 
    }
970
 
  else
971
 
    {
972
 
      *r_blob = blob;
973
 
    }
974
 
  return rc;
975
 
}
976
 
#endif /*KEYBOX_WITH_X509*/
977
 
 
978
 
 
979
 
 
980
 
int
981
 
_keybox_new_blob (KEYBOXBLOB *r_blob,
982
 
                  unsigned char *image, size_t imagelen, off_t off)
983
 
{
984
 
  KEYBOXBLOB blob;
985
 
  
986
 
  *r_blob = NULL;
987
 
  blob = xtrycalloc (1, sizeof *blob);
988
 
  if (!blob)
989
 
    return gpg_error_from_syserror ();
990
 
 
991
 
  blob->blob = image;
992
 
  blob->bloblen = imagelen;
993
 
  blob->fileoffset = off;
994
 
  *r_blob = blob;
995
 
  return 0;
996
 
}
997
 
 
998
 
 
999
 
void
1000
 
_keybox_release_blob (KEYBOXBLOB blob)
1001
 
{
1002
 
  int i;
1003
 
  if (!blob)
1004
 
    return;
1005
 
  /* hmmm: release membuf here?*/
1006
 
  xfree (blob->keys );
1007
 
  xfree (blob->serialbuf);
1008
 
  for (i=0; i < blob->nuids; i++)
1009
 
    xfree (blob->uids[i].name);
1010
 
  xfree (blob->uids );
1011
 
  xfree (blob->sigs );
1012
 
  xfree (blob->blob );
1013
 
  xfree (blob );
1014
 
}
1015
 
 
1016
 
 
1017
 
 
1018
 
const unsigned char *
1019
 
_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
1020
 
{
1021
 
  *n = blob->bloblen;
1022
 
  return blob->blob;
1023
 
}
1024
 
 
1025
 
off_t
1026
 
_keybox_get_blob_fileoffset (KEYBOXBLOB blob)
1027
 
{
1028
 
  return blob->fileoffset;
1029
 
}
1030
 
 
1031
 
 
1032
 
 
1033
 
void
1034
 
_keybox_update_header_blob (KEYBOXBLOB blob)
1035
 
{
1036
 
  if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
1037
 
    {
1038
 
      u32 val = make_timestamp ();
1039
 
 
1040
 
      /* Update the last maintenance run times tamp. */
1041
 
      blob->blob[20]   = (val >> 24);
1042
 
      blob->blob[20+1] = (val >> 16);
1043
 
      blob->blob[20+2] = (val >>  8);
1044
 
      blob->blob[20+3] = (val      );
1045
 
    }
1046
 
}