1 /* $NetBSD: params.c,v 1.31 2021/06/03 15:40:27 prlw1 Exp $ */ 2 3 /*- 4 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Roland C. Dowdeswell. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __RCSID("$NetBSD: params.c,v 1.31 2021/06/03 15:40:27 prlw1 Exp $"); 35 #endif 36 37 #include <sys/types.h> 38 #include <sys/param.h> 39 #include <sys/stat.h> 40 41 #include <err.h> 42 #include <errno.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <util.h> 47 48 #include "params.h" 49 #include "pkcs5_pbkdf2.h" 50 #include "utils.h" 51 #include "cgdconfig.h" 52 #include "extern.h" 53 54 static void params_init(struct params *); 55 56 static void print_kvpair_cstr(FILE *, int, const char *, const char *); 57 static void print_kvpair_string(FILE *, int, const char *, const string_t *); 58 static void print_kvpair_int(FILE *, int, const char *, size_t); 59 static void print_kvpair_b64(FILE *, int, int, const char *, bits_t *); 60 61 static void spaces(FILE *, int); 62 63 /* keygen defaults */ 64 #define DEFAULT_SALTLEN 128 65 #define DEFAULT_ITERATION_TIME 2000000 /* 1 second in microseconds */ 66 67 /* crypto defaults functions */ 68 static struct crypto_defaults { 69 char alg[32]; 70 int keylen; 71 } crypto_defaults[] = { 72 { "adiantum", 256 }, 73 { "aes-cbc", 128 }, 74 { "aes-xts", 256 }, 75 { "3des-cbc", 192 }, 76 { "blowfish-cbc", 128 } 77 }; 78 79 static int crypt_defaults_lookup(const char *); 80 81 struct params * 82 params_new(void) 83 { 84 struct params *p; 85 86 p = emalloc(sizeof(*p)); 87 params_init(p); 88 return p; 89 } 90 91 static void 92 params_init(struct params *p) 93 { 94 95 p->algorithm = NULL; 96 p->ivmeth = NULL; 97 p->key = NULL; 98 p->keylen = (size_t)-1; 99 p->bsize = (size_t)-1; 100 p->verify_method = VERIFY_UNKNOWN; 101 p->dep_keygen = NULL; 102 p->keygen = NULL; 103 } 104 105 void 106 params_free(struct params *p) 107 { 108 109 if (!p) 110 return; 111 string_free(p->algorithm); 112 string_free(p->ivmeth); 113 keygen_free(p->dep_keygen); 114 keygen_free(p->keygen); 115 } 116 117 struct params * 118 params_combine(struct params *p1, struct params *p2) 119 { 120 struct params *p; 121 122 if (p1) 123 p = p1; 124 else 125 p = params_new(); 126 127 if (!p2) 128 return p; 129 130 if (p2->algorithm) 131 string_assign(&p->algorithm, p2->algorithm); 132 if (p2->ivmeth) 133 string_assign(&p->ivmeth, p2->ivmeth); 134 if (p2->keylen != (size_t)-1) 135 p->keylen = p2->keylen; 136 if (p2->bsize != (size_t)-1) 137 p->bsize = p2->bsize; 138 if (p2->verify_method != VERIFY_UNKNOWN) 139 p->verify_method = p2->verify_method; 140 141 p->dep_keygen = keygen_combine(p->dep_keygen, p2->dep_keygen); 142 keygen_addlist(&p->keygen, p2->keygen); 143 144 /* 145 * at this point we should have moved all allocated data 146 * in p2 into p, so we can free it. 147 */ 148 free(p2); 149 return p; 150 } 151 152 int 153 params_filldefaults(struct params *p) 154 { 155 size_t i; 156 157 if (p->verify_method == VERIFY_UNKNOWN) 158 p->verify_method = VERIFY_NONE; 159 if (!p->ivmeth) 160 p->ivmeth = string_fromcharstar("encblkno1"); 161 if (p->keylen == (size_t)-1) { 162 if (p->algorithm == NULL) 163 return -1; 164 i = crypt_defaults_lookup(string_tocharstar(p->algorithm)); 165 if (i != (size_t)-1) { 166 p->keylen = crypto_defaults[i].keylen; 167 } else { 168 warnx("could not determine key length for unknown " 169 "algorithm \"%s\"", 170 string_tocharstar(p->algorithm)); 171 return -1; 172 } 173 } 174 return 0; 175 } 176 177 /* 178 * params_verify traverses the parameters and all of the keygen methods 179 * looking for inconsistencies. It outputs warnings on non-fatal errors 180 * such as unknown encryption methods, but returns failure on fatal 181 * conditions such as a PKCS5_PBKDF2 keygen without a salt. It is intended 182 * to run before key generation. 183 */ 184 185 int 186 params_verify(const struct params *p) 187 { 188 static const char *encblkno[] = { 189 "encblkno", "encblkno1", "encblkno8" 190 }; 191 static size_t i; 192 const char *meth; 193 194 if (!p->algorithm) { 195 warnx("unspecified algorithm"); 196 return 0; 197 } 198 /* 199 * we only warn for the encryption method so that it is possible 200 * to use an older cgdconfig(8) with a new kernel that supports 201 * additional crypto algorithms. 202 */ 203 if (crypt_defaults_lookup(string_tocharstar(p->algorithm)) == -1) 204 warnx("unknown algorithm \"%s\"(warning)", 205 string_tocharstar(p->algorithm)); 206 /* same rationale with IV methods. */ 207 if (!p->ivmeth) { 208 warnx("unspecified IV method"); 209 return 0; 210 } 211 212 meth = string_tocharstar(p->ivmeth); 213 for (i = 0; i < __arraycount(encblkno); i++) 214 if (strcmp(encblkno[i], meth) == 0) 215 break; 216 217 if (i == __arraycount(encblkno)) 218 warnx("unknown IV method \"%s\" (warning)", meth); 219 220 if (p->keylen == (size_t)-1) { 221 warnx("unspecified key length"); 222 return 0; 223 } 224 225 return keygen_verify(p->keygen); 226 } 227 228 struct params * 229 params_algorithm(string_t *in) 230 { 231 struct params *p = params_new(); 232 233 p->algorithm = in; 234 return p; 235 } 236 237 struct params * 238 params_ivmeth(string_t *in) 239 { 240 struct params *p = params_new(); 241 242 p->ivmeth = in; 243 return p; 244 } 245 246 struct params * 247 params_keylen(size_t in) 248 { 249 struct params *p = params_new(); 250 251 p->keylen = in; 252 return p; 253 } 254 255 struct params * 256 params_bsize(size_t in) 257 { 258 struct params *p = params_new(); 259 260 p->bsize = in; 261 return p; 262 } 263 264 struct params * 265 params_verify_method(string_t *in) 266 { 267 struct params *p = params_new(); 268 const char *vm = string_tocharstar(in); 269 270 if (!strcmp("none", vm)) 271 p->verify_method = VERIFY_NONE; 272 if (!strcmp("disklabel", vm)) 273 p->verify_method = VERIFY_DISKLABEL; 274 if (!strcmp("ffs", vm)) 275 p->verify_method = VERIFY_FFS; 276 if (!strcmp("re-enter", vm)) 277 p->verify_method = VERIFY_REENTER; 278 if (!strcmp("mbr", vm)) 279 p->verify_method = VERIFY_MBR; 280 if (!strcmp("gpt", vm)) 281 p->verify_method = VERIFY_GPT; 282 283 string_free(in); 284 285 if (p->verify_method == VERIFY_UNKNOWN) 286 warnx("params_setverify_method: unrecognized " 287 "verify method \"%s\"", vm); 288 return p; 289 } 290 291 struct params * 292 params_keygen(struct keygen *in) 293 { 294 struct params *p = params_new(); 295 296 p->keygen = in; 297 return p; 298 } 299 300 struct params * 301 params_dep_keygen(struct keygen *in) 302 { 303 struct params *p = params_new(); 304 305 p->dep_keygen = in; 306 return p; 307 } 308 309 struct keygen * 310 keygen_new(void) 311 { 312 struct keygen *kg; 313 314 kg = emalloc(sizeof(*kg)); 315 kg->kg_method = KEYGEN_UNKNOWN; 316 kg->kg_iterations = (size_t)-1; 317 kg->kg_salt = NULL; 318 kg->kg_key = NULL; 319 kg->kg_cmd = NULL; 320 kg->next = NULL; 321 return kg; 322 } 323 324 void 325 keygen_free(struct keygen *kg) 326 { 327 328 if (!kg) 329 return; 330 bits_free(kg->kg_salt); 331 bits_free(kg->kg_key); 332 string_free(kg->kg_cmd); 333 keygen_free(kg->next); 334 free(kg); 335 } 336 337 /* 338 * keygen_verify traverses the keygen structures and ensures 339 * that the appropriate information is available. 340 */ 341 342 int 343 keygen_verify(const struct keygen *kg) 344 { 345 346 if (!kg) 347 return 1; 348 switch (kg->kg_method) { 349 case KEYGEN_PKCS5_PBKDF2_OLD: 350 if (kg->kg_iterations == (size_t)-1) { 351 warnx("keygen pkcs5_pbkdf2 must provide `iterations'"); 352 return 0; 353 } 354 if (kg->kg_key) 355 warnx("keygen pkcs5_pbkdf2 does not need a `key'"); 356 if (!kg->kg_salt) { 357 warnx("keygen pkcs5_pbkdf2 must provide a salt"); 358 return 0; 359 } 360 if (kg->kg_cmd) 361 warnx("keygen pkcs5_pbkdf2 does not need a `cmd'"); 362 break; 363 case KEYGEN_PKCS5_PBKDF2_SHA1: 364 if (kg->kg_iterations == (size_t)-1) { 365 warnx("keygen pkcs5_pbkdf2/sha1 must provide `iterations'"); 366 return 0; 367 } 368 if (kg->kg_key) 369 warnx("keygen pkcs5_pbkdf2/sha1 does not need a `key'"); 370 if (!kg->kg_salt) { 371 warnx("keygen pkcs5_pbkdf2/sha1 must provide a salt"); 372 return 0; 373 } 374 if (kg->kg_cmd) 375 warnx("keygen pkcs5_pbkdf2/sha1 does not need a `cmd'"); 376 break; 377 case KEYGEN_STOREDKEY: 378 if (kg->kg_iterations != (size_t)-1) 379 warnx("keygen storedkey does not need `iterations'"); 380 if (!kg->kg_key) { 381 warnx("keygen storedkey must provide a key"); 382 return 0; 383 } 384 if (kg->kg_salt) 385 warnx("keygen storedkey does not need `salt'"); 386 if (kg->kg_cmd) 387 warnx("keygen storedkey does not need `cmd'"); 388 break; 389 case KEYGEN_RANDOMKEY: 390 case KEYGEN_URANDOMKEY: 391 if (kg->kg_iterations != (size_t)-1) 392 warnx("keygen [u]randomkey does not need `iterations'"); 393 if (kg->kg_key) 394 warnx("keygen [u]randomkey does not need `key'"); 395 if (kg->kg_salt) 396 warnx("keygen [u]randomkey does not need `salt'"); 397 if (kg->kg_cmd) 398 warnx("keygen [u]randomkey does not need `cmd'"); 399 break; 400 case KEYGEN_SHELL_CMD: 401 if (kg->kg_iterations != (size_t)-1) 402 warnx("keygen shell_cmd does not need `iterations'"); 403 if (kg->kg_key) 404 warnx("keygen shell_cmd does not need `key'"); 405 if (kg->kg_salt) 406 warnx("keygen shell_cmd does not need `salt'"); 407 if (!kg->kg_cmd) { 408 warnx("keygen shell_cmd must provide a `cmd'"); 409 return 0; 410 } 411 break; 412 } 413 return keygen_verify(kg->next); 414 } 415 416 struct keygen * 417 keygen_generate(int method) 418 { 419 struct keygen *kg; 420 421 kg = keygen_new(); 422 if (!kg) 423 return NULL; 424 425 kg->kg_method = method; 426 return kg; 427 } 428 429 /* 430 * keygen_filldefaults walks the keygen list and fills in 431 * default values. The defaults may be either calibrated 432 * or randomly generated so this function is designed to be 433 * called when generating a new parameters file, not when 434 * reading a parameters file. 435 */ 436 437 int 438 keygen_filldefaults(struct keygen *kg, size_t keylen) 439 { 440 441 if (!kg) 442 return 0; 443 switch (kg->kg_method) { 444 case KEYGEN_RANDOMKEY: 445 case KEYGEN_URANDOMKEY: 446 case KEYGEN_SHELL_CMD: 447 break; 448 case KEYGEN_PKCS5_PBKDF2_OLD: 449 case KEYGEN_PKCS5_PBKDF2_SHA1: 450 kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1); 451 kg->kg_iterations = pkcs5_pbkdf2_calibrate(BITS2BYTES(keylen), 452 DEFAULT_ITERATION_TIME); 453 if (kg->kg_iterations < 1) { 454 warnx("could not calibrate pkcs5_pbkdf2"); 455 return -1; 456 } 457 break; 458 case KEYGEN_STOREDKEY: 459 /* Generate a random stored key */ 460 kg->kg_key = bits_getrandombits(keylen, 1); 461 if (!kg->kg_key) { 462 warnx("can't generate random bits for storedkey"); 463 return -1; 464 } 465 break; 466 default: 467 return -1; 468 } 469 470 return keygen_filldefaults(kg->next, keylen); 471 } 472 473 struct keygen * 474 keygen_combine(struct keygen *kg1, struct keygen *kg2) 475 { 476 if (!kg1 && !kg2) 477 return NULL; 478 479 if (!kg1) 480 kg1 = keygen_new(); 481 482 if (!kg2) 483 return kg1; 484 485 if (kg2->kg_method != KEYGEN_UNKNOWN) 486 kg1->kg_method = kg2->kg_method; 487 488 if (kg2->kg_iterations != (size_t)-1 && kg2->kg_iterations > 0) 489 kg1->kg_iterations = kg2->kg_iterations; 490 491 if (kg2->kg_salt) 492 bits_assign(&kg1->kg_salt, kg2->kg_salt); 493 494 if (kg2->kg_key) 495 bits_assign(&kg1->kg_key, kg2->kg_key); 496 497 if (kg2->kg_cmd) 498 string_assign(&kg1->kg_cmd, kg2->kg_cmd); 499 500 return kg1; 501 } 502 503 struct keygen * 504 keygen_method(string_t *in) 505 { 506 struct keygen *kg = keygen_new(); 507 const char *kgm = string_tocharstar(in); 508 509 if (!strcmp("pkcs5_pbkdf2", kgm)) 510 kg->kg_method = KEYGEN_PKCS5_PBKDF2_OLD; 511 if (!strcmp("pkcs5_pbkdf2/sha1", kgm)) 512 kg->kg_method = KEYGEN_PKCS5_PBKDF2_SHA1; 513 if (!strcmp("randomkey", kgm)) 514 kg->kg_method = KEYGEN_RANDOMKEY; 515 if (!strcmp("storedkey", kgm)) 516 kg->kg_method = KEYGEN_STOREDKEY; 517 if (!strcmp("urandomkey", kgm)) 518 kg->kg_method = KEYGEN_URANDOMKEY; 519 if (!strcmp("shell_cmd", kgm)) 520 kg->kg_method = KEYGEN_SHELL_CMD; 521 522 string_free(in); 523 524 if (kg->kg_method == KEYGEN_UNKNOWN) 525 warnx("unrecognized key generation method \"%s\"", kgm); 526 return kg; 527 } 528 529 struct keygen * 530 keygen_set_method(struct keygen *kg, string_t *in) 531 { 532 533 return keygen_combine(kg, keygen_method(in)); 534 } 535 536 struct keygen * 537 keygen_salt(bits_t *in) 538 { 539 struct keygen *kg = keygen_new(); 540 541 kg->kg_salt = in; 542 return kg; 543 } 544 545 struct keygen * 546 keygen_iterations(size_t in) 547 { 548 struct keygen *kg = keygen_new(); 549 550 kg->kg_iterations = in; 551 return kg; 552 } 553 554 void 555 keygen_addlist(struct keygen **l, struct keygen *e) 556 { 557 struct keygen *t; 558 559 if (*l) { 560 t = *l; 561 for (;t->next; t = t->next) 562 ; 563 t->next = e; 564 } else { 565 *l = e; 566 } 567 } 568 569 struct keygen * 570 keygen_key(bits_t *in) 571 { 572 struct keygen *kg = keygen_new(); 573 574 kg->kg_key = in; 575 return kg; 576 } 577 578 struct keygen * 579 keygen_cmd(string_t *in) 580 { 581 struct keygen *kg = keygen_new(); 582 583 kg->kg_cmd = in; 584 return kg; 585 } 586 587 struct params * 588 params_fget(FILE *f) 589 { 590 struct params *p; 591 592 p = cgdparsefile(f); 593 594 if (!p) 595 return NULL; 596 597 /* 598 * We deal with the deprecated keygen structure by prepending it 599 * to the list of keygens, so that the rest of the code does not 600 * have to deal with this backwards compat issue. The deprecated 601 * ``xor_key'' field may be stored in p->dep_keygen->kg_key. If 602 * it exists, we construct a storedkey keygen struct as well. Also, 603 * default the iteration count to 128 as the old code did. 604 */ 605 606 if (p->dep_keygen) { 607 if (p->dep_keygen->kg_iterations == (size_t)-1) 608 p->dep_keygen->kg_iterations = 128; 609 p->dep_keygen->next = p->keygen; 610 if (p->dep_keygen->kg_key) { 611 p->keygen = keygen_generate(KEYGEN_STOREDKEY); 612 p->keygen->kg_key = p->dep_keygen->kg_key; 613 p->dep_keygen->kg_key = NULL; 614 p->keygen->next = p->dep_keygen; 615 } else { 616 p->keygen = p->dep_keygen; 617 } 618 p->dep_keygen = NULL; 619 } 620 return p; 621 } 622 623 struct params * 624 params_cget(const char *fn) 625 { 626 struct params *p; 627 FILE *f; 628 char filename[MAXPATHLEN]; 629 630 if ((f = fopen(fn, "r")) == NULL && fn[0] != '/') { 631 snprintf(filename, sizeof(filename), "%s/%s", 632 CGDCONFIG_DIR, fn); 633 fn = filename; 634 f = fopen(fn, "r"); 635 } 636 637 if (f == NULL) { 638 warn("failed to open params file \"%s\"", fn); 639 return NULL; 640 } 641 p = params_fget(f); 642 (void)fclose(f); 643 return p; 644 } 645 646 #define WRAP_COL 50 647 #define TAB_COL 8 648 649 static void 650 spaces(FILE *f, int len) 651 { 652 653 while (len-- > 0) 654 (void)fputc(' ', f); 655 } 656 657 static void 658 print_kvpair_cstr(FILE *f, int ts, const char *key, const char *val) 659 { 660 661 spaces(f, ts); 662 (void)fprintf(f, "%s %s;\n", key, val); 663 } 664 665 static void 666 print_kvpair_string(FILE *f, int ts, const char *key, const string_t *val) 667 { 668 669 print_kvpair_cstr(f, ts, key, string_tocharstar(val)); 670 } 671 672 static void 673 print_kvpair_int(FILE *f, int ts, const char *key, size_t val) 674 { 675 char *tmp; 676 677 if (!key || val == (size_t)-1) 678 return; 679 680 if (asprintf(&tmp, "%zu", val) == -1) 681 err(1, NULL); 682 print_kvpair_cstr(f, ts, key, tmp); 683 free(tmp); 684 } 685 686 /* 687 * prints out a base64 encoded k-v pair to f. It encodes the length 688 * of the bitstream as a 32bit unsigned integer in network byte order 689 * up front. 690 */ 691 692 static void 693 print_kvpair_b64(FILE *f, int curpos, int ts, const char *key, bits_t *val) 694 { 695 string_t *str; 696 int i; 697 int len; 698 int pos; 699 const char *out; 700 701 if (!key || !val) 702 return; 703 704 str = bits_encode(val); 705 out = string_tocharstar(str); 706 len = strlen(out); 707 708 spaces(f, ts); 709 (void)fprintf(f, "%s ", key); 710 curpos += ts + strlen(key) + 1; 711 ts = curpos; 712 713 for (i=0, pos=curpos; i < len; i++, pos++) { 714 if (pos > WRAP_COL) { 715 (void)fprintf(f, " \\\n"); 716 spaces(f, ts); 717 pos = ts; 718 } 719 (void)fputc(out[i], f); 720 } 721 (void)fprintf(f, ";\n"); 722 string_free(str); 723 } 724 725 int 726 keygen_fput(struct keygen *kg, int ts, FILE *f) 727 { 728 int curpos = 0; 729 730 if (!kg) 731 return 0; 732 (void)fprintf(f, "keygen "); 733 curpos += strlen("keygen "); 734 switch (kg->kg_method) { 735 case KEYGEN_STOREDKEY: 736 (void)fprintf(f, "storedkey "); 737 curpos += strlen("storedkey "); 738 print_kvpair_b64(f, curpos, 0, "key", kg->kg_key); 739 break; 740 case KEYGEN_RANDOMKEY: 741 (void)fprintf(f, "randomkey;\n"); 742 break; 743 case KEYGEN_URANDOMKEY: 744 (void)fprintf(f, "urandomkey;\n"); 745 break; 746 case KEYGEN_PKCS5_PBKDF2_OLD: 747 (void)fprintf(f, "pkcs5_pbkdf2 {\n"); 748 print_kvpair_int(f, ts, "iterations", kg->kg_iterations); 749 print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt); 750 (void)fprintf(f, "};\n"); 751 break; 752 case KEYGEN_PKCS5_PBKDF2_SHA1: 753 (void)fprintf(f, "pkcs5_pbkdf2/sha1 {\n"); 754 print_kvpair_int(f, ts, "iterations", kg->kg_iterations); 755 print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt); 756 (void)fprintf(f, "};\n"); 757 break; 758 default: 759 warnx("keygen_fput: %d not a valid method", kg->kg_method); 760 break; 761 } 762 return keygen_fput(kg->next, ts, f); 763 } 764 765 int 766 params_fput(struct params *p, FILE *f) 767 { 768 int ts = 0; /* tabstop of 0 spaces */ 769 770 print_kvpair_string(f, ts, "algorithm", p->algorithm); 771 print_kvpair_string(f, ts, "iv-method", p->ivmeth); 772 print_kvpair_int(f, ts, "keylength", p->keylen); 773 print_kvpair_int(f, ts, "blocksize", p->bsize); 774 switch (p->verify_method) { 775 case VERIFY_NONE: 776 print_kvpair_cstr(f, ts, "verify_method", "none"); 777 break; 778 case VERIFY_DISKLABEL: 779 print_kvpair_cstr(f, ts, "verify_method", "disklabel"); 780 break; 781 case VERIFY_FFS: 782 print_kvpair_cstr(f, ts, "verify_method", "ffs"); 783 break; 784 case VERIFY_REENTER: 785 print_kvpair_cstr(f, ts, "verify_method", "re-enter"); 786 break; 787 case VERIFY_MBR: 788 print_kvpair_cstr(f, ts, "verify_method", "mbr"); 789 break; 790 case VERIFY_GPT: 791 print_kvpair_cstr(f, ts, "verify_method", "gpt"); 792 break; 793 default: 794 warnx("unsupported verify_method (%d)", p->verify_method); 795 return -1; 796 } 797 return keygen_fput(p->keygen, TAB_COL, f); 798 } 799 800 int 801 params_cput(struct params *p, const char *fn) 802 { 803 FILE *f; 804 805 if (fn && *fn) { 806 if ((f = fopen(fn, "w")) == NULL) { 807 warn("could not open outfile \"%s\"", fn); 808 return -1; 809 } 810 } else { 811 f = stdout; 812 } 813 return params_fput(p, f); 814 } 815 816 static int 817 crypt_defaults_lookup(const char *alg) 818 { 819 unsigned i; 820 821 for (i=0; i < (sizeof(crypto_defaults) / sizeof(crypto_defaults[0])); i++) 822 if (!strcmp(alg, crypto_defaults[i].alg)) 823 return i; 824 825 return -1; 826 } 827