xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/signature.c (revision 0294a66b694d2a57b43f64b66c7a4aee89316c4e)
1 /*-
2  * Copyright (c) 2009 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Alistair Crooks (agc@NetBSD.org)
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 /*
30  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31  * All rights reserved.
32  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33  * their moral rights under the UK Copyright Design and Patents Act 1988 to
34  * be recorded as the authors of this copyright work.
35  *
36  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37  * use this file except in compliance with the License.
38  *
39  * You may obtain a copy of the License at
40  *     http://www.apache.org/licenses/LICENSE-2.0
41  *
42  * Unless required by applicable law or agreed to in writing, software
43  * distributed under the License is distributed on an "AS IS" BASIS,
44  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45  *
46  * See the License for the specific language governing permissions and
47  * limitations under the License.
48  */
49 
50 /** \file
51  */
52 #include "config.h"
53 
54 #ifdef HAVE_SYS_CDEFS_H
55 #include <sys/cdefs.h>
56 #endif
57 
58 #if defined(__NetBSD__)
59 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60 __RCSID("$NetBSD: 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 *
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 	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
ecdsa_sign(pgp_hash_t * hash,const pgp_ecdsa_pubkey_t * ecdsa,const pgp_ecdsa_seckey_t * secdsa,pgp_output_t * output)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
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)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
hash_add_key(pgp_hash_t * hash,const pgp_pubkey_t * key)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
initialise_hash(pgp_hash_t * hash,const pgp_sig_t * sig)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
init_key_sig(pgp_hash_t * hash,const pgp_sig_t * sig,const pgp_pubkey_t * key)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
hash_add_trailer(pgp_hash_t * hash,const pgp_sig_t * sig,const uint8_t * raw_packet)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
pgp_check_sig(const uint8_t * hash,unsigned length,const pgp_sig_t * sig,const pgp_pubkey_t * signer)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
hash_and_check_sig(pgp_hash_t * hash,const pgp_sig_t * sig,const pgp_pubkey_t * signer)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
finalise_sig(pgp_hash_t * hash,const pgp_sig_t * sig,const pgp_pubkey_t * signer,const uint8_t * raw_packet)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
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)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
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)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
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)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
pgp_check_direct_sig(const pgp_pubkey_t * key,const pgp_sig_t * sig,const pgp_pubkey_t * signer,const uint8_t * raw_packet)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
pgp_check_hash_sig(pgp_hash_t * hash,const pgp_sig_t * sig,const pgp_pubkey_t * signer)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
start_sig_in_mem(pgp_create_sig_t * sig)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
pgp_sig_start_key_sig(pgp_create_sig_t * sig,const pgp_pubkey_t * key,const uint8_t * id,pgp_sig_type_t type)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
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)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
pgp_sig_add_data(pgp_create_sig_t * sig,const void * buf,size_t length)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
pgp_end_hashed_subpkts(pgp_create_sig_t * sig)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
pgp_write_sig(pgp_output_t * output,pgp_create_sig_t * sig,const pgp_pubkey_t * key,const pgp_seckey_t * seckey)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
pgp_add_time(pgp_create_sig_t * sig,int64_t when,const char * type)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
pgp_add_issuer_keyid(pgp_create_sig_t * sig,const uint8_t keyid[PGP_KEY_ID_SIZE])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
pgp_add_primary_userid(pgp_create_sig_t * sig,unsigned primary)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     *
pgp_sig_get_hash(pgp_create_sig_t * sig)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
open_output_file(pgp_output_t ** output,const char * inname,const char * outname,const char * suffix,const unsigned overwrite)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
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)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