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