xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/signature.c (revision 5c46dd73a9bcb28b2994504ea090f64066b17a77)
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.28 2010/05/25 01:05:11 agc 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 __ops_create_sig_t {
94 	__ops_hash_t		 hash;
95 	__ops_sig_t		 sig;
96 	__ops_memory_t		*mem;
97 	__ops_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 __ops_create_sig_t
106    \return new __ops_create_sig_t
107    \note It is the caller's responsibility to call __ops_create_sig_delete()
108    \sa __ops_create_sig_delete()
109 */
110 __ops_create_sig_t *
111 __ops_create_sig_new(void)
112 {
113 	return calloc(1, sizeof(__ops_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 __ops_create_sig_new()
121 */
122 void
123 __ops_create_sig_delete(__ops_create_sig_t *sig)
124 {
125 	__ops_output_delete(sig->output);
126 	sig->output = NULL;
127 	free(sig);
128 }
129 
130 #if 0
131 void
132 __ops_dump_sig(__ops_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(__ops_hash_t *hash,
157 	const __ops_rsa_pubkey_t *pubrsa,
158 	const __ops_rsa_seckey_t *secrsa,
159 	__ops_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 = OPS_SHA1_HASH_SIZE + sizeof(prefix_sha1);
174 		prefix = prefix_sha1;
175 		prefixsize = sizeof(prefix_sha1);
176 		expected = OPS_SHA1_HASH_SIZE;
177 	} else {
178 		hashsize = OPS_SHA256_HASH_SIZE + sizeof(prefix_sha256);
179 		prefix = prefix_sha256;
180 		prefixsize = sizeof(prefix_sha256);
181 		expected = OPS_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 (__ops_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 	__ops_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 = __ops_rsa_private_encrypt(sigbuf, hashbuf, keysize, secrsa, pubrsa);
219 	bn = BN_bin2bn(sigbuf, (int)t, NULL);
220 	__ops_write_mpi(out, bn);
221 	BN_free(bn);
222 	return 1;
223 }
224 
225 static int
226 dsa_sign(__ops_hash_t *hash,
227 	 const __ops_dsa_pubkey_t *dsa,
228 	 const __ops_dsa_seckey_t *sdsa,
229 	 __ops_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 	__ops_write(output, &hashbuf[0], 2);
250 
251 	/* write signature to buf */
252 	dsasig = __ops_dsa_sign(hashbuf, hashsize, sdsa, dsa);
253 
254 	/* convert and write the sig out to memory */
255 	__ops_write_mpi(output, dsasig->r);
256 	__ops_write_mpi(output, dsasig->s);
257 	DSA_SIG_free(dsasig);
258 	return 1;
259 }
260 
261 static unsigned
262 rsa_verify(__ops_hash_alg_t type,
263 	   const uint8_t *hash,
264 	   size_t hash_length,
265 	   const __ops_rsa_sig_t *sig,
266 	   const __ops_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 = __ops_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 OPS_HASH_MD5:
307 		prefix = prefix_md5;
308 		plen = sizeof(prefix_md5);
309 		break;
310 	case OPS_HASH_SHA1:
311 		prefix = prefix_sha1;
312 		plen = sizeof(prefix_sha1);
313 		break;
314 	case OPS_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 (__ops_get_debug_level(__FILE__)) {
338 		(void) fprintf(stderr, "\nhashbuf_from_sig\n");
339 		hexdump(stderr, hashbuf_from_sig, debug_len_decrypted, " ");
340 		printf("\nprefix\n");
341 		hexdump(stderr, prefix, plen, " ");
342 		(void) fprintf(stderr, "\nhash from sig\n");
343 		hexdump(stderr, &hashbuf_from_sig[n + plen], hash_length, " ");
344 		(void) fprintf(stderr, "\nhash passed in (should match hash from sig)\n");
345 		hexdump(stderr, hash, hash_length, " ");
346 		printf("\n");
347 	}
348 	return (memcmp(&hashbuf_from_sig[n], prefix, plen) == 0 &&
349 	        memcmp(&hashbuf_from_sig[n + plen], hash, hash_length) == 0);
350 }
351 
352 static void
353 hash_add_key(__ops_hash_t *hash, const __ops_pubkey_t *key)
354 {
355 	__ops_memory_t	*mem = __ops_memory_new();
356 	const unsigned 	 dontmakepacket = 0;
357 	size_t		 len;
358 
359 	__ops_build_pubkey(mem, key, dontmakepacket);
360 	len = __ops_mem_len(mem);
361 	__ops_hash_add_int(hash, 0x99, 1);
362 	__ops_hash_add_int(hash, len, 2);
363 	hash->add(hash, __ops_mem_data(mem), len);
364 	__ops_memory_free(mem);
365 }
366 
367 static void
368 initialise_hash(__ops_hash_t *hash, const __ops_sig_t *sig)
369 {
370 	__ops_hash_any(hash, sig->info.hash_alg);
371 	if (!hash->init(hash)) {
372 		(void) fprintf(stderr,
373 			"initialise_hash: bad hash init\n");
374 		/* just continue and die */
375 		/* XXX - agc - no way to return failure */
376 	}
377 }
378 
379 static void
380 init_key_sig(__ops_hash_t *hash, const __ops_sig_t *sig,
381 		   const __ops_pubkey_t *key)
382 {
383 	initialise_hash(hash, sig);
384 	hash_add_key(hash, key);
385 }
386 
387 static void
388 hash_add_trailer(__ops_hash_t *hash, const __ops_sig_t *sig,
389 		 const uint8_t *raw_packet)
390 {
391 	if (sig->info.version == OPS_V4) {
392 		if (raw_packet) {
393 			hash->add(hash, raw_packet + sig->v4_hashstart,
394 				  sig->info.v4_hashlen);
395 		}
396 		__ops_hash_add_int(hash, (unsigned)sig->info.version, 1);
397 		__ops_hash_add_int(hash, 0xff, 1);
398 		__ops_hash_add_int(hash, sig->info.v4_hashlen, 4);
399 	} else {
400 		__ops_hash_add_int(hash, (unsigned)sig->info.type, 1);
401 		__ops_hash_add_int(hash, (unsigned)sig->info.birthtime, 4);
402 	}
403 }
404 
405 /**
406    \ingroup Core_Signature
407    \brief Checks a signature
408    \param hash Signature Hash to be checked
409    \param length Signature Length
410    \param sig The Signature to be checked
411    \param signer The signer's public key
412    \return 1 if good; else 0
413 */
414 unsigned
415 __ops_check_sig(const uint8_t *hash, unsigned length,
416 		    const __ops_sig_t * sig,
417 		    const __ops_pubkey_t * signer)
418 {
419 	unsigned   ret;
420 
421 	if (__ops_get_debug_level(__FILE__)) {
422 		printf("__ops_check_sig: (length %d) hash=", length);
423 		hexdump(stdout, hash, length, "");
424 	}
425 	ret = 0;
426 	switch (sig->info.key_alg) {
427 	case OPS_PKA_DSA:
428 		ret = __ops_dsa_verify(hash, length, &sig->info.sig.dsa,
429 				&signer->key.dsa);
430 		break;
431 
432 	case OPS_PKA_RSA:
433 		ret = rsa_verify(sig->info.hash_alg, hash, length,
434 				&sig->info.sig.rsa,
435 				&signer->key.rsa);
436 		break;
437 
438 	default:
439 		(void) fprintf(stderr, "__ops_check_sig: unusual alg\n");
440 		ret = 0;
441 	}
442 
443 	return ret;
444 }
445 
446 static unsigned
447 hash_and_check_sig(__ops_hash_t *hash,
448 			 const __ops_sig_t *sig,
449 			 const __ops_pubkey_t *signer)
450 {
451 	uint8_t   hashout[OPS_MAX_HASH_SIZE];
452 	unsigned	n;
453 
454 	n = hash->finish(hash, hashout);
455 	return __ops_check_sig(hashout, n, sig, signer);
456 }
457 
458 static unsigned
459 finalise_sig(__ops_hash_t *hash,
460 		   const __ops_sig_t *sig,
461 		   const __ops_pubkey_t *signer,
462 		   const uint8_t *raw_packet)
463 {
464 	hash_add_trailer(hash, sig, raw_packet);
465 	return hash_and_check_sig(hash, sig, signer);
466 }
467 
468 /**
469  * \ingroup Core_Signature
470  *
471  * \brief Verify a certification signature.
472  *
473  * \param key The public key that was signed.
474  * \param id The user ID that was signed
475  * \param sig The signature.
476  * \param signer The public key of the signer.
477  * \param raw_packet The raw signature packet.
478  * \return 1 if OK; else 0
479  */
480 unsigned
481 __ops_check_useridcert_sig(const __ops_pubkey_t *key,
482 			  const uint8_t *id,
483 			  const __ops_sig_t *sig,
484 			  const __ops_pubkey_t *signer,
485 			  const uint8_t *raw_packet)
486 {
487 	__ops_hash_t	hash;
488 	size_t          userid_len;
489 
490 	userid_len = strlen((const char *) id);
491 	init_key_sig(&hash, sig, key);
492 	if (sig->info.version == OPS_V4) {
493 		__ops_hash_add_int(&hash, 0xb4, 1);
494 		__ops_hash_add_int(&hash, userid_len, 4);
495 	}
496 	hash.add(&hash, id, userid_len);
497 	return finalise_sig(&hash, sig, signer, raw_packet);
498 }
499 
500 /**
501  * \ingroup Core_Signature
502  *
503  * Verify a certification signature.
504  *
505  * \param key The public key that was signed.
506  * \param attribute The user attribute that was signed
507  * \param sig The signature.
508  * \param signer The public key of the signer.
509  * \param raw_packet The raw signature packet.
510  * \return 1 if OK; else 0
511  */
512 unsigned
513 __ops_check_userattrcert_sig(const __ops_pubkey_t *key,
514 				const __ops_data_t *attribute,
515 				const __ops_sig_t *sig,
516 				const __ops_pubkey_t *signer,
517 				const uint8_t *raw_packet)
518 {
519 	__ops_hash_t      hash;
520 
521 	init_key_sig(&hash, sig, key);
522 	if (sig->info.version == OPS_V4) {
523 		__ops_hash_add_int(&hash, 0xd1, 1);
524 		__ops_hash_add_int(&hash, attribute->len, 4);
525 	}
526 	hash.add(&hash, attribute->contents, attribute->len);
527 	return finalise_sig(&hash, sig, signer, raw_packet);
528 }
529 
530 /**
531  * \ingroup Core_Signature
532  *
533  * Verify a subkey signature.
534  *
535  * \param key The public key whose subkey was signed.
536  * \param subkey The subkey of the public key that was signed.
537  * \param sig The signature.
538  * \param signer The public key of the signer.
539  * \param raw_packet The raw signature packet.
540  * \return 1 if OK; else 0
541  */
542 unsigned
543 __ops_check_subkey_sig(const __ops_pubkey_t *key,
544 			   const __ops_pubkey_t *subkey,
545 			   const __ops_sig_t *sig,
546 			   const __ops_pubkey_t *signer,
547 			   const uint8_t *raw_packet)
548 {
549 	__ops_hash_t	hash;
550 	unsigned	ret;
551 
552 	init_key_sig(&hash, sig, key);
553 	hash_add_key(&hash, subkey);
554 	ret = finalise_sig(&hash, sig, signer, raw_packet);
555 	return ret;
556 }
557 
558 /**
559  * \ingroup Core_Signature
560  *
561  * Verify a direct signature.
562  *
563  * \param key The public key which 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 __ops_check_direct_sig(const __ops_pubkey_t *key,
571 			   const __ops_sig_t *sig,
572 			   const __ops_pubkey_t *signer,
573 			   const uint8_t *raw_packet)
574 {
575 	__ops_hash_t	hash;
576 	unsigned	ret;
577 
578 	init_key_sig(&hash, sig, key);
579 	ret = finalise_sig(&hash, sig, signer, raw_packet);
580 	return ret;
581 }
582 
583 /**
584  * \ingroup Core_Signature
585  *
586  * Verify a signature on a hash (the hash will have already been fed
587  * the material that was being signed, for example signed cleartext).
588  *
589  * \param hash A hash structure of appropriate type that has been fed
590  * the material to be signed. This MUST NOT have been finalised.
591  * \param sig The signature to be verified.
592  * \param signer The public key of the signer.
593  * \return 1 if OK; else 0
594  */
595 unsigned
596 __ops_check_hash_sig(__ops_hash_t *hash,
597 			 const __ops_sig_t *sig,
598 			 const __ops_pubkey_t *signer)
599 {
600 	return (sig->info.hash_alg == hash->alg) ?
601 		finalise_sig(hash, sig, signer, NULL) :
602 		0;
603 }
604 
605 static void
606 start_sig_in_mem(__ops_create_sig_t *sig)
607 {
608 	/* since this has subpackets and stuff, we have to buffer the whole */
609 	/* thing to get counts before writing. */
610 	sig->mem = __ops_memory_new();
611 	__ops_memory_init(sig->mem, 100);
612 	__ops_writer_set_memory(sig->output, sig->mem);
613 
614 	/* write nearly up to the first subpacket */
615 	__ops_write_scalar(sig->output, (unsigned)sig->sig.info.version, 1);
616 	__ops_write_scalar(sig->output, (unsigned)sig->sig.info.type, 1);
617 	__ops_write_scalar(sig->output, (unsigned)sig->sig.info.key_alg, 1);
618 	__ops_write_scalar(sig->output, (unsigned)sig->sig.info.hash_alg, 1);
619 
620 	/* dummy hashed subpacket count */
621 	sig->hashoff = __ops_mem_len(sig->mem);
622 	__ops_write_scalar(sig->output, 0, 2);
623 }
624 
625 /**
626  * \ingroup Core_Signature
627  *
628  * __ops_sig_start() creates a V4 public key signature with a SHA1 hash.
629  *
630  * \param sig The signature structure to initialise
631  * \param key The public key to be signed
632  * \param id The user ID being bound to the key
633  * \param type Signature type
634  */
635 void
636 __ops_sig_start_key_sig(__ops_create_sig_t *sig,
637 				  const __ops_pubkey_t *key,
638 				  const uint8_t *id,
639 				  __ops_sig_type_t type)
640 {
641 	sig->output = __ops_output_new();
642 
643 	/* XXX:  refactor with check (in several ways - check should
644 	 * probably use the buffered writer to construct packets
645 	 * (done), and also should share code for hash calculation) */
646 	sig->sig.info.version = OPS_V4;
647 	sig->sig.info.hash_alg = OPS_HASH_SHA1;
648 	sig->sig.info.key_alg = key->alg;
649 	sig->sig.info.type = type;
650 	sig->hashlen = (unsigned)-1;
651 	init_key_sig(&sig->hash, &sig->sig, key);
652 	__ops_hash_add_int(&sig->hash, 0xb4, 1);
653 	__ops_hash_add_int(&sig->hash, strlen((const char *) id), 4);
654 	sig->hash.add(&sig->hash, id, strlen((const char *) id));
655 	start_sig_in_mem(sig);
656 }
657 
658 /**
659  * \ingroup Core_Signature
660  *
661  * Create a V4 public key signature over some cleartext.
662  *
663  * \param sig The signature structure to initialise
664  * \param id
665  * \param type
666  * \todo Expand description. Allow other hashes.
667  */
668 
669 void
670 __ops_start_sig(__ops_create_sig_t *sig,
671 	      const __ops_seckey_t *key,
672 	      const __ops_hash_alg_t hash,
673 	      const __ops_sig_type_t type)
674 {
675 	sig->output = __ops_output_new();
676 
677 	/* XXX:  refactor with check (in several ways - check should
678 	 * probably use the buffered writer to construct packets
679 	 * (done), and also should share code for hash calculation) */
680 	sig->sig.info.version = OPS_V4;
681 	sig->sig.info.key_alg = key->pubkey.alg;
682 	sig->sig.info.hash_alg = hash;
683 	sig->sig.info.type = type;
684 
685 	sig->hashlen = (unsigned)-1;
686 
687 	if (__ops_get_debug_level(__FILE__)) {
688 		fprintf(stderr, "initialising hash for sig in mem\n");
689 	}
690 	initialise_hash(&sig->hash, &sig->sig);
691 	start_sig_in_mem(sig);
692 }
693 
694 /**
695  * \ingroup Core_Signature
696  *
697  * Add plaintext data to a signature-to-be.
698  *
699  * \param sig The signature-to-be.
700  * \param buf The plaintext data.
701  * \param length The amount of plaintext data.
702  */
703 void
704 __ops_sig_add_data(__ops_create_sig_t *sig, const void *buf, size_t length)
705 {
706 	sig->hash.add(&sig->hash, buf, length);
707 }
708 
709 /**
710  * \ingroup Core_Signature
711  *
712  * Mark the end of the hashed subpackets in the signature
713  *
714  * \param sig
715  */
716 
717 unsigned
718 __ops_end_hashed_subpkts(__ops_create_sig_t *sig)
719 {
720 	sig->hashlen = __ops_mem_len(sig->mem) - sig->hashoff - 2;
721 	__ops_memory_place_int(sig->mem, sig->hashoff, sig->hashlen, 2);
722 	/* dummy unhashed subpacket count */
723 	sig->unhashoff = __ops_mem_len(sig->mem);
724 	return __ops_write_scalar(sig->output, 0, 2);
725 }
726 
727 /**
728  * \ingroup Core_Signature
729  *
730  * Write out a signature
731  *
732  * \param sig
733  * \param key
734  * \param seckey
735  * \param info
736  *
737  */
738 
739 unsigned
740 __ops_write_sig(__ops_output_t *output,
741 			__ops_create_sig_t *sig,
742 			const __ops_pubkey_t *key,
743 			const __ops_seckey_t *seckey)
744 {
745 	unsigned	ret = 0;
746 	size_t		len = __ops_mem_len(sig->mem);
747 
748 	/* check key not decrypted */
749 	switch (seckey->pubkey.alg) {
750 	case OPS_PKA_RSA:
751 	case OPS_PKA_RSA_ENCRYPT_ONLY:
752 	case OPS_PKA_RSA_SIGN_ONLY:
753 		if (seckey->key.rsa.d == NULL) {
754 			(void) fprintf(stderr, "__ops_write_sig: null rsa.d\n");
755 			return 0;
756 		}
757 		break;
758 
759 	case OPS_PKA_DSA:
760 		if (seckey->key.dsa.x == NULL) {
761 			(void) fprintf(stderr, "__ops_write_sig: null dsa.x\n");
762 			return 0;
763 		}
764 		break;
765 
766 	default:
767 		(void) fprintf(stderr, "Unsupported algorithm %d\n",
768 				seckey->pubkey.alg);
769 		return 0;
770 	}
771 
772 	if (sig->hashlen == (unsigned) -1) {
773 		(void) fprintf(stderr,
774 				"ops_write_sig: bad hashed data len\n");
775 		return 0;
776 	}
777 
778 	__ops_memory_place_int(sig->mem, sig->unhashoff,
779 			     len - sig->unhashoff - 2, 2);
780 
781 	/* add the packet from version number to end of hashed subpackets */
782 	if (__ops_get_debug_level(__FILE__)) {
783 		(void) fprintf(stderr, "ops_write_sig: hashed packet info\n");
784 	}
785 	sig->hash.add(&sig->hash, __ops_mem_data(sig->mem), sig->unhashoff);
786 
787 	/* add final trailer */
788 	__ops_hash_add_int(&sig->hash, (unsigned)sig->sig.info.version, 1);
789 	__ops_hash_add_int(&sig->hash, 0xff, 1);
790 	/* +6 for version, type, pk alg, hash alg, hashed subpacket length */
791 	__ops_hash_add_int(&sig->hash, sig->hashlen + 6, 4);
792 
793 	if (__ops_get_debug_level(__FILE__)) {
794 		(void) fprintf(stderr, "ops_write_sig: done writing hashed\n");
795 	}
796 	/* XXX: technically, we could figure out how big the signature is */
797 	/* and write it directly to the output instead of via memory. */
798 	switch (seckey->pubkey.alg) {
799 	case OPS_PKA_RSA:
800 	case OPS_PKA_RSA_ENCRYPT_ONLY:
801 	case OPS_PKA_RSA_SIGN_ONLY:
802 		if (!rsa_sign(&sig->hash, &key->key.rsa, &seckey->key.rsa,
803 				sig->output)) {
804 			(void) fprintf(stderr,
805 				"__ops_write_sig: rsa_sign failure\n");
806 			return 0;
807 		}
808 		break;
809 
810 	case OPS_PKA_DSA:
811 		if (!dsa_sign(&sig->hash, &key->key.dsa, &seckey->key.dsa,
812 				sig->output)) {
813 			(void) fprintf(stderr,
814 				"__ops_write_sig: dsa_sign failure\n");
815 			return 0;
816 		}
817 		break;
818 
819 	default:
820 		(void) fprintf(stderr, "Unsupported algorithm %d\n",
821 					seckey->pubkey.alg);
822 		return 0;
823 	}
824 
825 	ret = __ops_write_ptag(output, OPS_PTAG_CT_SIGNATURE);
826 	if (ret) {
827 		len = __ops_mem_len(sig->mem);
828 		ret = __ops_write_length(output, len) &&
829 			__ops_write(output, __ops_mem_data(sig->mem), len);
830 	}
831 	__ops_memory_free(sig->mem);
832 
833 	if (ret == 0) {
834 		OPS_ERROR(&output->errors, OPS_E_W, "Cannot write signature");
835 	}
836 	return ret;
837 }
838 
839 /**
840  * \ingroup Core_Signature
841  *
842  * __ops_add_birthtime() adds a creation time to the signature.
843  *
844  * \param sig
845  * \param when
846  */
847 unsigned
848 __ops_add_birthtime(__ops_create_sig_t *sig, time_t when)
849 {
850 	return __ops_write_ss_header(sig->output, 5,
851 					OPS_PTAG_SS_CREATION_TIME) &&
852 		__ops_write_scalar(sig->output, (unsigned)when, 4);
853 }
854 
855 /**
856  * __ops_add_expiry() adds an expiration amount (duration) to the signature.
857  *
858  */
859 unsigned
860 __ops_add_expiration(__ops_create_sig_t *sig, time_t duration)
861 {
862 	uint32_t	d;
863 
864 	d = (uint32_t)duration;
865 	return __ops_write_ss_header(sig->output, 5,
866 					OPS_PTAG_SS_EXPIRATION_TIME) &&
867 		__ops_write_scalar(sig->output, (unsigned)d, 4);
868 }
869 
870 /**
871  * \ingroup Core_Signature
872  *
873  * Adds issuer's key ID to the signature
874  *
875  * \param sig
876  * \param keyid
877  */
878 
879 unsigned
880 __ops_add_issuer_keyid(__ops_create_sig_t *sig,
881 				const uint8_t keyid[OPS_KEY_ID_SIZE])
882 {
883 	return __ops_write_ss_header(sig->output, OPS_KEY_ID_SIZE + 1,
884 				OPS_PTAG_SS_ISSUER_KEY_ID) &&
885 		__ops_write(sig->output, keyid, OPS_KEY_ID_SIZE);
886 }
887 
888 /**
889  * \ingroup Core_Signature
890  *
891  * Adds primary user ID to the signature
892  *
893  * \param sig
894  * \param primary
895  */
896 void
897 __ops_add_primary_userid(__ops_create_sig_t *sig, unsigned primary)
898 {
899 	__ops_write_ss_header(sig->output, 2, OPS_PTAG_SS_PRIMARY_USER_ID);
900 	__ops_write_scalar(sig->output, primary, 1);
901 }
902 
903 /**
904  * \ingroup Core_Signature
905  *
906  * Get the hash structure in use for the signature.
907  *
908  * \param sig The signature structure.
909  * \return The hash structure.
910  */
911 __ops_hash_t     *
912 __ops_sig_get_hash(__ops_create_sig_t *sig)
913 {
914 	return &sig->hash;
915 }
916 
917 /* open up an output file */
918 static int
919 open_output_file(__ops_output_t **output,
920 			const char *inname,
921 			const char *outname,
922 			const char *suffix,
923 			const unsigned overwrite)
924 {
925 	int             fd;
926 
927 	/* setup output file */
928 	if (outname) {
929 		fd = __ops_setup_file_write(output, outname, overwrite);
930 	} else {
931 		unsigned        flen = strlen(inname) + 4 + 1;
932 		char           *f = NULL;
933 
934 		if ((f = calloc(1, flen)) == NULL) {
935 			(void) fprintf(stderr, "open_output_file: bad alloc\n");
936 			fd = -1;
937 		} else {
938 			(void) snprintf(f, flen, "%s.%s", inname, suffix);
939 			fd = __ops_setup_file_write(output, f, overwrite);
940 			free(f);
941 		}
942 	}
943 	return fd;
944 }
945 
946 /**
947 \ingroup HighLevel_Sign
948 \brief Sign a file
949 \param inname Input filename
950 \param outname Output filename. If NULL, a name is constructed from the input filename.
951 \param seckey Secret Key to use for signing
952 \param armored Write armoured text, if set.
953 \param overwrite May overwrite existing file, if set.
954 \return 1 if OK; else 0;
955 
956 */
957 unsigned
958 __ops_sign_file(__ops_io_t *io,
959 		const char *inname,
960 		const char *outname,
961 		const __ops_seckey_t *seckey,
962 		const char *hashname,
963 		const int64_t from,
964 		const uint64_t duration,
965 		const unsigned armored,
966 		const unsigned cleartext,
967 		const unsigned overwrite)
968 {
969 	__ops_create_sig_t	*sig;
970 	__ops_sig_type_t	 sig_type;
971 	__ops_hash_alg_t	 hash_alg;
972 	__ops_memory_t		*infile;
973 	__ops_output_t		*output;
974 	__ops_hash_t		*hash;
975 	unsigned		 ret;
976 	uint8_t			 keyid[OPS_KEY_ID_SIZE];
977 	int			 fd_out;
978 
979 	sig = NULL;
980 	sig_type = OPS_SIG_BINARY;
981 	infile = NULL;
982 	output = NULL;
983 	hash = NULL;
984 	fd_out = 0;
985 
986 	/* find the hash algorithm */
987 	hash_alg = __ops_str_to_hash_alg(hashname);
988 	if (hash_alg == OPS_HASH_UNKNOWN) {
989 		(void) fprintf(io->errs,
990 			"__ops_sign_file: unknown hash algorithm: \"%s\"\n",
991 			hashname);
992 		return 0;
993 	}
994 
995 	/* read input file into buf */
996 	infile = __ops_memory_new();
997 	if (!__ops_mem_readfile(infile, inname)) {
998 		return 0;
999 	}
1000 
1001 	/* setup output file */
1002 	fd_out = open_output_file(&output, inname, outname,
1003 				(armored) ? "asc" : "gpg", overwrite);
1004 	if (fd_out < 0) {
1005 		__ops_memory_free(infile);
1006 		return 0;
1007 	}
1008 
1009 	/* set up signature */
1010 	sig = __ops_create_sig_new();
1011 	if (!sig) {
1012 		__ops_memory_free(infile);
1013 		__ops_teardown_file_write(output, fd_out);
1014 		return 0;
1015 	}
1016 
1017 	__ops_start_sig(sig, seckey, hash_alg, sig_type);
1018 
1019 	if (cleartext) {
1020 		if (__ops_writer_push_clearsigned(output, sig) != 1) {
1021 			return 0;
1022 		}
1023 
1024 		/* Do the signing */
1025 		__ops_write(output, __ops_mem_data(infile), __ops_mem_len(infile));
1026 		__ops_memory_free(infile);
1027 
1028 		/* add signature with subpackets: */
1029 		/* - creation time */
1030 		/* - key id */
1031 		ret = __ops_writer_use_armored_sig(output) &&
1032 				__ops_add_birthtime(sig, (long long)from) &&
1033 				__ops_add_expiration(sig, (long long)duration);
1034 		if (ret == 0) {
1035 			__ops_teardown_file_write(output, fd_out);
1036 			return 0;
1037 		}
1038 
1039 		__ops_keyid(keyid, OPS_KEY_ID_SIZE, &seckey->pubkey);
1040 		ret = __ops_add_issuer_keyid(sig, keyid) &&
1041 			__ops_end_hashed_subpkts(sig) &&
1042 			__ops_write_sig(output, sig, &seckey->pubkey, seckey);
1043 
1044 		__ops_teardown_file_write(output, fd_out);
1045 
1046 		if (ret == 0) {
1047 			OPS_ERROR(&output->errors, OPS_E_W,
1048 					"Cannot sign file as cleartext");
1049 		}
1050 	} else {
1051 		/* set armoured/not armoured here */
1052 		if (armored) {
1053 			__ops_writer_push_armor_msg(output);
1054 		}
1055 
1056 		/* write one_pass_sig */
1057 		__ops_write_one_pass_sig(output, seckey, hash_alg, sig_type);
1058 
1059 		/* hash file contents */
1060 		hash = __ops_sig_get_hash(sig);
1061 		hash->add(hash, __ops_mem_data(infile), __ops_mem_len(infile));
1062 
1063 #if 1
1064 		/* output file contents as Literal Data packet */
1065 		__ops_write_litdata(output, __ops_mem_data(infile),
1066 			(const int)__ops_mem_len(infile),
1067 			OPS_LDT_BINARY);
1068 #else
1069 		/* XXX - agc - sync with writer.c 1094 for ops_writez */
1070 		__ops_setup_memory_write(&litoutput, &litmem, bufsz);
1071 		__ops_setup_memory_write(&zoutput, &zmem, bufsz);
1072 		__ops_write_litdata(litoutput,
1073 			__ops_mem_data(__ops_mem_data(infile),
1074 			(const int)__ops_mem_len(infile), OPS_LDT_BINARY);
1075 		__ops_writez(zoutput, __ops_mem_data(litmem), __ops_mem_len(litmem));
1076 #endif
1077 
1078 		/* add creation time to signature */
1079 		__ops_add_birthtime(sig, (long long)from);
1080 		__ops_add_expiration(sig, (long long)duration);
1081 		/* add key id to signature */
1082 		__ops_keyid(keyid, OPS_KEY_ID_SIZE, &seckey->pubkey);
1083 		__ops_add_issuer_keyid(sig, keyid);
1084 		__ops_end_hashed_subpkts(sig);
1085 		__ops_write_sig(output, sig, &seckey->pubkey, seckey);
1086 
1087 		/* tidy up */
1088 		__ops_teardown_file_write(output, fd_out);
1089 
1090 		__ops_create_sig_delete(sig);
1091 		__ops_memory_free(infile);
1092 
1093 		ret = 1;
1094 	}
1095 
1096 	return ret;
1097 }
1098 
1099 /**
1100 \ingroup HighLevel_Sign
1101 \brief Signs a buffer
1102 \param input Input text to be signed
1103 \param input_len Length of input text
1104 \param sig_type Signature type
1105 \param seckey Secret Key
1106 \param armored Write armoured text, if set
1107 \return New __ops_memory_t struct containing signed text
1108 \note It is the caller's responsibility to call __ops_memory_free(me)
1109 
1110 */
1111 __ops_memory_t *
1112 __ops_sign_buf(__ops_io_t *io,
1113 		const void *input,
1114 		const size_t insize,
1115 		const __ops_seckey_t *seckey,
1116 		const int64_t from,
1117 		const uint64_t duration,
1118 		const char *hashname,
1119 		const unsigned armored,
1120 		const unsigned cleartext)
1121 {
1122 	__ops_litdata_enum	 ld_type;
1123 	__ops_create_sig_t	*sig;
1124 	__ops_sig_type_t	 sig_type;
1125 	__ops_hash_alg_t	 hash_alg;
1126 	__ops_output_t		*output;
1127 	__ops_memory_t		*mem;
1128 	uint8_t			 keyid[OPS_KEY_ID_SIZE];
1129 	__ops_hash_t		*hash;
1130 	unsigned		 ret;
1131 
1132 	sig = NULL;
1133 	sig_type = OPS_SIG_BINARY;
1134 	output = NULL;
1135 	mem = __ops_memory_new();
1136 	hash = NULL;
1137 	ret = 0;
1138 
1139 	hash_alg = __ops_str_to_hash_alg(hashname);
1140 	if (hash_alg == OPS_HASH_UNKNOWN) {
1141 		(void) fprintf(io->errs,
1142 			"__ops_sign_buf: unknown hash algorithm: \"%s\"\n",
1143 			hashname);
1144 		return NULL;
1145 	}
1146 
1147 	/* setup literal data packet type */
1148 	ld_type = (cleartext) ? OPS_LDT_TEXT : OPS_LDT_BINARY;
1149 
1150 	if (input == NULL) {
1151 		(void) fprintf(io->errs,
1152 			"__ops_sign_buf: null input\n");
1153 		return NULL;
1154 	}
1155 
1156 	/* set up signature */
1157 	if ((sig = __ops_create_sig_new()) == NULL) {
1158 		return NULL;
1159 	}
1160 	__ops_start_sig(sig, seckey, hash_alg, sig_type);
1161 
1162 	/* setup writer */
1163 	__ops_setup_memory_write(&output, &mem, insize);
1164 
1165 	if (cleartext) {
1166 		/* Do the signing */
1167 		/* add signature with subpackets: */
1168 		/* - creation time */
1169 		/* - key id */
1170 		ret = __ops_writer_push_clearsigned(output, sig) &&
1171 			__ops_write(output, input, insize) &&
1172 			__ops_writer_use_armored_sig(output) &&
1173 			__ops_add_birthtime(sig, from) &&
1174 			__ops_add_expiration(sig, (long long)duration);
1175 		if (ret == 0) {
1176 			return NULL;
1177 		}
1178 		__ops_output_delete(output);
1179 	} else {
1180 		/* set armoured/not armoured here */
1181 		if (armored) {
1182 			__ops_writer_push_armor_msg(output);
1183 		}
1184 		if (__ops_get_debug_level(__FILE__)) {
1185 			fprintf(io->errs, "** Writing out one pass sig\n");
1186 		}
1187 		/* write one_pass_sig */
1188 		__ops_write_one_pass_sig(output, seckey, hash_alg, sig_type);
1189 
1190 		/* hash memory */
1191 		hash = __ops_sig_get_hash(sig);
1192 		hash->add(hash, input, insize);
1193 
1194 		/* output file contents as Literal Data packet */
1195 		if (__ops_get_debug_level(__FILE__)) {
1196 			(void) fprintf(stderr, "** Writing out data now\n");
1197 		}
1198 		__ops_write_litdata(output, input, (const int)insize, ld_type);
1199 		if (__ops_get_debug_level(__FILE__)) {
1200 			fprintf(stderr, "** After Writing out data now\n");
1201 		}
1202 
1203 		/* add creation time to signature */
1204 		__ops_add_birthtime(sig, from);
1205 		__ops_add_expiration(sig, (long long)duration);
1206 		/* add key id to signature */
1207 		__ops_keyid(keyid, OPS_KEY_ID_SIZE, &seckey->pubkey);
1208 		__ops_add_issuer_keyid(sig, keyid);
1209 		__ops_end_hashed_subpkts(sig);
1210 
1211 		/* write out sig */
1212 		__ops_write_sig(output, sig, &seckey->pubkey, seckey);
1213 
1214 		/* tidy up */
1215 		__ops_writer_close(output);
1216 		__ops_create_sig_delete(sig);
1217 	}
1218 	return mem;
1219 }
1220 
1221 /* sign a file, and put the signature in a separate file */
1222 int
1223 __ops_sign_detached(__ops_io_t *io,
1224 			const char *f,
1225 			char *sigfile,
1226 			__ops_seckey_t *seckey,
1227 			const char *hash,
1228 			const int64_t from,
1229 			const uint64_t duration,
1230 			const unsigned armored, const unsigned overwrite)
1231 {
1232 	__ops_create_sig_t	*sig;
1233 	__ops_hash_alg_t	 alg;
1234 	__ops_output_t		*output;
1235 	__ops_memory_t		*mem;
1236 	uint8_t	 	 	 keyid[OPS_KEY_ID_SIZE];
1237 	int			 fd;
1238 
1239 	/* find out which hash algorithm to use */
1240 	alg = __ops_str_to_hash_alg(hash);
1241 	if (alg == OPS_HASH_UNKNOWN) {
1242 		(void) fprintf(io->errs,"Unknown hash algorithm: %s\n", hash);
1243 		return 0;
1244 	}
1245 
1246 	/* setup output file */
1247 	fd = open_output_file(&output, f, sigfile,
1248 				(armored) ? "asc" : "sig", overwrite);
1249 	if (fd < 0) {
1250 		(void) fprintf(io->errs,"Can't open output file: %s\n", f);
1251 		return 0;
1252 	}
1253 
1254 	/* create a new signature */
1255 	sig = __ops_create_sig_new();
1256 	__ops_start_sig(sig, seckey, alg, OPS_SIG_BINARY);
1257 
1258 	/* read the contents of 'f', and add that to the signature */
1259 	mem = __ops_memory_new();
1260 	if (!__ops_mem_readfile(mem, f)) {
1261 		__ops_teardown_file_write(output, fd);
1262 		return 0;
1263 	}
1264 	/* set armoured/not armoured here */
1265 	if (armored) {
1266 		__ops_writer_push_armor_msg(output);
1267 	}
1268 	__ops_sig_add_data(sig, __ops_mem_data(mem), __ops_mem_len(mem));
1269 	__ops_memory_free(mem);
1270 
1271 	/* calculate the signature */
1272 	__ops_add_birthtime(sig, from);
1273 	__ops_add_expiration(sig, (long long)duration);
1274 	__ops_keyid(keyid, sizeof(keyid), &seckey->pubkey);
1275 	__ops_add_issuer_keyid(sig, keyid);
1276 	__ops_end_hashed_subpkts(sig);
1277 	__ops_write_sig(output, sig, &seckey->pubkey, seckey);
1278 	__ops_teardown_file_write(output, fd);
1279 	__ops_seckey_free(seckey);
1280 
1281 	return 1;
1282 }
1283