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