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