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