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