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