1 /* 2 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) 3 * All rights reserved. 4 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted 5 * their moral rights under the UK Copyright Design and Patents Act 1988 to 6 * be recorded as the authors of this copyright work. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 9 * use this file except in compliance with the License. 10 * 11 * You may obtain a copy of the License at 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 /** \file 23 */ 24 #include "config.h" 25 26 #include <openssl/rand.h> 27 28 #include "errors.h" 29 #include "packet.h" 30 #include "crypto.h" 31 #include "create.h" 32 #include "packet-parse.h" 33 #include "packet-show.h" 34 #include "signature.h" 35 #include "netpgpsdk.h" 36 #include "netpgpdefs.h" 37 #include "memory.h" 38 #include "keyring_local.h" 39 #include "parse_local.h" 40 #include "readerwriter.h" 41 #include "loccreate.h" 42 #include "version.h" 43 44 #ifdef HAVE_ASSERT_H 45 #include <assert.h> 46 #endif 47 48 #include <stdarg.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 53 #ifdef HAVE_UNISTD_H 54 #include <unistd.h> 55 #endif 56 57 #ifdef WIN32 58 #define vsnprintf _vsnprintf 59 #endif 60 61 typedef struct { 62 __ops_keyring_t *keyring; 63 } accumulate_t; 64 65 /** 66 * \ingroup Core_Callbacks 67 */ 68 static __ops_parse_cb_return_t 69 accumulate_cb(const __ops_parser_content_t * contents, __ops_parse_cb_info_t * cbinfo) 70 { 71 accumulate_t *accumulate = __ops_parse_cb_get_arg(cbinfo); 72 const __ops_parser_content_union_t *content = &contents->u; 73 __ops_keyring_t *keyring = accumulate->keyring; 74 __ops_keydata_t *cur = NULL; 75 const __ops_public_key_t *pkey; 76 77 if (keyring->nkeys >= 0) 78 cur = &keyring->keys[keyring->nkeys]; 79 80 switch (contents->tag) { 81 case OPS_PTAG_CT_PUBLIC_KEY: 82 case OPS_PTAG_CT_SECRET_KEY: 83 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 84 if (__ops_get_debug_level(__FILE__)) { 85 (void) fprintf(stderr, "New key - tag %d\n", contents->tag); 86 } 87 ++keyring->nkeys; 88 EXPAND_ARRAY(keyring, keys); 89 90 if (contents->tag == OPS_PTAG_CT_PUBLIC_KEY) 91 pkey = &content->public_key; 92 else 93 pkey = &content->secret_key.public_key; 94 95 (void) memset(&keyring->keys[keyring->nkeys], 0x0, 96 sizeof(keyring->keys[keyring->nkeys])); 97 98 __ops_keyid(keyring->keys[keyring->nkeys].key_id, 99 OPS_KEY_ID_SIZE, OPS_KEY_ID_SIZE, pkey); 100 __ops_fingerprint(&keyring->keys[keyring->nkeys].fingerprint, pkey); 101 102 keyring->keys[keyring->nkeys].type = contents->tag; 103 104 if (contents->tag == OPS_PTAG_CT_PUBLIC_KEY) 105 keyring->keys[keyring->nkeys].key.pkey = *pkey; 106 else 107 keyring->keys[keyring->nkeys].key.skey = content->secret_key; 108 return OPS_KEEP_MEMORY; 109 110 case OPS_PTAG_CT_USER_ID: 111 if (__ops_get_debug_level(__FILE__)) { 112 (void) fprintf(stderr, "User ID: %s\n", content->user_id.user_id); 113 } 114 if (!cur) { 115 OPS_ERROR(cbinfo->errors, OPS_E_P_NO_USERID, "No user id found"); 116 return OPS_KEEP_MEMORY; 117 } 118 /* assert(cur); */ 119 __ops_add_userid_to_keydata(cur, &content->user_id); 120 return OPS_KEEP_MEMORY; 121 122 case OPS_PARSER_PACKET_END: 123 if (!cur) 124 return OPS_RELEASE_MEMORY; 125 __ops_add_packet_to_keydata(cur, &content->packet); 126 return OPS_KEEP_MEMORY; 127 128 case OPS_PARSER_ERROR: 129 fprintf(stderr, "Error: %s\n", content->error.error); 130 assert( /* CONSTCOND */ 0); 131 break; 132 133 case OPS_PARSER_ERRCODE: 134 switch (content->errcode.errcode) { 135 default: 136 fprintf(stderr, "parse error: %s\n", 137 __ops_errcode(content->errcode.errcode)); 138 /* assert(0); */ 139 } 140 break; 141 142 default: 143 break; 144 } 145 146 /* XXX: we now exclude so many things, we should either drop this or */ 147 /* do something to pass on copies of the stuff we keep */ 148 return __ops_parse_stacked_cb(contents, cbinfo); 149 } 150 151 /** 152 * \ingroup Core_Parse 153 * 154 * Parse packets from an input stream until EOF or error. 155 * 156 * Key data found in the parsed data is added to #keyring. 157 * 158 * \param keyring Pointer to an existing keyring 159 * \param parse Options to use when parsing 160 */ 161 162 int 163 __ops_parse_and_accumulate(__ops_keyring_t * keyring, __ops_parse_info_t *parse) 164 { 165 int rtn; 166 accumulate_t accumulate; 167 168 assert(!parse->rinfo.accumulate); 169 170 (void) memset(&accumulate, 0x0, sizeof(accumulate)); 171 172 accumulate.keyring = keyring; 173 /* Kinda weird, but to do with counting, and we put it back after */ 174 keyring->nkeys -= 1; 175 176 __ops_parse_cb_push(parse, accumulate_cb, &accumulate); 177 parse->rinfo.accumulate = true; 178 rtn = __ops_parse(parse); 179 180 keyring->nkeys += 1; 181 182 return rtn; 183 } 184 185 static void 186 dump_one_keydata(const __ops_keydata_t * key) 187 { 188 unsigned n; 189 190 printf("Key ID: "); 191 hexdump(key->key_id, OPS_KEY_ID_SIZE, ""); 192 193 printf("\nFingerpint: "); 194 hexdump(key->fingerprint.fingerprint, key->fingerprint.length, ""); 195 196 printf("\n\nUIDs\n====\n\n"); 197 for (n = 0; n < key->nuids; ++n) 198 printf("%s\n", key->uids[n].user_id); 199 200 printf("\nPackets\n=======\n"); 201 for (n = 0; n < key->npackets; ++n) { 202 printf("\n%03d: ", n); 203 hexdump(key->packets[n].raw, key->packets[n].length, ""); 204 } 205 printf("\n\n"); 206 } 207 208 /* XXX: not a maintained part of the API - use __ops_keyring_list() */ 209 /** __ops_dump_keyring 210 */ 211 void 212 __ops_dump_keyring(const __ops_keyring_t * keyring) 213 { 214 int n; 215 216 for (n = 0; n < keyring->nkeys; ++n) { 217 dump_one_keydata(&keyring->keys[n]); 218 } 219 } 220 221 222 /** \file 223 * \brief Error Handling 224 */ 225 #define ERRNAME(code) { code, #code } 226 227 static __ops_errcode_name_map_t errcode_name_map[] = { 228 ERRNAME(OPS_E_OK), 229 ERRNAME(OPS_E_FAIL), 230 ERRNAME(OPS_E_SYSTEM_ERROR), 231 ERRNAME(OPS_E_UNIMPLEMENTED), 232 233 ERRNAME(OPS_E_R), 234 ERRNAME(OPS_E_R_READ_FAILED), 235 ERRNAME(OPS_E_R_EARLY_EOF), 236 ERRNAME(OPS_E_R_BAD_FORMAT), 237 ERRNAME(OPS_E_R_UNCONSUMED_DATA), 238 239 ERRNAME(OPS_E_W), 240 ERRNAME(OPS_E_W_WRITE_FAILED), 241 ERRNAME(OPS_E_W_WRITE_TOO_SHORT), 242 243 ERRNAME(OPS_E_P), 244 ERRNAME(OPS_E_P_NOT_ENOUGH_DATA), 245 ERRNAME(OPS_E_P_UNKNOWN_TAG), 246 ERRNAME(OPS_E_P_PACKET_CONSUMED), 247 ERRNAME(OPS_E_P_MPI_FORMAT_ERROR), 248 249 ERRNAME(OPS_E_C), 250 251 ERRNAME(OPS_E_V), 252 ERRNAME(OPS_E_V_BAD_SIGNATURE), 253 ERRNAME(OPS_E_V_NO_SIGNATURE), 254 ERRNAME(OPS_E_V_UNKNOWN_SIGNER), 255 256 ERRNAME(OPS_E_ALG), 257 ERRNAME(OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG), 258 ERRNAME(OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG), 259 ERRNAME(OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG), 260 ERRNAME(OPS_E_ALG_UNSUPPORTED_HASH_ALG), 261 262 ERRNAME(OPS_E_PROTO), 263 ERRNAME(OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT), 264 ERRNAME(OPS_E_PROTO_UNKNOWN_SS), 265 ERRNAME(OPS_E_PROTO_CRITICAL_SS_IGNORED), 266 ERRNAME(OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN), 267 ERRNAME(OPS_E_PROTO_BAD_SIGNATURE_VRSN), 268 ERRNAME(OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN), 269 ERRNAME(OPS_E_PROTO_BAD_PKSK_VRSN), 270 ERRNAME(OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN), 271 ERRNAME(OPS_E_PROTO_BAD_SK_CHECKSUM), 272 273 {0x00, NULL}, /* this is the end-of-array marker */ 274 }; 275 276 /** 277 * \ingroup Core_Errors 278 * \brief returns error code name 279 * \param errcode 280 * \return error code name or "Unknown" 281 */ 282 const char * 283 __ops_errcode(const __ops_errcode_t errcode) 284 { 285 return (__ops_str_from_map((int) errcode, (__ops_map_t *) errcode_name_map)); 286 } 287 288 /** 289 * \ingroup Core_Errors 290 * \brief Pushes the given error on the given errorstack 291 * \param errstack Error stack to use 292 * \param errcode Code of error to push 293 * \param sys_errno System errno (used if errcode=OPS_E_SYSTEM_ERROR) 294 * \param file Source filename where error occurred 295 * \param line Line in source file where error occurred 296 * \param fmt Comment 297 * 298 */ 299 300 void 301 __ops_push_error(__ops_error_t ** errstack, __ops_errcode_t errcode, int sys_errno, 302 const char *file, int line, const char *fmt,...) 303 { 304 /* first get the varargs and generate the comment */ 305 __ops_error_t *err; 306 unsigned maxbuf = 128; 307 va_list args; 308 char *comment; 309 310 comment = calloc(1, maxbuf + 1); 311 assert(comment); 312 313 va_start(args, fmt); 314 vsnprintf(comment, maxbuf + 1, fmt, args); 315 va_end(args); 316 317 /* alloc a new error and add it to the top of the stack */ 318 319 err = calloc(1, sizeof(__ops_error_t)); 320 assert(err); 321 322 err->next = *errstack; 323 *errstack = err; 324 325 /* fill in the details */ 326 err->errcode = errcode; 327 err->sys_errno = sys_errno; 328 err->file = file; 329 err->line = line; 330 331 err->comment = comment; 332 } 333 334 /** 335 \ingroup Core_Errors 336 \brief print this error 337 \param err Error to print 338 */ 339 void 340 __ops_print_error(__ops_error_t * err) 341 { 342 printf("%s:%d: ", err->file, err->line); 343 if (err->errcode == OPS_E_SYSTEM_ERROR) 344 printf("system error %d returned from %s()\n", err->sys_errno, 345 err->comment); 346 else 347 printf("%s, %s\n", __ops_errcode(err->errcode), err->comment); 348 } 349 350 /** 351 \ingroup Core_Errors 352 \brief Print all errors on stack 353 \param errstack Error stack to print 354 */ 355 void 356 __ops_print_errors(__ops_error_t * errstack) 357 { 358 __ops_error_t *err; 359 360 for (err = errstack; err != NULL; err = err->next) 361 __ops_print_error(err); 362 } 363 364 /** 365 \ingroup Core_Errors 366 \brief Return true if given error is present anywhere on stack 367 \param errstack Error stack to check 368 \param errcode Error code to look for 369 \return 1 if found; else 0 370 */ 371 int 372 __ops_has_error(__ops_error_t * errstack, __ops_errcode_t errcode) 373 { 374 __ops_error_t *err; 375 for (err = errstack; err != NULL; err = err->next) { 376 if (err->errcode == errcode) 377 return 1; 378 } 379 return 0; 380 } 381 382 /** 383 \ingroup Core_Errors 384 \brief Frees all errors on stack 385 \param errstack Error stack to free 386 */ 387 void 388 __ops_free_errors(__ops_error_t * errstack) 389 { 390 __ops_error_t *next; 391 while (errstack != NULL) { 392 next = errstack->next; 393 free(errstack->comment); 394 free(errstack); 395 errstack = next; 396 } 397 } 398 399 /** \file 400 */ 401 402 /** 403 * \ingroup Core_Keys 404 * \brief Calculate a public key fingerprint. 405 * \param fp Where to put the calculated fingerprint 406 * \param key The key for which the fingerprint is calculated 407 */ 408 409 void 410 __ops_fingerprint(__ops_fingerprint_t * fp, const __ops_public_key_t * key) 411 { 412 if (key->version == 2 || key->version == 3) { 413 unsigned char *bn; 414 size_t n; 415 __ops_hash_t md5; 416 417 assert(key->algorithm == OPS_PKA_RSA 418 || key->algorithm == OPS_PKA_RSA_ENCRYPT_ONLY 419 || key->algorithm == OPS_PKA_RSA_SIGN_ONLY); 420 421 __ops_hash_md5(&md5); 422 md5.init(&md5); 423 424 n = BN_num_bytes(key->key.rsa.n); 425 bn = calloc(1, n); 426 BN_bn2bin(key->key.rsa.n, bn); 427 md5.add(&md5, bn, n); 428 (void) free(bn); 429 430 n = BN_num_bytes(key->key.rsa.e); 431 bn = calloc(1, n); 432 BN_bn2bin(key->key.rsa.e, bn); 433 md5.add(&md5, bn, n); 434 (void) free(bn); 435 436 md5.finish(&md5, fp->fingerprint); 437 fp->length = 16; 438 } else { 439 __ops_memory_t *mem = __ops_memory_new(); 440 __ops_hash_t sha1; 441 size_t l; 442 443 __ops_build_public_key(mem, key, false); 444 445 if (__ops_get_debug_level(__FILE__)) { 446 fprintf(stderr, "--- creating key fingerprint\n"); 447 } 448 __ops_hash_sha1(&sha1); 449 sha1.init(&sha1); 450 451 l = __ops_memory_get_length(mem); 452 453 __ops_hash_add_int(&sha1, 0x99, 1); 454 __ops_hash_add_int(&sha1, l, 2); 455 sha1.add(&sha1, __ops_memory_get_data(mem), l); 456 sha1.finish(&sha1, fp->fingerprint); 457 458 if (__ops_get_debug_level(__FILE__)) { 459 fprintf(stderr, "--- finished creating key fingerprint\n"); 460 } 461 fp->length = 20; 462 463 __ops_memory_free(mem); 464 } 465 } 466 467 /** 468 * \ingroup Core_Keys 469 * \brief Calculate the Key ID from the public key. 470 * \param keyid Space for the calculated ID to be stored 471 * \param key The key for which the ID is calculated 472 */ 473 474 void 475 __ops_keyid(unsigned char *keyid, const size_t idlen, const int last, 476 const __ops_public_key_t *key) 477 { 478 if (key->version == 2 || key->version == 3) { 479 unsigned char bn[NETPGP_BUFSIZ]; 480 unsigned n = BN_num_bytes(key->key.rsa.n); 481 482 assert(n <= sizeof(bn)); 483 assert(key->algorithm == OPS_PKA_RSA 484 || key->algorithm == OPS_PKA_RSA_ENCRYPT_ONLY 485 || key->algorithm == OPS_PKA_RSA_SIGN_ONLY); 486 BN_bn2bin(key->key.rsa.n, bn); 487 (void) memcpy(keyid, (last == 0) ? bn : bn + n - idlen, idlen); 488 } else { 489 __ops_fingerprint_t finger; 490 491 __ops_fingerprint(&finger, key); 492 (void) memcpy(keyid, 493 (last == 0) ? finger.fingerprint : 494 finger.fingerprint + finger.length - idlen, 495 idlen); 496 } 497 } 498 499 /** 500 \ingroup Core_Hashes 501 \brief Add to the hash 502 \param hash Hash to add to 503 \param n Int to add 504 \param length Length of int in bytes 505 */ 506 void 507 __ops_hash_add_int(__ops_hash_t * hash, unsigned n, unsigned length) 508 { 509 while (length--) { 510 unsigned char c[1]; 511 512 c[0] = n >> (length * 8); 513 hash->add(hash, c, 1); 514 } 515 } 516 517 /** 518 \ingroup Core_Hashes 519 \brief Setup hash for given hash algorithm 520 \param hash Hash to set up 521 \param alg Hash algorithm to use 522 */ 523 void 524 __ops_hash_any(__ops_hash_t * hash, __ops_hash_algorithm_t alg) 525 { 526 switch (alg) { 527 case OPS_HASH_MD5: 528 __ops_hash_md5(hash); 529 break; 530 531 case OPS_HASH_SHA1: 532 __ops_hash_sha1(hash); 533 break; 534 535 case OPS_HASH_SHA256: 536 __ops_hash_sha256(hash); 537 break; 538 539 case OPS_HASH_SHA384: 540 __ops_hash_sha384(hash); 541 break; 542 543 case OPS_HASH_SHA512: 544 __ops_hash_sha512(hash); 545 break; 546 547 case OPS_HASH_SHA224: 548 __ops_hash_sha224(hash); 549 break; 550 551 default: 552 assert( /* CONSTCOND */ 0); 553 } 554 } 555 556 /** 557 \ingroup Core_Hashes 558 \brief Returns size of hash for given hash algorithm 559 \param alg Hash algorithm to use 560 \return Size of hash algorithm in bytes 561 */ 562 unsigned 563 __ops_hash_size(__ops_hash_algorithm_t alg) 564 { 565 switch (alg) { 566 case OPS_HASH_MD5: 567 return 16; 568 569 case OPS_HASH_SHA1: 570 return 20; 571 572 case OPS_HASH_SHA256: 573 return 32; 574 575 case OPS_HASH_SHA224: 576 return 28; 577 578 case OPS_HASH_SHA512: 579 return 64; 580 581 case OPS_HASH_SHA384: 582 return 48; 583 584 default: 585 assert( /* CONSTCOND */ 0); 586 } 587 588 return 0; 589 } 590 591 /** 592 \ingroup Core_Hashes 593 \brief Returns hash enum corresponding to given string 594 \param hash Text name of hash algorithm i.e. "SHA1" 595 \returns Corresponding enum i.e. OPS_HASH_SHA1 596 */ 597 __ops_hash_algorithm_t 598 __ops_hash_algorithm_from_text(const char *hash) 599 { 600 if (!strcmp(hash, "SHA1")) 601 return OPS_HASH_SHA1; 602 else if (!strcmp(hash, "MD5")) 603 return OPS_HASH_MD5; 604 else if (!strcmp(hash, "SHA256")) 605 return OPS_HASH_SHA256; 606 /* 607 else if (!strcmp(hash,"SHA224")) 608 return OPS_HASH_SHA224; 609 */ 610 else if (!strcmp(hash, "SHA512")) 611 return OPS_HASH_SHA512; 612 else if (!strcmp(hash, "SHA384")) 613 return OPS_HASH_SHA384; 614 615 return OPS_HASH_UNKNOWN; 616 } 617 618 /** 619 \ingroup Core_Hashes 620 \brief Hash given data 621 \param out Where to write the hash 622 \param alg Hash algorithm to use 623 \param in Data to hash 624 \param length Length of data 625 \return Size of hash created 626 */ 627 unsigned 628 __ops_hash(unsigned char *out, __ops_hash_algorithm_t alg, const void *in, 629 size_t length) 630 { 631 __ops_hash_t hash; 632 633 __ops_hash_any(&hash, alg); 634 hash.init(&hash); 635 hash.add(&hash, in, length); 636 return hash.finish(&hash, out); 637 } 638 639 /** 640 \ingroup Core_Hashes 641 \brief Calculate hash for MDC packet 642 \param preamble Preamble to hash 643 \param sz_preamble Size of preamble 644 \param plaintext Plaintext to hash 645 \param sz_plaintext Size of plaintext 646 \param hashed Resulting hash 647 */ 648 void 649 __ops_calc_mdc_hash(const unsigned char *preamble, const size_t sz_preamble, const unsigned char *plaintext, const unsigned int sz_plaintext, unsigned char *hashed) 650 { 651 __ops_hash_t hash; 652 unsigned char c[1]; 653 654 if (__ops_get_debug_level(__FILE__)) { 655 unsigned int i = 0; 656 fprintf(stderr, "__ops_calc_mdc_hash():\n"); 657 658 fprintf(stderr, "\npreamble: "); 659 for (i = 0; i < sz_preamble; i++) 660 fprintf(stderr, " 0x%02x", preamble[i]); 661 fprintf(stderr, "\n"); 662 663 fprintf(stderr, "\nplaintext (len=%d): ", sz_plaintext); 664 for (i = 0; i < sz_plaintext; i++) 665 fprintf(stderr, " 0x%02x", plaintext[i]); 666 fprintf(stderr, "\n"); 667 } 668 /* init */ 669 __ops_hash_any(&hash, OPS_HASH_SHA1); 670 hash.init(&hash); 671 672 /* preamble */ 673 hash.add(&hash, preamble, sz_preamble); 674 /* plaintext */ 675 hash.add(&hash, plaintext, sz_plaintext); 676 /* MDC packet tag */ 677 c[0] = 0xD3; 678 hash.add(&hash, &c[0], 1); 679 /* MDC packet len */ 680 c[0] = 0x14; 681 hash.add(&hash, &c[0], 1); 682 683 /* finish */ 684 hash.finish(&hash, hashed); 685 686 if (__ops_get_debug_level(__FILE__)) { 687 unsigned int i = 0; 688 fprintf(stderr, "\nhashed (len=%d): ", OPS_SHA1_HASH_SIZE); 689 for (i = 0; i < OPS_SHA1_HASH_SIZE; i++) 690 fprintf(stderr, " 0x%02x", hashed[i]); 691 fprintf(stderr, "\n"); 692 } 693 } 694 695 /** 696 \ingroup HighLevel_Supported 697 \brief Is this Hash Algorithm supported? 698 \param hash_alg Hash Algorithm to check 699 \return true if supported; else false 700 */ 701 bool 702 __ops_is_hash_alg_supported(const __ops_hash_algorithm_t * hash_alg) 703 { 704 switch (*hash_alg) { 705 case OPS_HASH_MD5: 706 case OPS_HASH_SHA1: 707 case OPS_HASH_SHA256: 708 return true; 709 710 default: 711 return false; 712 } 713 } 714 715 void 716 __ops_random(void *dest, size_t length) 717 { 718 RAND_bytes(dest, (int)length); 719 } 720 721 /** 722 \ingroup HighLevel_Memory 723 \brief Memory to initialise 724 \param mem memory to initialise 725 \param needed Size to initialise to 726 */ 727 void 728 __ops_memory_init(__ops_memory_t * mem, size_t needed) 729 { 730 mem->length = 0; 731 if (mem->buf) { 732 if (mem->allocated < needed) { 733 mem->buf = realloc(mem->buf, needed); 734 mem->allocated = needed; 735 } 736 return; 737 } 738 mem->buf = calloc(1, needed); 739 mem->allocated = needed; 740 } 741 742 /** 743 \ingroup HighLevel_Memory 744 \brief Pad memory to required length 745 \param mem Memory to use 746 \param length New size 747 */ 748 void 749 __ops_memory_pad(__ops_memory_t * mem, size_t length) 750 { 751 assert(mem->allocated >= mem->length); 752 if (mem->allocated < mem->length + length) { 753 mem->allocated = mem->allocated * 2 + length; 754 mem->buf = realloc(mem->buf, mem->allocated); 755 } 756 assert(mem->allocated >= mem->length + length); 757 } 758 759 /** 760 \ingroup HighLevel_Memory 761 \brief Add data to memory 762 \param mem Memory to which to add 763 \param src Data to add 764 \param length Length of data to add 765 */ 766 void 767 __ops_memory_add(__ops_memory_t * mem, const unsigned char *src, size_t length) 768 { 769 __ops_memory_pad(mem, length); 770 (void) memcpy(mem->buf + mem->length, src, length); 771 mem->length += length; 772 } 773 774 /* XXX: this could be refactored via the writer, but an awful lot of */ 775 /* hoops to jump through for 2 lines of code! */ 776 void 777 __ops_memory_place_int(__ops_memory_t * mem, unsigned offset, unsigned n, 778 size_t length) 779 { 780 assert(mem->allocated >= offset + length); 781 782 while (length--) 783 mem->buf[offset++] = n >> (length * 8); 784 } 785 786 /** 787 * \ingroup HighLevel_Memory 788 * \brief Retains allocated memory and set length of stored data to zero. 789 * \param mem Memory to clear 790 * \sa __ops_memory_release() 791 * \sa __ops_memory_free() 792 */ 793 void 794 __ops_memory_clear(__ops_memory_t * mem) 795 { 796 mem->length = 0; 797 } 798 799 /** 800 \ingroup HighLevel_Memory 801 \brief Free memory and associated data 802 \param mem Memory to free 803 \note This does not free mem itself 804 \sa __ops_memory_clear() 805 \sa __ops_memory_free() 806 */ 807 void 808 __ops_memory_release(__ops_memory_t * mem) 809 { 810 free(mem->buf); 811 mem->buf = NULL; 812 mem->length = 0; 813 } 814 815 void 816 __ops_memory_make_packet(__ops_memory_t * out, __ops_content_tag_t tag) 817 { 818 size_t extra; 819 820 if (out->length < 192) 821 extra = 1; 822 else if (out->length < 8384) 823 extra = 2; 824 else 825 extra = 5; 826 827 __ops_memory_pad(out, extra + 1); 828 memmove(out->buf + extra + 1, out->buf, out->length); 829 830 out->buf[0] = OPS_PTAG_ALWAYS_SET | OPS_PTAG_NEW_FORMAT | tag; 831 832 if (out->length < 192) 833 out->buf[1] = out->length; 834 else if (out->length < 8192 + 192) { 835 out->buf[1] = ((out->length - 192) >> 8) + 192; 836 out->buf[2] = out->length - 192; 837 } else { 838 out->buf[1] = 0xff; 839 out->buf[2] = out->length >> 24; 840 out->buf[3] = out->length >> 16; 841 out->buf[4] = out->length >> 8; 842 out->buf[5] = out->length; 843 } 844 845 out->length += extra + 1; 846 } 847 848 /** 849 \ingroup HighLevel_Memory 850 \brief Create a new zeroed __ops_memory_t 851 \return Pointer to new __ops_memory_t 852 \note Free using __ops_memory_free() after use. 853 \sa __ops_memory_free() 854 */ 855 856 __ops_memory_t * 857 __ops_memory_new(void) 858 { 859 return calloc(1, sizeof(__ops_memory_t)); 860 } 861 862 /** 863 \ingroup HighLevel_Memory 864 \brief Free memory ptr and associated memory 865 \param mem Memory to be freed 866 \sa __ops_memory_release() 867 \sa __ops_memory_clear() 868 */ 869 870 void 871 __ops_memory_free(__ops_memory_t * mem) 872 { 873 __ops_memory_release(mem); 874 free(mem); 875 } 876 877 /** 878 \ingroup HighLevel_Memory 879 \brief Get length of data stored in __ops_memory_t struct 880 \return Number of bytes in data 881 */ 882 size_t 883 __ops_memory_get_length(const __ops_memory_t * mem) 884 { 885 return mem->length; 886 } 887 888 /** 889 \ingroup HighLevel_Memory 890 \brief Get data stored in __ops_memory_t struct 891 \return Pointer to data 892 */ 893 void * 894 __ops_memory_get_data(__ops_memory_t * mem) 895 { 896 return mem->buf; 897 } 898 899 typedef struct { 900 unsigned short sum; 901 } sum16_t; 902 903 904 /** 905 * Searches the given map for the given type. 906 * Returns a human-readable descriptive string if found, 907 * returns NULL if not found 908 * 909 * It is the responsibility of the calling function to handle the 910 * error case sensibly (i.e. don't just print out the return string. 911 * 912 */ 913 static const char * 914 str_from_map_or_null(int type, __ops_map_t * map) 915 { 916 __ops_map_t *row; 917 918 for (row = map; row->string != NULL; row++) { 919 if (row->type == type) { 920 return row->string; 921 } 922 } 923 return NULL; 924 } 925 926 /** 927 * \ingroup Core_Print 928 * 929 * Searches the given map for the given type. 930 * Returns a readable string if found, "Unknown" if not. 931 */ 932 933 const char * 934 __ops_str_from_map(int type, __ops_map_t * map) 935 { 936 const char *str; 937 938 str = str_from_map_or_null(type, map); 939 return (str) ? str : "Unknown"; 940 } 941 942 void 943 hexdump(const unsigned char *src, size_t length, const char *sep) 944 { 945 unsigned i; 946 947 for (i = 0 ; i < length ; i += 2) { 948 printf("%02x", *src++); 949 printf("%02x%s", *src++, sep); 950 } 951 } 952 953 /** 954 * \ingroup HighLevel_Functions 955 * \brief Initialises OpenPGP::SDK. To be called before any other OPS function. 956 * 957 * Initialises OpenPGP::SDK and the underlying openssl library. 958 */ 959 960 void 961 __ops_init(void) 962 { 963 __ops_crypto_init(); 964 } 965 966 /** 967 * \ingroup HighLevel_Functions 968 * \brief Closes down OpenPGP::SDK. 969 * 970 * Close down OpenPGP:SDK, release any resources under the control of 971 * the library. No OpenPGP:SDK function other than __ops_init() should 972 * be called after this function. 973 */ 974 975 void 976 __ops_finish(void) 977 { 978 __ops_crypto_finish(); 979 } 980 981 static int 982 sum16_reader(void *dest_, size_t length, __ops_error_t ** errors, 983 __ops_reader_info_t * rinfo, __ops_parse_cb_info_t * cbinfo) 984 { 985 const unsigned char *dest = dest_; 986 sum16_t *arg = __ops_reader_get_arg(rinfo); 987 int r = __ops_stacked_read(dest_, length, errors, rinfo, cbinfo); 988 int n; 989 990 if (r < 0) { 991 return r; 992 } 993 994 for (n = 0; n < r; ++n) { 995 arg->sum = (arg->sum + dest[n]) & 0xffff; 996 } 997 998 return r; 999 } 1000 1001 static void 1002 sum16_destroyer(__ops_reader_info_t * rinfo) 1003 { 1004 free(__ops_reader_get_arg(rinfo)); 1005 } 1006 1007 /** 1008 \ingroup Internal_Readers_Sum16 1009 \param pinfo Parse settings 1010 */ 1011 1012 void 1013 __ops_reader_push_sum16(__ops_parse_info_t * pinfo) 1014 { 1015 sum16_t *arg = calloc(1, sizeof(*arg)); 1016 1017 __ops_reader_push(pinfo, sum16_reader, sum16_destroyer, arg); 1018 } 1019 1020 /** 1021 \ingroup Internal_Readers_Sum16 1022 \param pinfo Parse settings 1023 \return sum 1024 */ 1025 unsigned short 1026 __ops_reader_pop_sum16(__ops_parse_info_t * pinfo) 1027 { 1028 sum16_t *arg = __ops_reader_get_arg(__ops_parse_get_rinfo(pinfo)); 1029 unsigned short sum = arg->sum; 1030 1031 __ops_reader_pop(pinfo); 1032 free(arg); 1033 1034 return sum; 1035 } 1036 1037 /* small useful functions for setting the file-level debugging levels */ 1038 /* if the debugv list contains the filename in question, we're debugging it */ 1039 1040 enum { 1041 MAX_DEBUG_NAMES = 32 1042 }; 1043 1044 static int debugc; 1045 static char *debugv[MAX_DEBUG_NAMES]; 1046 1047 /* set the debugging level per filename */ 1048 int 1049 __ops_set_debug_level(const char *f) 1050 { 1051 const char *name; 1052 int i; 1053 1054 if (f == NULL) { 1055 f = "all"; 1056 } 1057 if ((name = strrchr(f, '/')) == NULL) { 1058 name = f; 1059 } else { 1060 name += 1; 1061 } 1062 for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) { 1063 if (strcmp(debugv[i], name) == 0) { 1064 return 1; 1065 } 1066 } 1067 if (i == MAX_DEBUG_NAMES) { 1068 return 0; 1069 } 1070 debugv[debugc++] = strdup(name); 1071 return 1; 1072 } 1073 1074 /* get the debugging level per filename */ 1075 int 1076 __ops_get_debug_level(const char *f) 1077 { 1078 const char *name; 1079 int i; 1080 1081 if ((name = strrchr(f, '/')) == NULL) { 1082 name = f; 1083 } else { 1084 name += 1; 1085 } 1086 for (i = 0; i < debugc; i++) { 1087 if (strcmp(debugv[i], "all") == 0 || 1088 strcmp(debugv[i], name) == 0) { 1089 return 1; 1090 } 1091 } 1092 return 0; 1093 } 1094 1095 /* return the version for the library */ 1096 const char * 1097 __ops_get_info(const char *type) 1098 { 1099 if (strcmp(type, "version") == 0) { 1100 return NETPGP_VERSION_STRING; 1101 } 1102 if (strcmp(type, "maintainer") == 0) { 1103 return NETPGP_MAINTAINER; 1104 } 1105 return "[unknown]"; 1106 } 1107