1 /*-
2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@NetBSD.org)
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*
30 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31 * All rights reserved.
32 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33 * their moral rights under the UK Copyright Design and Patents Act 1988 to
34 * be recorded as the authors of this copyright work.
35 *
36 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37 * use this file except in compliance with the License.
38 *
39 * You may obtain a copy of the License at
40 * http://www.apache.org/licenses/LICENSE-2.0
41 *
42 * Unless required by applicable law or agreed to in writing, software
43 * distributed under the License is distributed on an "AS IS" BASIS,
44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45 *
46 * See the License for the specific language governing permissions and
47 * limitations under the License.
48 */
49
50 /** \file
51 * This file contains the base functions used by the writers.
52 */
53 #include "config.h"
54
55 #ifdef HAVE_SYS_CDEFS_H
56 #include <sys/cdefs.h>
57 #endif
58
59 #if defined(__NetBSD__)
60 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
61 __RCSID("$NetBSD: writer.c,v 1.33 2012/03/05 02:20:18 christos Exp $");
62 #endif
63
64 #include <sys/types.h>
65
66 #include <stdlib.h>
67 #include <string.h>
68
69 #ifdef HAVE_UNISTD_H
70 #include <unistd.h>
71 #endif
72
73 #ifdef HAVE_OPENSSL_CAST_H
74 #include <openssl/cast.h>
75 #endif
76
77 #include "create.h"
78 #include "writer.h"
79 #include "keyring.h"
80 #include "signature.h"
81 #include "packet.h"
82 #include "packet-parse.h"
83 #include "readerwriter.h"
84 #include "memory.h"
85 #include "netpgpdefs.h"
86 #include "version.h"
87 #include "netpgpdigest.h"
88
89
90 /*
91 * return 1 if OK, otherwise 0
92 */
93 static unsigned
base_write(pgp_output_t * out,const void * src,unsigned len)94 base_write(pgp_output_t *out, const void *src, unsigned len)
95 {
96 return out->writer.writer(src, len, &out->errors, &out->writer);
97 }
98
99 /**
100 * \ingroup Core_WritePackets
101 *
102 * \param src
103 * \param len
104 * \param output
105 * \return 1 if OK, otherwise 0
106 */
107
108 unsigned
pgp_write(pgp_output_t * output,const void * src,unsigned len)109 pgp_write(pgp_output_t *output, const void *src, unsigned len)
110 {
111 return base_write(output, src, len);
112 }
113
114 /**
115 * \ingroup Core_WritePackets
116 * \param n
117 * \param len
118 * \param output
119 * \return 1 if OK, otherwise 0
120 */
121
122 unsigned
pgp_write_scalar(pgp_output_t * output,unsigned n,unsigned len)123 pgp_write_scalar(pgp_output_t *output, unsigned n, unsigned len)
124 {
125 uint8_t c;
126
127 while (len-- > 0) {
128 c = n >> (len * 8);
129 if (!base_write(output, &c, 1)) {
130 return 0;
131 }
132 }
133 return 1;
134 }
135
136 /**
137 * \ingroup Core_WritePackets
138 * \param bn
139 * \param output
140 * \return 1 if OK, otherwise 0
141 */
142
143 unsigned
pgp_write_mpi(pgp_output_t * output,const BIGNUM * bn)144 pgp_write_mpi(pgp_output_t *output, const BIGNUM *bn)
145 {
146 unsigned bits;
147 uint8_t buf[NETPGP_BUFSIZ];
148
149 bits = (unsigned)BN_num_bits(bn);
150 if (bits > 65535) {
151 (void) fprintf(stderr, "pgp_write_mpi: too large %u\n", bits);
152 return 0;
153 }
154 BN_bn2bin(bn, buf);
155 return pgp_write_scalar(output, bits, 2) &&
156 pgp_write(output, buf, (bits + 7) / 8);
157 }
158
159 /**
160 * \ingroup Core_WritePackets
161 * \param tag
162 * \param output
163 * \return 1 if OK, otherwise 0
164 */
165
166 unsigned
pgp_write_ptag(pgp_output_t * output,pgp_content_enum tag)167 pgp_write_ptag(pgp_output_t *output, pgp_content_enum tag)
168 {
169 uint8_t c;
170
171 c = tag | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT;
172 return base_write(output, &c, 1);
173 }
174
175 /**
176 * \ingroup Core_WritePackets
177 * \param len
178 * \param output
179 * \return 1 if OK, otherwise 0
180 */
181
182 unsigned
pgp_write_length(pgp_output_t * output,unsigned len)183 pgp_write_length(pgp_output_t *output, unsigned len)
184 {
185 uint8_t c[2];
186
187 if (len < 192) {
188 c[0] = len;
189 return base_write(output, c, 1);
190 }
191 if (len < 8192 + 192) {
192 c[0] = ((len - 192) >> 8) + 192;
193 c[1] = (len - 192) % 256;
194 return base_write(output, c, 2);
195 }
196 return pgp_write_scalar(output, 0xff, 1) &&
197 pgp_write_scalar(output, len, 4);
198 }
199
200 /*
201 * Note that we finalise from the top down, so we don't use writers below
202 * that have already been finalised
203 */
204 unsigned
pgp_writer_info_finalise(pgp_error_t ** errors,pgp_writer_t * writer)205 pgp_writer_info_finalise(pgp_error_t **errors, pgp_writer_t *writer)
206 {
207 unsigned ret = 1;
208
209 if (writer->finaliser) {
210 ret = writer->finaliser(errors, writer);
211 writer->finaliser = NULL;
212 }
213 if (writer->next && !pgp_writer_info_finalise(errors, writer->next)) {
214 writer->finaliser = NULL;
215 return 0;
216 }
217 return ret;
218 }
219
220 void
pgp_writer_info_delete(pgp_writer_t * writer)221 pgp_writer_info_delete(pgp_writer_t *writer)
222 {
223 /* we should have finalised before deleting */
224 if (writer->finaliser) {
225 (void) fprintf(stderr, "pgp_writer_info_delete: not done\n");
226 return;
227 }
228 if (writer->next) {
229 pgp_writer_info_delete(writer->next);
230 free(writer->next);
231 writer->next = NULL;
232 }
233 if (writer->destroyer) {
234 writer->destroyer(writer);
235 writer->destroyer = NULL;
236 }
237 writer->writer = NULL;
238 }
239
240 /**
241 * \ingroup Core_Writers
242 *
243 * Set a writer in output. There should not be another writer set.
244 *
245 * \param output The output structure
246 * \param writer
247 * \param finaliser
248 * \param destroyer
249 * \param arg The argument for the writer and destroyer
250 */
251 void
pgp_writer_set(pgp_output_t * output,pgp_writer_func_t * writer,pgp_writer_finaliser_t * finaliser,pgp_writer_destroyer_t * destroyer,void * arg)252 pgp_writer_set(pgp_output_t *output,
253 pgp_writer_func_t *writer,
254 pgp_writer_finaliser_t *finaliser,
255 pgp_writer_destroyer_t *destroyer,
256 void *arg)
257 {
258 if (output->writer.writer) {
259 (void) fprintf(stderr, "pgp_writer_set: already set\n");
260 } else {
261 output->writer.writer = writer;
262 output->writer.finaliser = finaliser;
263 output->writer.destroyer = destroyer;
264 output->writer.arg = arg;
265 }
266 }
267
268 /**
269 * \ingroup Core_Writers
270 *
271 * Push a writer in output. There must already be another writer set.
272 *
273 * \param output The output structure
274 * \param writer
275 * \param finaliser
276 * \param destroyer
277 * \param arg The argument for the writer and destroyer
278 */
279 void
pgp_writer_push(pgp_output_t * output,pgp_writer_func_t * writer,pgp_writer_finaliser_t * finaliser,pgp_writer_destroyer_t * destroyer,void * arg)280 pgp_writer_push(pgp_output_t *output,
281 pgp_writer_func_t *writer,
282 pgp_writer_finaliser_t *finaliser,
283 pgp_writer_destroyer_t *destroyer,
284 void *arg)
285 {
286 pgp_writer_t *copy;
287
288 if ((copy = calloc(1, sizeof(*copy))) == NULL) {
289 (void) fprintf(stderr, "pgp_writer_push: bad alloc\n");
290 } else if (output->writer.writer == NULL) {
291 (void) fprintf(stderr, "pgp_writer_push: no orig writer\n");
292 } else {
293 *copy = output->writer;
294 output->writer.next = copy;
295
296 output->writer.writer = writer;
297 output->writer.finaliser = finaliser;
298 output->writer.destroyer = destroyer;
299 output->writer.arg = arg;
300 }
301 }
302
303 void
pgp_writer_pop(pgp_output_t * output)304 pgp_writer_pop(pgp_output_t *output)
305 {
306 pgp_writer_t *next;
307
308 /* Make sure the finaliser has been called. */
309 if (output->writer.finaliser) {
310 (void) fprintf(stderr,
311 "pgp_writer_pop: finaliser not called\n");
312 } else if (output->writer.next == NULL) {
313 (void) fprintf(stderr,
314 "pgp_writer_pop: not a stacked writer\n");
315 } else {
316 if (output->writer.destroyer) {
317 output->writer.destroyer(&output->writer);
318 }
319 next = output->writer.next;
320 output->writer = *next;
321 free(next);
322 }
323 }
324
325 /**
326 * \ingroup Core_Writers
327 *
328 * Close the writer currently set in output.
329 *
330 * \param output The output structure
331 */
332 unsigned
pgp_writer_close(pgp_output_t * output)333 pgp_writer_close(pgp_output_t *output)
334 {
335 unsigned ret;
336
337 ret = pgp_writer_info_finalise(&output->errors, &output->writer);
338 pgp_writer_info_delete(&output->writer);
339 return ret;
340 }
341
342 /**
343 * \ingroup Core_Writers
344 *
345 * Get the arg supplied to pgp_createinfo_set_writer().
346 *
347 * \param writer The writer_info structure
348 * \return The arg
349 */
350 void *
pgp_writer_get_arg(pgp_writer_t * writer)351 pgp_writer_get_arg(pgp_writer_t *writer)
352 {
353 return writer->arg;
354 }
355
356 /**
357 * \ingroup Core_Writers
358 *
359 * Write to the next writer down in the stack.
360 *
361 * \param src The data to write.
362 * \param len The length of src.
363 * \param errors A place to store errors.
364 * \param writer The writer_info structure.
365 * \return Success - if 0, then errors should contain the error.
366 */
367 static unsigned
stacked_write(pgp_writer_t * writer,const void * src,unsigned len,pgp_error_t ** errors)368 stacked_write(pgp_writer_t *writer, const void *src, unsigned len,
369 pgp_error_t ** errors)
370 {
371 return writer->next->writer(src, len, errors, writer->next);
372 }
373
374 /**
375 * \ingroup Core_Writers
376 *
377 * Free the arg. Many writers just have a calloc()ed lump of storage, this
378 * function releases it.
379 *
380 * \param writer the info structure.
381 */
382 static void
generic_destroyer(pgp_writer_t * writer)383 generic_destroyer(pgp_writer_t *writer)
384 {
385 free(pgp_writer_get_arg(writer));
386 }
387
388 /**
389 * \ingroup Core_Writers
390 *
391 * A writer that just writes to the next one down. Useful for when you
392 * want to insert just a finaliser into the stack.
393 */
394 unsigned
pgp_writer_passthrough(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)395 pgp_writer_passthrough(const uint8_t *src,
396 unsigned len,
397 pgp_error_t **errors,
398 pgp_writer_t *writer)
399 {
400 return stacked_write(writer, src, len, errors);
401 }
402
403 /**************************************************************************/
404
405 /**
406 * \struct dashesc_t
407 */
408 typedef struct {
409 unsigned seen_nl:1;
410 unsigned seen_cr:1;
411 pgp_create_sig_t *sig;
412 pgp_memory_t *trailing;
413 } dashesc_t;
414
415 static unsigned
dash_esc_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)416 dash_esc_writer(const uint8_t *src,
417 unsigned len,
418 pgp_error_t **errors,
419 pgp_writer_t *writer)
420 {
421 dashesc_t *dash = pgp_writer_get_arg(writer);
422 unsigned n;
423
424 if (pgp_get_debug_level(__FILE__)) {
425 unsigned i = 0;
426
427 (void) fprintf(stderr, "dash_esc_writer writing %u:\n", len);
428 for (i = 0; i < len; i++) {
429 fprintf(stderr, "0x%02x ", src[i]);
430 if (((i + 1) % 16) == 0) {
431 (void) fprintf(stderr, "\n");
432 } else if (((i + 1) % 8) == 0) {
433 (void) fprintf(stderr, " ");
434 }
435 }
436 (void) fprintf(stderr, "\n");
437 }
438 /* XXX: make this efficient */
439 for (n = 0; n < len; ++n) {
440 unsigned l;
441
442 if (dash->seen_nl) {
443 if (src[n] == '-' &&
444 !stacked_write(writer, "- ", 2, errors)) {
445 return 0;
446 }
447 dash->seen_nl = 0;
448 }
449 dash->seen_nl = src[n] == '\n';
450
451 if (dash->seen_nl && !dash->seen_cr) {
452 if (!stacked_write(writer, "\r", 1, errors)) {
453 return 0;
454 }
455 pgp_sig_add_data(dash->sig, "\r", 1);
456 }
457 dash->seen_cr = src[n] == '\r';
458
459 if (!stacked_write(writer, &src[n], 1, errors)) {
460 return 0;
461 }
462
463 /* trailing whitespace isn't included in the signature */
464 if (src[n] == ' ' || src[n] == '\t') {
465 pgp_memory_add(dash->trailing, &src[n], 1);
466 } else {
467 if ((l = (unsigned)pgp_mem_len(dash->trailing)) != 0) {
468 if (!dash->seen_nl && !dash->seen_cr) {
469 pgp_sig_add_data(dash->sig,
470 pgp_mem_data(dash->trailing), l);
471 }
472 pgp_memory_clear(dash->trailing);
473 }
474 pgp_sig_add_data(dash->sig, &src[n], 1);
475 }
476 }
477 return 1;
478 }
479
480 /**
481 * \param writer
482 */
483 static void
dash_escaped_destroyer(pgp_writer_t * writer)484 dash_escaped_destroyer(pgp_writer_t *writer)
485 {
486 dashesc_t *dash;
487
488 dash = pgp_writer_get_arg(writer);
489 pgp_memory_free(dash->trailing);
490 free(dash);
491 }
492
493 /**
494 * \ingroup Core_WritersNext
495 * \brief Push Clearsigned Writer onto stack
496 * \param output
497 * \param sig
498 */
499 unsigned
pgp_writer_push_clearsigned(pgp_output_t * output,pgp_create_sig_t * sig)500 pgp_writer_push_clearsigned(pgp_output_t *output, pgp_create_sig_t *sig)
501 {
502 static const char header[] =
503 "-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: ";
504 const char *hash;
505 dashesc_t *dash;
506 unsigned ret;
507
508 hash = pgp_text_from_hash(pgp_sig_get_hash(sig));
509 if ((dash = calloc(1, sizeof(*dash))) == NULL) {
510 PGP_ERROR_1(&output->errors, PGP_E_W, "%s", "Bad alloc");
511 return 0;
512 }
513 ret = (pgp_write(output, header, (unsigned)(sizeof(header) - 1)) &&
514 pgp_write(output, hash, (unsigned)strlen(hash)) &&
515 pgp_write(output, "\r\n\r\n", 4));
516
517 if (ret == 0) {
518 PGP_ERROR_1(&output->errors, PGP_E_W, "%s",
519 "Error pushing clearsigned header");
520 free(dash);
521 return ret;
522 }
523 dash->seen_nl = 1;
524 dash->sig = sig;
525 dash->trailing = pgp_memory_new();
526 pgp_writer_push(output, dash_esc_writer, NULL,
527 dash_escaped_destroyer, dash);
528 return ret;
529 }
530
531
532 /**
533 * \struct base64_t
534 */
535 typedef struct {
536 unsigned pos;
537 uint8_t t;
538 unsigned checksum;
539 } base64_t;
540
541 static const char b64map[] =
542 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
543
544 static unsigned
base64_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)545 base64_writer(const uint8_t *src,
546 unsigned len,
547 pgp_error_t **errors,
548 pgp_writer_t *writer)
549 {
550 base64_t *base64;
551 unsigned n;
552
553 base64 = pgp_writer_get_arg(writer);
554 for (n = 0; n < len;) {
555 base64->checksum = pgp_crc24(base64->checksum, src[n]);
556 if (base64->pos == 0) {
557 /* XXXXXX00 00000000 00000000 */
558 if (!stacked_write(writer,
559 &b64map[(unsigned)src[n] >> 2],
560 1, errors)) {
561 return 0;
562 }
563
564 /* 000000XX xxxx0000 00000000 */
565 base64->t = (src[n++] & 3) << 4;
566 base64->pos = 1;
567 } else if (base64->pos == 1) {
568 /* 000000xx XXXX0000 00000000 */
569 base64->t += (unsigned)src[n] >> 4;
570 if (!stacked_write(writer, &b64map[base64->t], 1,
571 errors)) {
572 return 0;
573 }
574
575 /* 00000000 0000XXXX xx000000 */
576 base64->t = (src[n++] & 0xf) << 2;
577 base64->pos = 2;
578 } else if (base64->pos == 2) {
579 /* 00000000 0000xxxx XX000000 */
580 base64->t += (unsigned)src[n] >> 6;
581 if (!stacked_write(writer, &b64map[base64->t], 1,
582 errors)) {
583 return 0;
584 }
585
586 /* 00000000 00000000 00XXXXXX */
587 if (!stacked_write(writer,
588 &b64map[src[n++] & 0x3f], 1, errors)) {
589 return 0;
590 }
591
592 base64->pos = 0;
593 }
594 }
595
596 return 1;
597 }
598
599 static unsigned
sig_finaliser(pgp_error_t ** errors,pgp_writer_t * writer)600 sig_finaliser(pgp_error_t **errors, pgp_writer_t *writer)
601 {
602 static const char trail[] = "\r\n-----END PGP SIGNATURE-----\r\n";
603 base64_t *base64;
604 uint8_t c[3];
605
606 base64 = pgp_writer_get_arg(writer);
607 if (base64->pos) {
608 if (!stacked_write(writer, &b64map[base64->t], 1, errors)) {
609 return 0;
610 }
611 if (base64->pos == 1 &&
612 !stacked_write(writer, "==", 2, errors)) {
613 return 0;
614 }
615 if (base64->pos == 2 &&
616 !stacked_write(writer, "=", 1, errors)) {
617 return 0;
618 }
619 }
620 /* Ready for the checksum */
621 if (!stacked_write(writer, "\r\n=", 3, errors)) {
622 return 0;
623 }
624
625 base64->pos = 0; /* get ready to write the checksum */
626
627 c[0] = base64->checksum >> 16;
628 c[1] = base64->checksum >> 8;
629 c[2] = base64->checksum;
630 /* push the checksum through our own writer */
631 if (!base64_writer(c, 3, errors, writer)) {
632 return 0;
633 }
634
635 return stacked_write(writer, trail, (unsigned)(sizeof(trail) - 1), errors);
636 }
637
638 /**
639 * \struct linebreak_t
640 */
641 typedef struct {
642 unsigned pos;
643 } linebreak_t;
644
645 #define BREAKPOS 76
646
647 static unsigned
linebreak_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)648 linebreak_writer(const uint8_t *src,
649 unsigned len,
650 pgp_error_t **errors,
651 pgp_writer_t *writer)
652 {
653 linebreak_t *linebreak;
654 unsigned n;
655
656 linebreak = pgp_writer_get_arg(writer);
657 for (n = 0; n < len; ++n, ++linebreak->pos) {
658 if (src[n] == '\r' || src[n] == '\n') {
659 linebreak->pos = 0;
660 }
661 if (linebreak->pos == BREAKPOS) {
662 if (!stacked_write(writer, "\r\n", 2, errors)) {
663 return 0;
664 }
665 linebreak->pos = 0;
666 }
667 if (!stacked_write(writer, &src[n], 1, errors)) {
668 return 0;
669 }
670 }
671
672 return 1;
673 }
674
675 /**
676 * \ingroup Core_WritersNext
677 * \brief Push armoured signature on stack
678 * \param output
679 */
680 unsigned
pgp_writer_use_armored_sig(pgp_output_t * output)681 pgp_writer_use_armored_sig(pgp_output_t *output)
682 {
683 static const char header[] =
684 "\r\n-----BEGIN PGP SIGNATURE-----\r\nVersion: "
685 NETPGP_VERSION_STRING
686 "\r\n\r\n";
687 linebreak_t *linebreak;
688 base64_t *base64;
689
690 pgp_writer_pop(output);
691 if (pgp_write(output, header, (unsigned)(sizeof(header) - 1)) == 0) {
692 PGP_ERROR_1(&output->errors, PGP_E_W, "%s",
693 "Error switching to armoured signature");
694 return 0;
695 }
696 if ((linebreak = calloc(1, sizeof(*linebreak))) == NULL) {
697 PGP_ERROR_1(&output->errors, PGP_E_W, "%s",
698 "pgp_writer_use_armored_sig: Bad alloc");
699 return 0;
700 }
701 pgp_writer_push(output, linebreak_writer, NULL,
702 generic_destroyer,
703 linebreak);
704 base64 = calloc(1, sizeof(*base64));
705 if (!base64) {
706 PGP_MEMORY_ERROR(&output->errors);
707 return 0;
708 }
709 base64->checksum = CRC24_INIT;
710 pgp_writer_push(output, base64_writer, sig_finaliser,
711 generic_destroyer, base64);
712 return 1;
713 }
714
715 static unsigned
armoured_message_finaliser(pgp_error_t ** errors,pgp_writer_t * writer)716 armoured_message_finaliser(pgp_error_t **errors, pgp_writer_t *writer)
717 {
718 /* TODO: This is same as sig_finaliser apart from trailer. */
719 static const char trailer[] =
720 "\r\n-----END PGP MESSAGE-----\r\n";
721 base64_t *base64;
722 uint8_t c[3];
723
724 base64 = pgp_writer_get_arg(writer);
725 if (base64->pos) {
726 if (!stacked_write(writer, &b64map[base64->t], 1, errors)) {
727 return 0;
728 }
729 if (base64->pos == 1 &&
730 !stacked_write(writer, "==", 2, errors)) {
731 return 0;
732 }
733 if (base64->pos == 2 &&
734 !stacked_write(writer, "=", 1, errors)) {
735 return 0;
736 }
737 }
738 /* Ready for the checksum */
739 if (!stacked_write(writer, "\r\n=", 3, errors)) {
740 return 0;
741 }
742
743 base64->pos = 0; /* get ready to write the checksum */
744
745 c[0] = base64->checksum >> 16;
746 c[1] = base64->checksum >> 8;
747 c[2] = base64->checksum;
748 /* push the checksum through our own writer */
749 if (!base64_writer(c, 3, errors, writer)) {
750 return 0;
751 }
752
753 return stacked_write(writer, trailer, (unsigned)strlen(trailer), errors);
754 }
755
756 /**
757 \ingroup Core_WritersNext
758 \brief Write a PGP MESSAGE
759 \todo replace with generic function
760 */
761 void
pgp_writer_push_armor_msg(pgp_output_t * output)762 pgp_writer_push_armor_msg(pgp_output_t *output)
763 {
764 static const char header[] = "-----BEGIN PGP MESSAGE-----\r\n";
765 linebreak_t *linebreak;
766 base64_t *base64;
767
768 pgp_write(output, header, (unsigned)(sizeof(header) - 1));
769 pgp_write(output, "\r\n", 2);
770 if ((linebreak = calloc(1, sizeof(*linebreak))) == NULL) {
771 (void) fprintf(stderr,
772 "pgp_writer_push_armor_msg: bad lb alloc\n");
773 return;
774 }
775 pgp_writer_push(output, linebreak_writer, NULL,
776 generic_destroyer,
777 linebreak);
778 if ((base64 = calloc(1, sizeof(*base64))) == NULL) {
779 (void) fprintf(stderr,
780 "pgp_writer_push_armor_msg: bad alloc\n");
781 return;
782 }
783 base64->checksum = CRC24_INIT;
784 pgp_writer_push(output, base64_writer,
785 armoured_message_finaliser, generic_destroyer,
786 base64);
787 }
788
789 static unsigned
armoured_finaliser(pgp_armor_type_t type,pgp_error_t ** errors,pgp_writer_t * writer)790 armoured_finaliser(pgp_armor_type_t type,
791 pgp_error_t **errors,
792 pgp_writer_t *writer)
793 {
794 static const char tail_pubkey[] =
795 "\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n";
796 static const char tail_private_key[] =
797 "\r\n-----END PGP PRIVATE KEY BLOCK-----\r\n";
798 const char *tail = NULL;
799 unsigned tailsize = 0;
800 base64_t *base64;
801 uint8_t c[3];
802
803 switch (type) {
804 case PGP_PGP_PUBLIC_KEY_BLOCK:
805 tail = tail_pubkey;
806 tailsize = sizeof(tail_pubkey) - 1;
807 break;
808
809 case PGP_PGP_PRIVATE_KEY_BLOCK:
810 tail = tail_private_key;
811 tailsize = sizeof(tail_private_key) - 1;
812 break;
813
814 default:
815 (void) fprintf(stderr, "armoured_finaliser: unusual type\n");
816 return 0;
817 }
818 base64 = pgp_writer_get_arg(writer);
819 if (base64->pos) {
820 if (!stacked_write(writer, &b64map[base64->t], 1,
821 errors)) {
822 return 0;
823 }
824 if (base64->pos == 1 && !stacked_write(writer, "==", 2,
825 errors)) {
826 return 0;
827 }
828 if (base64->pos == 2 && !stacked_write(writer, "=", 1,
829 errors)) {
830 return 0;
831 }
832 }
833 /* Ready for the checksum */
834 if (!stacked_write(writer, "\r\n=", 3, errors)) {
835 return 0;
836 }
837 base64->pos = 0; /* get ready to write the checksum */
838 c[0] = base64->checksum >> 16;
839 c[1] = base64->checksum >> 8;
840 c[2] = base64->checksum;
841 /* push the checksum through our own writer */
842 if (!base64_writer(c, 3, errors, writer)) {
843 return 0;
844 }
845 return stacked_write(writer, tail, tailsize, errors);
846 }
847
848 static unsigned
armored_pubkey_fini(pgp_error_t ** errors,pgp_writer_t * writer)849 armored_pubkey_fini(pgp_error_t **errors, pgp_writer_t *writer)
850 {
851 return armoured_finaliser(PGP_PGP_PUBLIC_KEY_BLOCK, errors, writer);
852 }
853
854 static unsigned
armored_privkey_fini(pgp_error_t ** errors,pgp_writer_t * writer)855 armored_privkey_fini(pgp_error_t **errors, pgp_writer_t *writer)
856 {
857 return armoured_finaliser(PGP_PGP_PRIVATE_KEY_BLOCK, errors, writer);
858 }
859
860 /* \todo use this for other armoured types */
861 /**
862 \ingroup Core_WritersNext
863 \brief Push Armoured Writer on stack (generic)
864 */
865 void
pgp_writer_push_armoured(pgp_output_t * output,pgp_armor_type_t type)866 pgp_writer_push_armoured(pgp_output_t *output, pgp_armor_type_t type)
867 {
868 static char hdr_pubkey[] =
869 "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: "
870 NETPGP_VERSION_STRING
871 "\r\n\r\n";
872 static char hdr_private_key[] =
873 "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\nVersion: "
874 NETPGP_VERSION_STRING
875 "\r\n\r\n";
876 unsigned hdrsize = 0;
877 unsigned (*finaliser) (pgp_error_t **, pgp_writer_t *);
878 base64_t *base64;
879 linebreak_t *linebreak;
880 char *header = NULL;
881
882 finaliser = NULL;
883 switch (type) {
884 case PGP_PGP_PUBLIC_KEY_BLOCK:
885 header = hdr_pubkey;
886 hdrsize = sizeof(hdr_pubkey) - 1;
887 finaliser = armored_pubkey_fini;
888 break;
889
890 case PGP_PGP_PRIVATE_KEY_BLOCK:
891 header = hdr_private_key;
892 hdrsize = sizeof(hdr_private_key) - 1;
893 finaliser = armored_privkey_fini;
894 break;
895
896 default:
897 (void) fprintf(stderr,
898 "pgp_writer_push_armoured: unusual type\n");
899 return;
900 }
901 if ((linebreak = calloc(1, sizeof(*linebreak))) == NULL) {
902 (void) fprintf(stderr,
903 "pgp_writer_push_armoured: bad alloc\n");
904 return;
905 }
906 pgp_write(output, header, hdrsize);
907 pgp_writer_push(output, linebreak_writer, NULL,
908 generic_destroyer,
909 linebreak);
910 if ((base64 = calloc(1, sizeof(*base64))) == NULL) {
911 (void) fprintf(stderr,
912 "pgp_writer_push_armoured: bad alloc\n");
913 return;
914 }
915 base64->checksum = CRC24_INIT;
916 pgp_writer_push(output, base64_writer, finaliser,
917 generic_destroyer, base64);
918 }
919
920 /**************************************************************************/
921
922 typedef struct {
923 pgp_crypt_t *crypt;
924 int free_crypt;
925 } crypt_t;
926
927 /*
928 * This writer simply takes plaintext as input,
929 * encrypts it with the given key
930 * and outputs the resulting encrypted text
931 */
932 static unsigned
encrypt_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)933 encrypt_writer(const uint8_t *src,
934 unsigned len,
935 pgp_error_t **errors,
936 pgp_writer_t *writer)
937 {
938 #define BUFSZ 1024 /* arbitrary number */
939 uint8_t encbuf[BUFSZ];
940 unsigned remaining;
941 unsigned done = 0;
942 crypt_t *pgp_encrypt;
943
944 remaining = len;
945 pgp_encrypt = (crypt_t *) pgp_writer_get_arg(writer);
946 if (!pgp_is_sa_supported(pgp_encrypt->crypt->alg)) {
947 (void) fprintf(stderr, "encrypt_writer: not supported\n");
948 return 0;
949 }
950 while (remaining > 0) {
951 unsigned size = (remaining < BUFSZ) ? remaining : BUFSZ;
952
953 /* memcpy(buf,src,size); // \todo copy needed here? */
954 pgp_encrypt->crypt->cfb_encrypt(pgp_encrypt->crypt, encbuf,
955 src + done, size);
956
957 if (pgp_get_debug_level(__FILE__)) {
958 hexdump(stderr, "unencrypted", &src[done], 16);
959 hexdump(stderr, "encrypted", encbuf, 16);
960 }
961 if (!stacked_write(writer, encbuf, size, errors)) {
962 if (pgp_get_debug_level(__FILE__)) {
963 fprintf(stderr,
964 "encrypted_writer: stacked write\n");
965 }
966 return 0;
967 }
968 remaining -= size;
969 done += size;
970 }
971
972 return 1;
973 }
974
975 static void
encrypt_destroyer(pgp_writer_t * writer)976 encrypt_destroyer(pgp_writer_t *writer)
977 {
978 crypt_t *pgp_encrypt;
979
980 pgp_encrypt = (crypt_t *) pgp_writer_get_arg(writer);
981 if (pgp_encrypt->free_crypt) {
982 free(pgp_encrypt->crypt);
983 }
984 free(pgp_encrypt);
985 }
986
987 /**
988 \ingroup Core_WritersNext
989 \brief Push Encrypted Writer onto stack (create SE packets)
990 */
991 void
pgp_push_enc_crypt(pgp_output_t * output,pgp_crypt_t * pgp_crypt)992 pgp_push_enc_crypt(pgp_output_t *output, pgp_crypt_t *pgp_crypt)
993 {
994 /* Create encrypt to be used with this writer */
995 /* Remember to free this in the destroyer */
996 crypt_t *pgp_encrypt;
997
998 if ((pgp_encrypt = calloc(1, sizeof(*pgp_encrypt))) == NULL) {
999 (void) fprintf(stderr, "pgp_push_enc_crypt: bad alloc\n");
1000 } else {
1001 /* Setup the encrypt */
1002 pgp_encrypt->crypt = pgp_crypt;
1003 pgp_encrypt->free_crypt = 0;
1004 /* And push writer on stack */
1005 pgp_writer_push(output, encrypt_writer, NULL,
1006 encrypt_destroyer, pgp_encrypt);
1007 }
1008 }
1009
1010 /**************************************************************************/
1011
1012 typedef struct {
1013 pgp_crypt_t *crypt;
1014 } encrypt_se_ip_t;
1015
1016 static unsigned encrypt_se_ip_writer(const uint8_t *,
1017 unsigned,
1018 pgp_error_t **,
1019 pgp_writer_t *);
1020 static void encrypt_se_ip_destroyer(pgp_writer_t *);
1021
1022 /* */
1023
1024 /**
1025 \ingroup Core_WritersNext
1026 \brief Push Encrypted SE IP Writer onto stack
1027 */
1028 int
pgp_push_enc_se_ip(pgp_output_t * output,const pgp_key_t * pubkey,const char * cipher)1029 pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *cipher)
1030 {
1031 pgp_pk_sesskey_t *encrypted_pk_sesskey;
1032 encrypt_se_ip_t *se_ip;
1033 pgp_crypt_t *encrypted;
1034 uint8_t *iv;
1035
1036 if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
1037 (void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
1038 return 0;
1039 }
1040
1041 /* Create and write encrypted PK session key */
1042 if ((encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher)) == NULL) {
1043 (void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n");
1044 return 0;
1045 }
1046 pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
1047
1048 /* Setup the se_ip */
1049 if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
1050 free(se_ip);
1051 (void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
1052 return 0;
1053 }
1054 pgp_crypt_any(encrypted, encrypted_pk_sesskey->symm_alg);
1055 if ((iv = calloc(1, encrypted->blocksize)) == NULL) {
1056 free(se_ip);
1057 free(encrypted);
1058 (void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
1059 return 0;
1060 }
1061 encrypted->set_iv(encrypted, iv);
1062 encrypted->set_crypt_key(encrypted, &encrypted_pk_sesskey->key[0]);
1063 pgp_encrypt_init(encrypted);
1064
1065 se_ip->crypt = encrypted;
1066
1067 /* And push writer on stack */
1068 pgp_writer_push(output, encrypt_se_ip_writer, NULL,
1069 encrypt_se_ip_destroyer, se_ip);
1070 /* tidy up */
1071 free(encrypted_pk_sesskey);
1072 free(iv);
1073 return 1;
1074 }
1075
1076 static unsigned
encrypt_se_ip_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)1077 encrypt_se_ip_writer(const uint8_t *src,
1078 unsigned len,
1079 pgp_error_t **errors,
1080 pgp_writer_t *writer)
1081 {
1082 const unsigned bufsz = 128;
1083 encrypt_se_ip_t *se_ip = pgp_writer_get_arg(writer);
1084 pgp_output_t *litoutput;
1085 pgp_output_t *zoutput;
1086 pgp_output_t *output;
1087 pgp_memory_t *litmem;
1088 pgp_memory_t *zmem;
1089 pgp_memory_t *localmem;
1090 unsigned ret = 1;
1091
1092 pgp_setup_memory_write(&litoutput, &litmem, bufsz);
1093 pgp_setup_memory_write(&zoutput, &zmem, bufsz);
1094 pgp_setup_memory_write(&output, &localmem, bufsz);
1095
1096 /* create literal data packet from source data */
1097 pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
1098 if (pgp_mem_len(litmem) <= len) {
1099 (void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
1100 return 0;
1101 }
1102
1103 /* create compressed packet from literal data packet */
1104 pgp_writez(zoutput, pgp_mem_data(litmem), (unsigned)pgp_mem_len(litmem));
1105
1106 /* create SE IP packet set from this compressed literal data */
1107 pgp_write_se_ip_pktset(output, pgp_mem_data(zmem),
1108 (unsigned)pgp_mem_len(zmem),
1109 se_ip->crypt);
1110 if (pgp_mem_len(localmem) <= pgp_mem_len(zmem)) {
1111 (void) fprintf(stderr,
1112 "encrypt_se_ip_writer: bad comp len\n");
1113 return 0;
1114 }
1115
1116 /* now write memory to next writer */
1117 ret = stacked_write(writer, pgp_mem_data(localmem),
1118 (unsigned)pgp_mem_len(localmem), errors);
1119
1120 pgp_memory_free(localmem);
1121 pgp_memory_free(zmem);
1122 pgp_memory_free(litmem);
1123
1124 return ret;
1125 }
1126
1127 static void
encrypt_se_ip_destroyer(pgp_writer_t * writer)1128 encrypt_se_ip_destroyer(pgp_writer_t *writer)
1129 {
1130 encrypt_se_ip_t *se_ip;
1131
1132 se_ip = pgp_writer_get_arg(writer);
1133 free(se_ip->crypt);
1134 free(se_ip);
1135 }
1136
1137 unsigned
pgp_write_se_ip_pktset(pgp_output_t * output,const uint8_t * data,const unsigned len,pgp_crypt_t * crypted)1138 pgp_write_se_ip_pktset(pgp_output_t *output,
1139 const uint8_t *data,
1140 const unsigned len,
1141 pgp_crypt_t *crypted)
1142 {
1143 pgp_output_t *mdcoutput;
1144 pgp_memory_t *mdc;
1145 uint8_t hashed[PGP_SHA1_HASH_SIZE];
1146 uint8_t *preamble;
1147 const size_t mdcsize = 1 + 1 + PGP_SHA1_HASH_SIZE;
1148 size_t preamblesize;
1149 size_t bufsize;
1150
1151 preamblesize = crypted->blocksize + 2;
1152 if ((preamble = calloc(1, preamblesize)) == NULL) {
1153 (void) fprintf(stderr, "pgp_write_se_ip_pktset: bad alloc\n");
1154 return 0;
1155 }
1156 bufsize = preamblesize + len + mdcsize;
1157
1158 if (!pgp_write_ptag(output, PGP_PTAG_CT_SE_IP_DATA) ||
1159 !pgp_write_length(output, (unsigned)(1 + bufsize)) ||
1160 !pgp_write_scalar(output, PGP_SE_IP_DATA_VERSION, 1)) {
1161 free(preamble);
1162 return 0;
1163 }
1164 pgp_random(preamble, crypted->blocksize);
1165 preamble[crypted->blocksize] = preamble[crypted->blocksize - 2];
1166 preamble[crypted->blocksize + 1] = preamble[crypted->blocksize - 1];
1167
1168 if (pgp_get_debug_level(__FILE__)) {
1169 hexdump(stderr, "preamble", preamble, preamblesize);
1170 }
1171
1172 /* now construct MDC packet and add to the end of the buffer */
1173 pgp_setup_memory_write(&mdcoutput, &mdc, mdcsize);
1174 pgp_calc_mdc_hash(preamble, preamblesize, data, len, hashed);
1175 pgp_write_mdc(mdcoutput, hashed);
1176
1177 if (pgp_get_debug_level(__FILE__)) {
1178 hexdump(stderr, "plaintext", data, len);
1179 hexdump(stderr, "mdc", pgp_mem_data(mdc), PGP_SHA1_HASH_SIZE + 1 + 1);
1180 }
1181
1182 /* and write it out */
1183 pgp_push_enc_crypt(output, crypted);
1184 if (pgp_get_debug_level(__FILE__)) {
1185 (void) fprintf(stderr,
1186 "writing %" PRIsize "u + %u + %" PRIsize "u\n",
1187 preamblesize, len, pgp_mem_len(mdc));
1188 }
1189 if (!pgp_write(output, preamble, (unsigned)preamblesize) ||
1190 !pgp_write(output, data, len) ||
1191 !pgp_write(output, pgp_mem_data(mdc), (unsigned)pgp_mem_len(mdc))) {
1192 /* \todo fix cleanup here and in old code functions */
1193 return 0;
1194 }
1195
1196 pgp_writer_pop(output);
1197
1198 /* cleanup */
1199 pgp_teardown_memory_write(mdcoutput, mdc);
1200 free(preamble);
1201
1202 return 1;
1203 }
1204
1205 typedef struct {
1206 int fd;
1207 } writer_fd_t;
1208
1209 static unsigned
fd_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)1210 fd_writer(const uint8_t *src, unsigned len,
1211 pgp_error_t **errors,
1212 pgp_writer_t *writer)
1213 {
1214 writer_fd_t *writerfd;
1215 int n;
1216
1217 writerfd = pgp_writer_get_arg(writer);
1218 n = (int)write(writerfd->fd, src, len);
1219 if (n == -1) {
1220 PGP_SYSTEM_ERROR_1(errors, PGP_E_W_WRITE_FAILED, "write",
1221 "file descriptor %d", writerfd->fd);
1222 return 0;
1223 }
1224 if ((unsigned) n != len) {
1225 PGP_ERROR_1(errors, PGP_E_W_WRITE_TOO_SHORT,
1226 "file descriptor %d", writerfd->fd);
1227 return 0;
1228 }
1229 return 1;
1230 }
1231
1232 static void
writer_fd_destroyer(pgp_writer_t * writer)1233 writer_fd_destroyer(pgp_writer_t *writer)
1234 {
1235 free(pgp_writer_get_arg(writer));
1236 }
1237
1238 /**
1239 * \ingroup Core_WritersFirst
1240 * \brief Write to a File
1241 *
1242 * Set the writer in output to be a stock writer that writes to a file
1243 * descriptor. If another writer has already been set, then that is
1244 * first destroyed.
1245 *
1246 * \param output The output structure
1247 * \param fd The file descriptor
1248 *
1249 */
1250
1251 void
pgp_writer_set_fd(pgp_output_t * output,int fd)1252 pgp_writer_set_fd(pgp_output_t *output, int fd)
1253 {
1254 writer_fd_t *writer;
1255
1256 if ((writer = calloc(1, sizeof(*writer))) == NULL) {
1257 (void) fprintf(stderr, "pgp_writer_set_fd: bad alloc\n");
1258 } else {
1259 writer->fd = fd;
1260 pgp_writer_set(output, fd_writer, NULL, writer_fd_destroyer, writer);
1261 }
1262 }
1263
1264 static unsigned
memory_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)1265 memory_writer(const uint8_t *src,
1266 unsigned len,
1267 pgp_error_t **errors,
1268 pgp_writer_t *writer)
1269 {
1270 pgp_memory_t *mem;
1271
1272 __PGP_USED(errors);
1273 mem = pgp_writer_get_arg(writer);
1274 pgp_memory_add(mem, src, len);
1275 return 1;
1276 }
1277
1278 /**
1279 * \ingroup Core_WritersFirst
1280 * \brief Write to memory
1281 *
1282 * Set a memory writer.
1283 *
1284 * \param output The output structure
1285 * \param mem The memory structure
1286 * \note It is the caller's responsiblity to call pgp_memory_free(mem)
1287 * \sa pgp_memory_free()
1288 */
1289
1290 void
pgp_writer_set_memory(pgp_output_t * output,pgp_memory_t * mem)1291 pgp_writer_set_memory(pgp_output_t *output, pgp_memory_t *mem)
1292 {
1293 pgp_writer_set(output, memory_writer, NULL, NULL, mem);
1294 }
1295
1296 /**************************************************************************/
1297
1298 typedef struct {
1299 pgp_hash_alg_t hash_alg;
1300 pgp_hash_t hash;
1301 uint8_t *hashed;
1302 } skey_checksum_t;
1303
1304 static unsigned
skey_checksum_writer(const uint8_t * src,const unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)1305 skey_checksum_writer(const uint8_t *src,
1306 const unsigned len,
1307 pgp_error_t **errors,
1308 pgp_writer_t *writer)
1309 {
1310 skey_checksum_t *sum;
1311 unsigned ret = 1;
1312
1313 sum = pgp_writer_get_arg(writer);
1314 /* add contents to hash */
1315 sum->hash.add(&sum->hash, src, len);
1316 /* write to next stacked writer */
1317 ret = stacked_write(writer, src, len, errors);
1318 /* tidy up and return */
1319 return ret;
1320 }
1321
1322 static unsigned
skey_checksum_finaliser(pgp_error_t ** errors,pgp_writer_t * writer)1323 skey_checksum_finaliser(pgp_error_t **errors, pgp_writer_t *writer)
1324 {
1325 skey_checksum_t *sum;
1326
1327 sum = pgp_writer_get_arg(writer);
1328 if (errors && *errors) {
1329 printf("errors in skey_checksum_finaliser\n");
1330 }
1331 (*sum->hash.finish)(&sum->hash, sum->hashed);
1332 return 1;
1333 }
1334
1335 static void
skey_checksum_destroyer(pgp_writer_t * writer)1336 skey_checksum_destroyer(pgp_writer_t *writer)
1337 {
1338 skey_checksum_t *sum;
1339
1340 sum = pgp_writer_get_arg(writer);
1341 free(sum);
1342 }
1343
1344 /**
1345 \ingroup Core_WritersNext
1346 \param output
1347 \param seckey
1348 */
1349 void
pgp_push_checksum_writer(pgp_output_t * output,pgp_seckey_t * seckey)1350 pgp_push_checksum_writer(pgp_output_t *output, pgp_seckey_t *seckey)
1351 {
1352 /* XXX: push a SHA-1 checksum writer (and change s2k to 254). */
1353 skey_checksum_t *sum;
1354 unsigned hashsize;
1355
1356 if ((sum = calloc(1, sizeof(*sum))) == NULL) {
1357 (void) fprintf(stderr,
1358 "pgp_push_checksum_writer: bad alloc\n");
1359 } else {
1360 /* configure the arg */
1361 /* Hardcoded SHA1 for just now */
1362 sum->hash_alg = PGP_HASH_SHA1;
1363 hashsize = pgp_hash_size(sum->hash_alg);
1364 if ((sum->hashed = seckey->checkhash) == NULL) {
1365 sum->hashed = seckey->checkhash = calloc(1, hashsize);
1366 }
1367 /* init the hash */
1368 pgp_hash_any(&sum->hash, sum->hash_alg);
1369 if (!sum->hash.init(&sum->hash)) {
1370 (void) fprintf(stderr,
1371 "pgp_push_checksum_writer: bad hash init\n");
1372 /* just continue and die */
1373 /* XXX - agc - no way to return failure */
1374 }
1375 pgp_writer_push(output, skey_checksum_writer,
1376 skey_checksum_finaliser, skey_checksum_destroyer, sum);
1377 }
1378 }
1379
1380 /**************************************************************************/
1381
1382 #define MAX_PARTIAL_DATA_LENGTH 1073741824
1383
1384 typedef struct {
1385 pgp_crypt_t *crypt;
1386 pgp_memory_t *mem_data;
1387 pgp_memory_t *litmem;
1388 pgp_output_t *litoutput;
1389 pgp_memory_t *se_ip_mem;
1390 pgp_output_t *se_ip_out;
1391 pgp_hash_t hash;
1392 } str_enc_se_ip_t;
1393
1394
1395 static unsigned
1396 str_enc_se_ip_writer(const uint8_t *src,
1397 unsigned len,
1398 pgp_error_t **errors,
1399 pgp_writer_t *writer);
1400
1401 static unsigned
1402 str_enc_se_ip_finaliser(pgp_error_t **errors,
1403 pgp_writer_t * writer);
1404
1405 static void str_enc_se_ip_destroyer(pgp_writer_t *writer);
1406
1407 /* */
1408
1409 /**
1410 \ingroup Core_WritersNext
1411 \param output
1412 \param pubkey
1413 */
1414 void
pgp_push_stream_enc_se_ip(pgp_output_t * output,const pgp_key_t * pubkey,const char * cipher)1415 pgp_push_stream_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *cipher)
1416 {
1417 pgp_pk_sesskey_t *encrypted_pk_sesskey;
1418 str_enc_se_ip_t *se_ip;
1419 const unsigned bufsz = 1024;
1420 pgp_crypt_t *encrypted;
1421 uint8_t *iv;
1422
1423 if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
1424 (void) fprintf(stderr,
1425 "pgp_push_stream_enc_se_ip: bad alloc\n");
1426 return;
1427 }
1428 encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher);
1429 pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
1430
1431 /* Setup the se_ip */
1432 if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
1433 free(se_ip);
1434 (void) fprintf(stderr,
1435 "pgp_push_stream_enc_se_ip: bad alloc\n");
1436 return;
1437 }
1438 pgp_crypt_any(encrypted, encrypted_pk_sesskey->symm_alg);
1439 if ((iv = calloc(1, encrypted->blocksize)) == NULL) {
1440 free(encrypted);
1441 free(se_ip);
1442 (void) fprintf(stderr,
1443 "pgp_push_stream_enc_se_ip: bad alloc\n");
1444 return;
1445 }
1446 encrypted->set_iv(encrypted, iv);
1447 encrypted->set_crypt_key(encrypted, &encrypted_pk_sesskey->key[0]);
1448 pgp_encrypt_init(encrypted);
1449
1450 se_ip->crypt = encrypted;
1451
1452 se_ip->mem_data = pgp_memory_new();
1453 pgp_memory_init(se_ip->mem_data, bufsz);
1454
1455 se_ip->litmem = NULL;
1456 se_ip->litoutput = NULL;
1457
1458 pgp_setup_memory_write(&se_ip->se_ip_out, &se_ip->se_ip_mem, bufsz);
1459
1460 /* And push writer on stack */
1461 pgp_writer_push(output,
1462 str_enc_se_ip_writer,
1463 str_enc_se_ip_finaliser,
1464 str_enc_se_ip_destroyer, se_ip);
1465 /* tidy up */
1466 free(encrypted_pk_sesskey);
1467 free(iv);
1468 }
1469
1470
1471 /* calculate the partial data length */
1472 static unsigned
partial_data_len(unsigned len)1473 partial_data_len(unsigned len)
1474 {
1475 unsigned mask;
1476 int i;
1477
1478 if (len == 0) {
1479 (void) fprintf(stderr, "partial_data_len: 0 len\n");
1480 return 0;
1481 }
1482 if (len > MAX_PARTIAL_DATA_LENGTH) {
1483 return MAX_PARTIAL_DATA_LENGTH;
1484 }
1485 mask = MAX_PARTIAL_DATA_LENGTH;
1486 for (i = 0; i <= 30; i++) {
1487 if (mask & len) {
1488 break;
1489 }
1490 mask >>= 1;
1491 }
1492 return mask;
1493 }
1494
1495 static unsigned
write_partial_len(pgp_output_t * output,unsigned len)1496 write_partial_len(pgp_output_t *output, unsigned len)
1497 {
1498 /* len must be a power of 2 from 0 to 30 */
1499 uint8_t c;
1500 int i;
1501
1502 for (i = 0; i <= 30; i++) {
1503 if ((len >> i) & 1) {
1504 break;
1505 }
1506 }
1507 c = 224 + i;
1508 return pgp_write(output, &c, 1);
1509 }
1510
1511 static unsigned
stream_write_litdata(pgp_output_t * output,const uint8_t * data,unsigned len)1512 stream_write_litdata(pgp_output_t *output,
1513 const uint8_t *data,
1514 unsigned len)
1515 {
1516 size_t pdlen;
1517
1518 while (len > 0) {
1519 pdlen = partial_data_len(len);
1520 write_partial_len(output, (unsigned)pdlen);
1521 pgp_write(output, data, (unsigned)pdlen);
1522 data += pdlen;
1523 len -= (unsigned)pdlen;
1524 }
1525 return 1;
1526 }
1527
1528 static unsigned
stream_write_litdata_first(pgp_output_t * output,const uint8_t * data,unsigned len,const pgp_litdata_enum type)1529 stream_write_litdata_first(pgp_output_t *output,
1530 const uint8_t *data,
1531 unsigned len,
1532 const pgp_litdata_enum type)
1533 {
1534 /* \todo add filename */
1535 /* \todo add date */
1536 /* \todo do we need to check text data for <cr><lf> line endings ? */
1537
1538 unsigned sz_towrite;
1539 size_t sz_pd;
1540
1541 sz_towrite = 1 + 1 + 4 + len;
1542 sz_pd = (size_t)partial_data_len(sz_towrite);
1543 if (sz_pd < 512) {
1544 (void) fprintf(stderr,
1545 "stream_write_litdata_first: bad sz_pd\n");
1546 return 0;
1547 }
1548 pgp_write_ptag(output, PGP_PTAG_CT_LITDATA);
1549 write_partial_len(output, (unsigned)sz_pd);
1550 pgp_write_scalar(output, (unsigned)type, 1);
1551 pgp_write_scalar(output, 0, 1);
1552 pgp_write_scalar(output, 0, 4);
1553 pgp_write(output, data, (unsigned)(sz_pd - 6));
1554
1555 data += (sz_pd - 6);
1556 sz_towrite -= (unsigned)sz_pd;
1557
1558 return stream_write_litdata(output, data, (unsigned)sz_towrite);
1559 }
1560
1561 static unsigned
stream_write_litdata_last(pgp_output_t * output,const uint8_t * data,unsigned len)1562 stream_write_litdata_last(pgp_output_t *output,
1563 const uint8_t *data,
1564 unsigned len)
1565 {
1566 pgp_write_length(output, len);
1567 return pgp_write(output, data, len);
1568 }
1569
1570 static unsigned
stream_write_se_ip(pgp_output_t * output,const uint8_t * data,unsigned len,str_enc_se_ip_t * se_ip)1571 stream_write_se_ip(pgp_output_t *output,
1572 const uint8_t *data,
1573 unsigned len,
1574 str_enc_se_ip_t *se_ip)
1575 {
1576 size_t pdlen;
1577
1578 while (len > 0) {
1579 pdlen = partial_data_len(len);
1580 write_partial_len(output, (unsigned)pdlen);
1581
1582 pgp_push_enc_crypt(output, se_ip->crypt);
1583 pgp_write(output, data, (unsigned)pdlen);
1584 pgp_writer_pop(output);
1585
1586 se_ip->hash.add(&se_ip->hash, data, (unsigned)pdlen);
1587
1588 data += pdlen;
1589 len -= (unsigned)pdlen;
1590 }
1591 return 1;
1592 }
1593
1594 static unsigned
stream_write_se_ip_first(pgp_output_t * output,const uint8_t * data,unsigned len,str_enc_se_ip_t * se_ip)1595 stream_write_se_ip_first(pgp_output_t *output,
1596 const uint8_t *data,
1597 unsigned len,
1598 str_enc_se_ip_t *se_ip)
1599 {
1600 uint8_t *preamble;
1601 size_t blocksize;
1602 size_t preamblesize;
1603 size_t sz_towrite;
1604 size_t sz_pd;
1605
1606 blocksize = se_ip->crypt->blocksize;
1607 preamblesize = blocksize + 2;
1608 sz_towrite = preamblesize + 1 + len;
1609 if ((preamble = calloc(1, preamblesize)) == NULL) {
1610 (void) fprintf(stderr,
1611 "stream_write_se_ip_first: bad alloc\n");
1612 return 0;
1613 }
1614 sz_pd = (size_t)partial_data_len((unsigned)sz_towrite);
1615 if (sz_pd < 512) {
1616 free(preamble);
1617 (void) fprintf(stderr,
1618 "stream_write_se_ip_first: bad sz_pd\n");
1619 return 0;
1620 }
1621 pgp_write_ptag(output, PGP_PTAG_CT_SE_IP_DATA);
1622 write_partial_len(output, (unsigned)sz_pd);
1623 pgp_write_scalar(output, PGP_SE_IP_DATA_VERSION, 1);
1624 pgp_push_enc_crypt(output, se_ip->crypt);
1625
1626 pgp_random(preamble, blocksize);
1627 preamble[blocksize] = preamble[blocksize - 2];
1628 preamble[blocksize + 1] = preamble[blocksize - 1];
1629 pgp_hash_any(&se_ip->hash, PGP_HASH_SHA1);
1630 if (!se_ip->hash.init(&se_ip->hash)) {
1631 free(preamble);
1632 (void) fprintf(stderr,
1633 "stream_write_se_ip_first: bad hash init\n");
1634 return 0;
1635 }
1636 pgp_write(output, preamble, (unsigned)preamblesize);
1637 se_ip->hash.add(&se_ip->hash, preamble, (unsigned)preamblesize);
1638 pgp_write(output, data, (unsigned)(sz_pd - preamblesize - 1));
1639 se_ip->hash.add(&se_ip->hash, data, (unsigned)(sz_pd - preamblesize - 1));
1640 data += (sz_pd - preamblesize - 1);
1641 sz_towrite -= sz_pd;
1642 pgp_writer_pop(output);
1643 stream_write_se_ip(output, data, (unsigned)sz_towrite, se_ip);
1644 free(preamble);
1645 return 1;
1646 }
1647
1648 static unsigned
stream_write_se_ip_last(pgp_output_t * output,const uint8_t * data,unsigned len,str_enc_se_ip_t * se_ip)1649 stream_write_se_ip_last(pgp_output_t *output,
1650 const uint8_t *data,
1651 unsigned len,
1652 str_enc_se_ip_t *se_ip)
1653 {
1654 pgp_output_t *mdcoutput;
1655 pgp_memory_t *mdcmem;
1656 const size_t mdcsize = 1 + 1 + PGP_SHA1_HASH_SIZE;
1657 uint8_t c;
1658 uint8_t hashed[PGP_SHA1_HASH_SIZE];
1659 size_t bufsize = len + mdcsize;
1660
1661 se_ip->hash.add(&se_ip->hash, data, len);
1662
1663 /* MDC packet tag */
1664 c = MDC_PKT_TAG;
1665 se_ip->hash.add(&se_ip->hash, &c, 1);
1666
1667 /* MDC packet len */
1668 c = PGP_SHA1_HASH_SIZE;
1669 se_ip->hash.add(&se_ip->hash, &c, 1);
1670
1671 /* finish */
1672 se_ip->hash.finish(&se_ip->hash, hashed);
1673
1674 pgp_setup_memory_write(&mdcoutput, &mdcmem, mdcsize);
1675 pgp_write_mdc(mdcoutput, hashed);
1676
1677 /* write length of last se_ip chunk */
1678 pgp_write_length(output, (unsigned)bufsize);
1679
1680 /* encode everting */
1681 pgp_push_enc_crypt(output, se_ip->crypt);
1682
1683 pgp_write(output, data, len);
1684 pgp_write(output, pgp_mem_data(mdcmem), (unsigned)pgp_mem_len(mdcmem));
1685
1686 pgp_writer_pop(output);
1687
1688 pgp_teardown_memory_write(mdcoutput, mdcmem);
1689
1690 return 1;
1691 }
1692
1693 static unsigned
str_enc_se_ip_writer(const uint8_t * src,unsigned len,pgp_error_t ** errors,pgp_writer_t * writer)1694 str_enc_se_ip_writer(const uint8_t *src,
1695 unsigned len,
1696 pgp_error_t **errors,
1697 pgp_writer_t *writer)
1698 {
1699 str_enc_se_ip_t *se_ip;
1700 unsigned ret;
1701 size_t datalength;
1702
1703 se_ip = pgp_writer_get_arg(writer);
1704 ret = 1;
1705 if (se_ip->litoutput == NULL) {
1706 /* first literal data chunk is not yet written */
1707
1708 pgp_memory_add(se_ip->mem_data, src, len);
1709 datalength = pgp_mem_len(se_ip->mem_data);
1710
1711 /* 4.2.2.4. Partial Body Lengths */
1712 /* The first partial length MUST be at least 512 octets long. */
1713 if (datalength < 512) {
1714 return 1; /* will wait for more data or
1715 * end of stream */
1716 }
1717 pgp_setup_memory_write(&se_ip->litoutput,
1718 &se_ip->litmem, datalength + 32);
1719 stream_write_litdata_first(se_ip->litoutput,
1720 pgp_mem_data(se_ip->mem_data),
1721 (unsigned)datalength,
1722 PGP_LDT_BINARY);
1723
1724 stream_write_se_ip_first(se_ip->se_ip_out,
1725 pgp_mem_data(se_ip->litmem),
1726 (unsigned)pgp_mem_len(se_ip->litmem), se_ip);
1727 } else {
1728 stream_write_litdata(se_ip->litoutput, src, len);
1729 stream_write_se_ip(se_ip->se_ip_out,
1730 pgp_mem_data(se_ip->litmem),
1731 (unsigned)pgp_mem_len(se_ip->litmem), se_ip);
1732 }
1733
1734 /* now write memory to next writer */
1735 ret = stacked_write(writer, pgp_mem_data(se_ip->se_ip_mem),
1736 (unsigned)pgp_mem_len(se_ip->se_ip_mem), errors);
1737
1738 pgp_memory_clear(se_ip->litmem);
1739 pgp_memory_clear(se_ip->se_ip_mem);
1740
1741 return ret;
1742 }
1743
1744 /* write last chunk of data */
1745 static unsigned
str_enc_se_ip_finaliser(pgp_error_t ** errors,pgp_writer_t * writer)1746 str_enc_se_ip_finaliser(pgp_error_t **errors, pgp_writer_t *writer)
1747 {
1748 str_enc_se_ip_t *se_ip;
1749
1750 se_ip = pgp_writer_get_arg(writer);
1751 if (se_ip->litoutput == NULL) {
1752 /* first literal data chunk was not written */
1753 /* so we know the total length of data, write a simple packet */
1754
1755 /* create literal data packet from buffered data */
1756 pgp_setup_memory_write(&se_ip->litoutput, &se_ip->litmem,
1757 pgp_mem_len(se_ip->mem_data) + 32);
1758
1759 pgp_write_litdata(se_ip->litoutput,
1760 pgp_mem_data(se_ip->mem_data),
1761 (const int)pgp_mem_len(se_ip->mem_data),
1762 PGP_LDT_BINARY);
1763
1764 /* create SE IP packet set from this literal data */
1765 pgp_write_se_ip_pktset(se_ip->se_ip_out,
1766 pgp_mem_data(se_ip->litmem),
1767 (unsigned)pgp_mem_len(se_ip->litmem),
1768 se_ip->crypt);
1769
1770 } else {
1771 /* finish writing */
1772 stream_write_litdata_last(se_ip->litoutput, NULL, 0);
1773 stream_write_se_ip_last(se_ip->se_ip_out,
1774 pgp_mem_data(se_ip->litmem),
1775 (unsigned)pgp_mem_len(se_ip->litmem), se_ip);
1776 }
1777
1778 /* now write memory to next writer */
1779 return stacked_write(writer, pgp_mem_data(se_ip->se_ip_mem),
1780 (unsigned)pgp_mem_len(se_ip->se_ip_mem), errors);
1781 }
1782
1783 static void
str_enc_se_ip_destroyer(pgp_writer_t * writer)1784 str_enc_se_ip_destroyer(pgp_writer_t *writer)
1785 {
1786 str_enc_se_ip_t *se_ip;
1787
1788 se_ip = pgp_writer_get_arg(writer);
1789 pgp_memory_free(se_ip->mem_data);
1790 pgp_teardown_memory_write(se_ip->litoutput, se_ip->litmem);
1791 pgp_teardown_memory_write(se_ip->se_ip_out, se_ip->se_ip_mem);
1792
1793 se_ip->crypt->decrypt_finish(se_ip->crypt);
1794
1795 free(se_ip->crypt);
1796 free(se_ip);
1797 }
1798