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