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.22 2009/10/07 16:19:51 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 if (mem->allocated < mem->length) { 821 (void) fprintf(stderr, "__ops_memory_pad: bad alloc in\n"); 822 return; 823 } 824 if (mem->allocated < mem->length + length) { 825 mem->allocated = mem->allocated * 2 + length; 826 mem->buf = realloc(mem->buf, mem->allocated); 827 } 828 if (mem->allocated < mem->length + length) { 829 (void) fprintf(stderr, "__ops_memory_pad: bad alloc out\n"); 830 } 831 } 832 833 /** 834 \ingroup HighLevel_Memory 835 \brief Add data to memory 836 \param mem Memory to which to add 837 \param src Data to add 838 \param length Length of data to add 839 */ 840 void 841 __ops_memory_add(__ops_memory_t *mem, const unsigned char *src, size_t length) 842 { 843 __ops_memory_pad(mem, length); 844 (void) memcpy(mem->buf + mem->length, src, length); 845 mem->length += length; 846 } 847 848 /* XXX: this could be refactored via the writer, but an awful lot of */ 849 /* hoops to jump through for 2 lines of code! */ 850 void 851 __ops_memory_place_int(__ops_memory_t *mem, unsigned offset, unsigned n, 852 size_t length) 853 { 854 if (mem->allocated < offset + length) { 855 (void) fprintf(stderr, 856 "__ops_memory_place_int: bad alloc\n"); 857 } else { 858 while (length-- > 0) { 859 mem->buf[offset++] = n >> (length * 8); 860 } 861 } 862 } 863 864 /** 865 * \ingroup HighLevel_Memory 866 * \brief Retains allocated memory and set length of stored data to zero. 867 * \param mem Memory to clear 868 * \sa __ops_memory_release() 869 * \sa __ops_memory_free() 870 */ 871 void 872 __ops_memory_clear(__ops_memory_t *mem) 873 { 874 mem->length = 0; 875 } 876 877 /** 878 \ingroup HighLevel_Memory 879 \brief Free memory and associated data 880 \param mem Memory to free 881 \note This does not free mem itself 882 \sa __ops_memory_clear() 883 \sa __ops_memory_free() 884 */ 885 void 886 __ops_memory_release(__ops_memory_t *mem) 887 { 888 if (mem->mmapped) { 889 (void) munmap(mem->buf, mem->length); 890 } else { 891 free(mem->buf); 892 } 893 mem->buf = NULL; 894 mem->length = 0; 895 } 896 897 void 898 __ops_memory_make_packet(__ops_memory_t *out, __ops_content_tag_t tag) 899 { 900 size_t extra; 901 902 extra = (out->length < 192) ? 1 : (out->length < 8192 + 192) ? 2 : 5; 903 __ops_memory_pad(out, extra + 1); 904 memmove(out->buf + extra + 1, out->buf, out->length); 905 906 out->buf[0] = OPS_PTAG_ALWAYS_SET | OPS_PTAG_NEW_FORMAT | tag; 907 908 if (out->length < 192) { 909 out->buf[1] = out->length; 910 } else if (out->length < 8192 + 192) { 911 out->buf[1] = ((out->length - 192) >> 8) + 192; 912 out->buf[2] = out->length - 192; 913 } else { 914 out->buf[1] = 0xff; 915 out->buf[2] = out->length >> 24; 916 out->buf[3] = out->length >> 16; 917 out->buf[4] = out->length >> 8; 918 out->buf[5] = out->length; 919 } 920 921 out->length += extra + 1; 922 } 923 924 /** 925 \ingroup HighLevel_Memory 926 \brief Create a new zeroed __ops_memory_t 927 \return Pointer to new __ops_memory_t 928 \note Free using __ops_memory_free() after use. 929 \sa __ops_memory_free() 930 */ 931 932 __ops_memory_t * 933 __ops_memory_new(void) 934 { 935 return calloc(1, sizeof(__ops_memory_t)); 936 } 937 938 /** 939 \ingroup HighLevel_Memory 940 \brief Free memory ptr and associated memory 941 \param mem Memory to be freed 942 \sa __ops_memory_release() 943 \sa __ops_memory_clear() 944 */ 945 946 void 947 __ops_memory_free(__ops_memory_t *mem) 948 { 949 __ops_memory_release(mem); 950 free(mem); 951 } 952 953 /** 954 \ingroup HighLevel_Memory 955 \brief Get length of data stored in __ops_memory_t struct 956 \return Number of bytes in data 957 */ 958 size_t 959 __ops_mem_len(const __ops_memory_t *mem) 960 { 961 return mem->length; 962 } 963 964 /** 965 \ingroup HighLevel_Memory 966 \brief Get data stored in __ops_memory_t struct 967 \return Pointer to data 968 */ 969 void * 970 __ops_mem_data(__ops_memory_t *mem) 971 { 972 return mem->buf; 973 } 974 975 /* read a gile into an __ops_memory_t */ 976 int 977 __ops_mem_readfile(__ops_memory_t *mem, const char *f) 978 { 979 struct stat st; 980 FILE *fp; 981 int cc; 982 983 if ((fp = fopen(f, "rb")) == NULL) { 984 (void) fprintf(stderr, 985 "__ops_mem_readfile: can't open \"%s\"\n", f); 986 return 0; 987 } 988 (void) fstat(fileno(fp), &st); 989 mem->allocated = (size_t)st.st_size; 990 mem->buf = mmap(NULL, mem->allocated, PROT_READ, 991 MAP_PRIVATE | MAP_FILE, fileno(fp), 0); 992 if (mem->buf == MAP_FAILED) { 993 /* mmap failed for some reason - try to allocate memory */ 994 if ((mem->buf = calloc(1, mem->allocated)) == NULL) { 995 (void) fprintf(stderr, "__ops_mem_readfile: calloc\n"); 996 (void) fclose(fp); 997 return 0; 998 } 999 /* read into contents of mem */ 1000 for (mem->length = 0 ; 1001 (cc = read(fileno(fp), &mem->buf[mem->length], 1002 mem->allocated - mem->length)) > 0 ; 1003 mem->length += (size_t)cc) { 1004 } 1005 } else { 1006 mem->length = mem->allocated; 1007 mem->mmapped = 1; 1008 } 1009 (void) fclose(fp); 1010 return (mem->allocated == mem->length); 1011 } 1012 1013 typedef struct { 1014 unsigned short sum; 1015 } sum16_t; 1016 1017 1018 /** 1019 * Searches the given map for the given type. 1020 * Returns a human-readable descriptive string if found, 1021 * returns NULL if not found 1022 * 1023 * It is the responsibility of the calling function to handle the 1024 * error case sensibly (i.e. don't just print out the return string. 1025 * 1026 */ 1027 static const char * 1028 str_from_map_or_null(int type, __ops_map_t *map) 1029 { 1030 __ops_map_t *row; 1031 1032 for (row = map; row->string != NULL; row++) { 1033 if (row->type == type) { 1034 return row->string; 1035 } 1036 } 1037 return NULL; 1038 } 1039 1040 /** 1041 * \ingroup Core_Print 1042 * 1043 * Searches the given map for the given type. 1044 * Returns a readable string if found, "Unknown" if not. 1045 */ 1046 1047 const char * 1048 __ops_str_from_map(int type, __ops_map_t *map) 1049 { 1050 const char *str; 1051 1052 str = str_from_map_or_null(type, map); 1053 return (str) ? str : "Unknown"; 1054 } 1055 1056 void 1057 hexdump(FILE *fp, const unsigned char *src, size_t length, const char *sep) 1058 { 1059 unsigned i; 1060 1061 for (i = 0 ; i < length ; i += 2) { 1062 (void) fprintf(fp, "%02x", *src++); 1063 (void) fprintf(fp, "%02x%s", *src++, sep); 1064 } 1065 } 1066 1067 /** 1068 * \ingroup HighLevel_Functions 1069 * \brief Initialises OpenPGP::SDK. To be called before any other OPS function. 1070 * 1071 * Initialises OpenPGP::SDK and the underlying openssl library. 1072 */ 1073 1074 void 1075 __ops_init(void) 1076 { 1077 __ops_crypto_init(); 1078 } 1079 1080 /** 1081 * \ingroup HighLevel_Functions 1082 * \brief Closes down OpenPGP::SDK. 1083 * 1084 * Close down OpenPGP:SDK, release any resources under the control of 1085 * the library. No OpenPGP:SDK function other than __ops_init() should 1086 * be called after this function. 1087 */ 1088 1089 void 1090 __ops_finish(void) 1091 { 1092 __ops_crypto_finish(); 1093 } 1094 1095 static int 1096 sum16_reader(void *dest_, size_t length, __ops_error_t **errors, 1097 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 1098 { 1099 const unsigned char *dest = dest_; 1100 sum16_t *arg = __ops_reader_get_arg(readinfo); 1101 int r; 1102 int n; 1103 1104 r = __ops_stacked_read(dest_, length, errors, readinfo, cbinfo); 1105 if (r < 0) { 1106 return r; 1107 } 1108 for (n = 0; n < r; ++n) { 1109 arg->sum = (arg->sum + dest[n]) & 0xffff; 1110 } 1111 return r; 1112 } 1113 1114 static void 1115 sum16_destroyer(__ops_reader_t *readinfo) 1116 { 1117 free(__ops_reader_get_arg(readinfo)); 1118 } 1119 1120 /** 1121 \ingroup Internal_Readers_Sum16 1122 \param stream Parse settings 1123 */ 1124 1125 void 1126 __ops_reader_push_sum16(__ops_stream_t *stream) 1127 { 1128 sum16_t *arg; 1129 1130 if ((arg = calloc(1, sizeof(*arg))) == NULL) { 1131 (void) fprintf(stderr, "__ops_reader_push_sum16: bad alloc\n"); 1132 } else { 1133 __ops_reader_push(stream, sum16_reader, sum16_destroyer, arg); 1134 } 1135 } 1136 1137 /** 1138 \ingroup Internal_Readers_Sum16 1139 \param stream Parse settings 1140 \return sum 1141 */ 1142 unsigned short 1143 __ops_reader_pop_sum16(__ops_stream_t *stream) 1144 { 1145 unsigned short sum; 1146 sum16_t *arg; 1147 1148 arg = __ops_reader_get_arg(__ops_readinfo(stream)); 1149 sum = arg->sum; 1150 __ops_reader_pop(stream); 1151 free(arg); 1152 return sum; 1153 } 1154 1155 /* small useful functions for setting the file-level debugging levels */ 1156 /* if the debugv list contains the filename in question, we're debugging it */ 1157 1158 enum { 1159 MAX_DEBUG_NAMES = 32 1160 }; 1161 1162 static int debugc; 1163 static char *debugv[MAX_DEBUG_NAMES]; 1164 1165 /* set the debugging level per filename */ 1166 int 1167 __ops_set_debug_level(const char *f) 1168 { 1169 const char *name; 1170 int i; 1171 1172 if (f == NULL) { 1173 f = "all"; 1174 } 1175 if ((name = strrchr(f, '/')) == NULL) { 1176 name = f; 1177 } else { 1178 name += 1; 1179 } 1180 for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) { 1181 if (strcmp(debugv[i], name) == 0) { 1182 return 1; 1183 } 1184 } 1185 if (i == MAX_DEBUG_NAMES) { 1186 return 0; 1187 } 1188 debugv[debugc++] = strdup(name); 1189 return 1; 1190 } 1191 1192 /* get the debugging level per filename */ 1193 int 1194 __ops_get_debug_level(const char *f) 1195 { 1196 const char *name; 1197 int i; 1198 1199 if ((name = strrchr(f, '/')) == NULL) { 1200 name = f; 1201 } else { 1202 name += 1; 1203 } 1204 for (i = 0; i < debugc; i++) { 1205 if (strcmp(debugv[i], "all") == 0 || 1206 strcmp(debugv[i], name) == 0) { 1207 return 1; 1208 } 1209 } 1210 return 0; 1211 } 1212 1213 /* return the version for the library */ 1214 const char * 1215 __ops_get_info(const char *type) 1216 { 1217 if (strcmp(type, "version") == 0) { 1218 return NETPGP_VERSION_STRING; 1219 } 1220 if (strcmp(type, "maintainer") == 0) { 1221 return NETPGP_MAINTAINER; 1222 } 1223 return "[unknown]"; 1224 } 1225 1226 void 1227 netpgp_log(const char *fmt, ...) 1228 { 1229 va_list vp; 1230 time_t t; 1231 char buf[BUFSIZ * 2]; 1232 char *cp; 1233 int cc; 1234 1235 (void) time(&t); 1236 cp = ctime(&t); 1237 cc = snprintf(buf, sizeof(buf), "%.24s: netpgp: ", cp); 1238 va_start(vp, fmt); 1239 (void) vsnprintf(&buf[cc], sizeof(buf) - (size_t)cc, fmt, vp); 1240 va_end(vp); 1241 /* do something with message */ 1242 /* put into log buffer? */ 1243 } 1244