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 <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 = 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 165 : init_membuf (struct membuf *mb, int initiallen)
238 : {
239 165 : mb->len = 0;
240 165 : mb->size = initiallen;
241 165 : mb->out_of_core = 0;
242 165 : mb->buf = xtrymalloc (initiallen);
243 165 : if (!mb->buf)
244 0 : mb->out_of_core = 1;
245 165 : }
246 :
247 : static void
248 6361 : put_membuf (struct membuf *mb, const void *buf, size_t len)
249 : {
250 6361 : if (mb->out_of_core)
251 0 : return;
252 :
253 6361 : if (mb->len + len >= mb->size)
254 : {
255 : char *p;
256 :
257 128 : mb->size += len + 1024;
258 128 : p = xtryrealloc (mb->buf, mb->size);
259 128 : if (!p)
260 : {
261 0 : mb->out_of_core = 1;
262 0 : return;
263 : }
264 128 : mb->buf = p;
265 : }
266 6361 : if (buf)
267 6196 : memcpy (mb->buf + mb->len, buf, len);
268 : else
269 165 : memset (mb->buf + mb->len, 0, len);
270 6361 : mb->len += len;
271 : }
272 :
273 : static void *
274 330 : get_membuf (struct membuf *mb, size_t *len)
275 : {
276 : char *p;
277 :
278 330 : if (mb->out_of_core)
279 : {
280 165 : xfree (mb->buf);
281 165 : mb->buf = NULL;
282 165 : return NULL;
283 : }
284 :
285 165 : p = mb->buf;
286 165 : *len = mb->len;
287 165 : mb->buf = NULL;
288 165 : mb->out_of_core = 1; /* don't allow a reuse */
289 165 : return p;
290 : }
291 :
292 :
293 : static void
294 1040 : put8 (struct membuf *mb, byte a )
295 : {
296 1040 : put_membuf (mb, &a, 1);
297 1040 : }
298 :
299 : static void
300 2313 : put16 (struct membuf *mb, u16 a )
301 : {
302 : unsigned char tmp[2];
303 2313 : tmp[0] = a>>8;
304 2313 : tmp[1] = a;
305 2313 : put_membuf (mb, tmp, 2);
306 2313 : }
307 :
308 : static void
309 2348 : put32 (struct membuf *mb, u32 a )
310 : {
311 : unsigned char tmp[4];
312 2348 : tmp[0] = a>>24;
313 2348 : tmp[1] = a>>16;
314 2348 : tmp[2] = a>>8;
315 2348 : tmp[3] = a;
316 2348 : put_membuf (mb, tmp, 4);
317 2348 : }
318 :
319 :
320 :
321 : /* Store a value in the fixup list */
322 : static void
323 1001 : add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
324 : {
325 : struct fixup_list *fl;
326 :
327 1001 : if (blob->fixup_out_of_core)
328 1001 : return;
329 :
330 1001 : fl = xtrycalloc(1, sizeof *fl);
331 1001 : if (!fl)
332 0 : blob->fixup_out_of_core = 1;
333 : else
334 : {
335 1001 : fl->off = off;
336 1001 : fl->val = val;
337 1001 : fl->next = blob->fixups;
338 1001 : 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 316 : 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 316 : fprlen = kinfo->fprlen;
381 316 : if (fprlen > 20)
382 0 : fprlen = 20;
383 316 : memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
384 316 : 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 316 : blob->keys[n].off_kid = 0; /* Will be fixed up later */
395 316 : blob->keys[n].flags = 0;
396 316 : return 0;
397 : }
398 :
399 :
400 : static gpg_error_t
401 162 : pgp_create_key_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
402 : {
403 : gpg_error_t err;
404 162 : int n = 0;
405 : struct _keybox_openpgp_key_info *kinfo;
406 :
407 162 : err = pgp_create_key_part_single (blob, n++, &info->primary);
408 162 : if (err)
409 0 : return err;
410 162 : if (info->nsubkeys)
411 286 : for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
412 154 : if ((err=pgp_create_key_part_single (blob, n++, kinfo)))
413 0 : return err;
414 :
415 162 : assert (n == blob->nkeys);
416 162 : return 0;
417 : }
418 :
419 :
420 : static void
421 162 : pgp_create_uid_part (KEYBOXBLOB blob, keybox_openpgp_info_t info)
422 : {
423 162 : int n = 0;
424 : struct _keybox_openpgp_uid_info *u;
425 :
426 162 : if (info->nuids)
427 : {
428 344 : for (u = &info->uids; u; u = u->next)
429 : {
430 182 : blob->uids[n].off = u->off;
431 182 : blob->uids[n].len = u->len;
432 182 : blob->uids[n].flags = 0;
433 182 : blob->uids[n].validity = 0;
434 182 : n++;
435 : }
436 : }
437 :
438 162 : assert (n == blob->nuids);
439 162 : }
440 :
441 :
442 : static void
443 162 : pgp_create_sig_part (KEYBOXBLOB blob, u32 *sigstatus)
444 : {
445 : int n;
446 :
447 653 : for (n=0; n < blob->nsigs; n++)
448 : {
449 491 : blob->sigs[n] = sigstatus? sigstatus[n+1] : 0;
450 : }
451 162 : }
452 :
453 :
454 : static int
455 162 : pgp_create_blob_keyblock (KEYBOXBLOB blob,
456 : const unsigned char *image, size_t imagelen)
457 : {
458 162 : struct membuf *a = blob->buf;
459 : int n;
460 162 : u32 kbstart = a->len;
461 :
462 162 : add_fixup (blob, 8, kbstart);
463 :
464 344 : for (n = 0; n < blob->nuids; n++)
465 182 : add_fixup (blob, blob->uids[n].off_addr, kbstart + blob->uids[n].off);
466 :
467 162 : put_membuf (a, image, imagelen);
468 :
469 162 : add_fixup (blob, 12, a->len - kbstart);
470 162 : 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 165 : release_kid_list (struct keyid_list *kl)
523 : {
524 : struct keyid_list *r, *r2;
525 :
526 165 : for ( r = kl; r; r = r2 )
527 : {
528 0 : r2 = r->next;
529 0 : xfree (r);
530 : }
531 165 : }
532 :
533 :
534 :
535 : static int
536 165 : create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
537 : {
538 165 : struct membuf *a = blob->buf;
539 : int i;
540 :
541 165 : put32 ( a, 0 ); /* blob length, needs fixup */
542 165 : put8 ( a, blobtype);
543 165 : put8 ( a, 1 ); /* blob type version */
544 165 : put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
545 :
546 165 : put32 ( a, 0 ); /* offset to the raw data, needs fixup */
547 165 : put32 ( a, 0 ); /* length of the raw data, needs fixup */
548 :
549 165 : put16 ( a, blob->nkeys );
550 165 : put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */
551 484 : for ( i=0; i < blob->nkeys; i++ )
552 : {
553 319 : put_membuf (a, blob->keys[i].fpr, 20);
554 319 : blob->keys[i].off_kid_addr = a->len;
555 319 : put32 ( a, 0 ); /* offset to keyid, fixed up later */
556 319 : put16 ( a, blob->keys[i].flags );
557 319 : put16 ( a, 0 ); /* reserved */
558 : }
559 :
560 165 : put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
561 165 : if (blob->serial)
562 3 : put_membuf (a, blob->serial, blob->seriallen);
563 :
564 165 : put16 ( a, blob->nuids );
565 165 : put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
566 355 : for (i=0; i < blob->nuids; i++)
567 : {
568 190 : blob->uids[i].off_addr = a->len;
569 190 : put32 ( a, 0 ); /* offset to userid, fixed up later */
570 190 : put32 ( a, blob->uids[i].len );
571 190 : put16 ( a, blob->uids[i].flags );
572 190 : put8 ( a, 0 ); /* validity */
573 190 : put8 ( a, 0 ); /* reserved */
574 : }
575 :
576 165 : put16 ( a, blob->nsigs );
577 165 : put16 ( a, 4 ); /* size of sig info */
578 659 : for (i=0; i < blob->nsigs; i++)
579 : {
580 494 : put32 ( a, blob->sigs[i]);
581 : }
582 :
583 165 : put8 ( a, 0 ); /* assigned ownertrust */
584 165 : put8 ( a, 0 ); /* validity of all user IDs */
585 165 : put16 ( a, 0 ); /* reserved */
586 165 : put32 ( a, 0 ); /* time of next recheck */
587 165 : put32 ( a, 0 ); /* newest timestamp (none) */
588 165 : put32 ( a, make_timestamp() ); /* creation time */
589 165 : 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 165 : 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 478 : for (i=0; i < blob->nkeys; i++ )
600 : {
601 316 : 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 316 : add_fixup (blob, blob->keys[i].off_kid_addr,
609 316 : blob->keys[i].off_kid_addr - 8);
610 : }
611 : }
612 : }
613 :
614 165 : 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 165 : return 0;
629 : }
630 :
631 :
632 :
633 : static int
634 165 : create_blob_trailer (KEYBOXBLOB blob)
635 : {
636 : (void)blob;
637 165 : return 0;
638 : }
639 :
640 :
641 : static int
642 165 : create_blob_finish (KEYBOXBLOB blob)
643 : {
644 165 : 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 165 : put_membuf (a, NULL, 20);
651 :
652 : /* get the memory area */
653 165 : n = 0; /* (Just to avoid compiler warning.) */
654 165 : p = get_membuf (a, &n);
655 165 : if (!p)
656 0 : return gpg_error (GPG_ERR_ENOMEM);
657 165 : assert (n >= 20);
658 :
659 : /* fixup the length */
660 165 : add_fixup (blob, 0, n);
661 :
662 : /* do the fixups */
663 165 : if (blob->fixup_out_of_core)
664 : {
665 0 : xfree (p);
666 0 : return gpg_error (GPG_ERR_ENOMEM);
667 : }
668 :
669 : {
670 : struct fixup_list *fl, *next;
671 1166 : for (fl = blob->fixups; fl; fl = next)
672 : {
673 1001 : assert (fl->off+4 <= n);
674 1001 : p[fl->off+0] = fl->val >> 24;
675 1001 : p[fl->off+1] = fl->val >> 16;
676 1001 : p[fl->off+2] = fl->val >> 8;
677 1001 : p[fl->off+3] = fl->val;
678 1001 : next = fl->next;
679 1001 : xfree (fl);
680 : }
681 165 : blob->fixups = NULL;
682 : }
683 :
684 : /* Compute and store the SHA-1 checksum. */
685 165 : gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20);
686 :
687 165 : pp = xtrymalloc (n);
688 165 : if ( !pp )
689 : {
690 0 : xfree (p);
691 0 : return gpg_error_from_syserror ();
692 : }
693 165 : memcpy (pp , p, n);
694 165 : xfree (p);
695 165 : blob->blob = pp;
696 165 : blob->bloblen = n;
697 :
698 165 : return 0;
699 : }
700 :
701 :
702 :
703 : gpg_error_t
704 162 : _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
705 : keybox_openpgp_info_t info,
706 : const unsigned char *image,
707 : size_t imagelen,
708 : u32 *sigstatus,
709 : int as_ephemeral)
710 : {
711 : gpg_error_t err;
712 : KEYBOXBLOB blob;
713 :
714 162 : *r_blob = NULL;
715 :
716 : /* If we have a signature status vector, check that the number of
717 : elements matches the actual number of signatures. */
718 162 : if (sigstatus && sigstatus[0] != info->nsigs)
719 0 : return gpg_error (GPG_ERR_INTERNAL);
720 :
721 162 : blob = xtrycalloc (1, sizeof *blob);
722 162 : if (!blob)
723 0 : return gpg_error_from_syserror ();
724 :
725 162 : blob->nkeys = 1 + info->nsubkeys;
726 162 : blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
727 162 : if (!blob->keys)
728 : {
729 0 : err = gpg_error_from_syserror ();
730 0 : goto leave;
731 : }
732 :
733 162 : blob->nuids = info->nuids;
734 162 : if (blob->nuids)
735 : {
736 162 : blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
737 162 : if (!blob->uids)
738 : {
739 0 : err = gpg_error_from_syserror ();
740 0 : goto leave;
741 : }
742 : }
743 :
744 162 : blob->nsigs = info->nsigs;
745 162 : if (blob->nsigs)
746 : {
747 160 : blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
748 160 : if (!blob->sigs)
749 : {
750 0 : err = gpg_error_from_syserror ();
751 0 : goto leave;
752 : }
753 : }
754 :
755 162 : err = pgp_create_key_part (blob, info);
756 162 : if (err)
757 0 : goto leave;
758 162 : pgp_create_uid_part (blob, info);
759 162 : pgp_create_sig_part (blob, sigstatus);
760 :
761 162 : init_membuf (&blob->bufbuf, 1024);
762 162 : blob->buf = &blob->bufbuf;
763 162 : err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral);
764 162 : if (err)
765 0 : goto leave;
766 162 : err = pgp_create_blob_keyblock (blob, image, imagelen);
767 162 : if (err)
768 0 : goto leave;
769 162 : err = create_blob_trailer (blob);
770 162 : if (err)
771 0 : goto leave;
772 162 : err = create_blob_finish (blob);
773 162 : if (err)
774 0 : goto leave;
775 :
776 : leave:
777 162 : release_kid_list (blob->temp_kids);
778 162 : blob->temp_kids = NULL;
779 162 : if (err)
780 0 : _keybox_release_blob (blob);
781 : else
782 162 : *r_blob = blob;
783 162 : return err;
784 : }
785 :
786 :
787 : #ifdef KEYBOX_WITH_X509
788 :
789 : /* Return an allocated string with the email address extracted from a
790 : DN. Note hat we use this code also in ../sm/keylist.c. */
791 : static char *
792 3 : x509_email_kludge (const char *name)
793 : {
794 : const char *p, *string;
795 : unsigned char *buf;
796 : int n;
797 :
798 3 : string = name;
799 : for (;;)
800 : {
801 3 : p = strstr (string, "1.2.840.113549.1.9.1=#");
802 3 : if (!p)
803 1 : return NULL;
804 2 : if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
805 : {
806 2 : name = p + 22;
807 2 : break;
808 : }
809 0 : string = p + 22;
810 0 : }
811 :
812 :
813 : /* This looks pretty much like an email address in the subject's DN
814 : we use this to add an additional user ID entry. This way,
815 : OpenSSL generated keys get a nicer and usable listing. */
816 2 : for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
817 : ;
818 2 : if (!n)
819 0 : return NULL;
820 2 : buf = xtrymalloc (n+3);
821 2 : if (!buf)
822 0 : return NULL; /* oops, out of core */
823 2 : *buf = '<';
824 73 : for (n=1, p=name; hexdigitp (p); p +=2, n++)
825 71 : buf[n] = xtoi_2 (p);
826 2 : buf[n++] = '>';
827 2 : buf[n] = 0;
828 2 : return (char*)buf;
829 : }
830 :
831 :
832 :
833 : /* Note: We should move calculation of the digest into libksba and
834 : remove that parameter */
835 : int
836 3 : _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
837 : unsigned char *sha1_digest, int as_ephemeral)
838 : {
839 3 : int i, rc = 0;
840 : KEYBOXBLOB blob;
841 : unsigned char *sn;
842 : char *p;
843 3 : char **names = NULL;
844 : size_t max_names;
845 :
846 3 : *r_blob = NULL;
847 3 : blob = xtrycalloc (1, sizeof *blob);
848 3 : if( !blob )
849 0 : return gpg_error_from_syserror ();
850 :
851 3 : sn = ksba_cert_get_serial (cert);
852 3 : if (sn)
853 : {
854 : size_t n, len;
855 3 : n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
856 3 : if (n < 2)
857 : {
858 0 : xfree (sn);
859 0 : return gpg_error (GPG_ERR_GENERAL);
860 : }
861 3 : blob->serialbuf = sn;
862 3 : sn++; n--; /* skip '(' */
863 6 : for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
864 3 : len = len*10 + atoi_1 (sn);
865 3 : if (*sn != ':')
866 : {
867 0 : xfree (blob->serialbuf);
868 0 : blob->serialbuf = NULL;
869 0 : return gpg_error (GPG_ERR_GENERAL);
870 : }
871 3 : sn++;
872 3 : blob->serial = sn;
873 3 : blob->seriallen = len;
874 : }
875 :
876 3 : blob->nkeys = 1;
877 :
878 : /* create list of names */
879 3 : blob->nuids = 0;
880 3 : max_names = 100;
881 3 : names = xtrymalloc (max_names * sizeof *names);
882 3 : if (!names)
883 : {
884 0 : rc = gpg_error_from_syserror ();
885 0 : goto leave;
886 : }
887 :
888 3 : p = ksba_cert_get_issuer (cert, 0);
889 3 : if (!p)
890 : {
891 0 : rc = gpg_error (GPG_ERR_MISSING_VALUE);
892 0 : goto leave;
893 : }
894 3 : names[blob->nuids++] = p;
895 6 : for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
896 : {
897 3 : if (blob->nuids >= max_names)
898 : {
899 : char **tmp;
900 :
901 0 : max_names += 100;
902 0 : tmp = xtryrealloc (names, max_names * sizeof *names);
903 0 : if (!tmp)
904 : {
905 0 : rc = gpg_error_from_syserror ();
906 0 : goto leave;
907 : }
908 0 : names = tmp;
909 : }
910 3 : names[blob->nuids++] = p;
911 3 : if (!i && (p=x509_email_kludge (p)))
912 2 : names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
913 : }
914 :
915 : /* space for signature information */
916 3 : blob->nsigs = 1;
917 :
918 3 : blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
919 3 : blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
920 3 : blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
921 3 : if (!blob->keys || !blob->uids || !blob->sigs)
922 : {
923 0 : rc = gpg_error (GPG_ERR_ENOMEM);
924 0 : goto leave;
925 : }
926 :
927 3 : memcpy (blob->keys[0].fpr, sha1_digest, 20);
928 3 : blob->keys[0].off_kid = 0; /* We don't have keyids */
929 3 : blob->keys[0].flags = 0;
930 :
931 : /* issuer and subject names */
932 11 : for (i=0; i < blob->nuids; i++)
933 : {
934 8 : blob->uids[i].name = names[i];
935 8 : blob->uids[i].len = strlen(names[i]);
936 8 : names[i] = NULL;
937 8 : blob->uids[i].flags = 0;
938 8 : blob->uids[i].validity = 0;
939 : }
940 3 : xfree (names);
941 3 : names = NULL;
942 :
943 : /* signatures */
944 3 : blob->sigs[0] = 0; /* not yet checked */
945 :
946 : /* Create a temporary buffer for further processing */
947 3 : init_membuf (&blob->bufbuf, 1024);
948 3 : blob->buf = &blob->bufbuf;
949 : /* write out what we already have */
950 3 : rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral);
951 3 : if (rc)
952 0 : goto leave;
953 3 : rc = x509_create_blob_cert (blob, cert);
954 3 : if (rc)
955 0 : goto leave;
956 3 : rc = create_blob_trailer (blob);
957 3 : if (rc)
958 0 : goto leave;
959 3 : rc = create_blob_finish ( blob );
960 3 : if (rc)
961 0 : goto leave;
962 :
963 :
964 : leave:
965 3 : release_kid_list (blob->temp_kids);
966 3 : blob->temp_kids = NULL;
967 3 : if (names)
968 : {
969 0 : for (i=0; i < blob->nuids; i++)
970 0 : xfree (names[i]);
971 0 : xfree (names);
972 : }
973 3 : if (rc)
974 : {
975 0 : _keybox_release_blob (blob);
976 0 : *r_blob = NULL;
977 : }
978 : else
979 : {
980 3 : *r_blob = blob;
981 : }
982 3 : return rc;
983 : }
984 : #endif /*KEYBOX_WITH_X509*/
985 :
986 :
987 :
988 : int
989 99681 : _keybox_new_blob (KEYBOXBLOB *r_blob,
990 : unsigned char *image, size_t imagelen, off_t off)
991 : {
992 : KEYBOXBLOB blob;
993 :
994 99681 : *r_blob = NULL;
995 99681 : blob = xtrycalloc (1, sizeof *blob);
996 99681 : if (!blob)
997 0 : return gpg_error_from_syserror ();
998 :
999 99681 : blob->blob = image;
1000 99681 : blob->bloblen = imagelen;
1001 99681 : blob->fileoffset = off;
1002 99681 : *r_blob = blob;
1003 99681 : return 0;
1004 : }
1005 :
1006 :
1007 : void
1008 108679 : _keybox_release_blob (KEYBOXBLOB blob)
1009 : {
1010 : int i;
1011 108679 : if (!blob)
1012 117512 : return;
1013 99846 : if (blob->buf)
1014 : {
1015 : size_t len;
1016 165 : xfree (get_membuf (blob->buf, &len));
1017 : }
1018 99846 : xfree (blob->keys );
1019 99846 : xfree (blob->serialbuf);
1020 100036 : for (i=0; i < blob->nuids; i++)
1021 190 : xfree (blob->uids[i].name);
1022 99846 : xfree (blob->uids );
1023 99846 : xfree (blob->sigs );
1024 99846 : xfree (blob->blob );
1025 99846 : xfree (blob );
1026 : }
1027 :
1028 :
1029 :
1030 : const unsigned char *
1031 306887 : _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
1032 : {
1033 306887 : *n = blob->bloblen;
1034 306887 : return blob->blob;
1035 : }
1036 :
1037 : off_t
1038 99 : _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
1039 : {
1040 99 : return blob->fileoffset;
1041 : }
1042 :
1043 :
1044 :
1045 : void
1046 0 : _keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp)
1047 : {
1048 0 : if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER)
1049 : {
1050 0 : u32 val = make_timestamp ();
1051 :
1052 : /* Update the last maintenance run times tamp. */
1053 0 : blob->blob[20] = (val >> 24);
1054 0 : blob->blob[20+1] = (val >> 16);
1055 0 : blob->blob[20+2] = (val >> 8);
1056 0 : blob->blob[20+3] = (val );
1057 :
1058 0 : if (for_openpgp)
1059 0 : blob->blob[7] |= 0x02; /* OpenPGP data may be available. */
1060 : }
1061 0 : }
|