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.21 2009/10/06 02:39:53 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 md5.init(&md5); 443 444 n = (size_t) BN_num_bytes(key->key.rsa.n); 445 if ((bn = calloc(1, n)) == NULL) { 446 (void) fprintf(stderr, 447 "__ops_fingerprint: bad bn alloc\n"); 448 return; 449 } 450 BN_bn2bin(key->key.rsa.n, bn); 451 md5.add(&md5, bn, n); 452 free(bn); 453 454 n = (size_t) BN_num_bytes(key->key.rsa.e); 455 if ((bn = calloc(1, n)) == NULL) { 456 (void) fprintf(stderr, 457 "__ops_fingerprint: bad bn alloc 2\n"); 458 return; 459 } 460 BN_bn2bin(key->key.rsa.e, bn); 461 md5.add(&md5, bn, n); 462 free(bn); 463 464 md5.finish(&md5, fp->fingerprint); 465 fp->length = 16; 466 } else { 467 __ops_memory_t *mem = __ops_memory_new(); 468 __ops_hash_t sha1; 469 size_t len; 470 471 __ops_build_pubkey(mem, key, 0); 472 473 if (__ops_get_debug_level(__FILE__)) { 474 fprintf(stderr, "-> creating key fingerprint\n"); 475 } 476 __ops_hash_sha1(&sha1); 477 sha1.init(&sha1); 478 479 len = __ops_mem_len(mem); 480 481 __ops_hash_add_int(&sha1, 0x99, 1); 482 __ops_hash_add_int(&sha1, len, 2); 483 sha1.add(&sha1, __ops_mem_data(mem), len); 484 sha1.finish(&sha1, fp->fingerprint); 485 486 if (__ops_get_debug_level(__FILE__)) { 487 fprintf(stderr, "<- finished making key fingerprint\n"); 488 } 489 fp->length = OPS_FINGERPRINT_SIZE; 490 491 __ops_memory_free(mem); 492 } 493 } 494 495 /** 496 * \ingroup Core_Keys 497 * \brief Calculate the Key ID from the public key. 498 * \param keyid Space for the calculated ID to be stored 499 * \param key The key for which the ID is calculated 500 */ 501 502 void 503 __ops_keyid(unsigned char *keyid, const size_t idlen, const __ops_pubkey_t *key) 504 { 505 if (key->version == 2 || key->version == 3) { 506 unsigned char bn[NETPGP_BUFSIZ]; 507 unsigned n; 508 509 n = (unsigned) BN_num_bytes(key->key.rsa.n); 510 if (n > sizeof(bn)) { 511 (void) fprintf(stderr, "__ops_keyid: bad num bytes\n"); 512 return; 513 } 514 if (key->alg != OPS_PKA_RSA && 515 key->alg != OPS_PKA_RSA_ENCRYPT_ONLY && 516 key->alg != OPS_PKA_RSA_SIGN_ONLY) { 517 (void) fprintf(stderr, "__ops_keyid: bad algorithm\n"); 518 return; 519 } 520 BN_bn2bin(key->key.rsa.n, bn); 521 (void) memcpy(keyid, bn + n - idlen, idlen); 522 } else { 523 __ops_fingerprint_t finger; 524 525 __ops_fingerprint(&finger, key); 526 (void) memcpy(keyid, 527 finger.fingerprint + finger.length - idlen, 528 idlen); 529 } 530 } 531 532 /** 533 \ingroup Core_Hashes 534 \brief Add to the hash 535 \param hash Hash to add to 536 \param n Int to add 537 \param length Length of int in bytes 538 */ 539 void 540 __ops_hash_add_int(__ops_hash_t *hash, unsigned n, unsigned length) 541 { 542 while (length--) { 543 unsigned char c; 544 545 c = n >> (length * 8); 546 hash->add(hash, &c, 1); 547 } 548 } 549 550 /** 551 \ingroup Core_Hashes 552 \brief Setup hash for given hash algorithm 553 \param hash Hash to set up 554 \param alg Hash algorithm to use 555 */ 556 void 557 __ops_hash_any(__ops_hash_t *hash, __ops_hash_alg_t alg) 558 { 559 switch (alg) { 560 case OPS_HASH_MD5: 561 __ops_hash_md5(hash); 562 break; 563 564 case OPS_HASH_SHA1: 565 __ops_hash_sha1(hash); 566 break; 567 568 case OPS_HASH_SHA256: 569 __ops_hash_sha256(hash); 570 break; 571 572 case OPS_HASH_SHA384: 573 __ops_hash_sha384(hash); 574 break; 575 576 case OPS_HASH_SHA512: 577 __ops_hash_sha512(hash); 578 break; 579 580 case OPS_HASH_SHA224: 581 __ops_hash_sha224(hash); 582 break; 583 584 default: 585 (void) fprintf(stderr, "__ops_hash_any: bad algorithm\n"); 586 } 587 } 588 589 /** 590 \ingroup Core_Hashes 591 \brief Returns size of hash for given hash algorithm 592 \param alg Hash algorithm to use 593 \return Size of hash algorithm in bytes 594 */ 595 unsigned 596 __ops_hash_size(__ops_hash_alg_t alg) 597 { 598 switch (alg) { 599 case OPS_HASH_MD5: 600 return 16; 601 602 case OPS_HASH_SHA1: 603 return 20; 604 605 case OPS_HASH_SHA256: 606 return 32; 607 608 case OPS_HASH_SHA224: 609 return 28; 610 611 case OPS_HASH_SHA512: 612 return 64; 613 614 case OPS_HASH_SHA384: 615 return 48; 616 617 default: 618 (void) fprintf(stderr, "__ops_hash_size: bad algorithm\n"); 619 } 620 621 return 0; 622 } 623 624 /** 625 \ingroup Core_Hashes 626 \brief Returns hash enum corresponding to given string 627 \param hash Text name of hash algorithm i.e. "SHA1" 628 \returns Corresponding enum i.e. OPS_HASH_SHA1 629 */ 630 __ops_hash_alg_t 631 __ops_str_to_hash_alg(const char *hash) 632 { 633 if (strcmp(hash, "SHA1") == 0) { 634 return OPS_HASH_SHA1; 635 } 636 if (strcmp(hash, "MD5") == 0) { 637 return OPS_HASH_MD5; 638 } 639 if (strcmp(hash, "SHA256") == 0) { 640 return OPS_HASH_SHA256; 641 } 642 /* 643 if (strcmp(hash,"SHA224") == 0) { 644 return OPS_HASH_SHA224; 645 } 646 */ 647 if (strcmp(hash, "SHA512") == 0) { 648 return OPS_HASH_SHA512; 649 } 650 if (strcmp(hash, "SHA384") == 0) { 651 return OPS_HASH_SHA384; 652 } 653 return OPS_HASH_UNKNOWN; 654 } 655 656 /** 657 \ingroup Core_Hashes 658 \brief Hash given data 659 \param out Where to write the hash 660 \param alg Hash algorithm to use 661 \param in Data to hash 662 \param length Length of data 663 \return Size of hash created 664 */ 665 unsigned 666 __ops_hash(unsigned char *out, __ops_hash_alg_t alg, const void *in, 667 size_t length) 668 { 669 __ops_hash_t hash; 670 671 __ops_hash_any(&hash, alg); 672 hash.init(&hash); 673 hash.add(&hash, in, length); 674 return hash.finish(&hash, out); 675 } 676 677 /** 678 \ingroup Core_Hashes 679 \brief Calculate hash for MDC packet 680 \param preamble Preamble to hash 681 \param sz_preamble Size of preamble 682 \param plaintext Plaintext to hash 683 \param sz_plaintext Size of plaintext 684 \param hashed Resulting hash 685 */ 686 void 687 __ops_calc_mdc_hash(const unsigned char *preamble, 688 const size_t sz_preamble, 689 const unsigned char *plaintext, 690 const unsigned sz_plaintext, 691 unsigned char *hashed) 692 { 693 unsigned char c; 694 __ops_hash_t hash; 695 696 if (__ops_get_debug_level(__FILE__)) { 697 unsigned i; 698 699 (void) fprintf(stderr, "__ops_calc_mdc_hash():\n"); 700 (void) fprintf(stderr, "\npreamble: "); 701 for (i = 0; i < sz_preamble; i++) 702 (void) fprintf(stderr, " 0x%02x", preamble[i]); 703 (void) fprintf(stderr, "\n"); 704 (void) fprintf(stderr, "\nplaintext (len=%u): ", sz_plaintext); 705 for (i = 0; i < sz_plaintext; i++) 706 (void) fprintf(stderr, " 0x%02x", plaintext[i]); 707 (void) fprintf(stderr, "\n"); 708 } 709 /* init */ 710 __ops_hash_any(&hash, OPS_HASH_SHA1); 711 hash.init(&hash); 712 713 /* preamble */ 714 hash.add(&hash, preamble, sz_preamble); 715 /* plaintext */ 716 hash.add(&hash, plaintext, sz_plaintext); 717 /* MDC packet tag */ 718 c = MDC_PKT_TAG; 719 hash.add(&hash, &c, 1); 720 /* MDC packet len */ 721 c = OPS_SHA1_HASH_SIZE; 722 hash.add(&hash, &c, 1); 723 724 /* finish */ 725 hash.finish(&hash, hashed); 726 727 if (__ops_get_debug_level(__FILE__)) { 728 unsigned i; 729 730 (void) fprintf(stderr, "\nhashed (len=%d): ", 731 OPS_SHA1_HASH_SIZE); 732 for (i = 0; i < OPS_SHA1_HASH_SIZE; i++) { 733 (void) fprintf(stderr, " 0x%02x", hashed[i]); 734 } 735 (void) fprintf(stderr, "\n"); 736 } 737 } 738 739 /** 740 \ingroup HighLevel_Supported 741 \brief Is this Hash Algorithm supported? 742 \param hash_alg Hash Algorithm to check 743 \return 1 if supported; else 0 744 */ 745 unsigned 746 __ops_is_hash_alg_supported(const __ops_hash_alg_t *hash_alg) 747 { 748 switch (*hash_alg) { 749 case OPS_HASH_MD5: 750 case OPS_HASH_SHA1: 751 case OPS_HASH_SHA256: 752 return 1; 753 754 default: 755 return 0; 756 } 757 } 758 759 void 760 __ops_random(void *dest, size_t length) 761 { 762 RAND_bytes(dest, (int)length); 763 } 764 765 /** 766 \ingroup HighLevel_Memory 767 \brief Memory to initialise 768 \param mem memory to initialise 769 \param needed Size to initialise to 770 */ 771 void 772 __ops_memory_init(__ops_memory_t *mem, size_t needed) 773 { 774 mem->length = 0; 775 if (mem->buf) { 776 if (mem->allocated < needed) { 777 mem->buf = realloc(mem->buf, needed); 778 mem->allocated = needed; 779 } 780 return; 781 } 782 mem->buf = calloc(1, needed); 783 mem->allocated = needed; 784 } 785 786 /** 787 \ingroup HighLevel_Memory 788 \brief Pad memory to required length 789 \param mem Memory to use 790 \param length New size 791 */ 792 void 793 __ops_memory_pad(__ops_memory_t *mem, size_t length) 794 { 795 if (mem->allocated < mem->length) { 796 (void) fprintf(stderr, "__ops_memory_pad: bad alloc in\n"); 797 return; 798 } 799 if (mem->allocated < mem->length + length) { 800 mem->allocated = mem->allocated * 2 + length; 801 mem->buf = realloc(mem->buf, mem->allocated); 802 } 803 if (mem->allocated < mem->length + length) { 804 (void) fprintf(stderr, "__ops_memory_pad: bad alloc out\n"); 805 } 806 } 807 808 /** 809 \ingroup HighLevel_Memory 810 \brief Add data to memory 811 \param mem Memory to which to add 812 \param src Data to add 813 \param length Length of data to add 814 */ 815 void 816 __ops_memory_add(__ops_memory_t *mem, const unsigned char *src, size_t length) 817 { 818 __ops_memory_pad(mem, length); 819 (void) memcpy(mem->buf + mem->length, src, length); 820 mem->length += length; 821 } 822 823 /* XXX: this could be refactored via the writer, but an awful lot of */ 824 /* hoops to jump through for 2 lines of code! */ 825 void 826 __ops_memory_place_int(__ops_memory_t *mem, unsigned offset, unsigned n, 827 size_t length) 828 { 829 if (mem->allocated < offset + length) { 830 (void) fprintf(stderr, 831 "__ops_memory_place_int: bad alloc\n"); 832 } else { 833 while (length-- > 0) { 834 mem->buf[offset++] = n >> (length * 8); 835 } 836 } 837 } 838 839 /** 840 * \ingroup HighLevel_Memory 841 * \brief Retains allocated memory and set length of stored data to zero. 842 * \param mem Memory to clear 843 * \sa __ops_memory_release() 844 * \sa __ops_memory_free() 845 */ 846 void 847 __ops_memory_clear(__ops_memory_t *mem) 848 { 849 mem->length = 0; 850 } 851 852 /** 853 \ingroup HighLevel_Memory 854 \brief Free memory and associated data 855 \param mem Memory to free 856 \note This does not free mem itself 857 \sa __ops_memory_clear() 858 \sa __ops_memory_free() 859 */ 860 void 861 __ops_memory_release(__ops_memory_t *mem) 862 { 863 if (mem->mmapped) { 864 (void) munmap(mem->buf, mem->length); 865 } else { 866 free(mem->buf); 867 } 868 mem->buf = NULL; 869 mem->length = 0; 870 } 871 872 void 873 __ops_memory_make_packet(__ops_memory_t *out, __ops_content_tag_t tag) 874 { 875 size_t extra; 876 877 extra = (out->length < 192) ? 1 : (out->length < 8192 + 192) ? 2 : 5; 878 __ops_memory_pad(out, extra + 1); 879 memmove(out->buf + extra + 1, out->buf, out->length); 880 881 out->buf[0] = OPS_PTAG_ALWAYS_SET | OPS_PTAG_NEW_FORMAT | tag; 882 883 if (out->length < 192) { 884 out->buf[1] = out->length; 885 } else if (out->length < 8192 + 192) { 886 out->buf[1] = ((out->length - 192) >> 8) + 192; 887 out->buf[2] = out->length - 192; 888 } else { 889 out->buf[1] = 0xff; 890 out->buf[2] = out->length >> 24; 891 out->buf[3] = out->length >> 16; 892 out->buf[4] = out->length >> 8; 893 out->buf[5] = out->length; 894 } 895 896 out->length += extra + 1; 897 } 898 899 /** 900 \ingroup HighLevel_Memory 901 \brief Create a new zeroed __ops_memory_t 902 \return Pointer to new __ops_memory_t 903 \note Free using __ops_memory_free() after use. 904 \sa __ops_memory_free() 905 */ 906 907 __ops_memory_t * 908 __ops_memory_new(void) 909 { 910 return calloc(1, sizeof(__ops_memory_t)); 911 } 912 913 /** 914 \ingroup HighLevel_Memory 915 \brief Free memory ptr and associated memory 916 \param mem Memory to be freed 917 \sa __ops_memory_release() 918 \sa __ops_memory_clear() 919 */ 920 921 void 922 __ops_memory_free(__ops_memory_t *mem) 923 { 924 __ops_memory_release(mem); 925 free(mem); 926 } 927 928 /** 929 \ingroup HighLevel_Memory 930 \brief Get length of data stored in __ops_memory_t struct 931 \return Number of bytes in data 932 */ 933 size_t 934 __ops_mem_len(const __ops_memory_t *mem) 935 { 936 return mem->length; 937 } 938 939 /** 940 \ingroup HighLevel_Memory 941 \brief Get data stored in __ops_memory_t struct 942 \return Pointer to data 943 */ 944 void * 945 __ops_mem_data(__ops_memory_t *mem) 946 { 947 return mem->buf; 948 } 949 950 /* read a gile into an __ops_memory_t */ 951 int 952 __ops_mem_readfile(__ops_memory_t *mem, const char *f) 953 { 954 struct stat st; 955 FILE *fp; 956 int cc; 957 958 if ((fp = fopen(f, "rb")) == NULL) { 959 (void) fprintf(stderr, 960 "__ops_mem_readfile: can't open \"%s\"\n", f); 961 return 0; 962 } 963 (void) fstat(fileno(fp), &st); 964 mem->allocated = (size_t)st.st_size; 965 mem->buf = mmap(NULL, mem->allocated, PROT_READ, 966 MAP_PRIVATE | MAP_FILE, fileno(fp), 0); 967 if (mem->buf == MAP_FAILED) { 968 /* mmap failed for some reason - try to allocate memory */ 969 if ((mem->buf = calloc(1, mem->allocated)) == NULL) { 970 (void) fprintf(stderr, "__ops_mem_readfile: calloc\n"); 971 (void) fclose(fp); 972 return 0; 973 } 974 /* read into contents of mem */ 975 for (mem->length = 0 ; 976 (cc = read(fileno(fp), &mem->buf[mem->length], 977 mem->allocated - mem->length)) > 0 ; 978 mem->length += (size_t)cc) { 979 } 980 } else { 981 mem->length = mem->allocated; 982 mem->mmapped = 1; 983 } 984 (void) fclose(fp); 985 return (mem->allocated == mem->length); 986 } 987 988 typedef struct { 989 unsigned short sum; 990 } sum16_t; 991 992 993 /** 994 * Searches the given map for the given type. 995 * Returns a human-readable descriptive string if found, 996 * returns NULL if not found 997 * 998 * It is the responsibility of the calling function to handle the 999 * error case sensibly (i.e. don't just print out the return string. 1000 * 1001 */ 1002 static const char * 1003 str_from_map_or_null(int type, __ops_map_t *map) 1004 { 1005 __ops_map_t *row; 1006 1007 for (row = map; row->string != NULL; row++) { 1008 if (row->type == type) { 1009 return row->string; 1010 } 1011 } 1012 return NULL; 1013 } 1014 1015 /** 1016 * \ingroup Core_Print 1017 * 1018 * Searches the given map for the given type. 1019 * Returns a readable string if found, "Unknown" if not. 1020 */ 1021 1022 const char * 1023 __ops_str_from_map(int type, __ops_map_t *map) 1024 { 1025 const char *str; 1026 1027 str = str_from_map_or_null(type, map); 1028 return (str) ? str : "Unknown"; 1029 } 1030 1031 void 1032 hexdump(FILE *fp, const unsigned char *src, size_t length, const char *sep) 1033 { 1034 unsigned i; 1035 1036 for (i = 0 ; i < length ; i += 2) { 1037 (void) fprintf(fp, "%02x", *src++); 1038 (void) fprintf(fp, "%02x%s", *src++, sep); 1039 } 1040 } 1041 1042 /** 1043 * \ingroup HighLevel_Functions 1044 * \brief Initialises OpenPGP::SDK. To be called before any other OPS function. 1045 * 1046 * Initialises OpenPGP::SDK and the underlying openssl library. 1047 */ 1048 1049 void 1050 __ops_init(void) 1051 { 1052 __ops_crypto_init(); 1053 } 1054 1055 /** 1056 * \ingroup HighLevel_Functions 1057 * \brief Closes down OpenPGP::SDK. 1058 * 1059 * Close down OpenPGP:SDK, release any resources under the control of 1060 * the library. No OpenPGP:SDK function other than __ops_init() should 1061 * be called after this function. 1062 */ 1063 1064 void 1065 __ops_finish(void) 1066 { 1067 __ops_crypto_finish(); 1068 } 1069 1070 static int 1071 sum16_reader(void *dest_, size_t length, __ops_error_t **errors, 1072 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 1073 { 1074 const unsigned char *dest = dest_; 1075 sum16_t *arg = __ops_reader_get_arg(readinfo); 1076 int r; 1077 int n; 1078 1079 r = __ops_stacked_read(dest_, length, errors, readinfo, cbinfo); 1080 if (r < 0) { 1081 return r; 1082 } 1083 for (n = 0; n < r; ++n) { 1084 arg->sum = (arg->sum + dest[n]) & 0xffff; 1085 } 1086 return r; 1087 } 1088 1089 static void 1090 sum16_destroyer(__ops_reader_t *readinfo) 1091 { 1092 free(__ops_reader_get_arg(readinfo)); 1093 } 1094 1095 /** 1096 \ingroup Internal_Readers_Sum16 1097 \param stream Parse settings 1098 */ 1099 1100 void 1101 __ops_reader_push_sum16(__ops_stream_t *stream) 1102 { 1103 sum16_t *arg = calloc(1, sizeof(*arg)); 1104 1105 __ops_reader_push(stream, sum16_reader, sum16_destroyer, arg); 1106 } 1107 1108 /** 1109 \ingroup Internal_Readers_Sum16 1110 \param stream Parse settings 1111 \return sum 1112 */ 1113 unsigned short 1114 __ops_reader_pop_sum16(__ops_stream_t *stream) 1115 { 1116 unsigned short sum; 1117 sum16_t *arg; 1118 1119 arg = __ops_reader_get_arg(__ops_readinfo(stream)); 1120 sum = arg->sum; 1121 __ops_reader_pop(stream); 1122 free(arg); 1123 return sum; 1124 } 1125 1126 /* small useful functions for setting the file-level debugging levels */ 1127 /* if the debugv list contains the filename in question, we're debugging it */ 1128 1129 enum { 1130 MAX_DEBUG_NAMES = 32 1131 }; 1132 1133 static int debugc; 1134 static char *debugv[MAX_DEBUG_NAMES]; 1135 1136 /* set the debugging level per filename */ 1137 int 1138 __ops_set_debug_level(const char *f) 1139 { 1140 const char *name; 1141 int i; 1142 1143 if (f == NULL) { 1144 f = "all"; 1145 } 1146 if ((name = strrchr(f, '/')) == NULL) { 1147 name = f; 1148 } else { 1149 name += 1; 1150 } 1151 for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) { 1152 if (strcmp(debugv[i], name) == 0) { 1153 return 1; 1154 } 1155 } 1156 if (i == MAX_DEBUG_NAMES) { 1157 return 0; 1158 } 1159 debugv[debugc++] = strdup(name); 1160 return 1; 1161 } 1162 1163 /* get the debugging level per filename */ 1164 int 1165 __ops_get_debug_level(const char *f) 1166 { 1167 const char *name; 1168 int i; 1169 1170 if ((name = strrchr(f, '/')) == NULL) { 1171 name = f; 1172 } else { 1173 name += 1; 1174 } 1175 for (i = 0; i < debugc; i++) { 1176 if (strcmp(debugv[i], "all") == 0 || 1177 strcmp(debugv[i], name) == 0) { 1178 return 1; 1179 } 1180 } 1181 return 0; 1182 } 1183 1184 /* return the version for the library */ 1185 const char * 1186 __ops_get_info(const char *type) 1187 { 1188 if (strcmp(type, "version") == 0) { 1189 return NETPGP_VERSION_STRING; 1190 } 1191 if (strcmp(type, "maintainer") == 0) { 1192 return NETPGP_MAINTAINER; 1193 } 1194 return "[unknown]"; 1195 } 1196 1197 void 1198 netpgp_log(const char *fmt, ...) 1199 { 1200 va_list vp; 1201 time_t t; 1202 char buf[BUFSIZ * 2]; 1203 char *cp; 1204 int cc; 1205 1206 (void) time(&t); 1207 cp = ctime(&t); 1208 cc = snprintf(buf, sizeof(buf), "%.24s: netpgp: ", cp); 1209 va_start(vp, fmt); 1210 (void) vsnprintf(&buf[cc], sizeof(buf) - (size_t)cc, fmt, vp); 1211 va_end(vp); 1212 /* do something with message */ 1213 /* put into log buffer? */ 1214 } 1215