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 #include "config.h"
50 
51 #ifdef HAVE_SYS_CDEFS_H
52 #include <sys/cdefs.h>
53 #endif
54 
55 #if defined(__NetBSD__)
56 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
57 __RCSID("$NetBSD: crypto.c,v 1.35 2011/01/02 18:13:10 agc Exp $");
58 #endif
59 
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 
63 #ifdef HAVE_UNISTD_H
64 #include <unistd.h>
65 #endif
66 
67 #include <string.h>
68 
69 #include "types.h"
70 #include "crypto.h"
71 #include "readerwriter.h"
72 #include "memory.h"
73 #include "netpgpdefs.h"
74 #include "signature.h"
75 
76 /**
77 \ingroup Core_MPI
78 \brief Decrypt and unencode MPI
79 \param buf Buffer in which to write decrypted unencoded MPI
80 \param buflen Length of buffer
81 \param encmpi
82 \param seckey
83 \return length of MPI
84 \note only RSA at present
85 */
86 int
87 pgp_decrypt_decode_mpi(uint8_t *buf,
88 				unsigned buflen,
89 				const BIGNUM *g_to_k,
90 				const BIGNUM *encmpi,
91 				const pgp_seckey_t *seckey)
92 {
93 	unsigned        mpisize;
94 	uint8_t		encmpibuf[NETPGP_BUFSIZ];
95 	uint8_t		mpibuf[NETPGP_BUFSIZ];
96 	uint8_t		gkbuf[NETPGP_BUFSIZ];
97 	int             i;
98 	int             n;
99 
100 	mpisize = (unsigned)BN_num_bytes(encmpi);
101 	/* MPI can't be more than 65,536 */
102 	if (mpisize > sizeof(encmpibuf)) {
103 		(void) fprintf(stderr, "mpisize too big %u\n", mpisize);
104 		return -1;
105 	}
106 	switch (seckey->pubkey.alg) {
107 	case PGP_PKA_RSA:
108 		BN_bn2bin(encmpi, encmpibuf);
109 		if (pgp_get_debug_level(__FILE__)) {
110 			hexdump(stderr, "encrypted", encmpibuf, 16);
111 		}
112 		n = pgp_rsa_private_decrypt(mpibuf, encmpibuf,
113 					(unsigned)(BN_num_bits(encmpi) + 7) / 8,
114 					&seckey->key.rsa, &seckey->pubkey.key.rsa);
115 		if (n == -1) {
116 			(void) fprintf(stderr, "ops_rsa_private_decrypt failure\n");
117 			return -1;
118 		}
119 		if (pgp_get_debug_level(__FILE__)) {
120 			hexdump(stderr, "decrypted", mpibuf, 16);
121 		}
122 		if (n <= 0) {
123 			return -1;
124 		}
125 		/* Decode EME-PKCS1_V1_5 (RFC 2437). */
126 		if (mpibuf[0] != 0 || mpibuf[1] != 2) {
127 			return -1;
128 		}
129 		/* Skip the random bytes. */
130 		for (i = 2; i < n && mpibuf[i]; ++i) {
131 		}
132 		if (i == n || i < 10) {
133 			return -1;
134 		}
135 		/* Skip the zero */
136 		i += 1;
137 		/* this is the unencoded m buf */
138 		if ((unsigned) (n - i) <= buflen) {
139 			(void) memcpy(buf, mpibuf + i, (unsigned)(n - i)); /* XXX - Flexelint */
140 		}
141 		if (pgp_get_debug_level(__FILE__)) {
142 			hexdump(stderr, "decoded m", buf, (size_t)(n - i));
143 		}
144 		return n - i;
145 	case PGP_PKA_DSA:
146 	case PGP_PKA_ELGAMAL:
147 		(void) BN_bn2bin(g_to_k, gkbuf);
148 		(void) BN_bn2bin(encmpi, encmpibuf);
149 		if (pgp_get_debug_level(__FILE__)) {
150 			hexdump(stderr, "encrypted", encmpibuf, 16);
151 		}
152 		n = pgp_elgamal_private_decrypt(mpibuf, gkbuf, encmpibuf,
153 					(unsigned)BN_num_bytes(encmpi),
154 					&seckey->key.elgamal, &seckey->pubkey.key.elgamal);
155 		if (n == -1) {
156 			(void) fprintf(stderr, "ops_elgamal_private_decrypt failure\n");
157 			return -1;
158 		}
159 		if (pgp_get_debug_level(__FILE__)) {
160 			hexdump(stderr, "decrypted", mpibuf, 16);
161 		}
162 		if (n <= 0) {
163 			return -1;
164 		}
165 		/* Decode EME-PKCS1_V1_5 (RFC 2437). */
166 		if (mpibuf[0] != 2) {
167 			fprintf(stderr, "mpibuf mismatch\n");
168 			return -1;
169 		}
170 		/* Skip the random bytes. */
171 		for (i = 1; i < n && mpibuf[i]; ++i) {
172 		}
173 		if (i == n || i < 10) {
174 			fprintf(stderr, "175 n %d\n", n);
175 			return -1;
176 		}
177 		/* Skip the zero */
178 		i += 1;
179 		/* this is the unencoded m buf */
180 		if ((unsigned) (n - i) <= buflen) {
181 			(void) memcpy(buf, mpibuf + i, (unsigned)(n - i)); /* XXX - Flexelint */
182 		}
183 		if (pgp_get_debug_level(__FILE__)) {
184 			hexdump(stderr, "decoded m", buf, (size_t)(n - i));
185 		}
186 		return n - i;
187 	default:
188 		(void) fprintf(stderr, "pubkey algorithm wrong\n");
189 		return -1;
190 	}
191 }
192 
193 /**
194 \ingroup Core_MPI
195 \brief RSA-encrypt an MPI
196 */
197 unsigned
198 pgp_rsa_encrypt_mpi(const uint8_t *encoded_m_buf,
199 		    const size_t sz_encoded_m_buf,
200 		    const pgp_pubkey_t * pubkey,
201 		    pgp_pk_sesskey_params_t * skp)
202 {
203 
204 	uint8_t   encmpibuf[NETPGP_BUFSIZ];
205 	int             n;
206 
207 	if (sz_encoded_m_buf != (size_t)BN_num_bytes(pubkey->key.rsa.n)) {
208 		(void) fprintf(stderr, "sz_encoded_m_buf wrong\n");
209 		return 0;
210 	}
211 
212 	n = pgp_rsa_public_encrypt(encmpibuf, encoded_m_buf,
213 				sz_encoded_m_buf, &pubkey->key.rsa);
214 	if (n == -1) {
215 		(void) fprintf(stderr, "pgp_rsa_public_encrypt failure\n");
216 		return 0;
217 	}
218 
219 	if (n <= 0)
220 		return 0;
221 
222 	skp->rsa.encrypted_m = BN_bin2bn(encmpibuf, n, NULL);
223 
224 	if (pgp_get_debug_level(__FILE__)) {
225 		hexdump(stderr, "encrypted mpi", encmpibuf, 16);
226 	}
227 	return 1;
228 }
229 
230 /**
231 \ingroup Core_MPI
232 \brief Elgamal-encrypt an MPI
233 */
234 unsigned
235 pgp_elgamal_encrypt_mpi(const uint8_t *encoded_m_buf,
236 		    const size_t sz_encoded_m_buf,
237 		    const pgp_pubkey_t * pubkey,
238 		    pgp_pk_sesskey_params_t * skp)
239 {
240 
241 	uint8_t   encmpibuf[NETPGP_BUFSIZ];
242 	uint8_t   g_to_k[NETPGP_BUFSIZ];
243 	int             n;
244 
245 	if (sz_encoded_m_buf != (size_t)BN_num_bytes(pubkey->key.elgamal.p)) {
246 		(void) fprintf(stderr, "sz_encoded_m_buf wrong\n");
247 		return 0;
248 	}
249 
250 	n = pgp_elgamal_public_encrypt(g_to_k, encmpibuf, encoded_m_buf,
251 				sz_encoded_m_buf, &pubkey->key.elgamal);
252 	if (n == -1) {
253 		(void) fprintf(stderr, "pgp_elgamal_public_encrypt failure\n");
254 		return 0;
255 	}
256 
257 	if (n <= 0)
258 		return 0;
259 
260 	skp->elgamal.g_to_k = BN_bin2bn(g_to_k, n / 2, NULL);
261 	skp->elgamal.encrypted_m = BN_bin2bn(encmpibuf, n / 2, NULL);
262 
263 	if (pgp_get_debug_level(__FILE__)) {
264 		hexdump(stderr, "encrypted mpi", encmpibuf, 16);
265 	}
266 	return 1;
267 }
268 
269 static pgp_cb_ret_t
270 write_parsed_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
271 {
272 	const pgp_contents_t	*content = &pkt->u;
273 
274 	if (pgp_get_debug_level(__FILE__)) {
275 		printf("write_parsed_cb: ");
276 		pgp_print_packet(&cbinfo->printstate, pkt);
277 	}
278 	if (pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT && cbinfo->printstate.skipping) {
279 		puts("...end of skip");
280 		cbinfo->printstate.skipping = 0;
281 	}
282 	switch (pkt->tag) {
283 	case PGP_PTAG_CT_UNARMOURED_TEXT:
284 		printf("PGP_PTAG_CT_UNARMOURED_TEXT\n");
285 		if (!cbinfo->printstate.skipping) {
286 			puts("Skipping...");
287 			cbinfo->printstate.skipping = 1;
288 		}
289 		fwrite(content->unarmoured_text.data, 1,
290 		       content->unarmoured_text.length, stdout);
291 		break;
292 
293 	case PGP_PTAG_CT_PK_SESSION_KEY:
294 		return pgp_pk_sesskey_cb(pkt, cbinfo);
295 
296 	case PGP_GET_SECKEY:
297 		if (cbinfo->sshseckey) {
298 			*content->get_seckey.seckey = cbinfo->sshseckey;
299 			return PGP_KEEP_MEMORY;
300 		}
301 		return pgp_get_seckey_cb(pkt, cbinfo);
302 
303 	case PGP_GET_PASSPHRASE:
304 		return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo);
305 
306 	case PGP_PTAG_CT_LITDATA_BODY:
307 		return pgp_litdata_cb(pkt, cbinfo);
308 
309 	case PGP_PTAG_CT_ARMOUR_HEADER:
310 	case PGP_PTAG_CT_ARMOUR_TRAILER:
311 	case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
312 	case PGP_PTAG_CT_COMPRESSED:
313 	case PGP_PTAG_CT_LITDATA_HEADER:
314 	case PGP_PTAG_CT_SE_IP_DATA_BODY:
315 	case PGP_PTAG_CT_SE_IP_DATA_HEADER:
316 	case PGP_PTAG_CT_SE_DATA_BODY:
317 	case PGP_PTAG_CT_SE_DATA_HEADER:
318 		/* Ignore these packets  */
319 		/* They're handled in parse_packet() */
320 		/* and nothing else needs to be done */
321 		break;
322 
323 	default:
324 		if (pgp_get_debug_level(__FILE__)) {
325 			fprintf(stderr, "Unexpected packet tag=%d (0x%x)\n",
326 				pkt->tag,
327 				pkt->tag);
328 		}
329 		break;
330 	}
331 
332 	return PGP_RELEASE_MEMORY;
333 }
334 
335 /**
336 \ingroup HighLevel_Crypto
337 Encrypt a file
338 \param infile Name of file to be encrypted
339 \param outfile Name of file to write to. If NULL, name is constructed from infile
340 \param pubkey Public Key to encrypt file for
341 \param use_armour Write armoured text, if set
342 \param allow_overwrite Allow output file to be overwrwritten if it exists
343 \return 1 if OK; else 0
344 */
345 unsigned
346 pgp_encrypt_file(pgp_io_t *io,
347 			const char *infile,
348 			const char *outfile,
349 			const pgp_key_t *key,
350 			const unsigned use_armour,
351 			const unsigned allow_overwrite,
352 			const char *cipher)
353 {
354 	pgp_output_t	*output;
355 	pgp_memory_t	*inmem;
356 	int		 fd_out;
357 
358 	__PGP_USED(io);
359 	inmem = pgp_memory_new();
360 	if (!pgp_mem_readfile(inmem, infile)) {
361 		return 0;
362 	}
363 	fd_out = pgp_setup_file_write(&output, outfile, allow_overwrite);
364 	if (fd_out < 0) {
365 		pgp_memory_free(inmem);
366 		return 0;
367 	}
368 
369 	/* set armoured/not armoured here */
370 	if (use_armour) {
371 		pgp_writer_push_armor_msg(output);
372 	}
373 
374 	/* Push the encrypted writer */
375 	if (!pgp_push_enc_se_ip(output, key, cipher)) {
376 		pgp_memory_free(inmem);
377 		return 0;
378 	}
379 
380 	/* This does the writing */
381 	pgp_write(output, pgp_mem_data(inmem), (unsigned)pgp_mem_len(inmem));
382 
383 	/* tidy up */
384 	pgp_memory_free(inmem);
385 	pgp_teardown_file_write(output, fd_out);
386 
387 	return 1;
388 }
389 
390 /* encrypt the contents of the input buffer, and return the mem structure */
391 pgp_memory_t *
392 pgp_encrypt_buf(pgp_io_t *io,
393 			const void *input,
394 			const size_t insize,
395 			const pgp_key_t *pubkey,
396 			const unsigned use_armour,
397 			const char *cipher)
398 {
399 	pgp_output_t	*output;
400 	pgp_memory_t	*outmem;
401 
402 	__PGP_USED(io);
403 	if (input == NULL) {
404 		(void) fprintf(io->errs,
405 			"pgp_encrypt_buf: null memory\n");
406 		return 0;
407 	}
408 
409 	pgp_setup_memory_write(&output, &outmem, insize);
410 
411 	/* set armoured/not armoured here */
412 	if (use_armour) {
413 		pgp_writer_push_armor_msg(output);
414 	}
415 
416 	/* Push the encrypted writer */
417 	pgp_push_enc_se_ip(output, pubkey, cipher);
418 
419 	/* This does the writing */
420 	pgp_write(output, input, (unsigned)insize);
421 
422 	/* tidy up */
423 	pgp_writer_close(output);
424 	pgp_output_delete(output);
425 
426 	return outmem;
427 }
428 
429 /**
430    \ingroup HighLevel_Crypto
431    \brief Decrypt a file.
432    \param infile Name of file to be decrypted
433    \param outfile Name of file to write to. If NULL, the filename is constructed from the input filename, following GPG conventions.
434    \param keyring Keyring to use
435    \param use_armour Expect armoured text, if set
436    \param allow_overwrite Allow output file to overwritten, if set.
437    \param getpassfunc Callback to use to get passphrase
438 */
439 
440 unsigned
441 pgp_decrypt_file(pgp_io_t *io,
442 			const char *infile,
443 			const char *outfile,
444 			pgp_keyring_t *secring,
445 			pgp_keyring_t *pubring,
446 			const unsigned use_armour,
447 			const unsigned allow_overwrite,
448 			const unsigned sshkeys,
449 			void *passfp,
450 			int numtries,
451 			pgp_cbfunc_t *getpassfunc)
452 {
453 	pgp_stream_t	*parse = NULL;
454 	const int	 printerrors = 1;
455 	char		*filename = NULL;
456 	int		 fd_in;
457 	int		 fd_out;
458 
459 	/* setup for reading from given input file */
460 	fd_in = pgp_setup_file_read(io, &parse, infile,
461 				    NULL,
462 				    write_parsed_cb,
463 				    0);
464 	if (fd_in < 0) {
465 		perror(infile);
466 		return 0;
467 	}
468 	/* setup output filename */
469 	if (outfile) {
470 		fd_out = pgp_setup_file_write(&parse->cbinfo.output, outfile,
471 				allow_overwrite);
472 		if (fd_out < 0) {
473 			perror(outfile);
474 			pgp_teardown_file_read(parse, fd_in);
475 			return 0;
476 		}
477 	} else {
478 		const int	suffixlen = 4;
479 		const char     *suffix = infile + strlen(infile) - suffixlen;
480 		unsigned	filenamelen;
481 
482 		if (strcmp(suffix, ".gpg") == 0 ||
483 		    strcmp(suffix, ".asc") == 0) {
484 			filenamelen = (unsigned)(strlen(infile) - strlen(suffix));
485 			if ((filename = calloc(1, filenamelen + 1)) == NULL) {
486 				(void) fprintf(stderr, "can't allocate %" PRIsize "d bytes\n",
487 					(size_t)(filenamelen + 1));
488 				return 0;
489 			}
490 			(void) strncpy(filename, infile, filenamelen);
491 			filename[filenamelen] = 0x0;
492 		}
493 
494 		fd_out = pgp_setup_file_write(&parse->cbinfo.output,
495 					filename, allow_overwrite);
496 		if (fd_out < 0) {
497 			perror(filename);
498 			free(filename);
499 			pgp_teardown_file_read(parse, fd_in);
500 			return 0;
501 		}
502 	}
503 
504 	/* \todo check for suffix matching armour param */
505 
506 	/* setup for writing decrypted contents to given output file */
507 
508 	/* setup keyring and passphrase callback */
509 	parse->cbinfo.cryptinfo.secring = secring;
510 	parse->cbinfo.passfp = passfp;
511 	parse->cbinfo.cryptinfo.getpassphrase = getpassfunc;
512 	parse->cbinfo.cryptinfo.pubring = pubring;
513 	parse->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL;
514 	parse->cbinfo.numtries = numtries;
515 
516 	/* Set up armour/passphrase options */
517 	if (use_armour) {
518 		pgp_reader_push_dearmour(parse);
519 	}
520 
521 	/* Do it */
522 	pgp_parse(parse, printerrors);
523 
524 	/* Unsetup */
525 	if (use_armour) {
526 		pgp_reader_pop_dearmour(parse);
527 	}
528 
529 	/* if we didn't get the passphrase, unlink output file */
530 	if (!parse->cbinfo.gotpass) {
531 		(void) unlink((filename) ? filename : outfile);
532 	}
533 
534 	if (filename) {
535 		pgp_teardown_file_write(parse->cbinfo.output, fd_out);
536 		free(filename);
537 	}
538 	pgp_teardown_file_read(parse, fd_in);
539 	/* \todo cleardown crypt */
540 
541 	return 1;
542 }
543 
544 /* decrypt an area of memory */
545 pgp_memory_t *
546 pgp_decrypt_buf(pgp_io_t *io,
547 			const void *input,
548 			const size_t insize,
549 			pgp_keyring_t *secring,
550 			pgp_keyring_t *pubring,
551 			const unsigned use_armour,
552 			const unsigned sshkeys,
553 			void *passfp,
554 			int numtries,
555 			pgp_cbfunc_t *getpassfunc)
556 {
557 	pgp_stream_t	*parse = NULL;
558 	pgp_memory_t	*outmem;
559 	pgp_memory_t	*inmem;
560 	const int	 printerrors = 1;
561 
562 	if (input == NULL) {
563 		(void) fprintf(io->errs,
564 			"pgp_encrypt_buf: null memory\n");
565 		return 0;
566 	}
567 
568 	inmem = pgp_memory_new();
569 	pgp_memory_add(inmem, input, insize);
570 
571 	/* set up to read from memory */
572 	pgp_setup_memory_read(io, &parse, inmem,
573 				    NULL,
574 				    write_parsed_cb,
575 				    0);
576 
577 	/* setup for writing decrypted contents to given output file */
578 	pgp_setup_memory_write(&parse->cbinfo.output, &outmem, insize);
579 
580 	/* setup keyring and passphrase callback */
581 	parse->cbinfo.cryptinfo.secring = secring;
582 	parse->cbinfo.cryptinfo.pubring = pubring;
583 	parse->cbinfo.passfp = passfp;
584 	parse->cbinfo.cryptinfo.getpassphrase = getpassfunc;
585 	parse->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL;
586 	parse->cbinfo.numtries = numtries;
587 
588 	/* Set up armour/passphrase options */
589 	if (use_armour) {
590 		pgp_reader_push_dearmour(parse);
591 	}
592 
593 	/* Do it */
594 	pgp_parse(parse, printerrors);
595 
596 	/* Unsetup */
597 	if (use_armour) {
598 		pgp_reader_pop_dearmour(parse);
599 	}
600 
601 	/* tidy up */
602 	pgp_teardown_memory_read(parse, inmem);
603 
604 	pgp_writer_close(parse->cbinfo.output);
605 	pgp_output_delete(parse->cbinfo.output);
606 
607 	/* if we didn't get the passphrase, return NULL */
608 	return (parse->cbinfo.gotpass) ? outmem : NULL;
609 }
610