Home | History | Annotate | Line # | Download | only in lib
      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 (at) 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
    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
    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
    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
    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
    163 mpi_length(const BIGNUM *bn)
    164 {
    165 	return (unsigned)(2 + (BN_num_bits(bn) + 7) / 8);
    166 }
    167 
    168 static unsigned
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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 *
    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
    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
    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
    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
    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 *
    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
   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
   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
   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
   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
   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
   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
   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