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