xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/create.c (revision 0294a66b694d2a57b43f64b66c7a4aee89316c4e)
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  */
52 #include "config.h"
53 
54 #ifdef HAVE_SYS_CDEFS_H
55 #include <sys/cdefs.h>
56 #endif
57 
58 #if defined(__NetBSD__)
59 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60 __RCSID("$NetBSD: create.c,v 1.39 2022/08/26 19:18:38 jhigh Exp $");
61 #endif
62 
63 #include <sys/types.h>
64 #include <sys/param.h>
65 #include <sys/stat.h>
66 
67 #ifdef HAVE_FCNTL_H
68 #include <fcntl.h>
69 #endif
70 
71 #include <string.h>
72 
73 #ifdef HAVE_UNISTD_H
74 #include <unistd.h>
75 #endif
76 
77 #ifdef HAVE_OPENSSL_CAST_H
78 #include <openssl/cast.h>
79 #endif
80 
81 #include "create.h"
82 #include "keyring.h"
83 #include "packet.h"
84 #include "signature.h"
85 #include "writer.h"
86 #include "readerwriter.h"
87 #include "memory.h"
88 #include "netpgpdefs.h"
89 #include "netpgpdigest.h"
90 
91 /**
92  * \ingroup Core_Create
93  * \param length
94  * \param type
95  * \param output
96  * \return 1 if OK, otherwise 0
97  */
98 
99 unsigned
pgp_write_ss_header(pgp_output_t * output,unsigned length,pgp_content_enum type)100 pgp_write_ss_header(pgp_output_t *output,
101 			unsigned length,
102 			pgp_content_enum type)
103 {
104 	return pgp_write_length(output, length) &&
105 		pgp_write_scalar(output, (unsigned)(type -
106 				(unsigned)PGP_PTAG_SIG_SUBPKT_BASE), 1);
107 }
108 
109 /*
110  * XXX: the general idea of _fast_ is that it doesn't copy stuff the safe
111  * (i.e. non _fast_) version will, and so will also need to be freed.
112  */
113 
114 /**
115  * \ingroup Core_Create
116  *
117  * pgp_fast_create_userid() sets id->userid to the given userid.
118  * This is fast because it is only copying a char*. However, if userid
119  * is changed or freed in the future, this could have injurious results.
120  * \param id
121  * \param userid
122  */
123 
124 void
pgp_fast_create_userid(uint8_t ** id,uint8_t * userid)125 pgp_fast_create_userid(uint8_t **id, uint8_t *userid)
126 {
127 	*id = userid;
128 }
129 
130 /**
131  * \ingroup Core_WritePackets
132  * \brief Writes a User Id packet
133  * \param id
134  * \param output
135  * \return 1 if OK, otherwise 0
136  */
137 unsigned
pgp_write_struct_userid(pgp_output_t * output,const uint8_t * id)138 pgp_write_struct_userid(pgp_output_t *output, const uint8_t *id)
139 {
140 	return pgp_write_ptag(output, PGP_PTAG_CT_USER_ID) &&
141 		pgp_write_length(output, (unsigned)strlen((const char *) id)) &&
142 		pgp_write(output, id, (unsigned)strlen((const char *) id));
143 }
144 
145 /**
146  * \ingroup Core_WritePackets
147  * \brief Write a User Id packet.
148  * \param userid
149  * \param output
150  *
151  * \return return value from pgp_write_struct_userid()
152  */
153 unsigned
pgp_write_userid(const uint8_t * userid,pgp_output_t * output)154 pgp_write_userid(const uint8_t *userid, pgp_output_t *output)
155 {
156 	return pgp_write_struct_userid(output, userid);
157 }
158 
159 /**
160 \ingroup Core_MPI
161 */
162 static unsigned
mpi_length(const BIGNUM * bn)163 mpi_length(const BIGNUM *bn)
164 {
165 	return (unsigned)(2 + (BN_num_bits(bn) + 7) / 8);
166 }
167 
168 static unsigned
pubkey_length(const pgp_pubkey_t * key)169 pubkey_length(const pgp_pubkey_t *key)
170 {
171 	switch (key->alg) {
172 	case PGP_PKA_DSA:
173 		return mpi_length(key->key.dsa.p) + mpi_length(key->key.dsa.q) +
174 			mpi_length(key->key.dsa.g) + mpi_length(key->key.dsa.y);
175 
176 	case PGP_PKA_RSA:
177 		return mpi_length(key->key.rsa.n) + mpi_length(key->key.rsa.e);
178 
179 	default:
180 		(void) fprintf(stderr,
181 			"pubkey_length: unknown key algorithm\n");
182 	}
183 	return 0;
184 }
185 
186 static unsigned
seckey_length(const pgp_seckey_t * key)187 seckey_length(const pgp_seckey_t *key)
188 {
189 	int             len;
190 
191 	len = 0;
192 	switch (key->pubkey.alg) {
193 	case PGP_PKA_DSA:
194 		return (unsigned)(mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey));
195 	case PGP_PKA_RSA:
196 		len = mpi_length(key->key.rsa.d) + mpi_length(key->key.rsa.p) +
197 			mpi_length(key->key.rsa.q) + mpi_length(key->key.rsa.u);
198 
199 		return (unsigned)(len + pubkey_length(&key->pubkey));
200 	default:
201 		(void) fprintf(stderr,
202 			"seckey_length: unknown key algorithm\n");
203 	}
204 	return 0;
205 }
206 
207 /**
208  * \ingroup Core_Create
209  * \param key
210  * \param t
211  * \param n
212  * \param e
213 */
214 void
pgp_fast_create_rsa_pubkey(pgp_pubkey_t * key,time_t t,BIGNUM * n,BIGNUM * e)215 pgp_fast_create_rsa_pubkey(pgp_pubkey_t *key, time_t t,
216 			       BIGNUM *n, BIGNUM *e)
217 {
218 	key->version = PGP_V4;
219 	key->birthtime = t;
220 	key->alg = PGP_PKA_RSA;
221 	key->key.rsa.n = n;
222 	key->key.rsa.e = e;
223 }
224 
225 /*
226  * Note that we support v3 keys here because they're needed for for
227  * verification - the writer doesn't allow them, though
228  */
229 static unsigned
write_pubkey_body(const pgp_pubkey_t * key,pgp_output_t * output)230 write_pubkey_body(const pgp_pubkey_t *key, pgp_output_t *output)
231 {
232 	if (!(pgp_write_scalar(output, (unsigned)key->version, 1) &&
233 	      pgp_write_scalar(output, (unsigned)key->birthtime, 4))) {
234 		return 0;
235 	}
236 
237 	if (key->version != 4 &&
238 	    !pgp_write_scalar(output, key->days_valid, 2)) {
239 		return 0;
240 	}
241 
242 	if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) {
243 		return 0;
244 	}
245 
246 	switch (key->alg) {
247 	case PGP_PKA_DSA:
248 		return pgp_write_mpi(output, key->key.dsa.p) &&
249 			pgp_write_mpi(output, key->key.dsa.q) &&
250 			pgp_write_mpi(output, key->key.dsa.g) &&
251 			pgp_write_mpi(output, key->key.dsa.y);
252 
253 	case PGP_PKA_ECDSA:
254 		return pgp_write(output, &key->key.ecdsa.len, 1) &&
255 			pgp_write(output, key->key.ecdsa.oid, key->key.ecdsa.len) &&
256 			pgp_write_mpi(output, key->key.ecdsa.p);
257 
258 	case PGP_PKA_RSA:
259 	case PGP_PKA_RSA_ENCRYPT_ONLY:
260 	case PGP_PKA_RSA_SIGN_ONLY:
261 		return pgp_write_mpi(output, key->key.rsa.n) &&
262 			pgp_write_mpi(output, key->key.rsa.e);
263 
264 	case PGP_PKA_ELGAMAL:
265 		return pgp_write_mpi(output, key->key.elgamal.p) &&
266 			pgp_write_mpi(output, key->key.elgamal.g) &&
267 			pgp_write_mpi(output, key->key.elgamal.y);
268 
269 	default:
270 		(void) fprintf(stderr,
271 			"write_pubkey_body: bad algorithm\n");
272 		break;
273 	}
274 	return 0;
275 }
276 
277 /*
278  * Note that we support v3 keys here because they're needed for
279  * verification.
280  */
281 static unsigned
write_seckey_body(const pgp_seckey_t * key,const uint8_t * passphrase,const size_t pplen,pgp_output_t * output)282 write_seckey_body(const pgp_seckey_t *key,
283 		      const uint8_t *passphrase,
284 		      const size_t pplen,
285 		      pgp_output_t *output)
286 {
287 	/* RFC4880 Section 5.5.3 Secret-Key Packet Formats */
288 
289 	pgp_crypt_t   crypted;
290 	pgp_hash_t    hash;
291 	unsigned	done = 0;
292 	unsigned	i = 0;
293 	uint8_t		*hashed;
294 	uint8_t		sesskey[CAST_KEY_LENGTH];
295 
296 	if (!write_pubkey_body(&key->pubkey, output)) {
297 		return 0;
298 	}
299 	if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) {
300 		(void) fprintf(stderr, "write_seckey_body: s2k usage\n");
301 		return 0;
302 	}
303 	if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) {
304 		return 0;
305 	}
306 
307 	if (key->alg != PGP_SA_CAST5) {
308 		(void) fprintf(stderr, "write_seckey_body: algorithm\n");
309 		return 0;
310 	}
311 	if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) {
312 		return 0;
313 	}
314 
315 	if (key->s2k_specifier != PGP_S2KS_SIMPLE &&
316 	    key->s2k_specifier != PGP_S2KS_SALTED) {
317 		/* = 1 \todo could also be iterated-and-salted */
318 		(void) fprintf(stderr, "write_seckey_body: s2k spec\n");
319 		return 0;
320 	}
321 	if (!pgp_write_scalar(output, (unsigned)key->s2k_specifier, 1)) {
322 		return 0;
323 	}
324 	if (!pgp_write_scalar(output, (unsigned)key->hash_alg, 1)) {
325 		return 0;
326 	}
327 
328 	switch (key->s2k_specifier) {
329 	case PGP_S2KS_SIMPLE:
330 		/* nothing more to do */
331 		break;
332 
333 	case PGP_S2KS_SALTED:
334 		/* 8-octet salt value */
335 		pgp_random(__UNCONST(&key->salt[0]), PGP_SALT_SIZE);
336 		if (!pgp_write(output, key->salt, PGP_SALT_SIZE)) {
337 			return 0;
338 		}
339 		break;
340 
341 		/*
342 		 * \todo case PGP_S2KS_ITERATED_AND_SALTED: // 8-octet salt
343 		 * value // 1-octet count break;
344 		 */
345 
346 	default:
347 		(void) fprintf(stderr,
348 			"invalid/unsupported s2k specifier %d\n",
349 			key->s2k_specifier);
350 		return 0;
351 	}
352 
353 	if (!pgp_write(output, &key->iv[0], pgp_block_size(key->alg))) {
354 		return 0;
355 	}
356 
357 	/*
358 	 * create the session key for encrypting the algorithm-specific
359 	 * fields
360 	 */
361 
362 	switch (key->s2k_specifier) {
363 	case PGP_S2KS_SIMPLE:
364 	case PGP_S2KS_SALTED:
365 		/* RFC4880: section 3.7.1.1 and 3.7.1.2 */
366 
367 		for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) {
368 			unsigned 	hashsize;
369 			unsigned 	j;
370 			unsigned	needed;
371 			unsigned	size;
372 			uint8_t		zero = 0;
373 
374 			/* Hard-coded SHA1 for session key */
375 			pgp_hash_any(&hash, PGP_HASH_SHA1);
376 			hashsize = pgp_hash_size(key->hash_alg);
377 			needed = CAST_KEY_LENGTH - done;
378 			size = MIN(needed, hashsize);
379 			if ((hashed = calloc(1, hashsize)) == NULL) {
380 				(void) fprintf(stderr, "write_seckey_body: bad alloc\n");
381 				return 0;
382 			}
383 			if (!hash.init(&hash)) {
384 				(void) fprintf(stderr, "write_seckey_body: bad alloc\n");
385 				return 0;
386 			}
387 
388 			/* preload if iterating  */
389 			for (j = 0; j < i; j++) {
390 				/*
391 				 * Coverity shows a DEADCODE error on this
392 				 * line. This is expected since the hardcoded
393 				 * use of SHA1 and CAST5 means that it will
394 				 * not used. This will change however when
395 				 * other algorithms are supported.
396 				 */
397 				hash.add(&hash, &zero, 1);
398 			}
399 
400 			if (key->s2k_specifier == PGP_S2KS_SALTED) {
401 				hash.add(&hash, key->salt, PGP_SALT_SIZE);
402 			}
403 			hash.add(&hash, passphrase, (unsigned)pplen);
404 			hash.finish(&hash, hashed);
405 
406 			/*
407 			 * if more in hash than is needed by session key, use
408 			 * the leftmost octets
409 			 */
410 			(void) memcpy(&sesskey[i * hashsize],
411 					hashed, (unsigned)size);
412 			done += (unsigned)size;
413 			if (done > CAST_KEY_LENGTH) {
414 				(void) fprintf(stderr,
415 					"write_seckey_body: short add\n");
416 				return 0;
417 			}
418 		}
419 
420 		break;
421 
422 		/*
423 		 * \todo case PGP_S2KS_ITERATED_AND_SALTED: * 8-octet salt
424 		 * value * 1-octet count break;
425 		 */
426 
427 	default:
428 		(void) fprintf(stderr,
429 			"invalid/unsupported s2k specifier %d\n",
430 			key->s2k_specifier);
431 		return 0;
432 	}
433 
434 	/* use this session key to encrypt */
435 
436 	pgp_crypt_any(&crypted, key->alg);
437 	crypted.set_iv(&crypted, key->iv);
438 	crypted.set_crypt_key(&crypted, sesskey);
439 	pgp_encrypt_init(&crypted);
440 
441 	if (pgp_get_debug_level(__FILE__)) {
442 		hexdump(stderr, "writing: iv=", key->iv, pgp_block_size(key->alg));
443 		hexdump(stderr, "key= ", sesskey, CAST_KEY_LENGTH);
444 		(void) fprintf(stderr, "\nturning encryption on...\n");
445 	}
446 	pgp_push_enc_crypt(output, &crypted);
447 
448 	switch (key->pubkey.alg) {
449 	case PGP_PKA_RSA:
450 	case PGP_PKA_RSA_ENCRYPT_ONLY:
451 	case PGP_PKA_RSA_SIGN_ONLY:
452 		if (!pgp_write_mpi(output, key->key.rsa.d) ||
453 		    !pgp_write_mpi(output, key->key.rsa.p) ||
454 		    !pgp_write_mpi(output, key->key.rsa.q) ||
455 		    !pgp_write_mpi(output, key->key.rsa.u)) {
456 			if (pgp_get_debug_level(__FILE__)) {
457 				(void) fprintf(stderr,
458 					"4 x mpi not written - problem\n");
459 			}
460 			return 0;
461 		}
462 		break;
463 	case PGP_PKA_DSA:
464 		return pgp_write_mpi(output, key->key.dsa.x);
465 	case PGP_PKA_ELGAMAL:
466 		return pgp_write_mpi(output, key->key.elgamal.x);
467 	default:
468 		return 0;
469 	}
470 
471 	if (!pgp_write(output, key->checkhash, PGP_CHECKHASH_SIZE)) {
472 		return 0;
473 	}
474 
475 	pgp_writer_pop(output);
476 
477 	return 1;
478 }
479 
480 /**
481  * \ingroup Core_WritePackets
482  * \brief Writes a Public Key packet
483  * \param key
484  * \param output
485  * \return 1 if OK, otherwise 0
486  */
487 static unsigned
write_struct_pubkey(pgp_output_t * output,const pgp_pubkey_t * key)488 write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key)
489 {
490 	return pgp_write_ptag(output, PGP_PTAG_CT_PUBLIC_KEY) &&
491 		pgp_write_length(output, 1 + 4 + 1 + pubkey_length(key)) &&
492 		write_pubkey_body(key, output);
493 }
494 
495 
496 /**
497    \ingroup HighLevel_KeyWrite
498 
499    \brief Writes a transferable PGP public key to the given output stream.
500 
501    \param keydata Key to be written
502    \param armoured Flag is set for armoured output
503    \param output Output stream
504 
505 */
506 
507 unsigned
pgp_write_xfer_pubkey(pgp_output_t * output,const pgp_key_t * key,const unsigned armoured)508 pgp_write_xfer_pubkey(pgp_output_t *output,
509 			const pgp_key_t *key,
510 			const unsigned armoured)
511 {
512 	unsigned    i, j;
513 
514 	if (armoured) {
515 		pgp_writer_push_armoured(output, PGP_PGP_PUBLIC_KEY_BLOCK);
516 	}
517 	/* public key */
518 	if (!write_struct_pubkey(output, &key->key.pubkey)) {
519 		return 0;
520 	}
521 
522 	/* TODO: revocation signatures go here */
523 
524 	/* user ids and corresponding signatures */
525 	for (i = 0; i < key->uidc; i++) {
526 		if (!pgp_write_struct_userid(output, key->uids[i])) {
527 			return 0;
528 		}
529 		for (j = 0; j < key->packetc; j++) {
530 			if (!pgp_write(output, key->packets[j].raw, (unsigned)key->packets[j].length)) {
531 				return 0;
532 			}
533 		}
534 	}
535 
536 	/* TODO: user attributes and corresponding signatures */
537 
538 	/*
539 	 * subkey packets and corresponding signatures and optional
540 	 * revocation
541 	 */
542 
543 	if (armoured) {
544 		pgp_writer_info_finalise(&output->errors, &output->writer);
545 		pgp_writer_pop(output);
546 	}
547 	return 1;
548 }
549 
550 /**
551    \ingroup HighLevel_KeyWrite
552 
553    \brief Writes a transferable PGP secret key to the given output stream.
554 
555    \param keydata Key to be written
556    \param passphrase
557    \param pplen
558    \param armoured Flag is set for armoured output
559    \param output Output stream
560 
561 */
562 
563 unsigned
pgp_write_xfer_seckey(pgp_output_t * output,const pgp_key_t * key,const uint8_t * passphrase,const size_t pplen,unsigned armoured)564 pgp_write_xfer_seckey(pgp_output_t *output,
565 				const pgp_key_t *key,
566 				const uint8_t *passphrase,
567 				const size_t pplen,
568 				unsigned armoured)
569 {
570 	unsigned	i, j;
571 
572 	if (armoured) {
573 		pgp_writer_push_armoured(output, PGP_PGP_PRIVATE_KEY_BLOCK);
574 	}
575 	/* public key */
576 	if (!pgp_write_struct_seckey(&key->key.seckey, passphrase,
577 			pplen, output)) {
578 		return 0;
579 	}
580 
581 	/* TODO: revocation signatures go here */
582 
583 	/* user ids and corresponding signatures */
584 	for (i = 0; i < key->uidc; i++) {
585 		if (!pgp_write_struct_userid(output, key->uids[i])) {
586 			return 0;
587 		}
588 		for (j = 0; j < key->packetc; j++) {
589 			if (!pgp_write(output, key->packets[j].raw, (unsigned)key->packets[j].length)) {
590 				return 0;
591 			}
592 		}
593 	}
594 
595 	/* TODO: user attributes and corresponding signatures */
596 
597 	/*
598 	 * subkey packets and corresponding signatures and optional
599 	 * revocation
600 	 */
601 
602 	if (armoured) {
603 		pgp_writer_info_finalise(&output->errors, &output->writer);
604 		pgp_writer_pop(output);
605 	}
606 	return 1;
607 }
608 
609 /**
610  * \ingroup Core_WritePackets
611  * \brief Writes one RSA public key packet.
612  * \param t Creation time
613  * \param n RSA public modulus
614  * \param e RSA public encryption exponent
615  * \param output Writer settings
616  *
617  * \return 1 if OK, otherwise 0
618  */
619 
620 unsigned
pgp_write_rsa_pubkey(time_t t,const BIGNUM * n,const BIGNUM * e,pgp_output_t * output)621 pgp_write_rsa_pubkey(time_t t, const BIGNUM *n,
622 			 const BIGNUM *e,
623 			 pgp_output_t *output)
624 {
625 	pgp_pubkey_t key;
626 
627 	pgp_fast_create_rsa_pubkey(&key, t, __UNCONST(n), __UNCONST(e));
628 	return write_struct_pubkey(output, &key);
629 }
630 
631 /**
632  * \ingroup Core_Create
633  * \param out
634  * \param key
635  * \param make_packet
636  */
637 
638 void
pgp_build_pubkey(pgp_memory_t * out,const pgp_pubkey_t * key,unsigned make_packet)639 pgp_build_pubkey(pgp_memory_t *out, const pgp_pubkey_t *key,
640 		     unsigned make_packet)
641 {
642 	pgp_output_t *output;
643 
644 	output = pgp_output_new();
645 	pgp_memory_init(out, 128);
646 	pgp_writer_set_memory(output, out);
647 	write_pubkey_body(key, output);
648 	if (make_packet) {
649 		pgp_memory_make_packet(out, PGP_PTAG_CT_PUBLIC_KEY);
650 	}
651 	pgp_output_delete(output);
652 }
653 
654 /**
655  * \ingroup Core_Create
656  *
657  * Create an RSA secret key structure. If a parameter is marked as
658  * [OPTIONAL], then it can be omitted and will be calculated from
659  * other params - or, in the case of e, will default to 0x10001.
660  *
661  * Parameters are _not_ copied, so will be freed if the structure is
662  * freed.
663  *
664  * \param key The key structure to be initialised.
665  * \param t
666  * \param d The RSA parameter d (=e^-1 mod (p-1)(q-1)) [OPTIONAL]
667  * \param p The RSA parameter p
668  * \param q The RSA parameter q (q > p)
669  * \param u The RSA parameter u (=p^-1 mod q) [OPTIONAL]
670  * \param n The RSA public parameter n (=p*q) [OPTIONAL]
671  * \param e The RSA public parameter e */
672 
673 void
pgp_fast_create_rsa_seckey(pgp_seckey_t * key,time_t t,BIGNUM * d,BIGNUM * p,BIGNUM * q,BIGNUM * u,BIGNUM * n,BIGNUM * e)674 pgp_fast_create_rsa_seckey(pgp_seckey_t *key, time_t t,
675 			     BIGNUM *d, BIGNUM *p, BIGNUM *q, BIGNUM *u,
676 			       BIGNUM *n, BIGNUM *e)
677 {
678 	pgp_fast_create_rsa_pubkey(&key->pubkey, t, n, e);
679 
680 	/* XXX: calculate optionals */
681 	key->key.rsa.d = d;
682 	key->key.rsa.p = p;
683 	key->key.rsa.q = q;
684 	key->key.rsa.u = u;
685 
686 	key->s2k_usage = PGP_S2KU_NONE;
687 
688 	/* XXX: sanity check and add errors... */
689 }
690 
691 /**
692  * \ingroup Core_WritePackets
693  * \brief Writes a Secret Key packet.
694  * \param key The secret key
695  * \param passphrase The passphrase
696  * \param pplen Length of passphrase
697  * \param output
698  * \return 1 if OK; else 0
699  */
700 unsigned
pgp_write_struct_seckey(const pgp_seckey_t * key,const uint8_t * passphrase,const size_t pplen,pgp_output_t * output)701 pgp_write_struct_seckey(const pgp_seckey_t *key,
702 			    const uint8_t *passphrase,
703 			    const size_t pplen,
704 			    pgp_output_t *output)
705 {
706 	int             length = 0;
707 
708 	if (key->pubkey.version != 4) {
709 		(void) fprintf(stderr,
710 			"pgp_write_struct_seckey: public key version\n");
711 		return 0;
712 	}
713 
714 	/* Ref: RFC4880 Section 5.5.3 */
715 
716 	/* pubkey, excluding MPIs */
717 	length += 1 + 4 + 1 + 1;
718 
719 	/* s2k usage */
720 	length += 1;
721 
722 	switch (key->s2k_usage) {
723 	case PGP_S2KU_NONE:
724 		/* nothing to add */
725 		break;
726 
727 	case PGP_S2KU_ENCRYPTED_AND_HASHED:	/* 254 */
728 	case PGP_S2KU_ENCRYPTED:	/* 255 */
729 
730 		/* Ref: RFC4880 Section 3.7 */
731 		length += 1;	/* s2k_specifier */
732 
733 		switch (key->s2k_specifier) {
734 		case PGP_S2KS_SIMPLE:
735 			length += 1;	/* hash algorithm */
736 			break;
737 
738 		case PGP_S2KS_SALTED:
739 			length += 1 + 8;	/* hash algorithm + salt */
740 			break;
741 
742 		case PGP_S2KS_ITERATED_AND_SALTED:
743 			length += 1 + 8 + 1;	/* hash algorithm, salt +
744 						 * count */
745 			break;
746 
747 		default:
748 			(void) fprintf(stderr,
749 				"pgp_write_struct_seckey: s2k spec\n");
750 			return 0;
751 		}
752 		break;
753 
754 	default:
755 		(void) fprintf(stderr,
756 			"pgp_write_struct_seckey: s2k usage\n");
757 		return 0;
758 	}
759 
760 	/* IV */
761 	if (key->s2k_usage) {
762 		length += pgp_block_size(key->alg);
763 	}
764 	/* checksum or hash */
765 	switch (key->s2k_usage) {
766 	case PGP_S2KU_NONE:
767 	case PGP_S2KU_ENCRYPTED:
768 		length += 2;
769 		break;
770 
771 	case PGP_S2KU_ENCRYPTED_AND_HASHED:
772 		length += PGP_CHECKHASH_SIZE;
773 		break;
774 
775 	default:
776 		(void) fprintf(stderr,
777 			"pgp_write_struct_seckey: s2k cksum usage\n");
778 		return 0;
779 	}
780 
781 	/* secret key and public key MPIs */
782 	length += (unsigned)seckey_length(key);
783 
784 	return pgp_write_ptag(output, PGP_PTAG_CT_SECRET_KEY) &&
785 		/* pgp_write_length(output,1+4+1+1+seckey_length(key)+2) && */
786 		pgp_write_length(output, (unsigned)length) &&
787 		write_seckey_body(key, passphrase, pplen, output);
788 }
789 
790 /**
791  * \ingroup Core_Create
792  *
793  * \brief Create a new pgp_output_t structure.
794  *
795  * \return the new structure.
796  * \note It is the responsiblity of the caller to call pgp_output_delete().
797  * \sa pgp_output_delete()
798  */
799 pgp_output_t *
pgp_output_new(void)800 pgp_output_new(void)
801 {
802 	return calloc(1, sizeof(pgp_output_t));
803 }
804 
805 /**
806  * \ingroup Core_Create
807  * \brief Delete an pgp_output_t strucut and associated resources.
808  *
809  * Delete an pgp_output_t structure. If a writer is active, then
810  * that is also deleted.
811  *
812  * \param info the structure to be deleted.
813  */
814 void
pgp_output_delete(pgp_output_t * output)815 pgp_output_delete(pgp_output_t *output)
816 {
817 	pgp_writer_info_delete(&output->writer);
818 	free(output);
819 }
820 
821 /**
822  \ingroup Core_Create
823  \brief Calculate the checksum for a session key
824  \param sesskey Session Key to use
825  \param cs Checksum to be written
826  \return 1 if OK; else 0
827 */
828 unsigned
pgp_calc_sesskey_checksum(pgp_pk_sesskey_t * sesskey,uint8_t cs[2])829 pgp_calc_sesskey_checksum(pgp_pk_sesskey_t *sesskey, uint8_t cs[2])
830 {
831 	uint32_t   checksum = 0;
832 	unsigned    i;
833 
834 	if (!pgp_is_sa_supported(sesskey->symm_alg)) {
835 		return 0;
836 	}
837 
838 	for (i = 0; i < pgp_key_size(sesskey->symm_alg); i++) {
839 		checksum += sesskey->key[i];
840 	}
841 	checksum = checksum % 65536;
842 
843 	cs[0] = (uint8_t)((checksum >> 8) & 0xff);
844 	cs[1] = (uint8_t)(checksum & 0xff);
845 
846 	if (pgp_get_debug_level(__FILE__)) {
847 		hexdump(stderr, "nm buf checksum:", cs, 2);
848 	}
849 	return 1;
850 }
851 
852 static unsigned
create_unencoded_m_buf(pgp_pk_sesskey_t * sesskey,pgp_crypt_t * cipherinfo,uint8_t * m_buf)853 create_unencoded_m_buf(pgp_pk_sesskey_t *sesskey, pgp_crypt_t *cipherinfo, uint8_t *m_buf)
854 {
855 	unsigned	i;
856 
857 	/* m_buf is the buffer which will be encoded in PKCS#1 block
858 	* encoding to form the "m" value used in the Public Key
859 	* Encrypted Session Key Packet as defined in RFC Section 5.1
860 	* "Public-Key Encrypted Session Key Packet"
861 	 */
862 	m_buf[0] = sesskey->symm_alg;
863 	for (i = 0; i < cipherinfo->keysize ; i++) {
864 		/* XXX - Flexelint - Warning 679: Suspicious Truncation in arithmetic expression combining with pointer */
865 		m_buf[1 + i] = sesskey->key[i];
866 	}
867 
868 	return pgp_calc_sesskey_checksum(sesskey,
869 				m_buf + 1 + cipherinfo->keysize);
870 }
871 
872 /**
873 \ingroup Core_Create
874 \brief implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC
875 \param M
876 \param mLen
877 \param pubkey
878 \param EM
879 \return 1 if OK; else 0
880 */
881 unsigned
encode_m_buf(const uint8_t * M,size_t mLen,const pgp_pubkey_t * pubkey,uint8_t * EM)882 encode_m_buf(const uint8_t *M, size_t mLen, const pgp_pubkey_t * pubkey,
883 	     uint8_t *EM)
884 {
885 	unsigned    k;
886 	unsigned        i;
887 
888 	/* implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC */
889 	switch (pubkey->alg) {
890 	case PGP_PKA_RSA:
891 		k = (unsigned)BN_num_bytes(pubkey->key.rsa.n);
892 		if (mLen > k - 11) {
893 			(void) fprintf(stderr, "encode_m_buf: message too long\n");
894 			return 0;
895 		}
896 		break;
897 	case PGP_PKA_DSA:
898 	case PGP_PKA_ELGAMAL:
899 		k = (unsigned)BN_num_bytes(pubkey->key.elgamal.p);
900 		if (mLen > k - 11) {
901 			(void) fprintf(stderr, "encode_m_buf: message too long\n");
902 			return 0;
903 		}
904 		break;
905 	default:
906 		(void) fprintf(stderr, "encode_m_buf: pubkey algorithm\n");
907 		return 0;
908 	}
909 	/* these two bytes defined by RFC */
910 	EM[0] = 0x00;
911 	EM[1] = 0x02;
912 	/* add non-zero random bytes of length k - mLen -3 */
913 	for (i = 2; i < (k - mLen) - 1; ++i) {
914 		do {
915 			pgp_random(EM + i, 1);
916 		} while (EM[i] == 0);
917 	}
918 	if (i < 8 + 2) {
919 		(void) fprintf(stderr, "encode_m_buf: bad i len\n");
920 		return 0;
921 	}
922 	EM[i++] = 0;
923 	(void) memcpy(EM + i, M, mLen);
924 	if (pgp_get_debug_level(__FILE__)) {
925 		hexdump(stderr, "Encoded Message:", EM, mLen);
926 	}
927 	return 1;
928 }
929 
930 /**
931  \ingroup Core_Create
932 \brief Creates an pgp_pk_sesskey_t struct from keydata
933 \param key Keydata to use
934 \return pgp_pk_sesskey_t struct
935 \note It is the caller's responsiblity to free the returned pointer
936 \note Currently hard-coded to use CAST5
937 \note Currently hard-coded to use RSA
938 */
939 pgp_pk_sesskey_t *
pgp_create_pk_sesskey(const pgp_key_t * key,const char * ciphername)940 pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
941 {
942 	/*
943          * Creates a random session key and encrypts it for the given key
944          *
945          * Encryption used is PK,
946          * can be any, we're hardcoding RSA for now
947          */
948 
949 	const pgp_pubkey_t	*pubkey;
950 	pgp_pk_sesskey_t	*sesskey;
951 	pgp_symm_alg_t	 cipher;
952 	const uint8_t		*id;
953 	pgp_crypt_t		 cipherinfo;
954 	uint8_t			*unencoded_m_buf;
955 	uint8_t			*encoded_m_buf;
956 	size_t			 sz_encoded_m_buf;
957 
958 	if (memcmp(key->encid, "\0\0\0\0\0\0\0\0", 8) == 0) {
959 		pubkey = pgp_get_pubkey(key);
960 		id = key->sigid;
961 	} else {
962 		pubkey = &key->enckey;
963 		id = key->encid;
964 	}
965 	/* allocate unencoded_m_buf here */
966 	(void) memset(&cipherinfo, 0x0, sizeof(cipherinfo));
967 	pgp_crypt_any(&cipherinfo,
968 		cipher = pgp_str_to_cipher((ciphername) ? ciphername : "cast5"));
969 	unencoded_m_buf = calloc(1, cipherinfo.keysize + 1 + 2);
970 	if (unencoded_m_buf == NULL) {
971 		(void) fprintf(stderr,
972 			"pgp_create_pk_sesskey: can't allocate\n");
973 		return NULL;
974 	}
975 	switch(pubkey->alg) {
976 	case PGP_PKA_RSA:
977 		sz_encoded_m_buf = BN_num_bytes(pubkey->key.rsa.n);
978 		break;
979 	case PGP_PKA_DSA:
980 	case PGP_PKA_ELGAMAL:
981 		sz_encoded_m_buf = BN_num_bytes(pubkey->key.elgamal.p);
982 		break;
983 	default:
984 		sz_encoded_m_buf = 0;
985 		break;
986 	}
987 	if ((encoded_m_buf = calloc(1, sz_encoded_m_buf)) == NULL) {
988 		(void) fprintf(stderr,
989 			"pgp_create_pk_sesskey: can't allocate\n");
990 		free(unencoded_m_buf);
991 		return NULL;
992 	}
993 	if ((sesskey = calloc(1, sizeof(*sesskey))) == NULL) {
994 		(void) fprintf(stderr,
995 			"pgp_create_pk_sesskey: can't allocate\n");
996 		free(unencoded_m_buf);
997 		free(encoded_m_buf);
998 		return NULL;
999 	}
1000 	if (key->type != PGP_PTAG_CT_PUBLIC_KEY) {
1001 		(void) fprintf(stderr,
1002 			"pgp_create_pk_sesskey: bad type\n");
1003 		free(unencoded_m_buf);
1004 		free(encoded_m_buf);
1005 		free(sesskey);
1006 		return NULL;
1007 	}
1008 	sesskey->version = PGP_PKSK_V3;
1009 	(void) memcpy(sesskey->key_id, id, sizeof(sesskey->key_id));
1010 
1011 	if (pgp_get_debug_level(__FILE__)) {
1012 		hexdump(stderr, "Encrypting for keyid", id, sizeof(sesskey->key_id));
1013 	}
1014 	switch (pubkey->alg) {
1015 	case PGP_PKA_RSA:
1016 	case PGP_PKA_DSA:
1017 	case PGP_PKA_ELGAMAL:
1018 		break;
1019 	default:
1020 		(void) fprintf(stderr,
1021 			"pgp_create_pk_sesskey: bad pubkey algorithm\n");
1022 		free(unencoded_m_buf);
1023 		free(encoded_m_buf);
1024 		free(sesskey);
1025 		return NULL;
1026 	}
1027 	sesskey->alg = pubkey->alg;
1028 
1029 	sesskey->symm_alg = cipher;
1030 	pgp_random(sesskey->key, cipherinfo.keysize);
1031 
1032 	if (pgp_get_debug_level(__FILE__)) {
1033 		hexdump(stderr, "sesskey created", sesskey->key,
1034 			cipherinfo.keysize + 1 + 2);
1035 	}
1036 	if (create_unencoded_m_buf(sesskey, &cipherinfo, &unencoded_m_buf[0]) == 0) {
1037 		free(unencoded_m_buf);
1038 		free(encoded_m_buf);
1039 		free(sesskey);
1040 		return NULL;
1041 	}
1042 	if (pgp_get_debug_level(__FILE__)) {
1043 		hexdump(stderr, "uuencoded m buf", unencoded_m_buf, cipherinfo.keysize + 1 + 2);
1044 	}
1045 	encode_m_buf(unencoded_m_buf, cipherinfo.keysize + 1 + 2, pubkey, encoded_m_buf);
1046 
1047 	/* and encrypt it */
1048 	switch (key->key.pubkey.alg) {
1049 	case PGP_PKA_RSA:
1050 		if (!pgp_rsa_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pubkey,
1051 				&sesskey->params)) {
1052 			free(unencoded_m_buf);
1053 			free(encoded_m_buf);
1054 			free(sesskey);
1055 			return NULL;
1056 		}
1057 		break;
1058 	case PGP_PKA_DSA:
1059 	case PGP_PKA_ELGAMAL:
1060 		if (!pgp_elgamal_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pubkey,
1061 				&sesskey->params)) {
1062 			free(unencoded_m_buf);
1063 			free(encoded_m_buf);
1064 			free(sesskey);
1065 			return NULL;
1066 		}
1067 		break;
1068 	default:
1069 		/* will not get here - for lint only */
1070 		break;
1071 	}
1072 	free(unencoded_m_buf);
1073 	free(encoded_m_buf);
1074 	return sesskey;
1075 }
1076 
1077 /**
1078 \ingroup Core_WritePackets
1079 \brief Writes Public Key Session Key packet
1080 \param info Write settings
1081 \param pksk Public Key Session Key to write out
1082 \return 1 if OK; else 0
1083 */
1084 unsigned
pgp_write_pk_sesskey(pgp_output_t * output,pgp_pk_sesskey_t * pksk)1085 pgp_write_pk_sesskey(pgp_output_t *output, pgp_pk_sesskey_t *pksk)
1086 {
1087 	/* XXX - Flexelint - Pointer parameter 'pksk' (line 1076) could be declared as pointing to const */
1088 	if (pksk == NULL) {
1089 		(void) fprintf(stderr,
1090 			"pgp_write_pk_sesskey: NULL pksk\n");
1091 		return 0;
1092 	}
1093 	switch (pksk->alg) {
1094 	case PGP_PKA_RSA:
1095 		return pgp_write_ptag(output, PGP_PTAG_CT_PK_SESSION_KEY) &&
1096 			pgp_write_length(output, (unsigned)(1 + 8 + 1 +
1097 				BN_num_bytes(pksk->params.rsa.encrypted_m) + 2)) &&
1098 			pgp_write_scalar(output, (unsigned)pksk->version, 1) &&
1099 			pgp_write(output, pksk->key_id, 8) &&
1100 			pgp_write_scalar(output, (unsigned)pksk->alg, 1) &&
1101 			pgp_write_mpi(output, pksk->params.rsa.encrypted_m)
1102 			/* ??	&& pgp_write_scalar(output, 0, 2); */
1103 			;
1104 	case PGP_PKA_DSA:
1105 	case PGP_PKA_ELGAMAL:
1106 		return pgp_write_ptag(output, PGP_PTAG_CT_PK_SESSION_KEY) &&
1107 			pgp_write_length(output, (unsigned)(1 + 8 + 1 +
1108 				BN_num_bytes(pksk->params.elgamal.g_to_k) + 2 +
1109 				BN_num_bytes(pksk->params.elgamal.encrypted_m) + 2)) &&
1110 			pgp_write_scalar(output, (unsigned)pksk->version, 1) &&
1111 			pgp_write(output, pksk->key_id, 8) &&
1112 			pgp_write_scalar(output, (unsigned)pksk->alg, 1) &&
1113 			pgp_write_mpi(output, pksk->params.elgamal.g_to_k) &&
1114 			pgp_write_mpi(output, pksk->params.elgamal.encrypted_m)
1115 			/* ??	&& pgp_write_scalar(output, 0, 2); */
1116 			;
1117 	default:
1118 		(void) fprintf(stderr,
1119 			"pgp_write_pk_sesskey: bad algorithm\n");
1120 		return 0;
1121 	}
1122 }
1123 
1124 /**
1125 \ingroup Core_WritePackets
1126 \brief Writes MDC packet
1127 \param hashed Hash for MDC
1128 \param output Write settings
1129 \return 1 if OK; else 0
1130 */
1131 
1132 unsigned
pgp_write_mdc(pgp_output_t * output,const uint8_t * hashed)1133 pgp_write_mdc(pgp_output_t *output, const uint8_t *hashed)
1134 {
1135 	/* write it out */
1136 	return pgp_write_ptag(output, PGP_PTAG_CT_MDC) &&
1137 		pgp_write_length(output, PGP_SHA1_HASH_SIZE) &&
1138 		pgp_write(output, hashed, PGP_SHA1_HASH_SIZE);
1139 }
1140 
1141 /**
1142 \ingroup Core_WritePackets
1143 \brief Writes Literal Data packet from buffer
1144 \param data Buffer to write out
1145 \param maxlen Max length of buffer
1146 \param type Literal Data Type
1147 \param output Write settings
1148 \return 1 if OK; else 0
1149 */
1150 unsigned
pgp_write_litdata(pgp_output_t * output,const uint8_t * data,const int maxlen,const pgp_litdata_enum type)1151 pgp_write_litdata(pgp_output_t *output,
1152 			const uint8_t *data,
1153 			const int maxlen,
1154 			const pgp_litdata_enum type)
1155 {
1156 	/*
1157          * RFC4880 does not specify a meaning for filename or date.
1158          * It is implementation-dependent.
1159          * We will not implement them.
1160          */
1161 	/* \todo do we need to check text data for <cr><lf> line endings ? */
1162 	return pgp_write_ptag(output, PGP_PTAG_CT_LITDATA) &&
1163 		pgp_write_length(output, (unsigned)(1 + 1 + 4 + maxlen)) &&
1164 		pgp_write_scalar(output, (unsigned)type, 1) &&
1165 		pgp_write_scalar(output, 0, 1) &&
1166 		pgp_write_scalar(output, 0, 4) &&
1167 		pgp_write(output, data, (unsigned)maxlen);
1168 }
1169 
1170 /**
1171 \ingroup Core_WritePackets
1172 \brief Writes Literal Data packet from contents of file
1173 \param filename Name of file to read from
1174 \param type Literal Data Type
1175 \param output Write settings
1176 \return 1 if OK; else 0
1177 */
1178 
1179 unsigned
pgp_fileread_litdata(const char * filename,const pgp_litdata_enum type,pgp_output_t * output)1180 pgp_fileread_litdata(const char *filename,
1181 				 const pgp_litdata_enum type,
1182 				 pgp_output_t *output)
1183 {
1184 	pgp_memory_t	*mem;
1185 	unsigned   	 ret;
1186 	int		 len;
1187 
1188 	mem = pgp_memory_new();
1189 	if (!pgp_mem_readfile(mem, filename)) {
1190 		(void) fprintf(stderr, "pgp_mem_readfile of '%s' failed\n", filename);
1191 		return 0;
1192 	}
1193 	len = (int)pgp_mem_len(mem);
1194 	ret = pgp_write_litdata(output, pgp_mem_data(mem), len, type);
1195 	pgp_memory_free(mem);
1196 	return ret;
1197 }
1198 
1199 /**
1200    \ingroup HighLevel_General
1201 
1202    \brief Writes contents of buffer into file
1203 
1204    \param filename Filename to write to
1205    \param buf Buffer to write to file
1206    \param len Size of buffer
1207    \param overwrite Flag to set whether to overwrite an existing file
1208    \return 1 if OK; 0 if error
1209 */
1210 
1211 int
pgp_filewrite(const char * filename,const char * buf,const size_t len,const unsigned overwrite)1212 pgp_filewrite(const char *filename, const char *buf,
1213 			const size_t len, const unsigned overwrite)
1214 {
1215 	int		flags;
1216 	int		fd;
1217 
1218 	flags = O_WRONLY | O_CREAT;
1219 	if (overwrite) {
1220 		flags |= O_TRUNC;
1221 	} else {
1222 		flags |= O_EXCL;
1223 	}
1224 #ifdef O_BINARY
1225 	flags |= O_BINARY;
1226 #endif
1227 	fd = open(filename, flags, 0600);
1228 	if (fd < 0) {
1229 		(void) fprintf(stderr, "can't open '%s'\n", filename);
1230 		return 0;
1231 	}
1232 	if (write(fd, buf, len) != (int)len) {
1233 		(void) close(fd);
1234 		return 0;
1235 	}
1236 
1237 	return (close(fd) == 0);
1238 }
1239 
1240 /**
1241 \ingroup Core_WritePackets
1242 \brief Write Symmetrically Encrypted packet
1243 \param data Data to encrypt
1244 \param len Length of data
1245 \param output Write settings
1246 \return 1 if OK; else 0
1247 \note Hard-coded to use AES256
1248 */
1249 unsigned
pgp_write_symm_enc_data(const uint8_t * data,const int len,pgp_output_t * output)1250 pgp_write_symm_enc_data(const uint8_t *data,
1251 				       const int len,
1252 				       pgp_output_t * output)
1253 {
1254 	pgp_crypt_t	crypt_info;
1255 	uint8_t		*encrypted = (uint8_t *) NULL;
1256 	size_t		encrypted_sz;
1257 	int             done = 0;
1258 
1259 	/* \todo assume AES256 for now */
1260 	pgp_crypt_any(&crypt_info, PGP_SA_AES_256);
1261 	pgp_encrypt_init(&crypt_info);
1262 
1263 	encrypted_sz = (size_t)(len + crypt_info.blocksize + 2);
1264 	if ((encrypted = calloc(1, encrypted_sz)) == NULL) {
1265 		(void) fprintf(stderr, "can't allocate %" PRIsize "d\n",
1266 			encrypted_sz);
1267 		return 0;
1268 	}
1269 
1270 	done = (int)pgp_encrypt_se(&crypt_info, encrypted, data, (unsigned)len);
1271 	if (done != len) {
1272 		(void) fprintf(stderr,
1273 			"pgp_write_symm_enc_data: done != len\n");
1274 		return 0;
1275 	}
1276 
1277 	return pgp_write_ptag(output, PGP_PTAG_CT_SE_DATA) &&
1278 		pgp_write_length(output, (unsigned)(1 + encrypted_sz)) &&
1279 		pgp_write(output, data, (unsigned)len);
1280 }
1281 
1282 /**
1283 \ingroup Core_WritePackets
1284 \brief Write a One Pass Signature packet
1285 \param seckey Secret Key to use
1286 \param hash_alg Hash Algorithm to use
1287 \param sig_type Signature type
1288 \param output Write settings
1289 \return 1 if OK; else 0
1290 */
1291 unsigned
pgp_write_one_pass_sig(pgp_output_t * output,const pgp_seckey_t * seckey,const pgp_hash_alg_t hash_alg,const pgp_sig_type_t sig_type)1292 pgp_write_one_pass_sig(pgp_output_t *output,
1293 			const pgp_seckey_t *seckey,
1294 			const pgp_hash_alg_t hash_alg,
1295 			const pgp_sig_type_t sig_type)
1296 {
1297 	uint8_t   keyid[PGP_KEY_ID_SIZE];
1298 
1299 	pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, PGP_HASH_SHA1); /* XXX - hardcoded */
1300 	return pgp_write_ptag(output, PGP_PTAG_CT_1_PASS_SIG) &&
1301 		pgp_write_length(output, 1 + 1 + 1 + 1 + 8 + 1) &&
1302 		pgp_write_scalar(output, 3, 1)	/* version */ &&
1303 		pgp_write_scalar(output, (unsigned)sig_type, 1) &&
1304 		pgp_write_scalar(output, (unsigned)hash_alg, 1) &&
1305 		pgp_write_scalar(output, (unsigned)seckey->pubkey.alg, 1) &&
1306 		pgp_write(output, keyid, 8) &&
1307 		pgp_write_scalar(output, 1, 1);
1308 }
1309