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