Coverage Report

Created: 2026-01-17 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/kbx/keybox-blob.c
Line
Count
Source
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 <https://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
   - u16  Header flags
46
          bit 0 - RFU
47
          bit 1 - Is being or has been used for OpenPGP blobs
48
   - b4   Magic 'KBXf'
49
   - u32  RFU
50
   - u32  file_created_at
51
   - u32  last_maintenance_run
52
   - u32  RFU
53
   - u32  RFU
54
55
** The OpenPGP and X.509 blobs
56
57
   The OpenPGP and X.509 blobs are very similar, things which are
58
   X.509 specific are noted like [X.509: xxx]
59
60
   - u32  Length of this blob (including these 4 bytes)
61
   - byte Blob type
62
           2 = OpenPGP
63
           3 = X509
64
   - byte Version number of this blob type
65
           1 = Blob with 20 byte fingerprints
66
           2 = Blob with 32 byte fingerprints and no keyids.
67
   - u16  Blob flags
68
          bit 0 = contains secret key material (not used)
69
          bit 1 = ephemeral blob (e.g. used while querying external resources)
70
   - u32  Offset to the OpenPGP keyblock or the X.509 DER encoded
71
          certificate
72
   - u32  The length of the keyblock or certificate
73
   - u16  [NKEYS] Number of keys (at least 1!) [X509: always 1]
74
   - u16  Size of the key information structure (at least 28 or 56).
75
   - NKEYS times:
76
     Version 1 blob:
77
      - b20  The fingerprint of the key.
78
             Fingerprints are always 20 bytes, MD5 left padded with zeroes.
79
      - u32  Offset to the n-th key's keyID (a keyID is always 8 byte)
80
             or 0 if not known which is the case only for X.509.
81
             Note that this separate keyid is not anymore used by
82
             gnupg since the support for v3 keys has been removed.
83
             We create this field anyway for backward compatibility with
84
             old EOL-ed versions.  Eventually we will completely move
85
             to the version 2 blob format.
86
      - u16  Key flags
87
             bit 0 = qualified signature (not yet implemented}
88
      - u16  RFU
89
      - bN   Optional filler up to the specified length of this
90
             structure.
91
     Version 2 blob:
92
      - b32  The fingerprint of the key.  This fingerprint is
93
             either 20 or 32 bytes.  A 20 byte fingerprint is
94
             right filled with zeroes.
95
      - u16  Key flags
96
             bit 0 = qualified signature (not yet implemented}
97
             bit 7 = 32 byte fingerprint in use.
98
      - u16  RFU
99
      - b20  keygrip  FIXME: Support a second grip.
100
      - bN   Optional filler up to the specified length of this
101
             structure.
102
   - u16  Size of the serial number (may be zero)
103
      -  bN  The serial number. N as given above.
104
   - u16  Number of user IDs
105
   - u16  [NUIDS] Size of user ID information structure
106
   - NUIDS times:
107
108
      For X509, the first user ID is the Issuer, the second the
109
      Subject and the others are subjectAltNames.  For OpenPGP we only
110
      store the information from UserID packets here.
111
112
      - u32  Blob offset to the n-th user ID
113
      - u32  Length of this user ID.
114
      - u16  User ID flags.
115
             (not yet used)
116
      - byte Validity
117
      - byte RFU
118
119
   - u16  [NSIGS] Number of signatures
120
   - u16  Size of signature information (4)
121
   - NSIGS times:
122
      - u32  Expiration time of signature with some special values.
123
             Since version 2.1.20 these special valuesare not anymore
124
             used for OpenPGP:
125
             - 0x00000000 = not checked
126
             - 0x00000001 = missing key
127
             - 0x00000002 = bad signature
128
             - 0x10000000 = valid and expires at some date in 1978.
129
             - 0xffffffff = valid and does not expire
130
   - u8 Assigned ownertrust [X509: not used]
131
   - u8 All_Validity
132
        OpenPGP: See ../g10/trustdb/TRUST_* [not yet used]
133
        X509: Bit 4 set := key has been revoked.
134
                           Note that this value matches TRUST_FLAG_REVOKED
135
   - u16  RFU
136
   - u32  Recheck_after
137
   - u32  Latest timestamp in the keyblock (useful for KS synchronization?)
138
   - u32  Blob created at
139
   - u32  [NRES] Size of reserved space (not including this field)
140
   - bN   Reserved space of size NRES for future use.
141
   - bN   Arbitrary space for example used to store data which is not
142
          part of the keyblock or certificate.  For example the v3 key
143
          IDs go here.
144
   - bN   Space for the keyblock or certificate.
145
   - bN   RFU.  This is the remaining space after keyblock and before
146
          the checksum.  Not part of the SHA-1 checksum.
147
   - b20  SHA-1 checksum (useful for KS synchronization?)
148
          Note, that KBX versions before GnuPG 2.1 used an MD5
149
          checksum.  However it was only created but never checked.
150
          Thus we do not expect problems if we switch to SHA-1.  If
151
          the checksum fails and the first 4 bytes are zero, we can
152
          try again with MD5.  SHA-1 has the advantage that it is
153
          faster on CPUs with dedicated SHA-1 support.
154
155
156
*/
157
158
159
#include <config.h>
160
#include <stdio.h>
161
#include <stdlib.h>
162
#include <string.h>
163
#include <errno.h>
164
#include <assert.h>
165
#include <time.h>
166
167
#include "keybox-defs.h"
168
#include <gcrypt.h>
169
170
#ifdef KEYBOX_WITH_X509
171
#include <ksba.h>
172
#endif
173
174
175
#include "../common/gettime.h"
176
#include "../common/host2net.h"
177
178
179
#define get32(a) buf32_to_ulong ((a))
180
181
182
/* special values of the signature status */
183
#define SF_NONE(a)  ( !(a) )
184
#define SF_NOKEY(a) ((a) & (1<<0))
185
#define SF_BAD(a)   ((a) & (1<<1))
186
#define SF_VALID(a) ((a) & (1<<29))
187
188
189
struct membuf {
190
  size_t len;
191
  size_t size;
192
  char *buf;
193
  int out_of_core;
194
};
195
196
197
struct keyboxblob_key {
198
  char   fpr[32];
199
  u32    off_kid;
200
  ulong  off_kid_addr;
201
  u16    flags;
202
  u16    fprlen;  /* Either 20 or 32 */
203
};
204
struct keyboxblob_uid {
205
  u32    off;
206
  ulong  off_addr;
207
  char   *name;     /* used only with x509 */
208
  u32    len;
209
  u16    flags;
210
  byte   validity;
211
};
212
213
struct keyid_list {
214
    struct keyid_list *next;
215
    int seqno;
216
    byte kid[8];
217
};
218
219
struct fixup_list {
220
    struct fixup_list *next;
221
    u32 off;
222
    u32 val;
223
};
224
225
226
struct keyboxblob {
227
  byte *blob;
228
  size_t bloblen;
229
  off_t fileoffset;
230
231
  /* stuff used only by keybox_create_blob */
232
  unsigned char *serialbuf;
233
  const unsigned char *serial;
234
  size_t seriallen;
235
  int nkeys;
236
  struct keyboxblob_key *keys;
237
  int nuids;
238
  struct keyboxblob_uid *uids;
239
  int nsigs;
240
  u32  *sigs;
241
  struct fixup_list *fixups;
242
  int fixup_out_of_core;
243
244
  struct keyid_list *temp_kids;
245
  struct membuf bufbuf; /* temporary store for the blob */
246
  struct membuf *buf;
247
};
248
249
250

251
/* A simple implementation of a dynamic buffer.  Use init_membuf() to
252
   create a buffer, put_membuf to append bytes and get_membuf to
253
   release and return the buffer.  Allocation errors are detected but
254
   only returned at the final get_membuf(), this helps not to clutter
255
   the code with out of core checks.  */
256
257
static void
258
init_membuf (struct membuf *mb, int initiallen)
259
0
{
260
0
  mb->len = 0;
261
0
  mb->size = initiallen;
262
0
  mb->out_of_core = 0;
263
0
  mb->buf = xtrymalloc (initiallen);
264
0
  if (!mb->buf)
265
0
      mb->out_of_core = 1;
266
0
}
267
268
static void
269
put_membuf (struct membuf *mb, const void *buf, size_t len)
270
0
{
271
0
  if (mb->out_of_core)
272
0
    return;
273
274
0
  if (mb->len + len >= mb->size)
275
0
    {
276
0
      char *p;
277
278
0
      mb->size += len + 1024;
279
0
      p = xtryrealloc (mb->buf, mb->size);
280
0
      if (!p)
281
0
        {
282
0
          mb->out_of_core = 1;
283
0
          return;
284
0
        }
285
0
      mb->buf = p;
286
0
    }
287
0
  if (buf)
288
0
    memcpy (mb->buf + mb->len, buf, len);
289
0
  else
290
0
    memset (mb->buf + mb->len, 0, len);
291
0
  mb->len += len;
292
0
}
293
294
static void *
295
get_membuf (struct membuf *mb, size_t *len)
296
0
{
297
0
  char *p;
298
299
0
  if (mb->out_of_core)
300
0
    {
301
0
      xfree (mb->buf);
302
0
      mb->buf = NULL;
303
0
      return NULL;
304
0
    }
305
306
0
  p = mb->buf;
307
0
  *len = mb->len;
308
0
  mb->buf = NULL;
309
0
  mb->out_of_core = 1; /* don't allow a reuse */
310
0
  return p;
311
0
}
312
313
314
static void
315
put8 (struct membuf *mb, byte a )
316
0
{
317
0
  put_membuf (mb, &a, 1);
318
0
}
319
320
static void
321
put16 (struct membuf *mb, u16 a )
322
0
{
323
0
  unsigned char tmp[2];
324
0
  tmp[0] = a>>8;
325
0
  tmp[1] = a;
326
0
  put_membuf (mb, tmp, 2);
327
0
}
328
329
static void
330
put32 (struct membuf *mb, u32 a )
331
0
{
332
0
  unsigned char tmp[4];
333
0
  tmp[0] = a>>24;
334
0
  tmp[1] = a>>16;
335
0
  tmp[2] = a>>8;
336
0
  tmp[3] = a;
337
0
  put_membuf (mb, tmp, 4);
338
0
}
339
340
341

342
/* Store a value in the fixup list */
343
static void
344
add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
345
0
{
346
0
  struct fixup_list *fl;
347
348
0
  if (blob->fixup_out_of_core)
349
0
    return;
350
351
0
  fl = xtrycalloc(1, sizeof *fl);
352
0
  if (!fl)
353
0
    blob->fixup_out_of_core = 1;
354
0
  else
355
0
    {
356
0
      fl->off = off;
357
0
      fl->val = val;
358
0
      fl->next = blob->fixups;
359
0
      blob->fixups = fl;
360
0
    }
361
0
}
362
363
364

365
/*
366
  OpenPGP specific stuff
367
*/
368
369
370
/* We must store the keyid at some place because we can't calculate
371
   the offset yet. This is only used for v3 keyIDs.  Function returns
372
   an index value for later fixup or -1 for out of core.  The value
373
   must be a non-zero value. */
374
static int
375
pgp_temp_store_kid (KEYBOXBLOB blob, struct _keybox_openpgp_key_info *kinfo)
376
0
{
377
0
  struct keyid_list *k, *r;
378
379
0
  k = xtrymalloc (sizeof *k);
380
0
  if (!k)
381
0
    return -1;
382
0
  memcpy (k->kid, kinfo->keyid, 8);
383
0
  k->seqno = 0;
384
0
  k->next = blob->temp_kids;
385
0
  blob->temp_kids = k;
386
0
  for (r=k; r; r = r->next)
387
0
    k->seqno++;
388
389
0
  return k->seqno;
390
0
}
391
392
393
/* Helper for pgp_create_key_part.  */
394
static gpg_error_t
395
pgp_create_key_part_single (KEYBOXBLOB blob, int n,
396
                            struct _keybox_openpgp_key_info *kinfo)
397
0
{
398
0
  size_t fprlen;
399
0
  int off;
400
401
0
  fprlen = kinfo->fprlen;
402
0
  memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
403
0
  blob->keys[n].fprlen = fprlen;
404
0
  if (fprlen < 20) /* v3 fpr - shift right and fill with zeroes. */
405
0
    {
406
0
      memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen);
407
0
      memset (blob->keys[n].fpr, 0, 20 - fprlen);
408
0
      off = pgp_temp_store_kid (blob, kinfo);
409
0
      if (off == -1)
410
0
        return gpg_error_from_syserror ();
411
0
      blob->keys[n].off_kid = off;
412
0
    }
413
0
  else
414
0
    blob->keys[n].off_kid = 0; /* Will be fixed up later */
415
0
  blob->keys[n].flags = 0;
416
0
  return 0;
417
0
}
418
419
420
static gpg_error_t
421
pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
422
0
{
423
0
  gpg_error_t err;
424
0
  int n = 0;
425
0
  struct _keybox_openpgp_key_info *kinfo;
426
427
0
  err = pgp_create_key_part_single (blob, n++, &info->primary);
428
0
  if (err)
429
0
    return err;
430
0
  if (info->nsubkeys)
431
0
    for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
432
0
      if ((err=pgp_create_key_part_single (blob, n++, kinfo)))
433
0
        return err;
434
435
0
  assert (n == blob->nkeys);
436
0
  return 0;
437
0
}
438
439
440
static void
441
pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
442
0
{
443
0
  int n = 0;
444
0
  struct _keybox_openpgp_uid_info *u;
445
446
0
  if (info->nuids)
447
0
    {
448
0
      for (u = &info->uids; u; u = u->next)
449
0
        {
450
0
          blob->uids[n].off = u->off;
451
0
          blob->uids[n].len = u->len;
452
0
          blob->uids[n].flags = 0;
453
0
          blob->uids[n].validity = 0;
454
0
          n++;
455
0
        }
456
0
    }
457
458
0
  assert (n == blob->nuids);
459
0
}
460
461
462
static void
463
pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus)
464
0
{
465
0
  int n;
466
467
0
  for (n=0; n < blob->nsigs; n++)
468
0
    {
469
0
      blob->sigs[n] = sigstatus? sigstatus[n+1] : 0;
470
0
    }
471
0
}
472
473
474
static int
475
pgp_create_blob_keyblock (KEYBOXBLOB blob,
476
                          const unsigned char *image, size_t imagelen)
477
0
{
478
0
  struct membuf *a = blob->buf;
479
0
  int n;
480
0
  u32 kbstart = a->len;
481
482
0
  add_fixup (blob, 8, kbstart);
483
484
0
  for (n = 0; n < blob->nuids; n++)
485
0
    add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off);
486
487
0
  put_membuf (a, image, imagelen);
488
489
0
  add_fixup (blob, 12, a->len - kbstart);
490
0
  return 0;
491
0
}
492
493
494

495
#ifdef KEYBOX_WITH_X509
496
/*
497
   X.509 specific stuff
498
 */
499
500
/* Write the raw certificate out */
501
static int
502
x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
503
{
504
  struct membuf *a = blob->buf;
505
  const unsigned char *image;
506
  size_t length;
507
  u32 kbstart = a->len;
508
509
  /* Store our offset for later fixup */
510
  add_fixup (blob, 8, kbstart);
511
512
  image = ksba_cert_get_image (cert, &length);
513
  if (!image)
514
    return gpg_error (GPG_ERR_GENERAL);
515
  put_membuf (a, image, length);
516
517
  add_fixup (blob, 12, a->len - kbstart);
518
  return 0;
519
}
520
521
#endif /*KEYBOX_WITH_X509*/
522
523
/* Write a stored keyID out to the buffer */
524
static void
525
write_stored_kid (KEYBOXBLOB blob, int seqno)
526
0
{
527
0
  struct keyid_list *r;
528
529
0
  for ( r = blob->temp_kids; r; r = r->next )
530
0
    {
531
0
      if (r->seqno == seqno )
532
0
        {
533
0
          put_membuf (blob->buf, r->kid, 8);
534
0
          return;
535
0
  }
536
0
    }
537
0
  never_reached ();
538
0
}
539
540
/* Release a list of key IDs */
541
static void
542
release_kid_list (struct keyid_list *kl)
543
0
{
544
0
  struct keyid_list *r, *r2;
545
546
0
  for ( r = kl; r; r = r2 )
547
0
    {
548
0
      r2 = r->next;
549
0
      xfree (r);
550
0
    }
551
0
}
552
553
554
/* Create a new blob header.  If WANT_FPR32 is set a version 2 blob is
555
 * created.  */
556
static int
557
create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral,
558
                    int want_fpr32)
559
0
{
560
0
  struct membuf *a = blob->buf;
561
0
  int i;
562
563
0
  put32 ( a, 0 ); /* blob length, needs fixup */
564
0
  put8 ( a, blobtype);
565
0
  put8 ( a, want_fpr32? 2:1 );  /* blob type version */
566
0
  put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
567
568
0
  put32 ( a, 0 ); /* offset to the raw data, needs fixup */
569
0
  put32 ( a, 0 ); /* length of the raw data, needs fixup */
570
571
0
  put16 ( a, blob->nkeys );
572
0
  if (want_fpr32)
573
0
    put16 ( a, 32 + 2 + 2 + 20);  /* size of key info */
574
0
  else
575
0
    put16 ( a, 20 + 4 + 2 + 2 );  /* size of key info */
576
0
  for ( i=0; i < blob->nkeys; i++ )
577
0
    {
578
0
      if (want_fpr32)
579
0
        {
580
0
          put_membuf (a, blob->keys[i].fpr, blob->keys[i].fprlen);
581
0
          if (blob->keys[i].fprlen < 32)
582
0
            put_membuf (a, NULL, 32 - blob->keys[i].fprlen);
583
0
          blob->keys[i].off_kid_addr = a->len;
584
0
          if (blob->keys[i].fprlen == 32)
585
0
            put16 ( a, (blob->keys[i].flags | 0x80));
586
0
          else
587
0
            put16 ( a, blob->keys[i].flags);
588
0
          put16 ( a, 0 ); /* reserved */
589
          /* FIXME: Put the real grip here instead of the filler.  */
590
0
          put_membuf (a, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20);
591
0
        }
592
0
      else
593
0
        {
594
0
          log_assert (blob->keys[i].fprlen <= 20);
595
0
          put_membuf (a, blob->keys[i].fpr, 20);
596
0
          blob->keys[i].off_kid_addr = a->len;
597
0
          put32 ( a, 0 ); /* offset to keyid, fixed up later */
598
0
          put16 ( a, blob->keys[i].flags );
599
0
          put16 ( a, 0 ); /* reserved */
600
0
        }
601
0
    }
602
603
0
  put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
604
0
  if (blob->serial)
605
0
    put_membuf (a, blob->serial, blob->seriallen);
606
607
0
  put16 ( a, blob->nuids );
608
0
  put16 ( a, 4 + 4 + 2 + 1 + 1 );  /* size of uid info */
609
0
  for (i=0; i < blob->nuids; i++)
610
0
    {
611
0
      blob->uids[i].off_addr = a->len;
612
0
      put32 ( a, 0 ); /* offset to userid, fixed up later */
613
0
      put32 ( a, blob->uids[i].len );
614
0
      put16 ( a, blob->uids[i].flags );
615
0
      put8  ( a, 0 ); /* validity */
616
0
      put8  ( a, 0 ); /* reserved */
617
0
    }
618
619
0
  put16 ( a, blob->nsigs );
620
0
  put16 ( a, 4 );  /* size of sig info */
621
0
  for (i=0; i < blob->nsigs; i++)
622
0
    {
623
0
      put32 ( a, blob->sigs[i]);
624
0
    }
625
626
0
  put8 ( a, 0 );  /* assigned ownertrust */
627
0
  put8 ( a, 0 );  /* validity of all user IDs */
628
0
  put16 ( a, 0 );  /* reserved */
629
0
  put32 ( a, 0 );  /* time of next recheck */
630
0
  put32 ( a, 0 );  /* newest timestamp (none) */
631
0
  put32 ( a, make_timestamp() );  /* creation time */
632
0
  put32 ( a, 0 );  /* size of reserved space */
633
  /* reserved space (which is currently of size 0) */
634
635
  /* space where we write keyIDs and other stuff so that the
636
     pointers can actually point to somewhere */
637
0
  if (blobtype == KEYBOX_BLOBTYPE_PGP && !want_fpr32)
638
0
    {
639
      /* For version 1 blobs, we need to store the keyids for all v3
640
       * keys because those key IDs are not part of the fingerprint.
641
       * While we are doing that, we fixup all the keyID offsets.  For
642
       * version 2 blobs (which can't carry v3 keys) we compute the
643
       * keyids in the fly because they are just stripped down
644
       * fingerprints.  */
645
0
      for (i=0; i < blob->nkeys; i++ )
646
0
        {
647
0
          if (blob->keys[i].off_kid)
648
0
            { /* this is a v3 one */
649
0
              add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
650
0
              write_stored_kid (blob, blob->keys[i].off_kid);
651
0
            }
652
0
          else
653
0
            { /* the better v4 key IDs - just store an offset 8 bytes back */
654
0
              add_fixup (blob, blob->keys[i].off_kid_addr,
655
0
                         blob->keys[i].off_kid_addr - 8);
656
0
            }
657
0
        }
658
0
    }
659
660
0
  if (blobtype == KEYBOX_BLOBTYPE_X509)
661
0
    {
662
      /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
663
         the utf-8 string representation of them */
664
0
      for (i=0; i < blob->nuids; i++ )
665
0
        {
666
0
          if (blob->uids[i].name)
667
0
            { /* this is a v3 one */
668
0
              add_fixup (blob, blob->uids[i].off_addr, a->len);
669
0
              put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
670
0
            }
671
0
        }
672
0
    }
673
674
0
    return 0;
675
0
}
676
677
678
679
static int
680
create_blob_trailer (KEYBOXBLOB blob)
681
0
{
682
0
  (void)blob;
683
0
  return 0;
684
0
}
685
686
687
static int
688
create_blob_finish (KEYBOXBLOB blob)
689
0
{
690
0
  struct membuf *a = blob->buf;
691
0
  unsigned char *p;
692
0
  unsigned char *pp;
693
0
  size_t n;
694
695
  /* Write placeholders for the checksum.  */
696
0
  put_membuf (a, NULL, 20);
697
698
  /* get the memory area */
699
0
  n = 0; /* (Just to avoid compiler warning.) */
700
0
  p = get_membuf (a, &n);
701
0
  if (!p)
702
0
    return gpg_error (GPG_ERR_ENOMEM);
703
0
  assert (n >= 20);
704
705
  /* fixup the length */
706
0
  add_fixup (blob, 0, n);
707
708
  /* do the fixups */
709
0
  if (blob->fixup_out_of_core)
710
0
    {
711
0
      xfree (p);
712
0
      return gpg_error (GPG_ERR_ENOMEM);
713
0
    }
714
715
0
  {
716
0
    struct fixup_list *fl, *next;
717
0
    for (fl = blob->fixups; fl; fl = next)
718
0
      {
719
0
        assert (fl->off+4 <= n);
720
0
        p[fl->off+0] = fl->val >> 24;
721
0
        p[fl->off+1] = fl->val >> 16;
722
0
        p[fl->off+2] = fl->val >>  8;
723
0
        p[fl->off+3] = fl->val;
724
0
        next = fl->next;
725
0
        xfree (fl);
726
0
      }
727
0
    blob->fixups = NULL;
728
0
  }
729
730
  /* Compute and store the SHA-1 checksum. */
731
0
  gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20);
732
733
0
  pp = xtrymalloc (n);
734
0
  if ( !pp )
735
0
    {
736
0
      xfree (p);
737
0
      return gpg_error_from_syserror ();
738
0
    }
739
0
  memcpy (pp , p, n);
740
0
  xfree (p);
741
0
  blob->blob = pp;
742
0
  blob->bloblen = n;
743
744
0
  return 0;
745
0
}
746
747
748

749
gpg_error_t
750
_keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
751
                             keybox_openpgp_info_t info,
752
                             const unsigned char *image,
753
                             size_t imagelen,
754
                             int as_ephemeral)
755
0
{
756
0
  gpg_error_t err;
757
0
  KEYBOXBLOB blob;
758
0
  int need_fpr32 = 0;
759
760
0
  *r_blob = NULL;
761
762
763
  /* Check whether we need a blob with 32 bit fingerprints. We could
764
   * use this always but for backward compatibility we do this only for
765
   * v5 keys.  */
766
0
  if (info->primary.version == 5)
767
0
    need_fpr32 = 1;
768
0
  else
769
0
    {
770
0
      struct _keybox_openpgp_key_info *kinfo;
771
0
      for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
772
0
        if (kinfo->version == 5)
773
0
          {
774
0
            need_fpr32 = 1;
775
0
            break;
776
0
          }
777
0
    }
778
779
0
  blob = xtrycalloc (1, sizeof *blob);
780
0
  if (!blob)
781
0
    return gpg_error_from_syserror ();
782
783
0
  blob->nkeys = 1 + info->nsubkeys;
784
0
  blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
785
0
  if (!blob->keys)
786
0
    {
787
0
      err = gpg_error_from_syserror ();
788
0
      goto leave;
789
0
    }
790
791
0
  blob->nuids = info->nuids;
792
0
  if (blob->nuids)
793
0
    {
794
0
      blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
795
0
      if (!blob->uids)
796
0
        {
797
0
          err = gpg_error_from_syserror ();
798
0
          goto leave;
799
0
        }
800
0
    }
801
802
0
  blob->nsigs = info->nsigs;
803
0
  if (blob->nsigs)
804
0
    {
805
0
      blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
806
0
      if (!blob->sigs)
807
0
        {
808
0
          err = gpg_error_from_syserror ();
809
0
          goto leave;
810
0
        }
811
0
    }
812
813
0
  err = pgp_create_key_part (blob, info);
814
0
  if (err)
815
0
    goto leave;
816
0
  pgp_create_uid_part (blob, info);
817
0
  pgp_create_sig_part (blob, NULL);
818
819
0
  init_membuf (&blob->bufbuf, 1024);
820
0
  blob->buf = &blob->bufbuf;
821
0
  err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP,
822
0
                            as_ephemeral, need_fpr32);
823
0
  if (err)
824
0
    goto leave;
825
0
  err = pgp_create_blob_keyblock (blob, image, imagelen);
826
0
  if (err)
827
0
    goto leave;
828
0
  err = create_blob_trailer (blob);
829
0
  if (err)
830
0
    goto leave;
831
0
  err = create_blob_finish (blob);
832
0
  if (err)
833
0
    goto leave;
834
835
0
 leave:
836
0
  release_kid_list (blob->temp_kids);
837
0
  blob->temp_kids = NULL;
838
0
  if (err)
839
0
    _keybox_release_blob (blob);
840
0
  else
841
0
    *r_blob = blob;
842
0
  return err;
843
0
}
844
845
846
/* Return an allocated string with the email address extracted from a
847
   DN.  Note hat we use this code also in ../sm/keylist.c.  */
848
char *
849
_keybox_x509_email_kludge (const char *name)
850
0
{
851
0
  const char *p, *string;
852
0
  unsigned char *buf;
853
0
  int n;
854
855
0
  string = name;
856
0
  for (;;)
857
0
    {
858
0
      p = strstr (string, "1.2.840.113549.1.9.1=#");
859
0
      if (!p)
860
0
        return NULL;
861
0
      if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
862
0
        {
863
0
          name = p + 22;
864
0
          break;
865
0
        }
866
0
      string = p + 22;
867
0
    }
868
869
870
  /* This looks pretty much like an email address in the subject's DN
871
     we use this to add an additional user ID entry.  This way,
872
     OpenSSL generated keys get a nicer and usable listing.  */
873
0
  for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
874
0
    ;
875
0
  if (!n)
876
0
    return NULL;
877
0
  buf = xtrymalloc (n+3);
878
0
  if (!buf)
879
0
    return NULL; /* oops, out of core */
880
0
  *buf = '<';
881
0
  for (n=1, p=name; hexdigitp (p); p +=2, n++)
882
0
    buf[n] = xtoi_2 (p);
883
0
  buf[n++] = '>';
884
0
  buf[n] = 0;
885
0
  return (char*)buf;
886
0
}
887
888
889
890
#ifdef KEYBOX_WITH_X509
891
892
/* Note: We should move calculation of the digest into libksba and
893
   remove that parameter */
894
int
895
_keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
896
                          unsigned char *sha1_digest, int as_ephemeral)
897
{
898
  int i, rc = 0;
899
  KEYBOXBLOB blob;
900
  unsigned char *sn;
901
  char *p;
902
  char **names = NULL;
903
  size_t max_names;
904
905
  *r_blob = NULL;
906
  blob = xtrycalloc (1, sizeof *blob);
907
  if( !blob )
908
    return gpg_error_from_syserror ();
909
910
  sn = ksba_cert_get_serial (cert);
911
  if (sn)
912
    {
913
      size_t n, len;
914
      n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
915
      if (n < 2)
916
        {
917
          xfree (sn);
918
          return gpg_error (GPG_ERR_GENERAL);
919
        }
920
      blob->serialbuf = sn;
921
      sn++; n--; /* skip '(' */
922
      for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
923
        len = len*10 + atoi_1 (sn);
924
      if (*sn != ':')
925
        {
926
          xfree (blob->serialbuf);
927
          blob->serialbuf = NULL;
928
          return gpg_error (GPG_ERR_GENERAL);
929
        }
930
      sn++;
931
      blob->serial = sn;
932
      blob->seriallen = len;
933
    }
934
935
  blob->nkeys = 1;
936
937
  /* create list of names */
938
  blob->nuids = 0;
939
  max_names = 100;
940
  names = xtrymalloc (max_names * sizeof *names);
941
  if (!names)
942
    {
943
      rc = gpg_error_from_syserror ();
944
      goto leave;
945
    }
946
947
  p = ksba_cert_get_issuer (cert, 0);
948
  if (!p)
949
    {
950
      rc =  gpg_error (GPG_ERR_MISSING_VALUE);
951
      goto leave;
952
    }
953
  names[blob->nuids++] = p;
954
  for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
955
    {
956
      if (blob->nuids >= max_names)
957
        {
958
          char **tmp;
959
960
          max_names += 100;
961
          tmp = xtryrealloc (names, max_names * sizeof *names);
962
          if (!tmp)
963
            {
964
              rc = gpg_error_from_syserror ();
965
              goto leave;
966
            }
967
          names = tmp;
968
        }
969
      names[blob->nuids++] = p;
970
      if (!i && (p=_keybox_x509_email_kludge (p)))
971
        names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
972
    }
973
974
  /* space for signature information */
975
  blob->nsigs = 1;
976
977
  blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
978
  blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
979
  blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
980
  if (!blob->keys || !blob->uids || !blob->sigs)
981
    {
982
      rc = gpg_error (GPG_ERR_ENOMEM);
983
      goto leave;
984
    }
985
986
  memcpy (blob->keys[0].fpr, sha1_digest, 20);
987
  blob->keys[0].off_kid = 0; /* We don't have keyids */
988
  blob->keys[0].flags = 0;
989
990
  /* issuer and subject names */
991
  for (i=0; i < blob->nuids; i++)
992
    {
993
      blob->uids[i].name = names[i];
994
      blob->uids[i].len = strlen(names[i]);
995
      names[i] = NULL;
996
      blob->uids[i].flags = 0;
997
      blob->uids[i].validity = 0;
998
    }
999
  xfree (names);
1000
  names = NULL;
1001
1002
  /* signatures */
1003
  blob->sigs[0] = 0;  /* not yet checked */
1004
1005
  /* Create a temporary buffer for further processing */
1006
  init_membuf (&blob->bufbuf, 1024);
1007
  blob->buf = &blob->bufbuf;
1008
  /* write out what we already have */
1009
  rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral, 0);
1010
  if (rc)
1011
    goto leave;
1012
  rc = x509_create_blob_cert (blob, cert);
1013
  if (rc)
1014
    goto leave;
1015
  rc = create_blob_trailer (blob);
1016
  if (rc)
1017
    goto leave;
1018
  rc = create_blob_finish ( blob );
1019
  if (rc)
1020
    goto leave;
1021
1022
1023
 leave:
1024
  release_kid_list (blob->temp_kids);
1025
  blob->temp_kids = NULL;
1026
  if (names)
1027
    {
1028
      for (i=0; i < blob->nuids; i++)
1029
        xfree (names[i]);
1030
      xfree (names);
1031
    }
1032
  if (rc)
1033
    {
1034
      _keybox_release_blob (blob);
1035
      *r_blob = NULL;
1036
    }
1037
  else
1038
    {
1039
      *r_blob = blob;
1040
    }
1041
  return rc;
1042
}
1043
#endif /*KEYBOX_WITH_X509*/
1044
1045
1046

1047
int
1048
_keybox_new_blob (KEYBOXBLOB *r_blob,
1049
                  unsigned char *image, size_t imagelen, off_t off)
1050
1.38k
{
1051
1.38k
  KEYBOXBLOB blob;
1052
1053
1.38k
  *r_blob = NULL;
1054
1.38k
  blob = xtrycalloc (1, sizeof *blob);
1055
1.38k
  if (!blob)
1056
0
    return gpg_error_from_syserror ();
1057
1058
1.38k
  blob->blob = image;
1059
1.38k
  blob->bloblen = imagelen;
1060
1.38k
  blob->fileoffset = off;
1061
1.38k
  *r_blob = blob;
1062
1.38k
  return 0;
1063
1.38k
}
1064
1065
1066
void
1067
_keybox_release_blob (KEYBOXBLOB blob)
1068
7.43k
{
1069
7.43k
  int i;
1070
7.43k
  if (!blob)
1071
6.05k
    return;
1072
1.38k
  if (blob->buf)
1073
0
    {
1074
0
      size_t len;
1075
0
      xfree (get_membuf (blob->buf, &len));
1076
0
    }
1077
1.38k
  xfree (blob->keys );
1078
1.38k
  xfree (blob->serialbuf);
1079
1.38k
  for (i=0; i < blob->nuids; i++)
1080
0
    xfree (blob->uids[i].name);
1081
1.38k
  xfree (blob->uids );
1082
1.38k
  xfree (blob->sigs );
1083
1.38k
  xfree (blob->blob );
1084
1.38k
  xfree (blob );
1085
1.38k
}
1086
1087
1088
1089
const unsigned char *
1090
_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
1091
1.38k
{
1092
1.38k
  *n = blob->bloblen;
1093
1.38k
  return blob->blob;
1094
1.38k
}
1095
1096
off_t
1097
_keybox_get_blob_fileoffset (KEYBOXBLOB blob)
1098
0
{
1099
0
  return blob->fileoffset;
1100
0
}
1101
1102
1103
1104
void
1105
_keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp)
1106
0
{
1107
0
  if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER)
1108
0
    {
1109
0
      u32 val = make_timestamp ();
1110
1111
      /* Update the last maintenance run timestamp. */
1112
0
      blob->blob[20]   = (val >> 24);
1113
0
      blob->blob[20+1] = (val >> 16);
1114
0
      blob->blob[20+2] = (val >>  8);
1115
0
      blob->blob[20+3] = (val      );
1116
1117
0
      if (for_openpgp)
1118
0
        blob->blob[7] |= 0x02;  /* OpenPGP data may be available.  */
1119
0
    }
1120
0
}