1 /*- 2 * Copyright (c) 2009 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.25 2009/12/05 07:08:18 agc Exp $"); 61 #endif 62 63 #include <sys/types.h> 64 #include <sys/stat.h> 65 #include <sys/mman.h> 66 67 #include <stdarg.h> 68 #include <stdio.h> 69 #include <stdlib.h> 70 #include <string.h> 71 72 #ifdef HAVE_UNISTD_H 73 #include <unistd.h> 74 #endif 75 76 #ifdef HAVE_OPENSSL_RAND_H 77 #include <openssl/rand.h> 78 #endif 79 80 #include "errors.h" 81 #include "packet.h" 82 #include "crypto.h" 83 #include "create.h" 84 #include "packet-parse.h" 85 #include "packet-show.h" 86 #include "signature.h" 87 #include "netpgpsdk.h" 88 #include "netpgpdefs.h" 89 #include "memory.h" 90 #include "readerwriter.h" 91 #include "version.h" 92 #include "netpgpdigest.h" 93 94 #ifdef WIN32 95 #define vsnprintf _vsnprintf 96 #endif 97 98 99 typedef struct { 100 __ops_keyring_t *keyring; 101 } accumulate_t; 102 103 /** 104 * \ingroup Core_Callbacks 105 */ 106 static __ops_cb_ret_t 107 accumulate_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 108 { 109 const __ops_contents_t *content = &pkt->u; 110 __ops_keyring_t *keyring; 111 accumulate_t *accumulate; 112 113 accumulate = __ops_callback_arg(cbinfo); 114 keyring = accumulate->keyring; 115 switch (pkt->tag) { 116 case OPS_PTAG_CT_PUBLIC_KEY: 117 case OPS_PTAG_CT_SECRET_KEY: 118 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 119 if (__ops_get_debug_level(__FILE__)) { 120 (void) fprintf(stderr, "Creating key %u - tag %u\n", 121 keyring->keyc, pkt->tag); 122 } 123 if (pkt->tag == OPS_PTAG_CT_PUBLIC_KEY) { 124 __ops_add_to_pubring(keyring, &content->pubkey); 125 } else { 126 __ops_add_to_secring(keyring, &content->seckey); 127 } 128 return OPS_KEEP_MEMORY; 129 case OPS_PTAG_CT_USER_ID: 130 if (__ops_get_debug_level(__FILE__)) { 131 (void) fprintf(stderr, "User ID: %s for key %d\n", 132 content->userid.userid, 133 keyring->keyc - 1); 134 } 135 if (keyring->keyc > 0) { 136 __ops_add_userid(&keyring->keys[keyring->keyc - 1], 137 &content->userid); 138 return OPS_KEEP_MEMORY; 139 } 140 OPS_ERROR(cbinfo->errors, OPS_E_P_NO_USERID, "No userid found"); 141 return OPS_KEEP_MEMORY; 142 143 case OPS_PARSER_PACKET_END: 144 if (keyring->keyc > 0) { 145 __ops_add_subpacket(&keyring->keys[keyring->keyc - 1], 146 &content->packet); 147 return OPS_KEEP_MEMORY; 148 } 149 return OPS_RELEASE_MEMORY; 150 151 case OPS_PARSER_ERROR: 152 (void) fprintf(stderr, "Error: %s\n", content->error.error); 153 return OPS_FINISHED; 154 155 case OPS_PARSER_ERRCODE: 156 (void) fprintf(stderr, "parse error: %s\n", 157 __ops_errcode(content->errcode.errcode)); 158 break; 159 160 default: 161 break; 162 } 163 164 /* XXX: we now exclude so many things, we should either drop this or */ 165 /* do something to pass on copies of the stuff we keep */ 166 return __ops_stacked_callback(pkt, cbinfo); 167 } 168 169 /** 170 * \ingroup Core_Parse 171 * 172 * Parse packets from an input stream until EOF or error. 173 * 174 * Key data found in the parsed data is added to #keyring. 175 * 176 * \param keyring Pointer to an existing keyring 177 * \param parse Options to use when parsing 178 */ 179 int 180 __ops_parse_and_accumulate(__ops_keyring_t *keyring, __ops_stream_t *parse) 181 { 182 accumulate_t accumulate; 183 const int printerrors = 1; 184 int ret; 185 186 if (parse->readinfo.accumulate) { 187 (void) fprintf(stderr, 188 "__ops_parse_and_accumulate: already init\n"); 189 return 0; 190 } 191 192 (void) memset(&accumulate, 0x0, sizeof(accumulate)); 193 194 accumulate.keyring = keyring; 195 196 __ops_callback_push(parse, accumulate_cb, &accumulate); 197 parse->readinfo.accumulate = 1; 198 ret = __ops_parse(parse, !printerrors); 199 200 return ret; 201 } 202 203 204 /** \file 205 * \brief Error Handling 206 */ 207 #define ERRNAME(code) { code, #code } 208 209 static __ops_errcode_name_map_t errcode_name_map[] = { 210 ERRNAME(OPS_E_OK), 211 ERRNAME(OPS_E_FAIL), 212 ERRNAME(OPS_E_SYSTEM_ERROR), 213 ERRNAME(OPS_E_UNIMPLEMENTED), 214 215 ERRNAME(OPS_E_R), 216 ERRNAME(OPS_E_R_READ_FAILED), 217 ERRNAME(OPS_E_R_EARLY_EOF), 218 ERRNAME(OPS_E_R_BAD_FORMAT), 219 ERRNAME(OPS_E_R_UNCONSUMED_DATA), 220 221 ERRNAME(OPS_E_W), 222 ERRNAME(OPS_E_W_WRITE_FAILED), 223 ERRNAME(OPS_E_W_WRITE_TOO_SHORT), 224 225 ERRNAME(OPS_E_P), 226 ERRNAME(OPS_E_P_NOT_ENOUGH_DATA), 227 ERRNAME(OPS_E_P_UNKNOWN_TAG), 228 ERRNAME(OPS_E_P_PACKET_CONSUMED), 229 ERRNAME(OPS_E_P_MPI_FORMAT_ERROR), 230 231 ERRNAME(OPS_E_C), 232 233 ERRNAME(OPS_E_V), 234 ERRNAME(OPS_E_V_BAD_SIGNATURE), 235 ERRNAME(OPS_E_V_NO_SIGNATURE), 236 ERRNAME(OPS_E_V_UNKNOWN_SIGNER), 237 238 ERRNAME(OPS_E_ALG), 239 ERRNAME(OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG), 240 ERRNAME(OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG), 241 ERRNAME(OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG), 242 ERRNAME(OPS_E_ALG_UNSUPPORTED_HASH_ALG), 243 244 ERRNAME(OPS_E_PROTO), 245 ERRNAME(OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT), 246 ERRNAME(OPS_E_PROTO_UNKNOWN_SS), 247 ERRNAME(OPS_E_PROTO_CRITICAL_SS_IGNORED), 248 ERRNAME(OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN), 249 ERRNAME(OPS_E_PROTO_BAD_SIGNATURE_VRSN), 250 ERRNAME(OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN), 251 ERRNAME(OPS_E_PROTO_BAD_PKSK_VRSN), 252 ERRNAME(OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN), 253 ERRNAME(OPS_E_PROTO_BAD_SK_CHECKSUM), 254 255 {0x00, NULL}, /* this is the end-of-array marker */ 256 }; 257 258 /** 259 * \ingroup Core_Errors 260 * \brief returns error code name 261 * \param errcode 262 * \return error code name or "Unknown" 263 */ 264 const char * 265 __ops_errcode(const __ops_errcode_t errcode) 266 { 267 return (__ops_str_from_map((int) errcode, 268 (__ops_map_t *) errcode_name_map)); 269 } 270 271 /* generic grab new storage function */ 272 void * 273 __ops_new(size_t size) 274 { 275 void *vp; 276 277 if ((vp = calloc(1, size)) == NULL) { 278 (void) fprintf(stderr, 279 "allocation failure for %" PRIsize "u bytes", size); 280 } 281 return vp; 282 } 283 284 /** 285 * \ingroup Core_Errors 286 * \brief Pushes the given error on the given errorstack 287 * \param errstack Error stack to use 288 * \param errcode Code of error to push 289 * \param sys_errno System errno (used if errcode=OPS_E_SYSTEM_ERROR) 290 * \param file Source filename where error occurred 291 * \param line Line in source file where error occurred 292 * \param fmt Comment 293 * 294 */ 295 296 void 297 __ops_push_error(__ops_error_t **errstack, __ops_errcode_t errcode, 298 int sys_errno, const char *file, int line, const char *fmt,...) 299 { 300 /* first get the varargs and generate the comment */ 301 __ops_error_t *err; 302 unsigned maxbuf = 128; 303 va_list args; 304 char *comment; 305 306 if ((comment = calloc(1, maxbuf + 1)) == NULL) { 307 (void) fprintf(stderr, "calloc comment failure\n"); 308 return; 309 } 310 311 va_start(args, fmt); 312 vsnprintf(comment, maxbuf + 1, fmt, args); 313 va_end(args); 314 315 /* alloc a new error and add it to the top of the stack */ 316 317 if ((err = calloc(1, sizeof(*err))) == NULL) { 318 (void) fprintf(stderr, "calloc comment failure\n"); 319 return; 320 } 321 322 err->next = *errstack; 323 *errstack = err; 324 325 /* fill in the details */ 326 err->errcode = errcode; 327 err->sys_errno = sys_errno; 328 err->file = file; 329 err->line = line; 330 331 err->comment = comment; 332 } 333 334 /** 335 \ingroup Core_Errors 336 \brief print this error 337 \param err Error to print 338 */ 339 void 340 __ops_print_error(__ops_error_t *err) 341 { 342 printf("%s:%d: ", err->file, err->line); 343 if (err->errcode == OPS_E_SYSTEM_ERROR) { 344 printf("system error %d returned from %s()\n", err->sys_errno, 345 err->comment); 346 } else { 347 printf("%s, %s\n", __ops_errcode(err->errcode), err->comment); 348 } 349 } 350 351 /** 352 \ingroup Core_Errors 353 \brief Print all errors on stack 354 \param errstack Error stack to print 355 */ 356 void 357 __ops_print_errors(__ops_error_t *errstack) 358 { 359 __ops_error_t *err; 360 361 for (err = errstack; err != NULL; err = err->next) { 362 __ops_print_error(err); 363 } 364 } 365 366 /** 367 \ingroup Core_Errors 368 \brief Return 1 if given error is present anywhere on stack 369 \param errstack Error stack to check 370 \param errcode Error code to look for 371 \return 1 if found; else 0 372 */ 373 int 374 __ops_has_error(__ops_error_t *errstack, __ops_errcode_t errcode) 375 { 376 __ops_error_t *err; 377 378 for (err = errstack; err != NULL; err = err->next) { 379 if (err->errcode == errcode) { 380 return 1; 381 } 382 } 383 return 0; 384 } 385 386 /** 387 \ingroup Core_Errors 388 \brief Frees all errors on stack 389 \param errstack Error stack to free 390 */ 391 void 392 __ops_free_errors(__ops_error_t *errstack) 393 { 394 __ops_error_t *next; 395 396 while (errstack != NULL) { 397 next = errstack->next; 398 free(errstack->comment); 399 free(errstack); 400 errstack = next; 401 } 402 } 403 404 /** \file 405 */ 406 407 /** 408 * \ingroup Core_Keys 409 * \brief Calculate a public key fingerprint. 410 * \param fp Where to put the calculated fingerprint 411 * \param key The key for which the fingerprint is calculated 412 */ 413 414 void 415 __ops_fingerprint(__ops_fingerprint_t *fp, const __ops_pubkey_t *key) 416 { 417 if (key->version == 2 || key->version == 3) { 418 unsigned char *bn; 419 size_t n; 420 __ops_hash_t md5; 421 422 if (key->alg != OPS_PKA_RSA && 423 key->alg != OPS_PKA_RSA_ENCRYPT_ONLY && 424 key->alg != OPS_PKA_RSA_SIGN_ONLY) { 425 (void) fprintf(stderr, 426 "__ops_fingerprint: bad algorithm\n"); 427 return; 428 } 429 430 __ops_hash_md5(&md5); 431 if (!md5.init(&md5)) { 432 (void) fprintf(stderr, 433 "__ops_fingerprint: bad md5 alloc\n"); 434 return; 435 } 436 437 n = (size_t) BN_num_bytes(key->key.rsa.n); 438 if ((bn = calloc(1, n)) == NULL) { 439 (void) fprintf(stderr, 440 "__ops_fingerprint: bad bn alloc\n"); 441 return; 442 } 443 BN_bn2bin(key->key.rsa.n, bn); 444 md5.add(&md5, bn, n); 445 free(bn); 446 447 n = (size_t) BN_num_bytes(key->key.rsa.e); 448 if ((bn = calloc(1, n)) == NULL) { 449 (void) fprintf(stderr, 450 "__ops_fingerprint: bad bn alloc 2\n"); 451 return; 452 } 453 BN_bn2bin(key->key.rsa.e, bn); 454 md5.add(&md5, bn, n); 455 free(bn); 456 457 md5.finish(&md5, fp->fingerprint); 458 fp->length = 16; 459 } else { 460 __ops_memory_t *mem = __ops_memory_new(); 461 __ops_hash_t sha1; 462 size_t len; 463 464 __ops_build_pubkey(mem, key, 0); 465 466 if (__ops_get_debug_level(__FILE__)) { 467 fprintf(stderr, "-> creating key fingerprint\n"); 468 } 469 __ops_hash_sha1(&sha1); 470 if (!sha1.init(&sha1)) { 471 (void) fprintf(stderr, 472 "__ops_fingerprint: bad sha1 alloc\n"); 473 return; 474 } 475 476 len = __ops_mem_len(mem); 477 478 __ops_hash_add_int(&sha1, 0x99, 1); 479 __ops_hash_add_int(&sha1, len, 2); 480 sha1.add(&sha1, __ops_mem_data(mem), len); 481 sha1.finish(&sha1, fp->fingerprint); 482 483 if (__ops_get_debug_level(__FILE__)) { 484 fprintf(stderr, "<- finished making key fingerprint\n"); 485 } 486 fp->length = OPS_FINGERPRINT_SIZE; 487 488 __ops_memory_free(mem); 489 } 490 } 491 492 /** 493 * \ingroup Core_Keys 494 * \brief Calculate the Key ID from the public key. 495 * \param keyid Space for the calculated ID to be stored 496 * \param key The key for which the ID is calculated 497 */ 498 499 void 500 __ops_keyid(unsigned char *keyid, const size_t idlen, const __ops_pubkey_t *key) 501 { 502 __ops_fingerprint_t finger; 503 504 if (key->version == 2 || key->version == 3) { 505 unsigned char bn[NETPGP_BUFSIZ]; 506 unsigned n; 507 508 n = (unsigned) BN_num_bytes(key->key.rsa.n); 509 if (n > sizeof(bn)) { 510 (void) fprintf(stderr, "__ops_keyid: bad num bytes\n"); 511 return; 512 } 513 if (key->alg != OPS_PKA_RSA && 514 key->alg != OPS_PKA_RSA_ENCRYPT_ONLY && 515 key->alg != OPS_PKA_RSA_SIGN_ONLY) { 516 (void) fprintf(stderr, "__ops_keyid: bad algorithm\n"); 517 return; 518 } 519 BN_bn2bin(key->key.rsa.n, bn); 520 (void) memcpy(keyid, bn + n - idlen, idlen); 521 } else { 522 __ops_fingerprint(&finger, key); 523 (void) memcpy(keyid, 524 finger.fingerprint + finger.length - idlen, 525 idlen); 526 } 527 } 528 529 /** 530 \ingroup Core_Hashes 531 \brief Add to the hash 532 \param hash Hash to add to 533 \param n Int to add 534 \param length Length of int in bytes 535 */ 536 void 537 __ops_hash_add_int(__ops_hash_t *hash, unsigned n, unsigned length) 538 { 539 while (length--) { 540 unsigned char c; 541 542 c = n >> (length * 8); 543 hash->add(hash, &c, 1); 544 } 545 } 546 547 /** 548 \ingroup Core_Hashes 549 \brief Setup hash for given hash algorithm 550 \param hash Hash to set up 551 \param alg Hash algorithm to use 552 */ 553 void 554 __ops_hash_any(__ops_hash_t *hash, __ops_hash_alg_t alg) 555 { 556 switch (alg) { 557 case OPS_HASH_MD5: 558 __ops_hash_md5(hash); 559 break; 560 561 case OPS_HASH_SHA1: 562 __ops_hash_sha1(hash); 563 break; 564 565 case OPS_HASH_SHA256: 566 __ops_hash_sha256(hash); 567 break; 568 569 case OPS_HASH_SHA384: 570 __ops_hash_sha384(hash); 571 break; 572 573 case OPS_HASH_SHA512: 574 __ops_hash_sha512(hash); 575 break; 576 577 case OPS_HASH_SHA224: 578 __ops_hash_sha224(hash); 579 break; 580 581 default: 582 (void) fprintf(stderr, "__ops_hash_any: bad algorithm\n"); 583 } 584 } 585 586 /** 587 \ingroup Core_Hashes 588 \brief Returns size of hash for given hash algorithm 589 \param alg Hash algorithm to use 590 \return Size of hash algorithm in bytes 591 */ 592 unsigned 593 __ops_hash_size(__ops_hash_alg_t alg) 594 { 595 switch (alg) { 596 case OPS_HASH_MD5: 597 return 16; 598 599 case OPS_HASH_SHA1: 600 return 20; 601 602 case OPS_HASH_SHA256: 603 return 32; 604 605 case OPS_HASH_SHA224: 606 return 28; 607 608 case OPS_HASH_SHA512: 609 return 64; 610 611 case OPS_HASH_SHA384: 612 return 48; 613 614 default: 615 (void) fprintf(stderr, "__ops_hash_size: bad algorithm\n"); 616 } 617 618 return 0; 619 } 620 621 /** 622 \ingroup Core_Hashes 623 \brief Returns hash enum corresponding to given string 624 \param hash Text name of hash algorithm i.e. "SHA1" 625 \returns Corresponding enum i.e. OPS_HASH_SHA1 626 */ 627 __ops_hash_alg_t 628 __ops_str_to_hash_alg(const char *hash) 629 { 630 if (strcasecmp(hash, "SHA1") == 0) { 631 return OPS_HASH_SHA1; 632 } 633 if (strcasecmp(hash, "MD5") == 0) { 634 return OPS_HASH_MD5; 635 } 636 if (strcasecmp(hash, "SHA256") == 0) { 637 return OPS_HASH_SHA256; 638 } 639 /* 640 if (strcasecmp(hash,"SHA224") == 0) { 641 return OPS_HASH_SHA224; 642 } 643 */ 644 if (strcasecmp(hash, "SHA512") == 0) { 645 return OPS_HASH_SHA512; 646 } 647 if (strcasecmp(hash, "SHA384") == 0) { 648 return OPS_HASH_SHA384; 649 } 650 return OPS_HASH_UNKNOWN; 651 } 652 653 /** 654 \ingroup Core_Hashes 655 \brief Hash given data 656 \param out Where to write the hash 657 \param alg Hash algorithm to use 658 \param in Data to hash 659 \param length Length of data 660 \return Size of hash created 661 */ 662 unsigned 663 __ops_hash(unsigned char *out, __ops_hash_alg_t alg, const void *in, 664 size_t length) 665 { 666 __ops_hash_t hash; 667 668 __ops_hash_any(&hash, alg); 669 if (!hash.init(&hash)) { 670 (void) fprintf(stderr, "__ops_hash: bad alloc\n"); 671 /* we'll just continue here - don't want to return a 0 hash */ 672 /* XXX - agc - no way to return failure */ 673 } 674 hash.add(&hash, in, length); 675 return hash.finish(&hash, out); 676 } 677 678 /** 679 \ingroup Core_Hashes 680 \brief Calculate hash for MDC packet 681 \param preamble Preamble to hash 682 \param sz_preamble Size of preamble 683 \param plaintext Plaintext to hash 684 \param sz_plaintext Size of plaintext 685 \param hashed Resulting hash 686 */ 687 void 688 __ops_calc_mdc_hash(const unsigned char *preamble, 689 const size_t sz_preamble, 690 const unsigned char *plaintext, 691 const unsigned sz_plaintext, 692 unsigned char *hashed) 693 { 694 unsigned char c; 695 __ops_hash_t hash; 696 697 if (__ops_get_debug_level(__FILE__)) { 698 unsigned i; 699 700 (void) fprintf(stderr, "__ops_calc_mdc_hash():\n"); 701 (void) fprintf(stderr, "\npreamble: "); 702 for (i = 0; i < sz_preamble; i++) 703 (void) fprintf(stderr, " 0x%02x", preamble[i]); 704 (void) fprintf(stderr, "\n"); 705 (void) fprintf(stderr, "\nplaintext (len=%u): ", sz_plaintext); 706 for (i = 0; i < sz_plaintext; i++) 707 (void) fprintf(stderr, " 0x%02x", plaintext[i]); 708 (void) fprintf(stderr, "\n"); 709 } 710 /* init */ 711 __ops_hash_any(&hash, OPS_HASH_SHA1); 712 if (!hash.init(&hash)) { 713 (void) fprintf(stderr, "__ops_calc_mdc_hash: bad alloc\n"); 714 /* we'll just continue here - it will die anyway */ 715 /* agc - XXX - no way to return failure */ 716 } 717 718 /* preamble */ 719 hash.add(&hash, preamble, sz_preamble); 720 /* plaintext */ 721 hash.add(&hash, plaintext, sz_plaintext); 722 /* MDC packet tag */ 723 c = MDC_PKT_TAG; 724 hash.add(&hash, &c, 1); 725 /* MDC packet len */ 726 c = OPS_SHA1_HASH_SIZE; 727 hash.add(&hash, &c, 1); 728 729 /* finish */ 730 hash.finish(&hash, hashed); 731 732 if (__ops_get_debug_level(__FILE__)) { 733 unsigned i; 734 735 (void) fprintf(stderr, "\nhashed (len=%d): ", 736 OPS_SHA1_HASH_SIZE); 737 for (i = 0; i < OPS_SHA1_HASH_SIZE; i++) { 738 (void) fprintf(stderr, " 0x%02x", hashed[i]); 739 } 740 (void) fprintf(stderr, "\n"); 741 } 742 } 743 744 /** 745 \ingroup HighLevel_Supported 746 \brief Is this Hash Algorithm supported? 747 \param hash_alg Hash Algorithm to check 748 \return 1 if supported; else 0 749 */ 750 unsigned 751 __ops_is_hash_alg_supported(const __ops_hash_alg_t *hash_alg) 752 { 753 switch (*hash_alg) { 754 case OPS_HASH_MD5: 755 case OPS_HASH_SHA1: 756 case OPS_HASH_SHA256: 757 return 1; 758 759 default: 760 return 0; 761 } 762 } 763 764 void 765 __ops_random(void *dest, size_t length) 766 { 767 RAND_bytes(dest, (int)length); 768 } 769 770 /** 771 \ingroup HighLevel_Memory 772 \brief Memory to initialise 773 \param mem memory to initialise 774 \param needed Size to initialise to 775 */ 776 void 777 __ops_memory_init(__ops_memory_t *mem, size_t needed) 778 { 779 unsigned char *temp; 780 781 mem->length = 0; 782 if (mem->buf) { 783 if (mem->allocated < needed) { 784 if ((temp = realloc(mem->buf, needed)) == NULL) { 785 (void) fprintf(stderr, "__ops_memory_init: bad alloc\n"); 786 } else { 787 mem->buf = temp; 788 mem->allocated = needed; 789 } 790 } 791 } else { 792 if ((mem->buf = calloc(1, needed)) == NULL) { 793 (void) fprintf(stderr, "__ops_memory_init: bad alloc\n"); 794 } else { 795 mem->allocated = needed; 796 } 797 } 798 } 799 800 /** 801 \ingroup HighLevel_Memory 802 \brief Pad memory to required length 803 \param mem Memory to use 804 \param length New size 805 */ 806 void 807 __ops_memory_pad(__ops_memory_t *mem, size_t length) 808 { 809 unsigned char *temp; 810 811 if (mem->allocated < mem->length) { 812 (void) fprintf(stderr, "__ops_memory_pad: bad alloc in\n"); 813 return; 814 } 815 if (mem->allocated < mem->length + length) { 816 mem->allocated = mem->allocated * 2 + length; 817 temp = realloc(mem->buf, mem->allocated); 818 if (temp == NULL) { 819 (void) fprintf(stderr, "__ops_memory_pad: bad alloc\n"); 820 } else { 821 mem->buf = temp; 822 } 823 } 824 if (mem->allocated < mem->length + length) { 825 (void) fprintf(stderr, "__ops_memory_pad: bad alloc out\n"); 826 } 827 } 828 829 /** 830 \ingroup HighLevel_Memory 831 \brief Add data to memory 832 \param mem Memory to which to add 833 \param src Data to add 834 \param length Length of data to add 835 */ 836 void 837 __ops_memory_add(__ops_memory_t *mem, const unsigned char *src, size_t length) 838 { 839 __ops_memory_pad(mem, length); 840 (void) memcpy(mem->buf + mem->length, src, length); 841 mem->length += length; 842 } 843 844 /* XXX: this could be refactored via the writer, but an awful lot of */ 845 /* hoops to jump through for 2 lines of code! */ 846 void 847 __ops_memory_place_int(__ops_memory_t *mem, unsigned offset, unsigned n, 848 size_t length) 849 { 850 if (mem->allocated < offset + length) { 851 (void) fprintf(stderr, 852 "__ops_memory_place_int: bad alloc\n"); 853 } else { 854 while (length-- > 0) { 855 mem->buf[offset++] = n >> (length * 8); 856 } 857 } 858 } 859 860 /** 861 * \ingroup HighLevel_Memory 862 * \brief Retains allocated memory and set length of stored data to zero. 863 * \param mem Memory to clear 864 * \sa __ops_memory_release() 865 * \sa __ops_memory_free() 866 */ 867 void 868 __ops_memory_clear(__ops_memory_t *mem) 869 { 870 mem->length = 0; 871 } 872 873 /** 874 \ingroup HighLevel_Memory 875 \brief Free memory and associated data 876 \param mem Memory to free 877 \note This does not free mem itself 878 \sa __ops_memory_clear() 879 \sa __ops_memory_free() 880 */ 881 void 882 __ops_memory_release(__ops_memory_t *mem) 883 { 884 if (mem->mmapped) { 885 (void) munmap(mem->buf, mem->length); 886 } else { 887 free(mem->buf); 888 } 889 mem->buf = NULL; 890 mem->length = 0; 891 } 892 893 void 894 __ops_memory_make_packet(__ops_memory_t *out, __ops_content_tag_t tag) 895 { 896 size_t extra; 897 898 extra = (out->length < 192) ? 1 : (out->length < 8192 + 192) ? 2 : 5; 899 __ops_memory_pad(out, extra + 1); 900 memmove(out->buf + extra + 1, out->buf, out->length); 901 902 out->buf[0] = OPS_PTAG_ALWAYS_SET | OPS_PTAG_NEW_FORMAT | tag; 903 904 if (out->length < 192) { 905 out->buf[1] = out->length; 906 } else if (out->length < 8192 + 192) { 907 out->buf[1] = ((out->length - 192) >> 8) + 192; 908 out->buf[2] = out->length - 192; 909 } else { 910 out->buf[1] = 0xff; 911 out->buf[2] = out->length >> 24; 912 out->buf[3] = out->length >> 16; 913 out->buf[4] = out->length >> 8; 914 out->buf[5] = out->length; 915 } 916 917 out->length += extra + 1; 918 } 919 920 /** 921 \ingroup HighLevel_Memory 922 \brief Create a new zeroed __ops_memory_t 923 \return Pointer to new __ops_memory_t 924 \note Free using __ops_memory_free() after use. 925 \sa __ops_memory_free() 926 */ 927 928 __ops_memory_t * 929 __ops_memory_new(void) 930 { 931 return calloc(1, sizeof(__ops_memory_t)); 932 } 933 934 /** 935 \ingroup HighLevel_Memory 936 \brief Free memory ptr and associated memory 937 \param mem Memory to be freed 938 \sa __ops_memory_release() 939 \sa __ops_memory_clear() 940 */ 941 942 void 943 __ops_memory_free(__ops_memory_t *mem) 944 { 945 __ops_memory_release(mem); 946 free(mem); 947 } 948 949 /** 950 \ingroup HighLevel_Memory 951 \brief Get length of data stored in __ops_memory_t struct 952 \return Number of bytes in data 953 */ 954 size_t 955 __ops_mem_len(const __ops_memory_t *mem) 956 { 957 return mem->length; 958 } 959 960 /** 961 \ingroup HighLevel_Memory 962 \brief Get data stored in __ops_memory_t struct 963 \return Pointer to data 964 */ 965 void * 966 __ops_mem_data(__ops_memory_t *mem) 967 { 968 return mem->buf; 969 } 970 971 /* read a gile into an __ops_memory_t */ 972 int 973 __ops_mem_readfile(__ops_memory_t *mem, const char *f) 974 { 975 struct stat st; 976 FILE *fp; 977 int cc; 978 979 if ((fp = fopen(f, "rb")) == NULL) { 980 (void) fprintf(stderr, 981 "__ops_mem_readfile: can't open \"%s\"\n", f); 982 return 0; 983 } 984 (void) fstat(fileno(fp), &st); 985 mem->allocated = (size_t)st.st_size; 986 mem->buf = mmap(NULL, mem->allocated, PROT_READ, 987 MAP_PRIVATE | MAP_FILE, fileno(fp), 0); 988 if (mem->buf == MAP_FAILED) { 989 /* mmap failed for some reason - try to allocate memory */ 990 if ((mem->buf = calloc(1, mem->allocated)) == NULL) { 991 (void) fprintf(stderr, "__ops_mem_readfile: calloc\n"); 992 (void) fclose(fp); 993 return 0; 994 } 995 /* read into contents of mem */ 996 for (mem->length = 0 ; 997 (cc = read(fileno(fp), &mem->buf[mem->length], 998 mem->allocated - mem->length)) > 0 ; 999 mem->length += (size_t)cc) { 1000 } 1001 } else { 1002 mem->length = mem->allocated; 1003 mem->mmapped = 1; 1004 } 1005 (void) fclose(fp); 1006 return (mem->allocated == mem->length); 1007 } 1008 1009 typedef struct { 1010 unsigned short sum; 1011 } sum16_t; 1012 1013 1014 /** 1015 * Searches the given map for the given type. 1016 * Returns a human-readable descriptive string if found, 1017 * returns NULL if not found 1018 * 1019 * It is the responsibility of the calling function to handle the 1020 * error case sensibly (i.e. don't just print out the return string. 1021 * 1022 */ 1023 static const char * 1024 str_from_map_or_null(int type, __ops_map_t *map) 1025 { 1026 __ops_map_t *row; 1027 1028 for (row = map; row->string != NULL; row++) { 1029 if (row->type == type) { 1030 return row->string; 1031 } 1032 } 1033 return NULL; 1034 } 1035 1036 /** 1037 * \ingroup Core_Print 1038 * 1039 * Searches the given map for the given type. 1040 * Returns a readable string if found, "Unknown" if not. 1041 */ 1042 1043 const char * 1044 __ops_str_from_map(int type, __ops_map_t *map) 1045 { 1046 const char *str; 1047 1048 str = str_from_map_or_null(type, map); 1049 return (str) ? str : "Unknown"; 1050 } 1051 1052 void 1053 hexdump(FILE *fp, const unsigned char *src, size_t length, const char *sep) 1054 { 1055 unsigned i; 1056 1057 for (i = 0 ; i < length ; i += 2) { 1058 (void) fprintf(fp, "%02x", *src++); 1059 (void) fprintf(fp, "%02x%s", *src++, sep); 1060 } 1061 } 1062 1063 /** 1064 * \ingroup HighLevel_Functions 1065 * \brief Initialises OpenPGP::SDK. To be called before any other OPS function. 1066 * 1067 * Initialises OpenPGP::SDK and the underlying openssl library. 1068 */ 1069 1070 void 1071 __ops_init(void) 1072 { 1073 __ops_crypto_init(); 1074 } 1075 1076 /** 1077 * \ingroup HighLevel_Functions 1078 * \brief Closes down OpenPGP::SDK. 1079 * 1080 * Close down OpenPGP:SDK, release any resources under the control of 1081 * the library. No OpenPGP:SDK function other than __ops_init() should 1082 * be called after this function. 1083 */ 1084 1085 void 1086 __ops_finish(void) 1087 { 1088 __ops_crypto_finish(); 1089 } 1090 1091 static int 1092 sum16_reader(void *dest_, size_t length, __ops_error_t **errors, 1093 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 1094 { 1095 const unsigned char *dest = dest_; 1096 sum16_t *arg = __ops_reader_get_arg(readinfo); 1097 int r; 1098 int n; 1099 1100 r = __ops_stacked_read(dest_, length, errors, readinfo, cbinfo); 1101 if (r < 0) { 1102 return r; 1103 } 1104 for (n = 0; n < r; ++n) { 1105 arg->sum = (arg->sum + dest[n]) & 0xffff; 1106 } 1107 return r; 1108 } 1109 1110 static void 1111 sum16_destroyer(__ops_reader_t *readinfo) 1112 { 1113 free(__ops_reader_get_arg(readinfo)); 1114 } 1115 1116 /** 1117 \ingroup Internal_Readers_Sum16 1118 \param stream Parse settings 1119 */ 1120 1121 void 1122 __ops_reader_push_sum16(__ops_stream_t *stream) 1123 { 1124 sum16_t *arg; 1125 1126 if ((arg = calloc(1, sizeof(*arg))) == NULL) { 1127 (void) fprintf(stderr, "__ops_reader_push_sum16: bad alloc\n"); 1128 } else { 1129 __ops_reader_push(stream, sum16_reader, sum16_destroyer, arg); 1130 } 1131 } 1132 1133 /** 1134 \ingroup Internal_Readers_Sum16 1135 \param stream Parse settings 1136 \return sum 1137 */ 1138 unsigned short 1139 __ops_reader_pop_sum16(__ops_stream_t *stream) 1140 { 1141 unsigned short sum; 1142 sum16_t *arg; 1143 1144 arg = __ops_reader_get_arg(__ops_readinfo(stream)); 1145 sum = arg->sum; 1146 __ops_reader_pop(stream); 1147 free(arg); 1148 return sum; 1149 } 1150 1151 /* small useful functions for setting the file-level debugging levels */ 1152 /* if the debugv list contains the filename in question, we're debugging it */ 1153 1154 enum { 1155 MAX_DEBUG_NAMES = 32 1156 }; 1157 1158 static int debugc; 1159 static char *debugv[MAX_DEBUG_NAMES]; 1160 1161 /* set the debugging level per filename */ 1162 int 1163 __ops_set_debug_level(const char *f) 1164 { 1165 const char *name; 1166 int i; 1167 1168 if (f == NULL) { 1169 f = "all"; 1170 } 1171 if ((name = strrchr(f, '/')) == NULL) { 1172 name = f; 1173 } else { 1174 name += 1; 1175 } 1176 for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) { 1177 if (strcmp(debugv[i], name) == 0) { 1178 return 1; 1179 } 1180 } 1181 if (i == MAX_DEBUG_NAMES) { 1182 return 0; 1183 } 1184 debugv[debugc++] = strdup(name); 1185 return 1; 1186 } 1187 1188 /* get the debugging level per filename */ 1189 int 1190 __ops_get_debug_level(const char *f) 1191 { 1192 const char *name; 1193 int i; 1194 1195 if ((name = strrchr(f, '/')) == NULL) { 1196 name = f; 1197 } else { 1198 name += 1; 1199 } 1200 for (i = 0; i < debugc; i++) { 1201 if (strcmp(debugv[i], "all") == 0 || 1202 strcmp(debugv[i], name) == 0) { 1203 return 1; 1204 } 1205 } 1206 return 0; 1207 } 1208 1209 /* return the version for the library */ 1210 const char * 1211 __ops_get_info(const char *type) 1212 { 1213 if (strcmp(type, "version") == 0) { 1214 return NETPGP_VERSION_STRING; 1215 } 1216 if (strcmp(type, "maintainer") == 0) { 1217 return NETPGP_MAINTAINER; 1218 } 1219 return "[unknown]"; 1220 } 1221 1222 void 1223 netpgp_log(const char *fmt, ...) 1224 { 1225 va_list vp; 1226 time_t t; 1227 char buf[BUFSIZ * 2]; 1228 char *cp; 1229 int cc; 1230 1231 (void) time(&t); 1232 cp = ctime(&t); 1233 cc = snprintf(buf, sizeof(buf), "%.24s: netpgp: ", cp); 1234 va_start(vp, fmt); 1235 (void) vsnprintf(&buf[cc], sizeof(buf) - (size_t)cc, fmt, vp); 1236 va_end(vp); 1237 /* do something with message */ 1238 /* put into log buffer? */ 1239 } 1240