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