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