xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/signature.c (revision 4e6df137e8e14049b5a701d249962c480449c141)
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.26 2010/03/05 16:01:10 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 		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 uint8_t *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 uint8_t *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 	uint8_t   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 uint8_t *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 uint8_t *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 uint8_t *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 uint8_t *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 uint8_t *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 uint8_t 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 	uint8_t		 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 #if 1
1087 		/* output file contents as Literal Data packet */
1088 		__ops_write_litdata(output, __ops_mem_data(infile),
1089 			(const int)__ops_mem_len(infile),
1090 			OPS_LDT_BINARY);
1091 #else
1092 		/* XXX - agc - sync with writer.c 1094 for ops_writez */
1093 		__ops_setup_memory_write(&litoutput, &litmem, bufsz);
1094 		__ops_setup_memory_write(&zoutput, &zmem, bufsz);
1095 		__ops_write_litdata(litoutput,
1096 			__ops_mem_data(__ops_mem_data(infile),
1097 			(const int)__ops_mem_len(infile), OPS_LDT_BINARY);
1098 		__ops_writez(zoutput, __ops_mem_data(litmem), __ops_mem_len(litmem));
1099 #endif
1100 
1101 		/* add creation time to signature */
1102 		__ops_add_birthtime(sig, (long long)from);
1103 		__ops_add_expiration(sig, (long long)duration);
1104 		/* add key id to signature */
1105 		__ops_keyid(keyid, OPS_KEY_ID_SIZE, &seckey->pubkey);
1106 		__ops_add_issuer_keyid(sig, keyid);
1107 		__ops_end_hashed_subpkts(sig);
1108 		__ops_write_sig(output, sig, &seckey->pubkey, seckey);
1109 
1110 		/* tidy up */
1111 		__ops_teardown_file_write(output, fd_out);
1112 
1113 		__ops_create_sig_delete(sig);
1114 		__ops_memory_free(infile);
1115 
1116 		ret = 1;
1117 	}
1118 
1119 	return ret;
1120 }
1121 
1122 /**
1123 \ingroup HighLevel_Sign
1124 \brief Signs a buffer
1125 \param input Input text to be signed
1126 \param input_len Length of input text
1127 \param sig_type Signature type
1128 \param seckey Secret Key
1129 \param armored Write armoured text, if set
1130 \return New __ops_memory_t struct containing signed text
1131 \note It is the caller's responsibility to call __ops_memory_free(me)
1132 
1133 */
1134 __ops_memory_t *
1135 __ops_sign_buf(__ops_io_t *io,
1136 		const void *input,
1137 		const size_t insize,
1138 		const __ops_seckey_t *seckey,
1139 		const int64_t from,
1140 		const uint64_t duration,
1141 		const char *hashname,
1142 		const unsigned armored,
1143 		const unsigned cleartext)
1144 {
1145 	__ops_litdata_type_t	 ld_type;
1146 	__ops_create_sig_t	*sig;
1147 	__ops_sig_type_t	 sig_type;
1148 	__ops_hash_alg_t	 hash_alg;
1149 	__ops_output_t		*output;
1150 	__ops_memory_t		*mem;
1151 	uint8_t		 keyid[OPS_KEY_ID_SIZE];
1152 	__ops_hash_t		*hash;
1153 	unsigned		 ret;
1154 
1155 	sig = NULL;
1156 	sig_type = OPS_SIG_BINARY;
1157 	output = NULL;
1158 	mem = __ops_memory_new();
1159 	hash = NULL;
1160 	ret = 0;
1161 
1162 	hash_alg = __ops_str_to_hash_alg(hashname);
1163 	if (hash_alg == OPS_HASH_UNKNOWN) {
1164 		(void) fprintf(io->errs,
1165 			"__ops_sign_buf: unknown hash algorithm: \"%s\"\n",
1166 			hashname);
1167 		return NULL;
1168 	}
1169 
1170 	/* setup literal data packet type */
1171 	ld_type = (cleartext) ? OPS_LDT_TEXT : OPS_LDT_BINARY;
1172 
1173 	if (input == NULL) {
1174 		(void) fprintf(io->errs,
1175 			"__ops_sign_buf: null input\n");
1176 		return NULL;
1177 	}
1178 
1179 	/* set up signature */
1180 	if ((sig = __ops_create_sig_new()) == NULL) {
1181 		return NULL;
1182 	}
1183 	__ops_start_sig(sig, seckey, hash_alg, sig_type);
1184 
1185 	/* setup writer */
1186 	__ops_setup_memory_write(&output, &mem, insize);
1187 
1188 	if (cleartext) {
1189 		/* Do the signing */
1190 		/* add signature with subpackets: */
1191 		/* - creation time */
1192 		/* - key id */
1193 		ret = __ops_writer_push_clearsigned(output, sig) &&
1194 			__ops_write(output, input, insize) &&
1195 			__ops_writer_use_armored_sig(output) &&
1196 			__ops_add_birthtime(sig, from) &&
1197 			__ops_add_expiration(sig, (long long)duration);
1198 		if (ret == 0) {
1199 			return NULL;
1200 		}
1201 		__ops_output_delete(output);
1202 	} else {
1203 		/* set armoured/not armoured here */
1204 		if (armored) {
1205 			__ops_writer_push_armor_msg(output);
1206 		}
1207 		if (__ops_get_debug_level(__FILE__)) {
1208 			fprintf(io->errs, "** Writing out one pass sig\n");
1209 		}
1210 		/* write one_pass_sig */
1211 		__ops_write_one_pass_sig(output, seckey, hash_alg, sig_type);
1212 
1213 		/* hash memory */
1214 		hash = __ops_sig_get_hash(sig);
1215 		hash->add(hash, input, insize);
1216 
1217 		/* output file contents as Literal Data packet */
1218 		if (__ops_get_debug_level(__FILE__)) {
1219 			(void) fprintf(stderr, "** Writing out data now\n");
1220 		}
1221 		__ops_write_litdata(output, input, (const int)insize, ld_type);
1222 		if (__ops_get_debug_level(__FILE__)) {
1223 			fprintf(stderr, "** After Writing out data now\n");
1224 		}
1225 
1226 		/* add creation time to signature */
1227 		__ops_add_birthtime(sig, from);
1228 		__ops_add_expiration(sig, (long long)duration);
1229 		/* add key id to signature */
1230 		__ops_keyid(keyid, OPS_KEY_ID_SIZE, &seckey->pubkey);
1231 		__ops_add_issuer_keyid(sig, keyid);
1232 		__ops_end_hashed_subpkts(sig);
1233 
1234 		/* write out sig */
1235 		__ops_write_sig(output, sig, &seckey->pubkey, seckey);
1236 
1237 		/* tidy up */
1238 		__ops_writer_close(output);
1239 		__ops_create_sig_delete(sig);
1240 	}
1241 	return mem;
1242 }
1243 
1244 /* sign a file, and put the signature in a separate file */
1245 int
1246 __ops_sign_detached(__ops_io_t *io,
1247 			const char *f,
1248 			char *sigfile,
1249 			__ops_seckey_t *seckey,
1250 			const char *hash,
1251 			const int64_t from,
1252 			const uint64_t duration)
1253 {
1254 	__ops_create_sig_t	*sig;
1255 	__ops_hash_alg_t	 alg;
1256 	__ops_output_t		*output;
1257 	__ops_memory_t		*mem;
1258 	uint8_t	 	 keyid[OPS_KEY_ID_SIZE];
1259 	char			 fname[MAXPATHLEN];
1260 	int			 fd;
1261 
1262 	/* find out which hash algorithm to use */
1263 	alg = __ops_str_to_hash_alg(hash);
1264 	if (alg == OPS_HASH_UNKNOWN) {
1265 		(void) fprintf(io->errs,"Unknown hash algorithm: %s\n", hash);
1266 		return 0;
1267 	}
1268 
1269 	/* create a new signature */
1270 	sig = __ops_create_sig_new();
1271 	__ops_start_sig(sig, seckey, alg, OPS_SIG_BINARY);
1272 
1273 	/* read the contents of 'f', and add that to the signature */
1274 	mem = __ops_memory_new();
1275 	if (!__ops_mem_readfile(mem, f)) {
1276 		return 0;
1277 	}
1278 	__ops_sig_add_data(sig, __ops_mem_data(mem), __ops_mem_len(mem));
1279 	__ops_memory_free(mem);
1280 
1281 	/* calculate the signature */
1282 	__ops_add_birthtime(sig, from);
1283 	__ops_add_expiration(sig, (long long)duration);
1284 	__ops_keyid(keyid, sizeof(keyid), &seckey->pubkey);
1285 	__ops_add_issuer_keyid(sig, keyid);
1286 	__ops_end_hashed_subpkts(sig);
1287 
1288 	/* write the signature to the detached file */
1289 	if (sigfile == NULL) {
1290 		(void) snprintf(fname, sizeof(fname), "%s.sig", f);
1291 		sigfile = fname;
1292 	}
1293 	fd = open(sigfile, O_CREAT|O_TRUNC|O_WRONLY, 0666);
1294 	if (fd < 0) {
1295 		(void) fprintf(io->errs, "can't write signature to \"%s\"\n",
1296 				sigfile);
1297 		return 0;
1298 	}
1299 
1300 	output = __ops_output_new();
1301 	__ops_writer_set_fd(output, fd);
1302 	__ops_write_sig(output, sig, &seckey->pubkey, seckey);
1303 	__ops_seckey_free(seckey);
1304 	(void) close(fd);
1305 
1306 	return 1;
1307 }
1308