xref: /netbsd/crypto/external/bsd/netpgp/dist/src/lib/misc.c (revision 45a5153a)
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.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
accumulate_cb(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)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
pgp_parse_and_accumulate(pgp_keyring_t * keyring,pgp_stream_t * parse)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     *
pgp_errcode(const pgp_errcode_t errcode)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 *
pgp_new(size_t size)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
pgp_push_error(pgp_error_t ** errstack,pgp_errcode_t errcode,int sys_errno,const char * file,int line,const char * fmt,...)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
pgp_print_error(pgp_error_t * err)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
pgp_print_errors(pgp_error_t * errstack)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
pgp_has_error(pgp_error_t * errstack,pgp_errcode_t errcode)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
pgp_free_errors(pgp_error_t * errstack)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
hash_uint32(pgp_hash_t * hash,uint32_t n)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
hash_string(pgp_hash_t * hash,const uint8_t * buf,uint32_t len)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
hash_bignum(pgp_hash_t * hash,BIGNUM * bignum)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
pgp_fingerprint(pgp_fingerprint_t * fp,const pgp_pubkey_t * key,pgp_hash_alg_t hashtype)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
pgp_keyid(uint8_t * keyid,const size_t idlen,const pgp_pubkey_t * key,pgp_hash_alg_t hashtype)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
pgp_hash_add_int(pgp_hash_t * hash,unsigned n,unsigned length)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
pgp_hash_any(pgp_hash_t * hash,pgp_hash_alg_t alg)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
pgp_hash_size(pgp_hash_alg_t alg)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
pgp_str_to_hash_alg(const char * hash)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
pgp_hash(uint8_t * out,pgp_hash_alg_t alg,const void * in,size_t length)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
pgp_calc_mdc_hash(const uint8_t * preamble,const size_t sz_preamble,const uint8_t * plaintext,const unsigned sz_plaintext,uint8_t * hashed)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
pgp_is_hash_alg_supported(const pgp_hash_alg_t * hash_alg)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
pgp_str_to_cipher(const char * cipher)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
pgp_random(void * dest,size_t length)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
pgp_memory_init(pgp_memory_t * mem,size_t needed)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
pgp_memory_pad(pgp_memory_t * mem,size_t length)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
pgp_memory_add(pgp_memory_t * mem,const uint8_t * src,size_t length)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
pgp_memory_place_int(pgp_memory_t * mem,unsigned offset,unsigned n,size_t length)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
pgp_memory_clear(pgp_memory_t * mem)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
pgp_memory_release(pgp_memory_t * mem)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
pgp_memory_make_packet(pgp_memory_t * out,pgp_content_enum tag)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   *
pgp_memory_new(void)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
pgp_memory_free(pgp_memory_t * mem)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
pgp_mem_len(const pgp_memory_t * mem)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 *
pgp_mem_data(pgp_memory_t * mem)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
pgp_mem_readfile(pgp_memory_t * mem,const char * f)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 *
str_from_map_or_null(int type,pgp_map_t * map)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     *
pgp_str_from_map(int type,pgp_map_t * map)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
hexdump(FILE * fp,const char * header,const uint8_t * src,size_t length)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
pgp_finish(void)1181 pgp_finish(void)
1182 {
1183 	pgp_crypto_finish();
1184 }
1185 
1186 static int
sum16_reader(pgp_stream_t * stream,void * dest_,size_t length,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)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
sum16_destroyer(pgp_reader_t * readinfo)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
pgp_reader_push_sum16(pgp_stream_t * stream)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
pgp_reader_pop_sum16(pgp_stream_t * stream)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
pgp_set_debug_level(const char * f)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
pgp_get_debug_level(const char * f)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 *
pgp_get_info(const char * type)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
pgp_asprintf(char ** ret,const char * fmt,...)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
netpgp_log(const char * fmt,...)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 *
netpgp_strdup(const char * s)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
netpgp_strcasecmp(const char * s1,const char * s2)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
ecdsa_nid(const pgp_ecdsa_pubkey_t * pub)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
ecdsa_numbits(const pgp_ecdsa_pubkey_t * pub)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
ecdsa_hashsize(const pgp_ecdsa_pubkey_t * pub)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
ecdsa_hashalg(const pgp_ecdsa_pubkey_t * pub)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