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