1 /*- 2 * Copyright (c) 2009,2010 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.31 2010/06/25 03:37:27 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 "fastctype.h" 85 #include "packet-parse.h" 86 #include "packet-show.h" 87 #include "signature.h" 88 #include "netpgpsdk.h" 89 #include "netpgpdefs.h" 90 #include "memory.h" 91 #include "readerwriter.h" 92 #include "version.h" 93 #include "netpgpdigest.h" 94 95 #ifdef WIN32 96 #define vsnprintf _vsnprintf 97 #endif 98 99 100 typedef struct { 101 __ops_keyring_t *keyring; 102 } accumulate_t; 103 104 /** 105 * \ingroup Core_Callbacks 106 */ 107 static __ops_cb_ret_t 108 accumulate_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 109 { 110 const __ops_contents_t *content = &pkt->u; 111 __ops_keyring_t *keyring; 112 accumulate_t *accumulate; 113 114 accumulate = __ops_callback_arg(cbinfo); 115 keyring = accumulate->keyring; 116 switch (pkt->tag) { 117 case OPS_PTAG_CT_PUBLIC_KEY: 118 case OPS_PTAG_CT_SECRET_KEY: 119 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 120 if (__ops_get_debug_level(__FILE__)) { 121 (void) fprintf(stderr, "Creating key %u - tag %u\n", 122 keyring->keyc, pkt->tag); 123 } 124 if (pkt->tag == OPS_PTAG_CT_PUBLIC_KEY) { 125 __ops_add_to_pubring(keyring, &content->pubkey); 126 } else { 127 __ops_add_to_secring(keyring, &content->seckey); 128 } 129 return OPS_KEEP_MEMORY; 130 case OPS_PTAG_CT_USER_ID: 131 if (__ops_get_debug_level(__FILE__)) { 132 (void) fprintf(stderr, "User ID: %s for key %d\n", 133 content->userid, 134 keyring->keyc - 1); 135 } 136 if (keyring->keyc > 0) { 137 __ops_add_userid(&keyring->keys[keyring->keyc - 1], 138 content->userid); 139 return OPS_KEEP_MEMORY; 140 } 141 OPS_ERROR(cbinfo->errors, OPS_E_P_NO_USERID, "No userid found"); 142 return OPS_KEEP_MEMORY; 143 144 case OPS_PARSER_PACKET_END: 145 if (keyring->keyc > 0) { 146 __ops_add_subpacket(&keyring->keys[keyring->keyc - 1], 147 &content->packet); 148 return OPS_KEEP_MEMORY; 149 } 150 return OPS_RELEASE_MEMORY; 151 152 case OPS_PARSER_ERROR: 153 (void) fprintf(stderr, "Error: %s\n", content->error); 154 return OPS_FINISHED; 155 156 case OPS_PARSER_ERRCODE: 157 (void) fprintf(stderr, "parse error: %s\n", 158 __ops_errcode(content->errcode.errcode)); 159 break; 160 161 default: 162 break; 163 } 164 165 /* XXX: we now exclude so many things, we should either drop this or */ 166 /* do something to pass on copies of the stuff we keep */ 167 return __ops_stacked_callback(pkt, cbinfo); 168 } 169 170 /** 171 * \ingroup Core_Parse 172 * 173 * Parse packets from an input stream until EOF or error. 174 * 175 * Key data found in the parsed data is added to #keyring. 176 * 177 * \param keyring Pointer to an existing keyring 178 * \param parse Options to use when parsing 179 */ 180 int 181 __ops_parse_and_accumulate(__ops_keyring_t *keyring, __ops_stream_t *parse) 182 { 183 accumulate_t accumulate; 184 const int printerrors = 1; 185 int ret; 186 187 if (parse->readinfo.accumulate) { 188 (void) fprintf(stderr, 189 "__ops_parse_and_accumulate: already init\n"); 190 return 0; 191 } 192 193 (void) memset(&accumulate, 0x0, sizeof(accumulate)); 194 195 accumulate.keyring = keyring; 196 197 __ops_callback_push(parse, accumulate_cb, &accumulate); 198 parse->readinfo.accumulate = 1; 199 ret = __ops_parse(parse, !printerrors); 200 201 return ret; 202 } 203 204 205 /** \file 206 * \brief Error Handling 207 */ 208 #define ERRNAME(code) { code, #code } 209 210 static __ops_errcode_name_map_t errcode_name_map[] = { 211 ERRNAME(OPS_E_OK), 212 ERRNAME(OPS_E_FAIL), 213 ERRNAME(OPS_E_SYSTEM_ERROR), 214 ERRNAME(OPS_E_UNIMPLEMENTED), 215 216 ERRNAME(OPS_E_R), 217 ERRNAME(OPS_E_R_READ_FAILED), 218 ERRNAME(OPS_E_R_EARLY_EOF), 219 ERRNAME(OPS_E_R_BAD_FORMAT), 220 ERRNAME(OPS_E_R_UNCONSUMED_DATA), 221 222 ERRNAME(OPS_E_W), 223 ERRNAME(OPS_E_W_WRITE_FAILED), 224 ERRNAME(OPS_E_W_WRITE_TOO_SHORT), 225 226 ERRNAME(OPS_E_P), 227 ERRNAME(OPS_E_P_NOT_ENOUGH_DATA), 228 ERRNAME(OPS_E_P_UNKNOWN_TAG), 229 ERRNAME(OPS_E_P_PACKET_CONSUMED), 230 ERRNAME(OPS_E_P_MPI_FORMAT_ERROR), 231 232 ERRNAME(OPS_E_C), 233 234 ERRNAME(OPS_E_V), 235 ERRNAME(OPS_E_V_BAD_SIGNATURE), 236 ERRNAME(OPS_E_V_NO_SIGNATURE), 237 ERRNAME(OPS_E_V_UNKNOWN_SIGNER), 238 239 ERRNAME(OPS_E_ALG), 240 ERRNAME(OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG), 241 ERRNAME(OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG), 242 ERRNAME(OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG), 243 ERRNAME(OPS_E_ALG_UNSUPPORTED_HASH_ALG), 244 245 ERRNAME(OPS_E_PROTO), 246 ERRNAME(OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT), 247 ERRNAME(OPS_E_PROTO_UNKNOWN_SS), 248 ERRNAME(OPS_E_PROTO_CRITICAL_SS_IGNORED), 249 ERRNAME(OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN), 250 ERRNAME(OPS_E_PROTO_BAD_SIGNATURE_VRSN), 251 ERRNAME(OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN), 252 ERRNAME(OPS_E_PROTO_BAD_PKSK_VRSN), 253 ERRNAME(OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN), 254 ERRNAME(OPS_E_PROTO_BAD_SK_CHECKSUM), 255 256 {0x00, NULL}, /* this is the end-of-array marker */ 257 }; 258 259 /** 260 * \ingroup Core_Errors 261 * \brief returns error code name 262 * \param errcode 263 * \return error code name or "Unknown" 264 */ 265 const char * 266 __ops_errcode(const __ops_errcode_t errcode) 267 { 268 return (__ops_str_from_map((int) errcode, 269 (__ops_map_t *) errcode_name_map)); 270 } 271 272 /* generic grab new storage function */ 273 void * 274 __ops_new(size_t size) 275 { 276 void *vp; 277 278 if ((vp = calloc(1, size)) == NULL) { 279 (void) fprintf(stderr, 280 "allocation failure for %" PRIsize "u bytes", size); 281 } 282 return vp; 283 } 284 285 /** 286 * \ingroup Core_Errors 287 * \brief Pushes the given error on the given errorstack 288 * \param errstack Error stack to use 289 * \param errcode Code of error to push 290 * \param sys_errno System errno (used if errcode=OPS_E_SYSTEM_ERROR) 291 * \param file Source filename where error occurred 292 * \param line Line in source file where error occurred 293 * \param fmt Comment 294 * 295 */ 296 297 void 298 __ops_push_error(__ops_error_t **errstack, __ops_errcode_t errcode, 299 int sys_errno, const char *file, int line, const char *fmt,...) 300 { 301 /* first get the varargs and generate the comment */ 302 __ops_error_t *err; 303 unsigned maxbuf = 128; 304 va_list args; 305 char *comment; 306 307 if ((comment = calloc(1, maxbuf + 1)) == NULL) { 308 (void) fprintf(stderr, "calloc comment failure\n"); 309 return; 310 } 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 if ((err = calloc(1, sizeof(*err))) == NULL) { 319 (void) fprintf(stderr, "calloc comment failure\n"); 320 return; 321 } 322 323 err->next = *errstack; 324 *errstack = err; 325 326 /* fill in the details */ 327 err->errcode = errcode; 328 err->sys_errno = sys_errno; 329 err->file = file; 330 err->line = line; 331 332 err->comment = comment; 333 } 334 335 /** 336 \ingroup Core_Errors 337 \brief print this error 338 \param err Error to print 339 */ 340 void 341 __ops_print_error(__ops_error_t *err) 342 { 343 printf("%s:%d: ", err->file, err->line); 344 if (err->errcode == OPS_E_SYSTEM_ERROR) { 345 printf("system error %d returned from %s()\n", err->sys_errno, 346 err->comment); 347 } else { 348 printf("%s, %s\n", __ops_errcode(err->errcode), err->comment); 349 } 350 } 351 352 /** 353 \ingroup Core_Errors 354 \brief Print all errors on stack 355 \param errstack Error stack to print 356 */ 357 void 358 __ops_print_errors(__ops_error_t *errstack) 359 { 360 __ops_error_t *err; 361 362 for (err = errstack; err != NULL; err = err->next) { 363 __ops_print_error(err); 364 } 365 } 366 367 /** 368 \ingroup Core_Errors 369 \brief Return 1 if given error is present anywhere on stack 370 \param errstack Error stack to check 371 \param errcode Error code to look for 372 \return 1 if found; else 0 373 */ 374 int 375 __ops_has_error(__ops_error_t *errstack, __ops_errcode_t errcode) 376 { 377 __ops_error_t *err; 378 379 for (err = errstack; err != NULL; err = err->next) { 380 if (err->errcode == errcode) { 381 return 1; 382 } 383 } 384 return 0; 385 } 386 387 /** 388 \ingroup Core_Errors 389 \brief Frees all errors on stack 390 \param errstack Error stack to free 391 */ 392 void 393 __ops_free_errors(__ops_error_t *errstack) 394 { 395 __ops_error_t *next; 396 397 while (errstack != NULL) { 398 next = errstack->next; 399 free(errstack->comment); 400 free(errstack); 401 errstack = next; 402 } 403 } 404 405 /* hash a 32-bit integer */ 406 static int 407 hash_uint32(__ops_hash_t *hash, uint32_t n) 408 { 409 uint8_t ibuf[4]; 410 411 ibuf[0] = (uint8_t)(n >> 24) & 0xff; 412 ibuf[1] = (uint8_t)(n >> 16) & 0xff; 413 ibuf[2] = (uint8_t)(n >> 8) & 0xff; 414 ibuf[3] = (uint8_t)n & 0xff; 415 (*hash->add)(hash, (const uint8_t *)(void *)ibuf, sizeof(ibuf)); 416 return sizeof(ibuf); 417 } 418 419 /* hash a string - first length, then string itself */ 420 static int 421 hash_string(__ops_hash_t *hash, const uint8_t *buf, uint32_t len) 422 { 423 if (__ops_get_debug_level(__FILE__)) { 424 hexdump(stderr, "hash_string", buf, len); 425 } 426 hash_uint32(hash, len); 427 (*hash->add)(hash, buf, len); 428 return sizeof(len) + (int)len; 429 } 430 431 /* hash a bignum, possibly padded - first length, then string itself */ 432 static int 433 hash_bignum(__ops_hash_t *hash, BIGNUM *bignum) 434 { 435 uint8_t *bn; 436 size_t len; 437 int padbyte; 438 439 if (BN_is_zero(bignum)) { 440 hash_uint32(hash, 0); 441 return sizeof(len); 442 } 443 if ((len = (size_t) BN_num_bytes(bignum)) < 1) { 444 (void) fprintf(stderr, "hash_bignum: bad size\n"); 445 return 0; 446 } 447 if ((bn = calloc(1, len)) == NULL) { 448 (void) fprintf(stderr, "hash_bignum: bad bn alloc\n"); 449 return 0; 450 } 451 BN_bn2bin(bignum, bn + 1); 452 bn[0] = 0x0; 453 padbyte = (bn[1] & 0x80) ? 1 : 0; 454 hash_string(hash, bn + 1 - padbyte, len + padbyte); 455 free(bn); 456 return sizeof(len) + len + padbyte; 457 } 458 459 /** \file 460 */ 461 462 /** 463 * \ingroup Core_Keys 464 * \brief Calculate a public key fingerprint. 465 * \param fp Where to put the calculated fingerprint 466 * \param key The key for which the fingerprint is calculated 467 */ 468 int 469 __ops_fingerprint(__ops_fingerprint_t *fp, const __ops_pubkey_t *key, __ops_hash_alg_t hashtype) 470 { 471 __ops_memory_t *mem; 472 __ops_hash_t hash; 473 const char *type; 474 uint32_t len; 475 476 mem = __ops_memory_new(); 477 if (key->version == 2 || key->version == 3) { 478 if (key->alg != OPS_PKA_RSA && 479 key->alg != OPS_PKA_RSA_ENCRYPT_ONLY && 480 key->alg != OPS_PKA_RSA_SIGN_ONLY) { 481 (void) fprintf(stderr, 482 "__ops_fingerprint: bad algorithm\n"); 483 return 0; 484 } 485 __ops_hash_md5(&hash); 486 if (!hash.init(&hash)) { 487 (void) fprintf(stderr, 488 "__ops_fingerprint: bad md5 alloc\n"); 489 return 0; 490 } 491 hash_bignum(&hash, key->key.rsa.n); 492 hash_bignum(&hash, key->key.rsa.e); 493 fp->length = hash.finish(&hash, fp->fingerprint); 494 if (__ops_get_debug_level(__FILE__)) { 495 hexdump(stderr, "v2/v3 fingerprint", fp->fingerprint, fp->length); 496 } 497 } else if (hashtype == OPS_HASH_MD5) { 498 __ops_hash_md5(&hash); 499 if (!hash.init(&hash)) { 500 (void) fprintf(stderr, 501 "__ops_fingerprint: bad md5 alloc\n"); 502 return 0; 503 } 504 type = (key->alg == OPS_PKA_RSA) ? "ssh-rsa" : "ssh-dsa"; 505 hash_string(&hash, (const uint8_t *)(const void *)type, strlen(type)); 506 switch(key->alg) { 507 case OPS_PKA_RSA: 508 hash_bignum(&hash, key->key.rsa.e); 509 hash_bignum(&hash, key->key.rsa.n); 510 break; 511 case OPS_PKA_DSA: 512 hash_bignum(&hash, key->key.dsa.p); 513 hash_bignum(&hash, key->key.dsa.q); 514 hash_bignum(&hash, key->key.dsa.g); 515 hash_bignum(&hash, key->key.dsa.y); 516 break; 517 default: 518 break; 519 } 520 fp->length = hash.finish(&hash, fp->fingerprint); 521 if (__ops_get_debug_level(__FILE__)) { 522 hexdump(stderr, "md5 fingerprint", fp->fingerprint, fp->length); 523 } 524 } else { 525 __ops_build_pubkey(mem, key, 0); 526 __ops_hash_sha1(&hash); 527 if (!hash.init(&hash)) { 528 (void) fprintf(stderr, 529 "__ops_fingerprint: bad sha1 alloc\n"); 530 return 0; 531 } 532 len = __ops_mem_len(mem); 533 __ops_hash_add_int(&hash, 0x99, 1); 534 __ops_hash_add_int(&hash, len, 2); 535 hash.add(&hash, __ops_mem_data(mem), len); 536 fp->length = hash.finish(&hash, fp->fingerprint); 537 __ops_memory_free(mem); 538 if (__ops_get_debug_level(__FILE__)) { 539 hexdump(stderr, "sha1 fingerprint", fp->fingerprint, fp->length); 540 } 541 } 542 return 1; 543 } 544 545 /** 546 * \ingroup Core_Keys 547 * \brief Calculate the Key ID from the public key. 548 * \param keyid Space for the calculated ID to be stored 549 * \param key The key for which the ID is calculated 550 */ 551 552 int 553 __ops_keyid(uint8_t *keyid, const size_t idlen, const __ops_pubkey_t *key, __ops_hash_alg_t hashtype) 554 { 555 __ops_fingerprint_t finger; 556 557 if (key->version == 2 || key->version == 3) { 558 unsigned n; 559 uint8_t bn[NETPGP_BUFSIZ]; 560 561 n = (unsigned) BN_num_bytes(key->key.rsa.n); 562 if (n > sizeof(bn)) { 563 (void) fprintf(stderr, "__ops_keyid: bad num bytes\n"); 564 return 0; 565 } 566 if (key->alg != OPS_PKA_RSA && 567 key->alg != OPS_PKA_RSA_ENCRYPT_ONLY && 568 key->alg != OPS_PKA_RSA_SIGN_ONLY) { 569 (void) fprintf(stderr, "__ops_keyid: bad algorithm\n"); 570 return 0; 571 } 572 BN_bn2bin(key->key.rsa.n, bn); 573 (void) memcpy(keyid, bn + n - idlen, idlen); 574 } else { 575 __ops_fingerprint(&finger, key, hashtype); 576 (void) memcpy(keyid, 577 finger.fingerprint + finger.length - idlen, 578 idlen); 579 } 580 return 1; 581 } 582 583 /** 584 \ingroup Core_Hashes 585 \brief Add to the hash 586 \param hash Hash to add to 587 \param n Int to add 588 \param length Length of int in bytes 589 */ 590 void 591 __ops_hash_add_int(__ops_hash_t *hash, unsigned n, unsigned length) 592 { 593 uint8_t c; 594 595 while (length--) { 596 c = n >> (length * 8); 597 hash->add(hash, &c, 1); 598 } 599 } 600 601 /** 602 \ingroup Core_Hashes 603 \brief Setup hash for given hash algorithm 604 \param hash Hash to set up 605 \param alg Hash algorithm to use 606 */ 607 void 608 __ops_hash_any(__ops_hash_t *hash, __ops_hash_alg_t alg) 609 { 610 switch (alg) { 611 case OPS_HASH_MD5: 612 __ops_hash_md5(hash); 613 break; 614 615 case OPS_HASH_SHA1: 616 __ops_hash_sha1(hash); 617 break; 618 619 case OPS_HASH_SHA256: 620 __ops_hash_sha256(hash); 621 break; 622 623 case OPS_HASH_SHA384: 624 __ops_hash_sha384(hash); 625 break; 626 627 case OPS_HASH_SHA512: 628 __ops_hash_sha512(hash); 629 break; 630 631 case OPS_HASH_SHA224: 632 __ops_hash_sha224(hash); 633 break; 634 635 default: 636 (void) fprintf(stderr, "__ops_hash_any: bad algorithm\n"); 637 } 638 } 639 640 /** 641 \ingroup Core_Hashes 642 \brief Returns size of hash for given hash algorithm 643 \param alg Hash algorithm to use 644 \return Size of hash algorithm in bytes 645 */ 646 unsigned 647 __ops_hash_size(__ops_hash_alg_t alg) 648 { 649 switch (alg) { 650 case OPS_HASH_MD5: 651 return 16; 652 653 case OPS_HASH_SHA1: 654 return 20; 655 656 case OPS_HASH_SHA256: 657 return 32; 658 659 case OPS_HASH_SHA224: 660 return 28; 661 662 case OPS_HASH_SHA512: 663 return 64; 664 665 case OPS_HASH_SHA384: 666 return 48; 667 668 default: 669 (void) fprintf(stderr, "__ops_hash_size: bad algorithm\n"); 670 } 671 672 return 0; 673 } 674 675 /** 676 \ingroup Core_Hashes 677 \brief Returns hash enum corresponding to given string 678 \param hash Text name of hash algorithm i.e. "SHA1" 679 \returns Corresponding enum i.e. OPS_HASH_SHA1 680 */ 681 __ops_hash_alg_t 682 __ops_str_to_hash_alg(const char *hash) 683 { 684 if (hash == NULL) { 685 return OPS_DEFAULT_HASH_ALGORITHM; 686 } 687 if (netpgp_strcasecmp(hash, "SHA1") == 0) { 688 return OPS_HASH_SHA1; 689 } 690 if (netpgp_strcasecmp(hash, "MD5") == 0) { 691 return OPS_HASH_MD5; 692 } 693 if (netpgp_strcasecmp(hash, "SHA256") == 0) { 694 return OPS_HASH_SHA256; 695 } 696 /* 697 if (netpgp_strcasecmp(hash,"SHA224") == 0) { 698 return OPS_HASH_SHA224; 699 } 700 */ 701 if (netpgp_strcasecmp(hash, "SHA512") == 0) { 702 return OPS_HASH_SHA512; 703 } 704 if (netpgp_strcasecmp(hash, "SHA384") == 0) { 705 return OPS_HASH_SHA384; 706 } 707 return OPS_HASH_UNKNOWN; 708 } 709 710 /** 711 \ingroup Core_Hashes 712 \brief Hash given data 713 \param out Where to write the hash 714 \param alg Hash algorithm to use 715 \param in Data to hash 716 \param length Length of data 717 \return Size of hash created 718 */ 719 unsigned 720 __ops_hash(uint8_t *out, __ops_hash_alg_t alg, const void *in, size_t length) 721 { 722 __ops_hash_t hash; 723 724 __ops_hash_any(&hash, alg); 725 if (!hash.init(&hash)) { 726 (void) fprintf(stderr, "__ops_hash: bad alloc\n"); 727 /* we'll just continue here - don't want to return a 0 hash */ 728 /* XXX - agc - no way to return failure */ 729 } 730 hash.add(&hash, in, length); 731 return hash.finish(&hash, out); 732 } 733 734 /** 735 \ingroup Core_Hashes 736 \brief Calculate hash for MDC packet 737 \param preamble Preamble to hash 738 \param sz_preamble Size of preamble 739 \param plaintext Plaintext to hash 740 \param sz_plaintext Size of plaintext 741 \param hashed Resulting hash 742 */ 743 void 744 __ops_calc_mdc_hash(const uint8_t *preamble, 745 const size_t sz_preamble, 746 const uint8_t *plaintext, 747 const unsigned sz_plaintext, 748 uint8_t *hashed) 749 { 750 __ops_hash_t hash; 751 uint8_t c; 752 753 if (__ops_get_debug_level(__FILE__)) { 754 hexdump(stderr, "preamble", preamble, sz_preamble); 755 hexdump(stderr, "plaintext", plaintext, sz_plaintext); 756 } 757 /* init */ 758 __ops_hash_any(&hash, OPS_HASH_SHA1); 759 if (!hash.init(&hash)) { 760 (void) fprintf(stderr, "__ops_calc_mdc_hash: bad alloc\n"); 761 /* we'll just continue here - it will die anyway */ 762 /* agc - XXX - no way to return failure */ 763 } 764 765 /* preamble */ 766 hash.add(&hash, preamble, sz_preamble); 767 /* plaintext */ 768 hash.add(&hash, plaintext, sz_plaintext); 769 /* MDC packet tag */ 770 c = MDC_PKT_TAG; 771 hash.add(&hash, &c, 1); 772 /* MDC packet len */ 773 c = OPS_SHA1_HASH_SIZE; 774 hash.add(&hash, &c, 1); 775 776 /* finish */ 777 hash.finish(&hash, hashed); 778 779 if (__ops_get_debug_level(__FILE__)) { 780 hexdump(stderr, "hashed", hashed, OPS_SHA1_HASH_SIZE); 781 } 782 } 783 784 /** 785 \ingroup HighLevel_Supported 786 \brief Is this Hash Algorithm supported? 787 \param hash_alg Hash Algorithm to check 788 \return 1 if supported; else 0 789 */ 790 unsigned 791 __ops_is_hash_alg_supported(const __ops_hash_alg_t *hash_alg) 792 { 793 switch (*hash_alg) { 794 case OPS_HASH_MD5: 795 case OPS_HASH_SHA1: 796 case OPS_HASH_SHA256: 797 return 1; 798 799 default: 800 return 0; 801 } 802 } 803 804 void 805 __ops_random(void *dest, size_t length) 806 { 807 RAND_bytes(dest, (int)length); 808 } 809 810 /** 811 \ingroup HighLevel_Memory 812 \brief Memory to initialise 813 \param mem memory to initialise 814 \param needed Size to initialise to 815 */ 816 void 817 __ops_memory_init(__ops_memory_t *mem, size_t needed) 818 { 819 uint8_t *temp; 820 821 mem->length = 0; 822 if (mem->buf) { 823 if (mem->allocated < needed) { 824 if ((temp = realloc(mem->buf, needed)) == NULL) { 825 (void) fprintf(stderr, "__ops_memory_init: bad alloc\n"); 826 } else { 827 mem->buf = temp; 828 mem->allocated = needed; 829 } 830 } 831 } else { 832 if ((mem->buf = calloc(1, needed)) == NULL) { 833 (void) fprintf(stderr, "__ops_memory_init: bad alloc\n"); 834 } else { 835 mem->allocated = needed; 836 } 837 } 838 } 839 840 /** 841 \ingroup HighLevel_Memory 842 \brief Pad memory to required length 843 \param mem Memory to use 844 \param length New size 845 */ 846 void 847 __ops_memory_pad(__ops_memory_t *mem, size_t length) 848 { 849 uint8_t *temp; 850 851 if (mem->allocated < mem->length) { 852 (void) fprintf(stderr, "__ops_memory_pad: bad alloc in\n"); 853 return; 854 } 855 if (mem->allocated < mem->length + length) { 856 mem->allocated = mem->allocated * 2 + length; 857 temp = realloc(mem->buf, mem->allocated); 858 if (temp == NULL) { 859 (void) fprintf(stderr, "__ops_memory_pad: bad alloc\n"); 860 } else { 861 mem->buf = temp; 862 } 863 } 864 if (mem->allocated < mem->length + length) { 865 (void) fprintf(stderr, "__ops_memory_pad: bad alloc out\n"); 866 } 867 } 868 869 /** 870 \ingroup HighLevel_Memory 871 \brief Add data to memory 872 \param mem Memory to which to add 873 \param src Data to add 874 \param length Length of data to add 875 */ 876 void 877 __ops_memory_add(__ops_memory_t *mem, const uint8_t *src, size_t length) 878 { 879 __ops_memory_pad(mem, length); 880 (void) memcpy(mem->buf + mem->length, src, length); 881 mem->length += length; 882 } 883 884 /* XXX: this could be refactored via the writer, but an awful lot of */ 885 /* hoops to jump through for 2 lines of code! */ 886 void 887 __ops_memory_place_int(__ops_memory_t *mem, unsigned offset, unsigned n, 888 size_t length) 889 { 890 if (mem->allocated < offset + length) { 891 (void) fprintf(stderr, 892 "__ops_memory_place_int: bad alloc\n"); 893 } else { 894 while (length-- > 0) { 895 mem->buf[offset++] = n >> (length * 8); 896 } 897 } 898 } 899 900 /** 901 * \ingroup HighLevel_Memory 902 * \brief Retains allocated memory and set length of stored data to zero. 903 * \param mem Memory to clear 904 * \sa __ops_memory_release() 905 * \sa __ops_memory_free() 906 */ 907 void 908 __ops_memory_clear(__ops_memory_t *mem) 909 { 910 mem->length = 0; 911 } 912 913 /** 914 \ingroup HighLevel_Memory 915 \brief Free memory and associated data 916 \param mem Memory to free 917 \note This does not free mem itself 918 \sa __ops_memory_clear() 919 \sa __ops_memory_free() 920 */ 921 void 922 __ops_memory_release(__ops_memory_t *mem) 923 { 924 if (mem->mmapped) { 925 (void) munmap(mem->buf, mem->length); 926 } else { 927 free(mem->buf); 928 } 929 mem->buf = NULL; 930 mem->length = 0; 931 } 932 933 void 934 __ops_memory_make_packet(__ops_memory_t *out, __ops_content_enum tag) 935 { 936 size_t extra; 937 938 extra = (out->length < 192) ? 1 : (out->length < 8192 + 192) ? 2 : 5; 939 __ops_memory_pad(out, extra + 1); 940 memmove(out->buf + extra + 1, out->buf, out->length); 941 942 out->buf[0] = OPS_PTAG_ALWAYS_SET | OPS_PTAG_NEW_FORMAT | tag; 943 944 if (out->length < 192) { 945 out->buf[1] = out->length; 946 } else if (out->length < 8192 + 192) { 947 out->buf[1] = ((out->length - 192) >> 8) + 192; 948 out->buf[2] = out->length - 192; 949 } else { 950 out->buf[1] = 0xff; 951 out->buf[2] = out->length >> 24; 952 out->buf[3] = out->length >> 16; 953 out->buf[4] = out->length >> 8; 954 out->buf[5] = out->length; 955 } 956 957 out->length += extra + 1; 958 } 959 960 /** 961 \ingroup HighLevel_Memory 962 \brief Create a new zeroed __ops_memory_t 963 \return Pointer to new __ops_memory_t 964 \note Free using __ops_memory_free() after use. 965 \sa __ops_memory_free() 966 */ 967 968 __ops_memory_t * 969 __ops_memory_new(void) 970 { 971 return calloc(1, sizeof(__ops_memory_t)); 972 } 973 974 /** 975 \ingroup HighLevel_Memory 976 \brief Free memory ptr and associated memory 977 \param mem Memory to be freed 978 \sa __ops_memory_release() 979 \sa __ops_memory_clear() 980 */ 981 982 void 983 __ops_memory_free(__ops_memory_t *mem) 984 { 985 __ops_memory_release(mem); 986 free(mem); 987 } 988 989 /** 990 \ingroup HighLevel_Memory 991 \brief Get length of data stored in __ops_memory_t struct 992 \return Number of bytes in data 993 */ 994 size_t 995 __ops_mem_len(const __ops_memory_t *mem) 996 { 997 return mem->length; 998 } 999 1000 /** 1001 \ingroup HighLevel_Memory 1002 \brief Get data stored in __ops_memory_t struct 1003 \return Pointer to data 1004 */ 1005 void * 1006 __ops_mem_data(__ops_memory_t *mem) 1007 { 1008 return mem->buf; 1009 } 1010 1011 /* read a gile into an __ops_memory_t */ 1012 int 1013 __ops_mem_readfile(__ops_memory_t *mem, const char *f) 1014 { 1015 struct stat st; 1016 FILE *fp; 1017 int cc; 1018 1019 if ((fp = fopen(f, "rb")) == NULL) { 1020 (void) fprintf(stderr, 1021 "__ops_mem_readfile: can't open \"%s\"\n", f); 1022 return 0; 1023 } 1024 (void) fstat(fileno(fp), &st); 1025 mem->allocated = (size_t)st.st_size; 1026 mem->buf = mmap(NULL, mem->allocated, PROT_READ, 1027 MAP_PRIVATE | MAP_FILE, fileno(fp), 0); 1028 if (mem->buf == MAP_FAILED) { 1029 /* mmap failed for some reason - try to allocate memory */ 1030 if ((mem->buf = calloc(1, mem->allocated)) == NULL) { 1031 (void) fprintf(stderr, "__ops_mem_readfile: calloc\n"); 1032 (void) fclose(fp); 1033 return 0; 1034 } 1035 /* read into contents of mem */ 1036 for (mem->length = 0 ; 1037 (cc = read(fileno(fp), &mem->buf[mem->length], 1038 mem->allocated - mem->length)) > 0 ; 1039 mem->length += (size_t)cc) { 1040 } 1041 } else { 1042 mem->length = mem->allocated; 1043 mem->mmapped = 1; 1044 } 1045 (void) fclose(fp); 1046 return (mem->allocated == mem->length); 1047 } 1048 1049 typedef struct { 1050 uint16_t sum; 1051 } sum16_t; 1052 1053 1054 /** 1055 * Searches the given map for the given type. 1056 * Returns a human-readable descriptive string if found, 1057 * returns NULL if not found 1058 * 1059 * It is the responsibility of the calling function to handle the 1060 * error case sensibly (i.e. don't just print out the return string. 1061 * 1062 */ 1063 static const char * 1064 str_from_map_or_null(int type, __ops_map_t *map) 1065 { 1066 __ops_map_t *row; 1067 1068 for (row = map; row->string != NULL; row++) { 1069 if (row->type == type) { 1070 return row->string; 1071 } 1072 } 1073 return NULL; 1074 } 1075 1076 /** 1077 * \ingroup Core_Print 1078 * 1079 * Searches the given map for the given type. 1080 * Returns a readable string if found, "Unknown" if not. 1081 */ 1082 1083 const char * 1084 __ops_str_from_map(int type, __ops_map_t *map) 1085 { 1086 const char *str; 1087 1088 str = str_from_map_or_null(type, map); 1089 return (str) ? str : "Unknown"; 1090 } 1091 1092 #define LINELEN 16 1093 1094 /* show hexadecimal/ascii dump */ 1095 void 1096 hexdump(FILE *fp, const char *header, const uint8_t *src, size_t length) 1097 { 1098 size_t i; 1099 char line[LINELEN + 1]; 1100 1101 (void) fprintf(fp, "%s%s", (header) ? header : "", (header) ? "\n" : ""); 1102 (void) fprintf(fp, "[%d chars]\n", length); 1103 for (i = 0 ; i < length ; i++) { 1104 if (i % LINELEN == 0) { 1105 (void) fprintf(fp, "%.5d | ", i); 1106 } 1107 (void) fprintf(fp, "%.02x ", (uint8_t)src[i]); 1108 line[i % LINELEN] = (isprint(src[i])) ? src[i] : '.'; 1109 if (i % LINELEN == LINELEN - 1) { 1110 line[LINELEN] = 0x0; 1111 (void) fprintf(fp, " | %s\n", line); 1112 } 1113 } 1114 if (i % LINELEN != 0) { 1115 for ( ; i % LINELEN != 0 ; i++) { 1116 (void) fprintf(fp, " "); 1117 line[i % LINELEN] = ' '; 1118 } 1119 line[LINELEN] = 0x0; 1120 (void) fprintf(fp, " | %s\n", line); 1121 } 1122 } 1123 1124 /** 1125 * \ingroup HighLevel_Functions 1126 * \brief Closes down OpenPGP::SDK. 1127 * 1128 * Close down OpenPGP:SDK, release any resources under the control of 1129 * the library. 1130 */ 1131 1132 void 1133 __ops_finish(void) 1134 { 1135 __ops_crypto_finish(); 1136 } 1137 1138 static int 1139 sum16_reader(void *dest_, size_t length, __ops_error_t **errors, 1140 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 1141 { 1142 const uint8_t *dest = dest_; 1143 sum16_t *arg = __ops_reader_get_arg(readinfo); 1144 int r; 1145 int n; 1146 1147 r = __ops_stacked_read(dest_, length, errors, readinfo, cbinfo); 1148 if (r < 0) { 1149 return r; 1150 } 1151 for (n = 0; n < r; ++n) { 1152 arg->sum = (arg->sum + dest[n]) & 0xffff; 1153 } 1154 return r; 1155 } 1156 1157 static void 1158 sum16_destroyer(__ops_reader_t *readinfo) 1159 { 1160 free(__ops_reader_get_arg(readinfo)); 1161 } 1162 1163 /** 1164 \ingroup Internal_Readers_Sum16 1165 \param stream Parse settings 1166 */ 1167 1168 void 1169 __ops_reader_push_sum16(__ops_stream_t *stream) 1170 { 1171 sum16_t *arg; 1172 1173 if ((arg = calloc(1, sizeof(*arg))) == NULL) { 1174 (void) fprintf(stderr, "__ops_reader_push_sum16: bad alloc\n"); 1175 } else { 1176 __ops_reader_push(stream, sum16_reader, sum16_destroyer, arg); 1177 } 1178 } 1179 1180 /** 1181 \ingroup Internal_Readers_Sum16 1182 \param stream Parse settings 1183 \return sum 1184 */ 1185 uint16_t 1186 __ops_reader_pop_sum16(__ops_stream_t *stream) 1187 { 1188 uint16_t sum; 1189 sum16_t *arg; 1190 1191 arg = __ops_reader_get_arg(__ops_readinfo(stream)); 1192 sum = arg->sum; 1193 __ops_reader_pop(stream); 1194 free(arg); 1195 return sum; 1196 } 1197 1198 /* small useful functions for setting the file-level debugging levels */ 1199 /* if the debugv list contains the filename in question, we're debugging it */ 1200 1201 enum { 1202 MAX_DEBUG_NAMES = 32 1203 }; 1204 1205 static int debugc; 1206 static char *debugv[MAX_DEBUG_NAMES]; 1207 1208 /* set the debugging level per filename */ 1209 int 1210 __ops_set_debug_level(const char *f) 1211 { 1212 const char *name; 1213 int i; 1214 1215 if (f == NULL) { 1216 f = "all"; 1217 } 1218 if ((name = strrchr(f, '/')) == NULL) { 1219 name = f; 1220 } else { 1221 name += 1; 1222 } 1223 for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) { 1224 if (strcmp(debugv[i], name) == 0) { 1225 return 1; 1226 } 1227 } 1228 if (i == MAX_DEBUG_NAMES) { 1229 return 0; 1230 } 1231 debugv[debugc++] = netpgp_strdup(name); 1232 return 1; 1233 } 1234 1235 /* get the debugging level per filename */ 1236 int 1237 __ops_get_debug_level(const char *f) 1238 { 1239 const char *name; 1240 int i; 1241 1242 if ((name = strrchr(f, '/')) == NULL) { 1243 name = f; 1244 } else { 1245 name += 1; 1246 } 1247 for (i = 0; i < debugc; i++) { 1248 if (strcmp(debugv[i], "all") == 0 || 1249 strcmp(debugv[i], name) == 0) { 1250 return 1; 1251 } 1252 } 1253 return 0; 1254 } 1255 1256 /* return the version for the library */ 1257 const char * 1258 __ops_get_info(const char *type) 1259 { 1260 if (strcmp(type, "version") == 0) { 1261 return NETPGP_VERSION_STRING; 1262 } 1263 if (strcmp(type, "maintainer") == 0) { 1264 return NETPGP_MAINTAINER; 1265 } 1266 return "[unknown]"; 1267 } 1268 1269 /* local version of asprintf so we don't have to play autoconf games */ 1270 int 1271 __ops_asprintf(char **ret, const char *fmt, ...) 1272 { 1273 va_list args; 1274 char buf[120 * 1024]; /* XXX - "huge" buffer on stack */ 1275 int cc; 1276 1277 va_start(args, fmt); 1278 cc = vsnprintf(buf, sizeof(buf), fmt, args); 1279 va_end(args); 1280 if ((*ret = calloc(1, (size_t)(cc + 1))) == NULL) { 1281 *ret = NULL; 1282 return -1; 1283 } 1284 (void) memcpy(*ret, buf, (size_t)cc); 1285 (*ret)[cc] = 0x0; 1286 return cc; 1287 } 1288 1289 void 1290 netpgp_log(const char *fmt, ...) 1291 { 1292 va_list vp; 1293 time_t t; 1294 char buf[BUFSIZ * 2]; 1295 int cc; 1296 1297 (void) time(&t); 1298 cc = snprintf(buf, sizeof(buf), "%.24s: netpgp: ", ctime(&t)); 1299 va_start(vp, fmt); 1300 (void) vsnprintf(&buf[cc], sizeof(buf) - (size_t)cc, fmt, vp); 1301 va_end(vp); 1302 /* do something with message */ 1303 /* put into log buffer? */ 1304 } 1305 1306 /* portable replacement for strdup(3) */ 1307 char * 1308 netpgp_strdup(const char *s) 1309 { 1310 size_t len; 1311 char *cp; 1312 1313 len = strlen(s); 1314 if ((cp = calloc(1, len + 1)) != NULL) { 1315 (void) memcpy(cp, s, len); 1316 cp[len] = 0x0; 1317 } 1318 return cp; 1319 } 1320 1321 /* portable replacement for strcasecmp(3) */ 1322 int 1323 netpgp_strcasecmp(const char *s1, const char *s2) 1324 { 1325 int n; 1326 1327 for (n = 0 ; *s1 && *s2 && (n = tolower(*s1) - tolower(*s2)) == 0 ; s1++, s2++) { 1328 } 1329 return n; 1330 } 1331