1/*-
2 * Copyright (c) 2009,2010 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: misc.c,v 1.39 2010/11/11 00:58:04 agc Exp $");
61#endif
62
63#include <sys/types.h>
64#include <sys/stat.h>
65#include <sys/mman.h>
66
67#include <ctype.h>
68#include <stdarg.h>
69#include <stdio.h>
70#include <stdlib.h>
71#include <string.h>
72
73#ifdef HAVE_UNISTD_H
74#include <unistd.h>
75#endif
76
77#ifdef HAVE_OPENSSL_RAND_H
78#include <openssl/rand.h>
79#endif
80
81#include "errors.h"
82#include "packet.h"
83#include "crypto.h"
84#include "create.h"
85#include "packet-parse.h"
86#include "packet-show.h"
87#include "signature.h"
88#include "netpgpsdk.h"
89#include "netpgpdefs.h"
90#include "memory.h"
91#include "readerwriter.h"
92#include "version.h"
93#include "netpgpdigest.h"
94
95#ifdef WIN32
96#define vsnprintf _vsnprintf
97#endif
98
99
100typedef struct {
101	pgp_keyring_t		*keyring;
102} accumulate_t;
103
104/**
105 * \ingroup Core_Callbacks
106 */
107static pgp_cb_ret_t
108accumulate_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
109{
110	const pgp_contents_t	*content = &pkt->u;
111	pgp_keyring_t		*keyring;
112	accumulate_t		*accumulate;
113
114	if (pgp_get_debug_level(__FILE__)) {
115		(void) fprintf(stderr, "accumulate callback: packet tag %u\n", pkt->tag);
116	}
117	accumulate = pgp_callback_arg(cbinfo);
118	keyring = accumulate->keyring;
119	switch (pkt->tag) {
120	case PGP_PTAG_CT_PUBLIC_KEY:
121	case PGP_PTAG_CT_PUBLIC_SUBKEY:
122		pgp_add_to_pubring(keyring, &content->pubkey, pkt->tag);
123		return PGP_KEEP_MEMORY;
124	case PGP_PTAG_CT_SECRET_KEY:
125	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
126		pgp_add_to_secring(keyring, &content->seckey);
127		return PGP_KEEP_MEMORY;
128	case PGP_PTAG_CT_USER_ID:
129		if (pgp_get_debug_level(__FILE__)) {
130			(void) fprintf(stderr, "User ID: %s for key %d\n",
131					content->userid,
132					keyring->keyc - 1);
133		}
134		if (keyring->keyc == 0) {
135			PGP_ERROR(cbinfo->errors, PGP_E_P_NO_USERID, "No userid found");
136		} else {
137			pgp_add_userid(&keyring->keys[keyring->keyc - 1], content->userid);
138		}
139		return PGP_KEEP_MEMORY;
140	case PGP_PARSER_PACKET_END:
141		if (keyring->keyc > 0) {
142			pgp_add_subpacket(&keyring->keys[keyring->keyc - 1],
143						&content->packet);
144			return PGP_KEEP_MEMORY;
145		}
146		return PGP_RELEASE_MEMORY;
147	case PGP_PARSER_ERROR:
148		(void) fprintf(stderr, "Error: %s\n", content->error);
149		return PGP_FINISHED;
150	case PGP_PARSER_ERRCODE:
151		(void) fprintf(stderr, "parse error: %s\n",
152				pgp_errcode(content->errcode.errcode));
153		break;
154	default:
155		break;
156	}
157	/* XXX: we now exclude so many things, we should either drop this or */
158	/* do something to pass on copies of the stuff we keep */
159	return pgp_stacked_callback(pkt, cbinfo);
160}
161
162/**
163 * \ingroup Core_Parse
164 *
165 * Parse packets from an input stream until EOF or error.
166 *
167 * Key data found in the parsed data is added to #keyring.
168 *
169 * \param keyring Pointer to an existing keyring
170 * \param parse Options to use when parsing
171*/
172int
173pgp_parse_and_accumulate(pgp_keyring_t *keyring, pgp_stream_t *parse)
174{
175	accumulate_t	accumulate;
176	const int	printerrors = 1;
177	int             ret;
178
179	if (parse->readinfo.accumulate) {
180		(void) fprintf(stderr,
181			"pgp_parse_and_accumulate: already init\n");
182		return 0;
183	}
184
185	(void) memset(&accumulate, 0x0, sizeof(accumulate));
186
187	accumulate.keyring = keyring;
188
189	pgp_callback_push(parse, accumulate_cb, &accumulate);
190	parse->readinfo.accumulate = 1;
191	ret = pgp_parse(parse, !printerrors);
192
193	return ret;
194}
195
196
197/** \file
198 * \brief Error Handling
199 */
200#define ERRNAME(code)	{ code, #code }
201
202static pgp_errcode_name_map_t errcode_name_map[] = {
203	ERRNAME(PGP_E_OK),
204	ERRNAME(PGP_E_FAIL),
205	ERRNAME(PGP_E_SYSTEM_ERROR),
206	ERRNAME(PGP_E_UNIMPLEMENTED),
207
208	ERRNAME(PGP_E_R),
209	ERRNAME(PGP_E_R_READ_FAILED),
210	ERRNAME(PGP_E_R_EARLY_EOF),
211	ERRNAME(PGP_E_R_BAD_FORMAT),
212	ERRNAME(PGP_E_R_UNCONSUMED_DATA),
213
214	ERRNAME(PGP_E_W),
215	ERRNAME(PGP_E_W_WRITE_FAILED),
216	ERRNAME(PGP_E_W_WRITE_TOO_SHORT),
217
218	ERRNAME(PGP_E_P),
219	ERRNAME(PGP_E_P_NOT_ENOUGH_DATA),
220	ERRNAME(PGP_E_P_UNKNOWN_TAG),
221	ERRNAME(PGP_E_P_PACKET_CONSUMED),
222	ERRNAME(PGP_E_P_MPI_FORMAT_ERROR),
223
224	ERRNAME(PGP_E_C),
225
226	ERRNAME(PGP_E_V),
227	ERRNAME(PGP_E_V_BAD_SIGNATURE),
228	ERRNAME(PGP_E_V_NO_SIGNATURE),
229	ERRNAME(PGP_E_V_UNKNOWN_SIGNER),
230
231	ERRNAME(PGP_E_ALG),
232	ERRNAME(PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG),
233	ERRNAME(PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG),
234	ERRNAME(PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG),
235	ERRNAME(PGP_E_ALG_UNSUPPORTED_HASH_ALG),
236
237	ERRNAME(PGP_E_PROTO),
238	ERRNAME(PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT),
239	ERRNAME(PGP_E_PROTO_UNKNOWN_SS),
240	ERRNAME(PGP_E_PROTO_CRITICAL_SS_IGNORED),
241	ERRNAME(PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN),
242	ERRNAME(PGP_E_PROTO_BAD_SIGNATURE_VRSN),
243	ERRNAME(PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN),
244	ERRNAME(PGP_E_PROTO_BAD_PKSK_VRSN),
245	ERRNAME(PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN),
246	ERRNAME(PGP_E_PROTO_BAD_SK_CHECKSUM),
247
248	{0x00, NULL},		/* this is the end-of-array marker */
249};
250
251/**
252 * \ingroup Core_Errors
253 * \brief returns error code name
254 * \param errcode
255 * \return error code name or "Unknown"
256 */
257const char     *
258pgp_errcode(const pgp_errcode_t errcode)
259{
260	return (pgp_str_from_map((int) errcode,
261			(pgp_map_t *) errcode_name_map));
262}
263
264/* generic grab new storage function */
265void *
266pgp_new(size_t size)
267{
268	void	*vp;
269
270	if ((vp = calloc(1, size)) == NULL) {
271		(void) fprintf(stderr,
272			"allocation failure for %" PRIsize "u bytes", size);
273	}
274	return vp;
275}
276
277/**
278 * \ingroup Core_Errors
279 * \brief Pushes the given error on the given errorstack
280 * \param errstack Error stack to use
281 * \param errcode Code of error to push
282 * \param sys_errno System errno (used if errcode=PGP_E_SYSTEM_ERROR)
283 * \param file Source filename where error occurred
284 * \param line Line in source file where error occurred
285 * \param fmt Comment
286 *
287 */
288
289void
290pgp_push_error(pgp_error_t **errstack, pgp_errcode_t errcode,
291		int sys_errno, const char *file, int line, const char *fmt,...)
292{
293	/* first get the varargs and generate the comment */
294	pgp_error_t  *err;
295	unsigned	maxbuf = 128;
296	va_list		args;
297	char           *comment;
298
299	if ((comment = calloc(1, maxbuf + 1)) == NULL) {
300		(void) fprintf(stderr, "calloc comment failure\n");
301		return;
302	}
303
304	va_start(args, fmt);
305	vsnprintf(comment, maxbuf + 1, fmt, args);
306	va_end(args);
307
308	/* alloc a new error and add it to the top of the stack */
309
310	if ((err = calloc(1, sizeof(*err))) == NULL) {
311		(void) fprintf(stderr, "calloc comment failure\n");
312		return;
313	}
314
315	err->next = *errstack;
316	*errstack = err;
317
318	/* fill in the details */
319	err->errcode = errcode;
320	err->sys_errno = sys_errno;
321	err->file = file;
322	err->line = line;
323
324	err->comment = comment;
325}
326
327/**
328\ingroup Core_Errors
329\brief print this error
330\param err Error to print
331*/
332void
333pgp_print_error(pgp_error_t *err)
334{
335	printf("%s:%d: ", err->file, err->line);
336	if (err->errcode == PGP_E_SYSTEM_ERROR) {
337		printf("system error %d returned from %s()\n", err->sys_errno,
338		       err->comment);
339	} else {
340		printf("%s, %s\n", pgp_errcode(err->errcode), err->comment);
341	}
342}
343
344/**
345\ingroup Core_Errors
346\brief Print all errors on stack
347\param errstack Error stack to print
348*/
349void
350pgp_print_errors(pgp_error_t *errstack)
351{
352	pgp_error_t    *err;
353
354	for (err = errstack; err != NULL; err = err->next) {
355		pgp_print_error(err);
356	}
357}
358
359/**
360\ingroup Core_Errors
361\brief Return 1 if given error is present anywhere on stack
362\param errstack Error stack to check
363\param errcode Error code to look for
364\return 1 if found; else 0
365*/
366int
367pgp_has_error(pgp_error_t *errstack, pgp_errcode_t errcode)
368{
369	pgp_error_t    *err;
370
371	for (err = errstack; err != NULL; err = err->next) {
372		if (err->errcode == errcode) {
373			return 1;
374		}
375	}
376	return 0;
377}
378
379/**
380\ingroup Core_Errors
381\brief Frees all errors on stack
382\param errstack Error stack to free
383*/
384void
385pgp_free_errors(pgp_error_t *errstack)
386{
387	pgp_error_t    *next;
388
389	while (errstack != NULL) {
390		next = errstack->next;
391		free(errstack->comment);
392		free(errstack);
393		errstack = next;
394	}
395}
396
397/* hash a 32-bit integer */
398static int
399hash_uint32(pgp_hash_t *hash, uint32_t n)
400{
401	uint8_t	ibuf[4];
402
403	ibuf[0] = (uint8_t)(n >> 24) & 0xff;
404	ibuf[1] = (uint8_t)(n >> 16) & 0xff;
405	ibuf[2] = (uint8_t)(n >> 8) & 0xff;
406	ibuf[3] = (uint8_t)n & 0xff;
407	(*hash->add)(hash, (const uint8_t *)(void *)ibuf, (unsigned)sizeof(ibuf));
408	return sizeof(ibuf);
409}
410
411/* hash a string - first length, then string itself */
412static int
413hash_string(pgp_hash_t *hash, const uint8_t *buf, uint32_t len)
414{
415	if (pgp_get_debug_level(__FILE__)) {
416		hexdump(stderr, "hash_string", buf, len);
417	}
418	hash_uint32(hash, len);
419	(*hash->add)(hash, buf, len);
420	return (int)(sizeof(len) + len);
421}
422
423/* hash a bignum, possibly padded - first length, then string itself */
424static int
425hash_bignum(pgp_hash_t *hash, BIGNUM *bignum)
426{
427	uint8_t	*bn;
428	size_t	 len;
429	int	 padbyte;
430
431	if (BN_is_zero(bignum)) {
432		hash_uint32(hash, 0);
433		return sizeof(len);
434	}
435	if ((len = (size_t) BN_num_bytes(bignum)) < 1) {
436		(void) fprintf(stderr, "hash_bignum: bad size\n");
437		return 0;
438	}
439	if ((bn = calloc(1, len)) == NULL) {
440		(void) fprintf(stderr, "hash_bignum: bad bn alloc\n");
441		return 0;
442	}
443	BN_bn2bin(bignum, bn + 1);
444	bn[0] = 0x0;
445	padbyte = (bn[1] & 0x80) ? 1 : 0;
446	hash_string(hash, bn + 1 - padbyte, (unsigned)(len + padbyte));
447	free(bn);
448	return (int)(sizeof(len) + len + padbyte);
449}
450
451/** \file
452 */
453
454/**
455 * \ingroup Core_Keys
456 * \brief Calculate a public key fingerprint.
457 * \param fp Where to put the calculated fingerprint
458 * \param key The key for which the fingerprint is calculated
459 */
460int
461pgp_fingerprint(pgp_fingerprint_t *fp, const pgp_pubkey_t *key, pgp_hash_alg_t hashtype)
462{
463	pgp_memory_t	*mem;
464	pgp_hash_t	 hash;
465	const char	*type;
466	uint32_t	 len;
467
468	mem = pgp_memory_new();
469	if (key->version == 2 || key->version == 3) {
470		if (key->alg != PGP_PKA_RSA &&
471		    key->alg != PGP_PKA_RSA_ENCRYPT_ONLY &&
472		    key->alg != PGP_PKA_RSA_SIGN_ONLY) {
473			(void) fprintf(stderr,
474				"pgp_fingerprint: bad algorithm\n");
475			return 0;
476		}
477		pgp_hash_md5(&hash);
478		if (!hash.init(&hash)) {
479			(void) fprintf(stderr,
480				"pgp_fingerprint: bad md5 alloc\n");
481			return 0;
482		}
483		hash_bignum(&hash, key->key.rsa.n);
484		hash_bignum(&hash, key->key.rsa.e);
485		fp->length = hash.finish(&hash, fp->fingerprint);
486		if (pgp_get_debug_level(__FILE__)) {
487			hexdump(stderr, "v2/v3 fingerprint", fp->fingerprint, fp->length);
488		}
489	} else if (hashtype == PGP_HASH_MD5) {
490		pgp_hash_md5(&hash);
491		if (!hash.init(&hash)) {
492			(void) fprintf(stderr,
493				"pgp_fingerprint: bad md5 alloc\n");
494			return 0;
495		}
496		type = (key->alg == PGP_PKA_RSA) ? "ssh-rsa" : "ssh-dss";
497		hash_string(&hash, (const uint8_t *)(const void *)type, (unsigned)strlen(type));
498		switch(key->alg) {
499		case PGP_PKA_RSA:
500			hash_bignum(&hash, key->key.rsa.e);
501			hash_bignum(&hash, key->key.rsa.n);
502			break;
503		case PGP_PKA_DSA:
504			hash_bignum(&hash, key->key.dsa.p);
505			hash_bignum(&hash, key->key.dsa.q);
506			hash_bignum(&hash, key->key.dsa.g);
507			hash_bignum(&hash, key->key.dsa.y);
508			break;
509		default:
510			break;
511		}
512		fp->length = hash.finish(&hash, fp->fingerprint);
513		if (pgp_get_debug_level(__FILE__)) {
514			hexdump(stderr, "md5 fingerprint", fp->fingerprint, fp->length);
515		}
516	} else {
517		pgp_build_pubkey(mem, key, 0);
518		pgp_hash_sha1(&hash);
519		if (!hash.init(&hash)) {
520			(void) fprintf(stderr,
521				"pgp_fingerprint: bad sha1 alloc\n");
522			return 0;
523		}
524		len = (unsigned)pgp_mem_len(mem);
525		pgp_hash_add_int(&hash, 0x99, 1);
526		pgp_hash_add_int(&hash, len, 2);
527		hash.add(&hash, pgp_mem_data(mem), len);
528		fp->length = hash.finish(&hash, fp->fingerprint);
529		pgp_memory_free(mem);
530		if (pgp_get_debug_level(__FILE__)) {
531			hexdump(stderr, "sha1 fingerprint", fp->fingerprint, fp->length);
532		}
533	}
534	return 1;
535}
536
537/**
538 * \ingroup Core_Keys
539 * \brief Calculate the Key ID from the public key.
540 * \param keyid Space for the calculated ID to be stored
541 * \param key The key for which the ID is calculated
542 */
543
544int
545pgp_keyid(uint8_t *keyid, const size_t idlen, const pgp_pubkey_t *key, pgp_hash_alg_t hashtype)
546{
547	pgp_fingerprint_t finger;
548
549	if (key->version == 2 || key->version == 3) {
550		unsigned	n;
551		uint8_t		bn[NETPGP_BUFSIZ];
552
553		n = (unsigned) BN_num_bytes(key->key.rsa.n);
554		if (n > sizeof(bn)) {
555			(void) fprintf(stderr, "pgp_keyid: bad num bytes\n");
556			return 0;
557		}
558		if (key->alg != PGP_PKA_RSA &&
559		    key->alg != PGP_PKA_RSA_ENCRYPT_ONLY &&
560		    key->alg != PGP_PKA_RSA_SIGN_ONLY) {
561			(void) fprintf(stderr, "pgp_keyid: bad algorithm\n");
562			return 0;
563		}
564		BN_bn2bin(key->key.rsa.n, bn);
565		(void) memcpy(keyid, bn + n - idlen, idlen);
566	} else {
567		pgp_fingerprint(&finger, key, hashtype);
568		(void) memcpy(keyid,
569				finger.fingerprint + finger.length - idlen,
570				idlen);
571	}
572	return 1;
573}
574
575/**
576\ingroup Core_Hashes
577\brief Add to the hash
578\param hash Hash to add to
579\param n Int to add
580\param length Length of int in bytes
581*/
582void
583pgp_hash_add_int(pgp_hash_t *hash, unsigned n, unsigned length)
584{
585	uint8_t   c;
586
587	while (length--) {
588		c = n >> (length * 8);
589		hash->add(hash, &c, 1);
590	}
591}
592
593/**
594\ingroup Core_Hashes
595\brief Setup hash for given hash algorithm
596\param hash Hash to set up
597\param alg Hash algorithm to use
598*/
599void
600pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
601{
602	switch (alg) {
603	case PGP_HASH_MD5:
604		pgp_hash_md5(hash);
605		break;
606
607	case PGP_HASH_SHA1:
608		pgp_hash_sha1(hash);
609		break;
610
611	case PGP_HASH_SHA256:
612		pgp_hash_sha256(hash);
613		break;
614
615	case PGP_HASH_SHA384:
616		pgp_hash_sha384(hash);
617		break;
618
619	case PGP_HASH_SHA512:
620		pgp_hash_sha512(hash);
621		break;
622
623	case PGP_HASH_SHA224:
624		pgp_hash_sha224(hash);
625		break;
626
627	default:
628		(void) fprintf(stderr, "pgp_hash_any: bad algorithm\n");
629	}
630}
631
632/**
633\ingroup Core_Hashes
634\brief Returns size of hash for given hash algorithm
635\param alg Hash algorithm to use
636\return Size of hash algorithm in bytes
637*/
638unsigned
639pgp_hash_size(pgp_hash_alg_t alg)
640{
641	switch (alg) {
642	case PGP_HASH_MD5:
643		return 16;
644
645	case PGP_HASH_SHA1:
646		return 20;
647
648	case PGP_HASH_SHA256:
649		return 32;
650
651	case PGP_HASH_SHA224:
652		return 28;
653
654	case PGP_HASH_SHA512:
655		return 64;
656
657	case PGP_HASH_SHA384:
658		return 48;
659
660	default:
661		(void) fprintf(stderr, "pgp_hash_size: bad algorithm\n");
662	}
663
664	return 0;
665}
666
667/**
668\ingroup Core_Hashes
669\brief Returns hash enum corresponding to given string
670\param hash Text name of hash algorithm i.e. "SHA1"
671\returns Corresponding enum i.e. PGP_HASH_SHA1
672*/
673pgp_hash_alg_t
674pgp_str_to_hash_alg(const char *hash)
675{
676	if (hash == NULL) {
677		return PGP_DEFAULT_HASH_ALGORITHM;
678	}
679	if (netpgp_strcasecmp(hash, "SHA1") == 0) {
680		return PGP_HASH_SHA1;
681	}
682	if (netpgp_strcasecmp(hash, "MD5") == 0) {
683		return PGP_HASH_MD5;
684	}
685	if (netpgp_strcasecmp(hash, "SHA256") == 0) {
686		return PGP_HASH_SHA256;
687	}
688	/*
689        if (netpgp_strcasecmp(hash,"SHA224") == 0) {
690		return PGP_HASH_SHA224;
691	}
692        */
693	if (netpgp_strcasecmp(hash, "SHA512") == 0) {
694		return PGP_HASH_SHA512;
695	}
696	if (netpgp_strcasecmp(hash, "SHA384") == 0) {
697		return PGP_HASH_SHA384;
698	}
699	return PGP_HASH_UNKNOWN;
700}
701
702/**
703\ingroup Core_Hashes
704\brief Hash given data
705\param out Where to write the hash
706\param alg Hash algorithm to use
707\param in Data to hash
708\param length Length of data
709\return Size of hash created
710*/
711unsigned
712pgp_hash(uint8_t *out, pgp_hash_alg_t alg, const void *in, size_t length)
713{
714	pgp_hash_t      hash;
715
716	pgp_hash_any(&hash, alg);
717	if (!hash.init(&hash)) {
718		(void) fprintf(stderr, "pgp_hash: bad alloc\n");
719		/* we'll just continue here - don't want to return a 0 hash */
720		/* XXX - agc - no way to return failure */
721	}
722	hash.add(&hash, in, (unsigned)length);
723	return hash.finish(&hash, out);
724}
725
726/**
727\ingroup Core_Hashes
728\brief Calculate hash for MDC packet
729\param preamble Preamble to hash
730\param sz_preamble Size of preamble
731\param plaintext Plaintext to hash
732\param sz_plaintext Size of plaintext
733\param hashed Resulting hash
734*/
735void
736pgp_calc_mdc_hash(const uint8_t *preamble,
737			const size_t sz_preamble,
738			const uint8_t *plaintext,
739			const unsigned sz_plaintext,
740			uint8_t *hashed)
741{
742	pgp_hash_t	hash;
743	uint8_t		c;
744
745	if (pgp_get_debug_level(__FILE__)) {
746		hexdump(stderr, "preamble", preamble, sz_preamble);
747		hexdump(stderr, "plaintext", plaintext, sz_plaintext);
748	}
749	/* init */
750	pgp_hash_any(&hash, PGP_HASH_SHA1);
751	if (!hash.init(&hash)) {
752		(void) fprintf(stderr, "pgp_calc_mdc_hash: bad alloc\n");
753		/* we'll just continue here - it will die anyway */
754		/* agc - XXX - no way to return failure */
755	}
756
757	/* preamble */
758	hash.add(&hash, preamble, (unsigned)sz_preamble);
759	/* plaintext */
760	hash.add(&hash, plaintext, sz_plaintext);
761	/* MDC packet tag */
762	c = MDC_PKT_TAG;
763	hash.add(&hash, &c, 1);
764	/* MDC packet len */
765	c = PGP_SHA1_HASH_SIZE;
766	hash.add(&hash, &c, 1);
767
768	/* finish */
769	hash.finish(&hash, hashed);
770
771	if (pgp_get_debug_level(__FILE__)) {
772		hexdump(stderr, "hashed", hashed, PGP_SHA1_HASH_SIZE);
773	}
774}
775
776/**
777\ingroup HighLevel_Supported
778\brief Is this Hash Algorithm supported?
779\param hash_alg Hash Algorithm to check
780\return 1 if supported; else 0
781*/
782unsigned
783pgp_is_hash_alg_supported(const pgp_hash_alg_t *hash_alg)
784{
785	switch (*hash_alg) {
786	case PGP_HASH_MD5:
787	case PGP_HASH_SHA1:
788	case PGP_HASH_SHA256:
789		return 1;
790
791	default:
792		return 0;
793	}
794}
795
796/* structure to map string to cipher def */
797typedef struct str2cipher_t {
798	const char	*s;	/* cipher name */
799	pgp_symm_alg_t i;	/* cipher def */
800} str2cipher_t;
801
802static str2cipher_t	str2cipher[] = {
803	{	"cast5",		PGP_SA_CAST5		},
804	{	"idea",			PGP_SA_IDEA		},
805	{	"aes128",		PGP_SA_AES_128		},
806	{	"aes256",		PGP_SA_AES_256		},
807	{	"camellia128",		PGP_SA_CAMELLIA_128	},
808	{	"camellia256",		PGP_SA_CAMELLIA_256	},
809	{	"tripledes",		PGP_SA_TRIPLEDES	},
810	{	NULL,			0			}
811};
812
813/* convert from a string to a cipher definition */
814pgp_symm_alg_t
815pgp_str_to_cipher(const char *cipher)
816{
817	str2cipher_t	*sp;
818
819	for (sp = str2cipher ; cipher && sp->s ; sp++) {
820		if (netpgp_strcasecmp(cipher, sp->s) == 0) {
821			return sp->i;
822		}
823	}
824	return PGP_SA_DEFAULT_CIPHER;
825}
826
827void
828pgp_random(void *dest, size_t length)
829{
830	RAND_bytes(dest, (int)length);
831}
832
833/**
834\ingroup HighLevel_Memory
835\brief Memory to initialise
836\param mem memory to initialise
837\param needed Size to initialise to
838*/
839void
840pgp_memory_init(pgp_memory_t *mem, size_t needed)
841{
842	uint8_t	*temp;
843
844	mem->length = 0;
845	if (mem->buf) {
846		if (mem->allocated < needed) {
847			if ((temp = realloc(mem->buf, needed)) == NULL) {
848				(void) fprintf(stderr, "pgp_memory_init: bad alloc\n");
849			} else {
850				mem->buf = temp;
851				mem->allocated = needed;
852			}
853		}
854	} else {
855		if ((mem->buf = calloc(1, needed)) == NULL) {
856			(void) fprintf(stderr, "pgp_memory_init: bad alloc\n");
857		} else {
858			mem->allocated = needed;
859		}
860	}
861}
862
863/**
864\ingroup HighLevel_Memory
865\brief Pad memory to required length
866\param mem Memory to use
867\param length New size
868*/
869void
870pgp_memory_pad(pgp_memory_t *mem, size_t length)
871{
872	uint8_t	*temp;
873
874	if (mem->allocated < mem->length) {
875		(void) fprintf(stderr, "pgp_memory_pad: bad alloc in\n");
876		return;
877	}
878	if (mem->allocated < mem->length + length) {
879		mem->allocated = mem->allocated * 2 + length;
880		temp = realloc(mem->buf, mem->allocated);
881		if (temp == NULL) {
882			(void) fprintf(stderr, "pgp_memory_pad: bad alloc\n");
883		} else {
884			mem->buf = temp;
885		}
886	}
887	if (mem->allocated < mem->length + length) {
888		(void) fprintf(stderr, "pgp_memory_pad: bad alloc out\n");
889	}
890}
891
892/**
893\ingroup HighLevel_Memory
894\brief Add data to memory
895\param mem Memory to which to add
896\param src Data to add
897\param length Length of data to add
898*/
899void
900pgp_memory_add(pgp_memory_t *mem, const uint8_t *src, size_t length)
901{
902	pgp_memory_pad(mem, length);
903	(void) memcpy(mem->buf + mem->length, src, length);
904	mem->length += length;
905}
906
907/* XXX: this could be refactored via the writer, but an awful lot of */
908/* hoops to jump through for 2 lines of code! */
909void
910pgp_memory_place_int(pgp_memory_t *mem, unsigned offset, unsigned n,
911		     size_t length)
912{
913	if (mem->allocated < offset + length) {
914		(void) fprintf(stderr,
915			"pgp_memory_place_int: bad alloc\n");
916	} else {
917		while (length-- > 0) {
918			mem->buf[offset++] = n >> (length * 8);
919		}
920	}
921}
922
923/**
924 * \ingroup HighLevel_Memory
925 * \brief Retains allocated memory and set length of stored data to zero.
926 * \param mem Memory to clear
927 * \sa pgp_memory_release()
928 * \sa pgp_memory_free()
929 */
930void
931pgp_memory_clear(pgp_memory_t *mem)
932{
933	mem->length = 0;
934}
935
936/**
937\ingroup HighLevel_Memory
938\brief Free memory and associated data
939\param mem Memory to free
940\note This does not free mem itself
941\sa pgp_memory_clear()
942\sa pgp_memory_free()
943*/
944void
945pgp_memory_release(pgp_memory_t *mem)
946{
947	if (mem->mmapped) {
948		(void) munmap(mem->buf, mem->length);
949	} else {
950		free(mem->buf);
951	}
952	mem->buf = NULL;
953	mem->length = 0;
954}
955
956void
957pgp_memory_make_packet(pgp_memory_t *out, pgp_content_enum tag)
958{
959	size_t          extra;
960
961	extra = (out->length < 192) ? 1 : (out->length < 8192 + 192) ? 2 : 5;
962	pgp_memory_pad(out, extra + 1);
963	memmove(out->buf + extra + 1, out->buf, out->length);
964
965	out->buf[0] = PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT | tag;
966
967	if (out->length < 192) {
968		out->buf[1] = (uint8_t)out->length;
969	} else if (out->length < 8192 + 192) {
970		out->buf[1] = (uint8_t)((out->length - 192) >> 8) + 192;
971		out->buf[2] = (uint8_t)(out->length - 192);
972	} else {
973		out->buf[1] = 0xff;
974		out->buf[2] = (uint8_t)(out->length >> 24);
975		out->buf[3] = (uint8_t)(out->length >> 16);
976		out->buf[4] = (uint8_t)(out->length >> 8);
977		out->buf[5] = (uint8_t)(out->length);
978	}
979
980	out->length += extra + 1;
981}
982
983/**
984   \ingroup HighLevel_Memory
985   \brief Create a new zeroed pgp_memory_t
986   \return Pointer to new pgp_memory_t
987   \note Free using pgp_memory_free() after use.
988   \sa pgp_memory_free()
989*/
990
991pgp_memory_t   *
992pgp_memory_new(void)
993{
994	return calloc(1, sizeof(pgp_memory_t));
995}
996
997/**
998   \ingroup HighLevel_Memory
999   \brief Free memory ptr and associated memory
1000   \param mem Memory to be freed
1001   \sa pgp_memory_release()
1002   \sa pgp_memory_clear()
1003*/
1004
1005void
1006pgp_memory_free(pgp_memory_t *mem)
1007{
1008	pgp_memory_release(mem);
1009	free(mem);
1010}
1011
1012/**
1013   \ingroup HighLevel_Memory
1014   \brief Get length of data stored in pgp_memory_t struct
1015   \return Number of bytes in data
1016*/
1017size_t
1018pgp_mem_len(const pgp_memory_t *mem)
1019{
1020	return mem->length;
1021}
1022
1023/**
1024   \ingroup HighLevel_Memory
1025   \brief Get data stored in pgp_memory_t struct
1026   \return Pointer to data
1027*/
1028void *
1029pgp_mem_data(pgp_memory_t *mem)
1030{
1031	return mem->buf;
1032}
1033
1034/* read a gile into an pgp_memory_t */
1035int
1036pgp_mem_readfile(pgp_memory_t *mem, const char *f)
1037{
1038	struct stat	 st;
1039	FILE		*fp;
1040	int		 cc;
1041
1042	if ((fp = fopen(f, "rb")) == NULL) {
1043		(void) fprintf(stderr,
1044				"pgp_mem_readfile: can't open \"%s\"\n", f);
1045		return 0;
1046	}
1047	(void) fstat(fileno(fp), &st);
1048	mem->allocated = (size_t)st.st_size;
1049	mem->buf = mmap(NULL, mem->allocated, PROT_READ,
1050				MAP_PRIVATE | MAP_FILE, fileno(fp), 0);
1051	if (mem->buf == MAP_FAILED) {
1052		/* mmap failed for some reason - try to allocate memory */
1053		if ((mem->buf = calloc(1, mem->allocated)) == NULL) {
1054			(void) fprintf(stderr, "pgp_mem_readfile: calloc\n");
1055			(void) fclose(fp);
1056			return 0;
1057		}
1058		/* read into contents of mem */
1059		for (mem->length = 0 ;
1060		     (cc = (int)read(fileno(fp), &mem->buf[mem->length],
1061					(size_t)(mem->allocated - mem->length))) > 0 ;
1062		     mem->length += (size_t)cc) {
1063		}
1064	} else {
1065		mem->length = mem->allocated;
1066		mem->mmapped = 1;
1067	}
1068	(void) fclose(fp);
1069	return (mem->allocated == mem->length);
1070}
1071
1072typedef struct {
1073	uint16_t  sum;
1074} sum16_t;
1075
1076
1077/**
1078 * Searches the given map for the given type.
1079 * Returns a human-readable descriptive string if found,
1080 * returns NULL if not found
1081 *
1082 * It is the responsibility of the calling function to handle the
1083 * error case sensibly (i.e. don't just print out the return string.
1084 *
1085 */
1086static const char *
1087str_from_map_or_null(int type, pgp_map_t *map)
1088{
1089	pgp_map_t      *row;
1090
1091	for (row = map; row->string != NULL; row++) {
1092		if (row->type == type) {
1093			return row->string;
1094		}
1095	}
1096	return NULL;
1097}
1098
1099/**
1100 * \ingroup Core_Print
1101 *
1102 * Searches the given map for the given type.
1103 * Returns a readable string if found, "Unknown" if not.
1104 */
1105
1106const char     *
1107pgp_str_from_map(int type, pgp_map_t *map)
1108{
1109	const char     *str;
1110
1111	str = str_from_map_or_null(type, map);
1112	return (str) ? str : "Unknown";
1113}
1114
1115#define LINELEN	16
1116
1117/* show hexadecimal/ascii dump */
1118void
1119hexdump(FILE *fp, const char *header, const uint8_t *src, size_t length)
1120{
1121	size_t	i;
1122	char	line[LINELEN + 1];
1123
1124	(void) fprintf(fp, "%s%s", (header) ? header : "", (header) ? "\n" : "");
1125	(void) fprintf(fp, "[%" PRIsize "u char%s]\n", length, (length == 1) ? "" : "s");
1126	for (i = 0 ; i < length ; i++) {
1127		if (i % LINELEN == 0) {
1128			(void) fprintf(fp, "%.5" PRIsize "u | ", i);
1129		}
1130		(void) fprintf(fp, "%.02x ", (uint8_t)src[i]);
1131		line[i % LINELEN] = (isprint(src[i])) ? src[i] : '.';
1132		if (i % LINELEN == LINELEN - 1) {
1133			line[LINELEN] = 0x0;
1134			(void) fprintf(fp, " | %s\n", line);
1135		}
1136	}
1137	if (i % LINELEN != 0) {
1138		for ( ; i % LINELEN != 0 ; i++) {
1139			(void) fprintf(fp, "   ");
1140			line[i % LINELEN] = ' ';
1141		}
1142		line[LINELEN] = 0x0;
1143		(void) fprintf(fp, " | %s\n", line);
1144	}
1145}
1146
1147/**
1148 * \ingroup HighLevel_Functions
1149 * \brief Closes down OpenPGP::SDK.
1150 *
1151 * Close down OpenPGP:SDK, release any resources under the control of
1152 * the library.
1153 */
1154
1155void
1156pgp_finish(void)
1157{
1158	pgp_crypto_finish();
1159}
1160
1161static int
1162sum16_reader(pgp_stream_t *stream, void *dest_, size_t length, pgp_error_t **errors,
1163	     pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
1164{
1165	const uint8_t	*dest = dest_;
1166	sum16_t		*arg = pgp_reader_get_arg(readinfo);
1167	int		 r;
1168	int		 n;
1169
1170	r = pgp_stacked_read(stream, dest_, length, errors, readinfo, cbinfo);
1171	if (r < 0) {
1172		return r;
1173	}
1174	for (n = 0; n < r; ++n) {
1175		arg->sum = (arg->sum + dest[n]) & 0xffff;
1176	}
1177	return r;
1178}
1179
1180static void
1181sum16_destroyer(pgp_reader_t *readinfo)
1182{
1183	free(pgp_reader_get_arg(readinfo));
1184}
1185
1186/**
1187   \ingroup Internal_Readers_Sum16
1188   \param stream Parse settings
1189*/
1190
1191void
1192pgp_reader_push_sum16(pgp_stream_t *stream)
1193{
1194	sum16_t    *arg;
1195
1196	if ((arg = calloc(1, sizeof(*arg))) == NULL) {
1197		(void) fprintf(stderr, "pgp_reader_push_sum16: bad alloc\n");
1198	} else {
1199		pgp_reader_push(stream, sum16_reader, sum16_destroyer, arg);
1200	}
1201}
1202
1203/**
1204   \ingroup Internal_Readers_Sum16
1205   \param stream Parse settings
1206   \return sum
1207*/
1208uint16_t
1209pgp_reader_pop_sum16(pgp_stream_t *stream)
1210{
1211	uint16_t	 sum;
1212	sum16_t		*arg;
1213
1214	arg = pgp_reader_get_arg(pgp_readinfo(stream));
1215	sum = arg->sum;
1216	pgp_reader_pop(stream);
1217	free(arg);
1218	return sum;
1219}
1220
1221/* small useful functions for setting the file-level debugging levels */
1222/* if the debugv list contains the filename in question, we're debugging it */
1223
1224enum {
1225	MAX_DEBUG_NAMES = 32
1226};
1227
1228static int      debugc;
1229static char    *debugv[MAX_DEBUG_NAMES];
1230
1231/* set the debugging level per filename */
1232int
1233pgp_set_debug_level(const char *f)
1234{
1235	const char     *name;
1236	int             i;
1237
1238	if (f == NULL) {
1239		f = "all";
1240	}
1241	if ((name = strrchr(f, '/')) == NULL) {
1242		name = f;
1243	} else {
1244		name += 1;
1245	}
1246	for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) {
1247		if (strcmp(debugv[i], name) == 0) {
1248			return 1;
1249		}
1250	}
1251	if (i == MAX_DEBUG_NAMES) {
1252		return 0;
1253	}
1254	debugv[debugc++] = netpgp_strdup(name);
1255	return 1;
1256}
1257
1258/* get the debugging level per filename */
1259int
1260pgp_get_debug_level(const char *f)
1261{
1262	const char     *name;
1263	int             i;
1264
1265	if ((name = strrchr(f, '/')) == NULL) {
1266		name = f;
1267	} else {
1268		name += 1;
1269	}
1270	for (i = 0; i < debugc; i++) {
1271		if (strcmp(debugv[i], "all") == 0 ||
1272		    strcmp(debugv[i], name) == 0) {
1273			return 1;
1274		}
1275	}
1276	return 0;
1277}
1278
1279/* return the version for the library */
1280const char *
1281pgp_get_info(const char *type)
1282{
1283	if (strcmp(type, "version") == 0) {
1284		return NETPGP_VERSION_STRING;
1285	}
1286	if (strcmp(type, "maintainer") == 0) {
1287		return NETPGP_MAINTAINER;
1288	}
1289	return "[unknown]";
1290}
1291
1292/* local version of asprintf so we don't have to play autoconf games */
1293int
1294pgp_asprintf(char **ret, const char *fmt, ...)
1295{
1296	va_list args;
1297	char    buf[120 * 1024];	/* XXX - "huge" buffer on stack */
1298	int     cc;
1299
1300	va_start(args, fmt);
1301	cc = vsnprintf(buf, sizeof(buf), fmt, args);
1302	va_end(args);
1303	if ((*ret = calloc(1, (size_t)(cc + 1))) == NULL) {
1304		*ret = NULL;
1305		return -1;
1306	}
1307	(void) memcpy(*ret, buf, (size_t)cc);
1308	(*ret)[cc] = 0x0;
1309	return cc;
1310}
1311
1312void
1313netpgp_log(const char *fmt, ...)
1314{
1315	va_list	 vp;
1316	time_t	 t;
1317	char	 buf[BUFSIZ * 2];
1318	int	 cc;
1319
1320	(void) time(&t);
1321	cc = snprintf(buf, sizeof(buf), "%.24s: netpgp: ", ctime(&t));
1322	va_start(vp, fmt);
1323	(void) vsnprintf(&buf[cc], sizeof(buf) - (size_t)cc, fmt, vp);
1324	va_end(vp);
1325	/* do something with message */
1326	/* put into log buffer? */
1327}
1328
1329/* portable replacement for strdup(3) */
1330char *
1331netpgp_strdup(const char *s)
1332{
1333	size_t	 len;
1334	char	*cp;
1335
1336	len = strlen(s);
1337	if ((cp = calloc(1, len + 1)) != NULL) {
1338		(void) memcpy(cp, s, len);
1339		cp[len] = 0x0;
1340	}
1341	return cp;
1342}
1343
1344/* portable replacement for strcasecmp(3) */
1345int
1346netpgp_strcasecmp(const char *s1, const char *s2)
1347{
1348	int	n;
1349
1350	for (n = 0 ; *s1 && *s2 && (n = tolower((uint8_t)*s1) - tolower((uint8_t)*s2)) == 0 ; s1++, s2++) {
1351	}
1352	return n;
1353}
1354