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: signature.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 
     66 #ifdef HAVE_FCNTL_H
     67 #include <fcntl.h>
     68 #endif
     69 
     70 #include <string.h>
     71 
     72 #ifdef HAVE_UNISTD_H
     73 #include <unistd.h>
     74 #endif
     75 
     76 #ifdef HAVE_OPENSSL_DSA_H
     77 #include <openssl/dsa.h>
     78 #endif
     79 
     80 #include "signature.h"
     81 #include "crypto.h"
     82 #include "create.h"
     83 #include "netpgpsdk.h"
     84 #include "readerwriter.h"
     85 #include "validate.h"
     86 #include "netpgpdefs.h"
     87 #include "netpgpdigest.h"
     88 
     89 
     90 /** \ingroup Core_Create
     91  * needed for signature creation
     92  */
     93 struct pgp_create_sig_t {
     94 	pgp_hash_t		 hash;
     95 	pgp_sig_t		 sig;
     96 	pgp_memory_t		*mem;
     97 	pgp_output_t		*output;	/* how to do the writing */
     98 	unsigned		 hashoff;	/* hashed count offset */
     99 	unsigned		 hashlen;
    100 	unsigned 		 unhashoff;
    101 };
    102 
    103 /**
    104    \ingroup Core_Signature
    105    Creates new pgp_create_sig_t
    106    \return new pgp_create_sig_t
    107    \note It is the caller's responsibility to call pgp_create_sig_delete()
    108    \sa pgp_create_sig_delete()
    109 */
    110 pgp_create_sig_t *
    111 pgp_create_sig_new(void)
    112 {
    113 	return calloc(1, sizeof(pgp_create_sig_t));
    114 }
    115 
    116 /**
    117    \ingroup Core_Signature
    118    Free signature and memory associated with it
    119    \param sig struct to free
    120    \sa pgp_create_sig_new()
    121 */
    122 void
    123 pgp_create_sig_delete(pgp_create_sig_t *sig)
    124 {
    125 	pgp_output_delete(sig->output);
    126 	sig->output = NULL;
    127 	free(sig);
    128 }
    129 
    130 #if 0
    131 void
    132 pgp_dump_sig(pgp_sig_t *sig)
    133 {
    134 }
    135 #endif
    136 
    137 static uint8_t prefix_md5[] = {
    138 	0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
    139 	0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
    140 };
    141 
    142 static uint8_t prefix_sha1[] = {
    143 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02,
    144 	0x1A, 0x05, 0x00, 0x04, 0x14
    145 };
    146 
    147 static uint8_t prefix_sha256[] = {
    148 	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
    149 	0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
    150 };
    151 
    152 
    153 /* XXX: both this and verify would be clearer if the signature were */
    154 /* treated as an MPI. */
    155 static int
    156 rsa_sign(pgp_hash_t *hash,
    157 	const pgp_rsa_pubkey_t *pubrsa,
    158 	const pgp_rsa_seckey_t *secrsa,
    159 	pgp_output_t *out)
    160 {
    161 	unsigned        prefixsize;
    162 	unsigned        expected;
    163 	unsigned        hashsize;
    164 	unsigned        keysize;
    165 	unsigned        n;
    166 	unsigned        t;
    167 	uint8_t		hashbuf[NETPGP_BUFSIZ];
    168 	uint8_t		sigbuf[NETPGP_BUFSIZ];
    169 	uint8_t		*prefix;
    170 	BIGNUM         *bn;
    171 
    172 	if (strcmp(hash->name, "SHA1") == 0) {
    173 		hashsize = PGP_SHA1_HASH_SIZE + sizeof(prefix_sha1);
    174 		prefix = prefix_sha1;
    175 		prefixsize = sizeof(prefix_sha1);
    176 		expected = PGP_SHA1_HASH_SIZE;
    177 	} else {
    178 		hashsize = PGP_SHA256_HASH_SIZE + sizeof(prefix_sha256);
    179 		prefix = prefix_sha256;
    180 		prefixsize = sizeof(prefix_sha256);
    181 		expected = PGP_SHA256_HASH_SIZE;
    182 	}
    183 	keysize = (BN_num_bits(pubrsa->n) + 7) / 8;
    184 	if (keysize > sizeof(hashbuf)) {
    185 		(void) fprintf(stderr, "rsa_sign: keysize too big\n");
    186 		return 0;
    187 	}
    188 	if (10 + hashsize > keysize) {
    189 		(void) fprintf(stderr, "rsa_sign: hashsize too big\n");
    190 		return 0;
    191 	}
    192 
    193 	hashbuf[0] = 0;
    194 	hashbuf[1] = 1;
    195 	if (pgp_get_debug_level(__FILE__)) {
    196 		printf("rsa_sign: PS is %d\n", keysize - hashsize - 1 - 2);
    197 	}
    198 	for (n = 2; n < keysize - hashsize - 1; ++n) {
    199 		hashbuf[n] = 0xff;
    200 	}
    201 	hashbuf[n++] = 0;
    202 
    203 	(void) memcpy(&hashbuf[n], prefix, prefixsize);
    204 	n += prefixsize;
    205 	if ((t = hash->finish(hash, &hashbuf[n])) != expected) {
    206 		(void) fprintf(stderr, "rsa_sign: short %s hash\n", hash->name);
    207 		return 0;
    208 	}
    209 
    210 	pgp_write(out, &hashbuf[n], 2);
    211 
    212 	n += t;
    213 	if (n != keysize) {
    214 		(void) fprintf(stderr, "rsa_sign: n != keysize\n");
    215 		return 0;
    216 	}
    217 
    218 	t = pgp_rsa_private_encrypt(sigbuf, hashbuf, keysize, secrsa, pubrsa);
    219 	bn = BN_bin2bn(sigbuf, (int)t, NULL);
    220 	pgp_write_mpi(out, bn);
    221 	BN_free(bn);
    222 	return 1;
    223 }
    224 
    225 static int
    226 dsa_sign(pgp_hash_t *hash,
    227 	 const pgp_dsa_pubkey_t *dsa,
    228 	 const pgp_dsa_seckey_t *sdsa,
    229 	 pgp_output_t *output)
    230 {
    231 	unsigned        hashsize;
    232 	unsigned        t;
    233 	uint8_t		hashbuf[NETPGP_BUFSIZ];
    234 	DSA_SIG        *dsasig;
    235 	const BIGNUM   *r, *s;
    236 
    237 	/* hashsize must be "equal in size to the number of bits of q,  */
    238 	/* the group generated by the DSA key's generator value */
    239 	/* 160/8 = 20 */
    240 
    241 	hashsize = 20;
    242 
    243 	/* finalise hash */
    244 	t = hash->finish(hash, &hashbuf[0]);
    245 	if (t != 20) {
    246 		(void) fprintf(stderr, "dsa_sign: hashfinish not 20\n");
    247 		return 0;
    248 	}
    249 
    250 	pgp_write(output, &hashbuf[0], 2);
    251 
    252 	/* write signature to buf */
    253 	dsasig = pgp_dsa_sign(hashbuf, hashsize, sdsa, dsa);
    254 
    255 	/* convert and write the sig out to memory */
    256 #if OPENSSL_VERSION_NUMBER >= 0x10100000
    257 	DSA_SIG_get0(dsasig, &r, &s);
    258 #else
    259 	r = dsasig->r;
    260 	s = dsasig->s;
    261 #endif
    262 	pgp_write_mpi(output, r);
    263 	pgp_write_mpi(output, s);
    264 	DSA_SIG_free(dsasig);
    265 	return 1;
    266 }
    267 
    268 static int
    269 ecdsa_sign(pgp_hash_t *hash,
    270 	   const pgp_ecdsa_pubkey_t *ecdsa,
    271 	   const pgp_ecdsa_seckey_t *secdsa,
    272 	   pgp_output_t *output)
    273 {
    274 	unsigned        hashsize;
    275 	unsigned        t;
    276 	uint8_t         hashbuf[NETPGP_BUFSIZ];
    277 	ECDSA_SIG        *ecdsasig;
    278 	const BIGNUM   *r, *s;
    279 
    280 	hashsize = ecdsa_hashsize(ecdsa);
    281 
    282 	if (hashsize == -1) {
    283 		return 0;
    284 	}
    285 
    286 	t = hash->finish(hash, &hashbuf[0]);
    287 
    288 	if (t != hashsize) {
    289 		(void) fprintf(stderr, "ecdsa_sign: hashfinish %d not %d\n", t, hashsize);
    290 		return 0;
    291 	}
    292 
    293 	pgp_write(output, &hashbuf[0], 2);
    294 
    295 	/* write signature to buf */
    296 	ecdsasig = pgp_ecdsa_sign(hashbuf, hashsize, secdsa, ecdsa);
    297 
    298 	if (ecdsasig == NULL) {
    299 		(void) fprintf(stderr, "ecdsa_sign: invalid ecdsa sig\n");
    300 		return 0;
    301 	}
    302 
    303 	/* convert and write the sig out to memory */
    304 #if OPENSSL_VERSION_NUMBER >= 0x10100000
    305 	ECDSA_SIG_get0(ecdsasig, &r, &s);
    306 #else
    307 	r = ecdsasig->r;
    308 	s = ecdsasig->s;
    309 #endif
    310 	pgp_write_mpi(output, r);
    311 	pgp_write_mpi(output, s);
    312 
    313 	ECDSA_SIG_free(ecdsasig);
    314 
    315 	return 1;
    316 }
    317 
    318 static unsigned
    319 rsa_verify(pgp_hash_alg_t type,
    320 	   const uint8_t *hash,
    321 	   size_t hash_length,
    322 	   const pgp_rsa_sig_t *sig,
    323 	   const pgp_rsa_pubkey_t *pubrsa)
    324 {
    325 	const uint8_t	*prefix;
    326 	unsigned       	 n;
    327 	unsigned       	 keysize;
    328 	unsigned	 plen;
    329 	unsigned	 debug_len_decrypted;
    330 	uint8_t   	 sigbuf[NETPGP_BUFSIZ];
    331 	uint8_t   	 hashbuf_from_sig[NETPGP_BUFSIZ];
    332 
    333 	plen = 0;
    334 	prefix = (const uint8_t *) "";
    335 	keysize = BN_num_bytes(pubrsa->n);
    336 	/* RSA key can't be bigger than 65535 bits, so... */
    337 	if (keysize > sizeof(hashbuf_from_sig)) {
    338 		(void) fprintf(stderr, "rsa_verify: keysize too big\n");
    339 		return 0;
    340 	}
    341 	if ((unsigned) BN_num_bits(sig->sig) > 8 * sizeof(sigbuf)) {
    342 		(void) fprintf(stderr, "rsa_verify: BN_numbits too big\n");
    343 		return 0;
    344 	}
    345 	BN_bn2bin(sig->sig, sigbuf);
    346 
    347 	n = pgp_rsa_public_decrypt(hashbuf_from_sig, sigbuf,
    348 		(unsigned)(BN_num_bits(sig->sig) + 7) / 8, pubrsa);
    349 	debug_len_decrypted = n;
    350 
    351 	if (n != keysize) {
    352 		/* obviously, this includes error returns */
    353 		return 0;
    354 	}
    355 
    356 	/* XXX: why is there a leading 0? The first byte should be 1... */
    357 	/* XXX: because the decrypt should use keysize and not sigsize? */
    358 	if (hashbuf_from_sig[0] != 0 || hashbuf_from_sig[1] != 1) {
    359 		return 0;
    360 	}
    361 
    362 	switch (type) {
    363 	case PGP_HASH_MD5:
    364 		prefix = prefix_md5;
    365 		plen = sizeof(prefix_md5);
    366 		break;
    367 	case PGP_HASH_SHA1:
    368 		prefix = prefix_sha1;
    369 		plen = sizeof(prefix_sha1);
    370 		break;
    371 	case PGP_HASH_SHA256:
    372 		prefix = prefix_sha256;
    373 		plen = sizeof(prefix_sha256);
    374 		break;
    375 	default:
    376 		(void) fprintf(stderr, "Unknown hash algorithm: %d\n", type);
    377 		return 0;
    378 	}
    379 
    380 	if (keysize - plen - hash_length < 10) {
    381 		return 0;
    382 	}
    383 
    384 	for (n = 2; n < keysize - plen - hash_length - 1; ++n) {
    385 		if (hashbuf_from_sig[n] != 0xff) {
    386 			return 0;
    387 		}
    388 	}
    389 
    390 	if (hashbuf_from_sig[n++] != 0) {
    391 		return 0;
    392 	}
    393 
    394 	if (pgp_get_debug_level(__FILE__)) {
    395 		hexdump(stderr, "sig hashbuf", hashbuf_from_sig, debug_len_decrypted);
    396 		hexdump(stderr, "prefix", prefix, plen);
    397 		hexdump(stderr, "sig hash", &hashbuf_from_sig[n + plen], hash_length);
    398 		hexdump(stderr, "input hash", hash, hash_length);
    399 	}
    400 	return (memcmp(&hashbuf_from_sig[n], prefix, plen) == 0 &&
    401 	        memcmp(&hashbuf_from_sig[n + plen], hash, hash_length) == 0);
    402 }
    403 
    404 static void
    405 hash_add_key(pgp_hash_t *hash, const pgp_pubkey_t *key)
    406 {
    407 	pgp_memory_t	*mem = pgp_memory_new();
    408 	const unsigned 	 dontmakepacket = 0;
    409 	size_t		 len;
    410 
    411 	pgp_build_pubkey(mem, key, dontmakepacket);
    412 	len = pgp_mem_len(mem);
    413 	pgp_hash_add_int(hash, 0x99, 1);
    414 	pgp_hash_add_int(hash, (unsigned)len, 2);
    415 	hash->add(hash, pgp_mem_data(mem), (unsigned)len);
    416 	pgp_memory_free(mem);
    417 }
    418 
    419 static void
    420 initialise_hash(pgp_hash_t *hash, const pgp_sig_t *sig)
    421 {
    422 	pgp_hash_any(hash, sig->info.hash_alg);
    423 	if (!hash->init(hash)) {
    424 		(void) fprintf(stderr,
    425 			"initialise_hash: bad hash init\n");
    426 		/* just continue and die */
    427 		/* XXX - agc - no way to return failure */
    428 	}
    429 }
    430 
    431 static void
    432 init_key_sig(pgp_hash_t *hash, const pgp_sig_t *sig,
    433 		   const pgp_pubkey_t *key)
    434 {
    435 	initialise_hash(hash, sig);
    436 	hash_add_key(hash, key);
    437 }
    438 
    439 static void
    440 hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig,
    441 		 const uint8_t *raw_packet)
    442 {
    443 	if (sig->info.version == PGP_V4) {
    444 		if (raw_packet) {
    445 			hash->add(hash, raw_packet + sig->v4_hashstart,
    446 				  (unsigned)sig->info.v4_hashlen);
    447 		}
    448 		pgp_hash_add_int(hash, (unsigned)sig->info.version, 1);
    449 		pgp_hash_add_int(hash, 0xff, 1);
    450 		pgp_hash_add_int(hash, (unsigned)sig->info.v4_hashlen, 4);
    451 	} else {
    452 		pgp_hash_add_int(hash, (unsigned)sig->info.type, 1);
    453 		pgp_hash_add_int(hash, (unsigned)sig->info.birthtime, 4);
    454 	}
    455 }
    456 
    457 /**
    458    \ingroup Core_Signature
    459    \brief Checks a signature
    460    \param hash Signature Hash to be checked
    461    \param length Signature Length
    462    \param sig The Signature to be checked
    463    \param signer The signer's public key
    464    \return 1 if good; else 0
    465 */
    466 unsigned
    467 pgp_check_sig(const uint8_t *hash, unsigned length,
    468 		    const pgp_sig_t * sig,
    469 		    const pgp_pubkey_t * signer)
    470 {
    471 	unsigned   ret;
    472 
    473 	if (pgp_get_debug_level(__FILE__)) {
    474 		hexdump(stdout, "hash", hash, length);
    475 	}
    476 	ret = 0;
    477 	switch (sig->info.key_alg) {
    478 	case PGP_PKA_DSA:
    479 		ret = pgp_dsa_verify(hash, length, &sig->info.sig.dsa,
    480 				&signer->key.dsa);
    481 		break;
    482 
    483 	case PGP_PKA_ECDSA:
    484 		ret = pgp_ecdsa_verify(hash, length,
    485 				&sig->info.sig.ecdsa,
    486 				&signer->key.ecdsa);
    487 		break;
    488 
    489 	case PGP_PKA_RSA:
    490 		ret = rsa_verify(sig->info.hash_alg, hash, length,
    491 				&sig->info.sig.rsa,
    492 				&signer->key.rsa);
    493 		break;
    494 
    495 	default:
    496 		(void) fprintf(stderr, "pgp_check_sig: unusual alg\n");
    497 		ret = 0;
    498 	}
    499 
    500 	return ret;
    501 }
    502 
    503 static unsigned
    504 hash_and_check_sig(pgp_hash_t *hash,
    505 			 const pgp_sig_t *sig,
    506 			 const pgp_pubkey_t *signer)
    507 {
    508 	uint8_t   hashout[PGP_MAX_HASH_SIZE];
    509 	unsigned	n;
    510 
    511 	n = hash->finish(hash, hashout);
    512 	return pgp_check_sig(hashout, n, sig, signer);
    513 }
    514 
    515 static unsigned
    516 finalise_sig(pgp_hash_t *hash,
    517 		   const pgp_sig_t *sig,
    518 		   const pgp_pubkey_t *signer,
    519 		   const uint8_t *raw_packet)
    520 {
    521 	hash_add_trailer(hash, sig, raw_packet);
    522 	return hash_and_check_sig(hash, sig, signer);
    523 }
    524 
    525 /**
    526  * \ingroup Core_Signature
    527  *
    528  * \brief Verify a certification signature.
    529  *
    530  * \param key The public key that was signed.
    531  * \param id The user ID that was signed
    532  * \param sig The signature.
    533  * \param signer The public key of the signer.
    534  * \param raw_packet The raw signature packet.
    535  * \return 1 if OK; else 0
    536  */
    537 unsigned
    538 pgp_check_useridcert_sig(const pgp_pubkey_t *key,
    539 			  const uint8_t *id,
    540 			  const pgp_sig_t *sig,
    541 			  const pgp_pubkey_t *signer,
    542 			  const uint8_t *raw_packet)
    543 {
    544 	pgp_hash_t	hash;
    545 	size_t          userid_len;
    546 
    547 	userid_len = strlen((const char *) id);
    548 	init_key_sig(&hash, sig, key);
    549 	if (sig->info.version == PGP_V4) {
    550 		pgp_hash_add_int(&hash, 0xb4, 1);
    551 		pgp_hash_add_int(&hash, (unsigned)userid_len, 4);
    552 	}
    553 	hash.add(&hash, id, (unsigned)userid_len);
    554 	return finalise_sig(&hash, sig, signer, raw_packet);
    555 }
    556 
    557 /**
    558  * \ingroup Core_Signature
    559  *
    560  * Verify a certification signature.
    561  *
    562  * \param key The public key that was signed.
    563  * \param attribute The user attribute that was signed
    564  * \param sig The signature.
    565  * \param signer The public key of the signer.
    566  * \param raw_packet The raw signature packet.
    567  * \return 1 if OK; else 0
    568  */
    569 unsigned
    570 pgp_check_userattrcert_sig(const pgp_pubkey_t *key,
    571 				const pgp_data_t *attribute,
    572 				const pgp_sig_t *sig,
    573 				const pgp_pubkey_t *signer,
    574 				const uint8_t *raw_packet)
    575 {
    576 	pgp_hash_t      hash;
    577 
    578 	init_key_sig(&hash, sig, key);
    579 	if (sig->info.version == PGP_V4) {
    580 		pgp_hash_add_int(&hash, 0xd1, 1);
    581 		pgp_hash_add_int(&hash, (unsigned)attribute->len, 4);
    582 	}
    583 	hash.add(&hash, attribute->contents, (unsigned)attribute->len);
    584 	return finalise_sig(&hash, sig, signer, raw_packet);
    585 }
    586 
    587 /**
    588  * \ingroup Core_Signature
    589  *
    590  * Verify a subkey signature.
    591  *
    592  * \param key The public key whose subkey was signed.
    593  * \param subkey The subkey of the public key that was signed.
    594  * \param sig The signature.
    595  * \param signer The public key of the signer.
    596  * \param raw_packet The raw signature packet.
    597  * \return 1 if OK; else 0
    598  */
    599 unsigned
    600 pgp_check_subkey_sig(const pgp_pubkey_t *key,
    601 			   const pgp_pubkey_t *subkey,
    602 			   const pgp_sig_t *sig,
    603 			   const pgp_pubkey_t *signer,
    604 			   const uint8_t *raw_packet)
    605 {
    606 	pgp_hash_t	hash;
    607 	unsigned	ret;
    608 
    609 	init_key_sig(&hash, sig, key);
    610 	hash_add_key(&hash, subkey);
    611 	ret = finalise_sig(&hash, sig, signer, raw_packet);
    612 	return ret;
    613 }
    614 
    615 /**
    616  * \ingroup Core_Signature
    617  *
    618  * Verify a direct signature.
    619  *
    620  * \param key The public key which was signed.
    621  * \param sig The signature.
    622  * \param signer The public key of the signer.
    623  * \param raw_packet The raw signature packet.
    624  * \return 1 if OK; else 0
    625  */
    626 unsigned
    627 pgp_check_direct_sig(const pgp_pubkey_t *key,
    628 			   const pgp_sig_t *sig,
    629 			   const pgp_pubkey_t *signer,
    630 			   const uint8_t *raw_packet)
    631 {
    632 	pgp_hash_t	hash;
    633 	unsigned	ret;
    634 
    635 	init_key_sig(&hash, sig, key);
    636 	ret = finalise_sig(&hash, sig, signer, raw_packet);
    637 	return ret;
    638 }
    639 
    640 /**
    641  * \ingroup Core_Signature
    642  *
    643  * Verify a signature on a hash (the hash will have already been fed
    644  * the material that was being signed, for example signed cleartext).
    645  *
    646  * \param hash A hash structure of appropriate type that has been fed
    647  * the material to be signed. This MUST NOT have been finalised.
    648  * \param sig The signature to be verified.
    649  * \param signer The public key of the signer.
    650  * \return 1 if OK; else 0
    651  */
    652 unsigned
    653 pgp_check_hash_sig(pgp_hash_t *hash,
    654 			 const pgp_sig_t *sig,
    655 			 const pgp_pubkey_t *signer)
    656 {
    657 	return (sig->info.hash_alg == hash->alg) ?
    658 		finalise_sig(hash, sig, signer, NULL) :
    659 		0;
    660 }
    661 
    662 static void
    663 start_sig_in_mem(pgp_create_sig_t *sig)
    664 {
    665 	/* since this has subpackets and stuff, we have to buffer the whole */
    666 	/* thing to get counts before writing. */
    667 	sig->mem = pgp_memory_new();
    668 	pgp_memory_init(sig->mem, 100);
    669 	pgp_writer_set_memory(sig->output, sig->mem);
    670 
    671 	/* write nearly up to the first subpacket */
    672 	pgp_write_scalar(sig->output, (unsigned)sig->sig.info.version, 1);
    673 	pgp_write_scalar(sig->output, (unsigned)sig->sig.info.type, 1);
    674 	pgp_write_scalar(sig->output, (unsigned)sig->sig.info.key_alg, 1);
    675 	pgp_write_scalar(sig->output, (unsigned)sig->sig.info.hash_alg, 1);
    676 
    677 	/* dummy hashed subpacket count */
    678 	sig->hashoff = (unsigned)pgp_mem_len(sig->mem);
    679 	pgp_write_scalar(sig->output, 0, 2);
    680 }
    681 
    682 /**
    683  * \ingroup Core_Signature
    684  *
    685  * pgp_sig_start() creates a V4 public key signature with a SHA1 hash.
    686  *
    687  * \param sig The signature structure to initialise
    688  * \param key The public key to be signed
    689  * \param id The user ID being bound to the key
    690  * \param type Signature type
    691  */
    692 void
    693 pgp_sig_start_key_sig(pgp_create_sig_t *sig,
    694 				  const pgp_pubkey_t *key,
    695 				  const uint8_t *id,
    696 				  pgp_sig_type_t type)
    697 {
    698 	sig->output = pgp_output_new();
    699 
    700 	/* XXX:  refactor with check (in several ways - check should
    701 	 * probably use the buffered writer to construct packets
    702 	 * (done), and also should share code for hash calculation) */
    703 	sig->sig.info.version = PGP_V4;
    704 	sig->sig.info.hash_alg = PGP_HASH_SHA1;
    705 	sig->sig.info.key_alg = key->alg;
    706 	sig->sig.info.type = type;
    707 	sig->hashlen = (unsigned)-1;
    708 	init_key_sig(&sig->hash, &sig->sig, key);
    709 	pgp_hash_add_int(&sig->hash, 0xb4, 1);
    710 	pgp_hash_add_int(&sig->hash, (unsigned)strlen((const char *) id), 4);
    711 	sig->hash.add(&sig->hash, id, (unsigned)strlen((const char *) id));
    712 	start_sig_in_mem(sig);
    713 }
    714 
    715 /**
    716  * \ingroup Core_Signature
    717  *
    718  * Create a V4 public key signature over some cleartext.
    719  *
    720  * \param sig The signature structure to initialise
    721  * \param id
    722  * \param type
    723  * \todo Expand description. Allow other hashes.
    724  */
    725 
    726 void
    727 pgp_start_sig(pgp_create_sig_t *sig,
    728 	      const pgp_seckey_t *key,
    729 	      const pgp_hash_alg_t hash,
    730 	      const pgp_sig_type_t type)
    731 {
    732 	sig->output = pgp_output_new();
    733 
    734 	/* XXX:  refactor with check (in several ways - check should
    735 	 * probably use the buffered writer to construct packets
    736 	 * (done), and also should share code for hash calculation) */
    737 	sig->sig.info.version = PGP_V4;
    738 	sig->sig.info.key_alg = key->pubkey.alg;
    739 	sig->sig.info.hash_alg = hash;
    740 	sig->sig.info.type = type;
    741 
    742 	sig->hashlen = (unsigned)-1;
    743 
    744 	if (pgp_get_debug_level(__FILE__)) {
    745 		fprintf(stderr, "initialising hash for sig in mem\n");
    746 	}
    747 	initialise_hash(&sig->hash, &sig->sig);
    748 	start_sig_in_mem(sig);
    749 }
    750 
    751 /**
    752  * \ingroup Core_Signature
    753  *
    754  * Add plaintext data to a signature-to-be.
    755  *
    756  * \param sig The signature-to-be.
    757  * \param buf The plaintext data.
    758  * \param length The amount of plaintext data.
    759  */
    760 void
    761 pgp_sig_add_data(pgp_create_sig_t *sig, const void *buf, size_t length)
    762 {
    763 	sig->hash.add(&sig->hash, buf, (unsigned)length);
    764 }
    765 
    766 /**
    767  * \ingroup Core_Signature
    768  *
    769  * Mark the end of the hashed subpackets in the signature
    770  *
    771  * \param sig
    772  */
    773 
    774 unsigned
    775 pgp_end_hashed_subpkts(pgp_create_sig_t *sig)
    776 {
    777 	sig->hashlen = (unsigned)(pgp_mem_len(sig->mem) - sig->hashoff - 2);
    778 	pgp_memory_place_int(sig->mem, sig->hashoff, sig->hashlen, 2);
    779 	/* dummy unhashed subpacket count */
    780 	sig->unhashoff = (unsigned)pgp_mem_len(sig->mem);
    781 	return pgp_write_scalar(sig->output, 0, 2);
    782 }
    783 
    784 /**
    785  * \ingroup Core_Signature
    786  *
    787  * Write out a signature
    788  *
    789  * \param sig
    790  * \param key
    791  * \param seckey
    792  * \param info
    793  *
    794  */
    795 
    796 unsigned
    797 pgp_write_sig(pgp_output_t *output,
    798 			pgp_create_sig_t *sig,
    799 			const pgp_pubkey_t *key,
    800 			const pgp_seckey_t *seckey)
    801 {
    802 	unsigned	ret = 0;
    803 	size_t		len = pgp_mem_len(sig->mem);
    804 
    805 	/* check key not decrypted */
    806 	switch (seckey->pubkey.alg) {
    807 	case PGP_PKA_RSA:
    808 	case PGP_PKA_RSA_ENCRYPT_ONLY:
    809 	case PGP_PKA_RSA_SIGN_ONLY:
    810 		if (seckey->key.rsa.d == NULL) {
    811 			(void) fprintf(stderr, "pgp_write_sig: null rsa.d\n");
    812 			return 0;
    813 		}
    814 		break;
    815 
    816 	case PGP_PKA_DSA:
    817 		if (seckey->key.dsa.x == NULL) {
    818 			(void) fprintf(stderr, "pgp_write_sig: null dsa.x\n");
    819 			return 0;
    820 		}
    821 		break;
    822 
    823 	case PGP_PKA_ECDSA:
    824 		if (seckey->key.ecdsa.x == NULL) {
    825 			(void) fprintf(stderr, "pgp_write_sig: null ecdsa.x\n");
    826 			return 0;
    827 		}
    828 
    829 		break;
    830 
    831 	default:
    832 		(void) fprintf(stderr, "Unsupported algorithm %d\n",
    833 				seckey->pubkey.alg);
    834 		return 0;
    835 	}
    836 
    837 	if (sig->hashlen == (unsigned) -1) {
    838 		(void) fprintf(stderr,
    839 				"ops_write_sig: bad hashed data len\n");
    840 		return 0;
    841 	}
    842 
    843 	pgp_memory_place_int(sig->mem, sig->unhashoff,
    844 			     (unsigned)(len - sig->unhashoff - 2), 2);
    845 
    846 	/* add the packet from version number to end of hashed subpackets */
    847 	if (pgp_get_debug_level(__FILE__)) {
    848 		(void) fprintf(stderr, "ops_write_sig: hashed packet info\n");
    849 	}
    850 	sig->hash.add(&sig->hash, pgp_mem_data(sig->mem), sig->unhashoff);
    851 
    852 	/* add final trailer */
    853 	pgp_hash_add_int(&sig->hash, (unsigned)sig->sig.info.version, 1);
    854 	pgp_hash_add_int(&sig->hash, 0xff, 1);
    855 	/* +6 for version, type, pk alg, hash alg, hashed subpacket length */
    856 	pgp_hash_add_int(&sig->hash, sig->hashlen + 6, 4);
    857 
    858 	if (pgp_get_debug_level(__FILE__)) {
    859 		(void) fprintf(stderr, "ops_write_sig: done writing hashed\n");
    860 	}
    861 	/* XXX: technically, we could figure out how big the signature is */
    862 	/* and write it directly to the output instead of via memory. */
    863 	switch (seckey->pubkey.alg) {
    864 	case PGP_PKA_RSA:
    865 	case PGP_PKA_RSA_ENCRYPT_ONLY:
    866 	case PGP_PKA_RSA_SIGN_ONLY:
    867 		if (!rsa_sign(&sig->hash, &key->key.rsa, &seckey->key.rsa,
    868 				sig->output)) {
    869 			(void) fprintf(stderr,
    870 				"pgp_write_sig: rsa_sign failure\n");
    871 			return 0;
    872 		}
    873 		break;
    874 
    875 	case PGP_PKA_DSA:
    876 		if (!dsa_sign(&sig->hash, &key->key.dsa, &seckey->key.dsa,
    877 				sig->output)) {
    878 			(void) fprintf(stderr,
    879 				"pgp_write_sig: dsa_sign failure\n");
    880 			return 0;
    881 		}
    882 		break;
    883 
    884 	case PGP_PKA_ECDSA:
    885 		if (!ecdsa_sign(&sig->hash, &key->key.ecdsa, &seckey->key.ecdsa,
    886 				sig->output)) {
    887 			(void) fprintf(stderr,
    888 				"pgp_write_sig: ecdsa_sign failure\n");
    889 			return 0;
    890 		}
    891 		break;
    892 
    893 	default:
    894 		(void) fprintf(stderr, "Unsupported algorithm %d\n",
    895 					seckey->pubkey.alg);
    896 		return 0;
    897 	}
    898 
    899 	ret = pgp_write_ptag(output, PGP_PTAG_CT_SIGNATURE);
    900 	if (ret) {
    901 		len = pgp_mem_len(sig->mem);
    902 		ret = pgp_write_length(output, (unsigned)len) &&
    903 			pgp_write(output, pgp_mem_data(sig->mem), (unsigned)len);
    904 	}
    905 	pgp_memory_free(sig->mem);
    906 
    907 	if (ret == 0) {
    908 		PGP_ERROR_1(&output->errors, PGP_E_W, "%s",
    909 		    "Cannot write signature");
    910 	}
    911 	return ret;
    912 }
    913 
    914 /* add a time stamp to the output */
    915 unsigned
    916 pgp_add_time(pgp_create_sig_t *sig, int64_t when, const char *type)
    917 {
    918 	pgp_content_enum	tag;
    919 
    920 	tag = (strcmp(type, "birth") == 0) ?
    921 		PGP_PTAG_SS_CREATION_TIME : PGP_PTAG_SS_EXPIRATION_TIME;
    922 	/* just do 32-bit timestamps for just now - it's in the protocol */
    923 	return pgp_write_ss_header(sig->output, 5, tag) &&
    924 		pgp_write_scalar(sig->output, (uint32_t)when, (unsigned)sizeof(uint32_t));
    925 }
    926 
    927 /**
    928  * \ingroup Core_Signature
    929  *
    930  * Adds issuer's key ID to the signature
    931  *
    932  * \param sig
    933  * \param keyid
    934  */
    935 
    936 unsigned
    937 pgp_add_issuer_keyid(pgp_create_sig_t *sig,
    938 				const uint8_t keyid[PGP_KEY_ID_SIZE])
    939 {
    940 	return pgp_write_ss_header(sig->output, PGP_KEY_ID_SIZE + 1,
    941 				PGP_PTAG_SS_ISSUER_KEY_ID) &&
    942 		pgp_write(sig->output, keyid, PGP_KEY_ID_SIZE);
    943 }
    944 
    945 /**
    946  * \ingroup Core_Signature
    947  *
    948  * Adds primary user ID to the signature
    949  *
    950  * \param sig
    951  * \param primary
    952  */
    953 void
    954 pgp_add_primary_userid(pgp_create_sig_t *sig, unsigned primary)
    955 {
    956 	pgp_write_ss_header(sig->output, 2, PGP_PTAG_SS_PRIMARY_USER_ID);
    957 	pgp_write_scalar(sig->output, primary, 1);
    958 }
    959 
    960 /**
    961  * \ingroup Core_Signature
    962  *
    963  * Get the hash structure in use for the signature.
    964  *
    965  * \param sig The signature structure.
    966  * \return The hash structure.
    967  */
    968 pgp_hash_t     *
    969 pgp_sig_get_hash(pgp_create_sig_t *sig)
    970 {
    971 	return &sig->hash;
    972 }
    973 
    974 /* open up an output file */
    975 static int
    976 open_output_file(pgp_output_t **output,
    977 			const char *inname,
    978 			const char *outname,
    979 			const char *suffix,
    980 			const unsigned overwrite)
    981 {
    982 	int             fd;
    983 
    984 	/* setup output file */
    985 	if (outname) {
    986 		if (strcmp(outname, "-") == 0) {
    987 			fd = pgp_setup_file_write(output, NULL, overwrite);
    988 		} else {
    989 			fd = pgp_setup_file_write(output, outname, overwrite);
    990 		}
    991 	} else {
    992 		size_t          flen = strlen(inname) + 1 + strlen(suffix) + 1;
    993 		char           *f = NULL;
    994 
    995 		if ((f = calloc(1, flen)) == NULL) {
    996 			(void) fprintf(stderr, "open_output_file: bad alloc\n");
    997 			fd = -1;
    998 		} else {
    999 			(void) snprintf(f, flen, "%s.%s", inname, suffix);
   1000 			fd = pgp_setup_file_write(output, f, overwrite);
   1001 			free(f);
   1002 		}
   1003 	}
   1004 	return fd;
   1005 }
   1006 
   1007 /**
   1008 \ingroup HighLevel_Sign
   1009 \brief Sign a file
   1010 \param inname Input filename
   1011 \param outname Output filename. If NULL, a name is constructed from the input filename.
   1012 \param seckey Secret Key to use for signing
   1013 \param armored Write armoured text, if set.
   1014 \param overwrite May overwrite existing file, if set.
   1015 \return 1 if OK; else 0;
   1016 
   1017 */
   1018 unsigned
   1019 pgp_sign_file(pgp_io_t *io,
   1020 		const char *inname,
   1021 		const char *outname,
   1022 		const pgp_seckey_t *seckey,
   1023 		const char *hashname,
   1024 		const int64_t from,
   1025 		const uint64_t duration,
   1026 		const unsigned armored,
   1027 		const unsigned cleartext,
   1028 		const unsigned overwrite)
   1029 {
   1030 	pgp_create_sig_t	*sig;
   1031 	pgp_sig_type_t	 sig_type;
   1032 	pgp_hash_alg_t	 hash_alg;
   1033 	pgp_memory_t		*infile;
   1034 	pgp_output_t		*output;
   1035 	pgp_hash_t		*hash;
   1036 	unsigned		 ret;
   1037 	uint8_t			 keyid[PGP_KEY_ID_SIZE];
   1038 	int			 fd_out;
   1039 
   1040 	sig = NULL;
   1041 	sig_type = PGP_SIG_BINARY;
   1042 	infile = NULL;
   1043 	output = NULL;
   1044 	hash = NULL;
   1045 	fd_out = 0;
   1046 
   1047 	/* find the hash algorithm */
   1048 	switch (seckey->pubkey.alg) {
   1049 		case PGP_PKA_ECDSA:
   1050 			hash_alg = ecdsa_hashalg(&seckey->pubkey.key.ecdsa);
   1051 			break;
   1052 		default:
   1053 			hash_alg = pgp_str_to_hash_alg(hashname);
   1054 	}
   1055 
   1056 	if (hash_alg == PGP_HASH_UNKNOWN) {
   1057 		(void) fprintf(io->errs,
   1058 			"pgp_sign_file: unknown hash algorithm: \"%s\"\n",
   1059 			hashname);
   1060 		return 0;
   1061 	}
   1062 
   1063 	/* read input file into buf */
   1064 	infile = pgp_memory_new();
   1065 	if (!pgp_mem_readfile(infile, inname)) {
   1066 		return 0;
   1067 	}
   1068 
   1069 	/* setup output file */
   1070 	fd_out = open_output_file(&output, inname, outname,
   1071 				(armored) ? "asc" : "gpg", overwrite);
   1072 	if (fd_out < 0) {
   1073 		pgp_memory_free(infile);
   1074 		return 0;
   1075 	}
   1076 
   1077 	/* set up signature */
   1078 	sig = pgp_create_sig_new();
   1079 	if (!sig) {
   1080 		pgp_memory_free(infile);
   1081 		pgp_teardown_file_write(output, fd_out);
   1082 		return 0;
   1083 	}
   1084 
   1085 	pgp_start_sig(sig, seckey, hash_alg, sig_type);
   1086 
   1087 	if (cleartext) {
   1088 		if (pgp_writer_push_clearsigned(output, sig) != 1) {
   1089 			return 0;
   1090 		}
   1091 
   1092 		/* Do the signing */
   1093 		pgp_write(output, pgp_mem_data(infile), (unsigned)pgp_mem_len(infile));
   1094 		pgp_memory_free(infile);
   1095 
   1096 		/* add signature with subpackets: */
   1097 		/* - creation time */
   1098 		/* - key id */
   1099 		ret = pgp_writer_use_armored_sig(output) &&
   1100 				pgp_add_time(sig, (int64_t)from, "birth") &&
   1101 				pgp_add_time(sig, (int64_t)duration, "expiration");
   1102 		if (ret == 0) {
   1103 			pgp_teardown_file_write(output, fd_out);
   1104 			return 0;
   1105 		}
   1106 
   1107 		pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
   1108 		ret = pgp_add_issuer_keyid(sig, keyid) &&
   1109 			pgp_end_hashed_subpkts(sig) &&
   1110 			pgp_write_sig(output, sig, &seckey->pubkey, seckey);
   1111 
   1112 		pgp_teardown_file_write(output, fd_out);
   1113 
   1114 		if (ret == 0) {
   1115 			PGP_ERROR_1(&output->errors, PGP_E_W, "%s",
   1116 			    "Cannot sign file as cleartext");
   1117 		}
   1118 	} else {
   1119 		/* set armoured/not armoured here */
   1120 		if (armored) {
   1121 			pgp_writer_push_armor_msg(output);
   1122 		}
   1123 
   1124 		/* write one_pass_sig */
   1125 		pgp_write_one_pass_sig(output, seckey, hash_alg, sig_type);
   1126 
   1127 		/* hash file contents */
   1128 		hash = pgp_sig_get_hash(sig);
   1129 		hash->add(hash, pgp_mem_data(infile), (unsigned)pgp_mem_len(infile));
   1130 
   1131 #if 1
   1132 		/* output file contents as Literal Data packet */
   1133 		pgp_write_litdata(output, pgp_mem_data(infile),
   1134 			(const int)pgp_mem_len(infile),
   1135 			PGP_LDT_BINARY);
   1136 #else
   1137 		/* XXX - agc - sync with writer.c 1094 for ops_writez */
   1138 		pgp_setup_memory_write(&litoutput, &litmem, bufsz);
   1139 		pgp_setup_memory_write(&zoutput, &zmem, bufsz);
   1140 		pgp_write_litdata(litoutput,
   1141 			pgp_mem_data(pgp_mem_data(infile),
   1142 			(const int)pgp_mem_len(infile), PGP_LDT_BINARY);
   1143 		pgp_writez(zoutput, pgp_mem_data(litmem), pgp_mem_len(litmem));
   1144 #endif
   1145 
   1146 		/* add creation time to signature */
   1147 		pgp_add_time(sig, (int64_t)from, "birth");
   1148 		pgp_add_time(sig, (int64_t)duration, "expiration");
   1149 		/* add key id to signature */
   1150 		pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
   1151 		pgp_add_issuer_keyid(sig, keyid);
   1152 		pgp_end_hashed_subpkts(sig);
   1153 		pgp_write_sig(output, sig, &seckey->pubkey, seckey);
   1154 
   1155 		/* tidy up */
   1156 		pgp_teardown_file_write(output, fd_out);
   1157 
   1158 		pgp_create_sig_delete(sig);
   1159 		pgp_memory_free(infile);
   1160 
   1161 		ret = 1;
   1162 	}
   1163 
   1164 	return ret;
   1165 }
   1166 
   1167 /**
   1168 \ingroup HighLevel_Sign
   1169 \brief Signs a buffer
   1170 \param input Input text to be signed
   1171 \param input_len Length of input text
   1172 \param sig_type Signature type
   1173 \param seckey Secret Key
   1174 \param armored Write armoured text, if set
   1175 \return New pgp_memory_t struct containing signed text
   1176 \note It is the caller's responsibility to call pgp_memory_free(me)
   1177 
   1178 */
   1179 pgp_memory_t *
   1180 pgp_sign_buf(pgp_io_t *io,
   1181 		const void *input,
   1182 		const size_t insize,
   1183 		const pgp_seckey_t *seckey,
   1184 		const int64_t from,
   1185 		const uint64_t duration,
   1186 		const char *hashname,
   1187 		const unsigned armored,
   1188 		const unsigned cleartext)
   1189 {
   1190 	pgp_litdata_enum	 ld_type;
   1191 	pgp_create_sig_t	*sig;
   1192 	pgp_sig_type_t	 sig_type;
   1193 	pgp_hash_alg_t	 hash_alg;
   1194 	pgp_output_t		*output;
   1195 	pgp_memory_t		*mem;
   1196 	uint8_t			 keyid[PGP_KEY_ID_SIZE];
   1197 	pgp_hash_t		*hash;
   1198 	unsigned		 ret;
   1199 
   1200 	sig = NULL;
   1201 	sig_type = PGP_SIG_BINARY;
   1202 	output = NULL;
   1203 	mem = pgp_memory_new();
   1204 	hash = NULL;
   1205 	ret = 0;
   1206 
   1207 	hash_alg = pgp_str_to_hash_alg(hashname);
   1208 	if (hash_alg == PGP_HASH_UNKNOWN) {
   1209 		(void) fprintf(io->errs,
   1210 			"pgp_sign_buf: unknown hash algorithm: \"%s\"\n",
   1211 			hashname);
   1212 		return NULL;
   1213 	}
   1214 
   1215 	/* setup literal data packet type */
   1216 	ld_type = (cleartext) ? PGP_LDT_TEXT : PGP_LDT_BINARY;
   1217 
   1218 	if (input == NULL) {
   1219 		(void) fprintf(io->errs,
   1220 			"pgp_sign_buf: null input\n");
   1221 		return NULL;
   1222 	}
   1223 
   1224 	/* set up signature */
   1225 	if ((sig = pgp_create_sig_new()) == NULL) {
   1226 		return NULL;
   1227 	}
   1228 	pgp_start_sig(sig, seckey, hash_alg, sig_type);
   1229 
   1230 	/* setup writer */
   1231 	pgp_setup_memory_write(&output, &mem, insize);
   1232 
   1233 	if (cleartext) {
   1234 		/* Do the signing */
   1235 		/* add signature with subpackets: */
   1236 		/* - creation time */
   1237 		/* - key id */
   1238 		ret = pgp_writer_push_clearsigned(output, sig) &&
   1239 			pgp_write(output, input, (unsigned)insize) &&
   1240 			pgp_writer_use_armored_sig(output) &&
   1241 			pgp_add_time(sig, from, "birth") &&
   1242 			pgp_add_time(sig, (int64_t)duration, "expiration");
   1243 		if (ret == 0) {
   1244 			return NULL;
   1245 		}
   1246 		pgp_output_delete(output);
   1247 	} else {
   1248 		/* set armoured/not armoured here */
   1249 		if (armored) {
   1250 			pgp_writer_push_armor_msg(output);
   1251 		}
   1252 		if (pgp_get_debug_level(__FILE__)) {
   1253 			fprintf(io->errs, "** Writing out one pass sig\n");
   1254 		}
   1255 		/* write one_pass_sig */
   1256 		pgp_write_one_pass_sig(output, seckey, hash_alg, sig_type);
   1257 
   1258 		/* hash memory */
   1259 		hash = pgp_sig_get_hash(sig);
   1260 		hash->add(hash, input, (unsigned)insize);
   1261 
   1262 		/* output file contents as Literal Data packet */
   1263 		if (pgp_get_debug_level(__FILE__)) {
   1264 			(void) fprintf(stderr, "** Writing out data now\n");
   1265 		}
   1266 		pgp_write_litdata(output, input, (const int)insize, ld_type);
   1267 		if (pgp_get_debug_level(__FILE__)) {
   1268 			fprintf(stderr, "** After Writing out data now\n");
   1269 		}
   1270 
   1271 		/* add creation time to signature */
   1272 		pgp_add_time(sig, from, "birth");
   1273 		pgp_add_time(sig, (int64_t)duration, "expiration");
   1274 		/* add key id to signature */
   1275 		pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg);
   1276 		pgp_add_issuer_keyid(sig, keyid);
   1277 		pgp_end_hashed_subpkts(sig);
   1278 
   1279 		/* write out sig */
   1280 		pgp_write_sig(output, sig, &seckey->pubkey, seckey);
   1281 
   1282 		/* tidy up */
   1283 		pgp_writer_close(output);
   1284 		pgp_create_sig_delete(sig);
   1285 	}
   1286 	return mem;
   1287 }
   1288 
   1289 /* sign a file, and put the signature in a separate file */
   1290 int
   1291 pgp_sign_detached(pgp_io_t *io,
   1292 			const char *f,
   1293 			char *sigfile,
   1294 			pgp_seckey_t *seckey,
   1295 			const char *hash,
   1296 			const int64_t from,
   1297 			const uint64_t duration,
   1298 			const unsigned armored, const unsigned overwrite)
   1299 {
   1300 	pgp_create_sig_t	*sig;
   1301 	pgp_hash_alg_t	 hash_alg;
   1302 	pgp_output_t		*output;
   1303 	pgp_memory_t		*mem;
   1304 	uint8_t	 	 	 keyid[PGP_KEY_ID_SIZE];
   1305 	int			 fd;
   1306 
   1307 	/* find out which hash algorithm to use */
   1308 	hash_alg = pgp_str_to_hash_alg(hash);
   1309 	if (hash_alg == PGP_HASH_UNKNOWN) {
   1310 		(void) fprintf(io->errs,"Unknown hash algorithm: %s\n", hash);
   1311 		return 0;
   1312 	}
   1313 
   1314 	/* setup output file */
   1315 	fd = open_output_file(&output, f, sigfile,
   1316 				(armored) ? "asc" : "sig", overwrite);
   1317 	if (fd < 0) {
   1318 		(void) fprintf(io->errs,"Can't open output file: %s\n", f);
   1319 		return 0;
   1320 	}
   1321 
   1322 	/* create a new signature */
   1323 	sig = pgp_create_sig_new();
   1324 	pgp_start_sig(sig, seckey, hash_alg, PGP_SIG_BINARY);
   1325 
   1326 	/* read the contents of 'f', and add that to the signature */
   1327 	mem = pgp_memory_new();
   1328 	if (!pgp_mem_readfile(mem, f)) {
   1329 		pgp_teardown_file_write(output, fd);
   1330 		return 0;
   1331 	}
   1332 	/* set armoured/not armoured here */
   1333 	if (armored) {
   1334 		pgp_writer_push_armor_msg(output);
   1335 	}
   1336 	pgp_sig_add_data(sig, pgp_mem_data(mem), pgp_mem_len(mem));
   1337 	pgp_memory_free(mem);
   1338 
   1339 	/* calculate the signature */
   1340 	pgp_add_time(sig, from, "birth");
   1341 	pgp_add_time(sig, (int64_t)duration, "expiration");
   1342 	pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg);
   1343 	pgp_add_issuer_keyid(sig, keyid);
   1344 	pgp_end_hashed_subpkts(sig);
   1345 	pgp_write_sig(output, sig, &seckey->pubkey, seckey);
   1346 	pgp_teardown_file_write(output, fd);
   1347 	pgp_seckey_free(seckey);
   1348 
   1349 	return 1;
   1350 }
   1351