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