1 /* $NetBSD: hxtool.c,v 1.1.1.2 2014/04/24 12:45:42 pettai Exp $ */ 2 3 /* 4 * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 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 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 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 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "hx_locl.h" 37 38 #include <hxtool-commands.h> 39 #include <krb5/sl.h> 40 #include <krb5/rtbl.h> 41 #include <krb5/parse_time.h> 42 43 static hx509_context context; 44 45 static char *stat_file_string; 46 static int version_flag; 47 static int help_flag; 48 49 struct getargs args[] = { 50 { "statistic-file", 0, arg_string, &stat_file_string, NULL, NULL }, 51 { "version", 0, arg_flag, &version_flag, NULL, NULL }, 52 { "help", 0, arg_flag, &help_flag, NULL, NULL } 53 }; 54 int num_args = sizeof(args) / sizeof(args[0]); 55 56 static void 57 usage(int code) 58 { 59 arg_printusage(args, num_args, NULL, "command"); 60 printf("Use \"%s help\" to get more help\n", getprogname()); 61 exit(code); 62 } 63 64 /* 65 * 66 */ 67 68 static void 69 lock_strings(hx509_lock lock, getarg_strings *pass) 70 { 71 int i; 72 for (i = 0; i < pass->num_strings; i++) { 73 int ret = hx509_lock_command_string(lock, pass->strings[i]); 74 if (ret) 75 errx(1, "hx509_lock_command_string: %s: %d", 76 pass->strings[i], ret); 77 } 78 } 79 80 /* 81 * 82 */ 83 84 static void 85 certs_strings(hx509_context contextp, const char *type, hx509_certs certs, 86 hx509_lock lock, const getarg_strings *s) 87 { 88 int i, ret; 89 90 for (i = 0; i < s->num_strings; i++) { 91 ret = hx509_certs_append(contextp, certs, lock, s->strings[i]); 92 if (ret) 93 hx509_err(contextp, 1, ret, 94 "hx509_certs_append: %s %s", type, s->strings[i]); 95 } 96 } 97 98 /* 99 * 100 */ 101 102 static void 103 parse_oid(const char *str, const heim_oid *def, heim_oid *oid) 104 { 105 int ret; 106 if (str) 107 ret = der_parse_heim_oid (str, " .", oid); 108 else 109 ret = der_copy_oid(def, oid); 110 if (ret) 111 errx(1, "parse_oid failed for: %s", str ? str : "default oid"); 112 } 113 114 /* 115 * 116 */ 117 118 static void 119 peer_strings(hx509_context contextp, 120 hx509_peer_info *peer, 121 const getarg_strings *s) 122 { 123 AlgorithmIdentifier *val; 124 int ret, i; 125 126 ret = hx509_peer_info_alloc(contextp, peer); 127 if (ret) 128 hx509_err(contextp, 1, ret, "hx509_peer_info_alloc"); 129 130 val = calloc(s->num_strings, sizeof(*val)); 131 if (val == NULL) 132 err(1, "malloc"); 133 134 for (i = 0; i < s->num_strings; i++) 135 parse_oid(s->strings[i], NULL, &val[i].algorithm); 136 137 ret = hx509_peer_info_set_cms_algs(contextp, *peer, val, s->num_strings); 138 if (ret) 139 hx509_err(contextp, 1, ret, "hx509_peer_info_set_cms_algs"); 140 141 for (i = 0; i < s->num_strings; i++) 142 free_AlgorithmIdentifier(&val[i]); 143 free(val); 144 } 145 146 /* 147 * 148 */ 149 150 struct pem_data { 151 heim_octet_string *os; 152 int detached_data; 153 }; 154 155 static int 156 pem_reader(hx509_context contextp, const char *type, 157 const hx509_pem_header *headers, 158 const void *data , size_t length, void *ctx) 159 { 160 struct pem_data *p = (struct pem_data *)ctx; 161 const char *h; 162 163 p->os->data = malloc(length); 164 if (p->os->data == NULL) 165 return ENOMEM; 166 memcpy(p->os->data, data, length); 167 p->os->length = length; 168 169 h = hx509_pem_find_header(headers, "Content-disposition"); 170 if (h && strcasecmp(h, "detached") == 0) 171 p->detached_data = 1; 172 173 return 0; 174 } 175 176 /* 177 * 178 */ 179 180 int 181 cms_verify_sd(struct cms_verify_sd_options *opt, int argc, char **argv) 182 { 183 hx509_verify_ctx ctx = NULL; 184 heim_oid type; 185 heim_octet_string c, co, signeddata, *sd = NULL; 186 hx509_certs store = NULL; 187 hx509_certs signers = NULL; 188 hx509_certs anchors = NULL; 189 hx509_lock lock; 190 int ret, flags = 0; 191 192 size_t sz; 193 void *p = NULL; 194 195 if (opt->missing_revoke_flag) 196 hx509_context_set_missing_revoke(context, 1); 197 198 hx509_lock_init(context, &lock); 199 lock_strings(lock, &opt->pass_strings); 200 201 ret = hx509_verify_init_ctx(context, &ctx); 202 if (ret) 203 hx509_err(context, 1, ret, "hx509_verify_init_ctx"); 204 205 ret = hx509_certs_init(context, "MEMORY:cms-anchors", 0, NULL, &anchors); 206 if (ret) 207 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 208 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &store); 209 if (ret) 210 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 211 212 certs_strings(context, "anchors", anchors, lock, &opt->anchors_strings); 213 certs_strings(context, "store", store, lock, &opt->certificate_strings); 214 215 if (opt->pem_flag) { 216 struct pem_data pd; 217 FILE *f; 218 219 pd.os = &co; 220 pd.detached_data = 0; 221 222 f = fopen(argv[0], "r"); 223 if (f == NULL) 224 err(1, "Failed to open file %s", argv[0]); 225 226 ret = hx509_pem_read(context, f, pem_reader, &pd); 227 fclose(f); 228 if (ret) 229 errx(1, "PEM reader failed: %d", ret); 230 231 if (pd.detached_data && opt->signed_content_string == NULL) { 232 char *r = strrchr(argv[0], '.'); 233 if (r && strcasecmp(r, ".pem") == 0) { 234 char *s = strdup(argv[0]); 235 if (s == NULL) 236 errx(1, "malloc: out of memory"); 237 s[r - argv[0]] = '\0'; 238 ret = _hx509_map_file_os(s, &signeddata); 239 if (ret) 240 errx(1, "map_file: %s: %d", s, ret); 241 free(s); 242 sd = &signeddata; 243 } 244 } 245 246 } else { 247 ret = rk_undumpdata(argv[0], &p, &sz); 248 if (ret) 249 err(1, "map_file: %s: %d", argv[0], ret); 250 251 co.data = p; 252 co.length = sz; 253 } 254 255 if (opt->signed_content_string) { 256 ret = _hx509_map_file_os(opt->signed_content_string, &signeddata); 257 if (ret) 258 errx(1, "map_file: %s: %d", opt->signed_content_string, ret); 259 sd = &signeddata; 260 } 261 262 if (opt->content_info_flag) { 263 heim_octet_string uwco; 264 heim_oid oid; 265 266 ret = hx509_cms_unwrap_ContentInfo(&co, &oid, &uwco, NULL); 267 if (ret) 268 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret); 269 270 if (der_heim_oid_cmp(&oid, &asn1_oid_id_pkcs7_signedData) != 0) 271 errx(1, "Content is not SignedData"); 272 der_free_oid(&oid); 273 274 if (p == NULL) 275 der_free_octet_string(&co); 276 else { 277 rk_xfree(p); 278 p = NULL; 279 } 280 co = uwco; 281 } 282 283 hx509_verify_attach_anchors(ctx, anchors); 284 285 if (!opt->signer_allowed_flag) 286 flags |= HX509_CMS_VS_ALLOW_ZERO_SIGNER; 287 if (opt->allow_wrong_oid_flag) 288 flags |= HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH; 289 290 ret = hx509_cms_verify_signed(context, ctx, flags, co.data, co.length, sd, 291 store, &type, &c, &signers); 292 if (p != co.data) 293 der_free_octet_string(&co); 294 else 295 rk_xfree(p); 296 if (ret) 297 hx509_err(context, 1, ret, "hx509_cms_verify_signed"); 298 299 { 300 char *str; 301 der_print_heim_oid(&type, '.', &str); 302 printf("type: %s\n", str); 303 free(str); 304 der_free_oid(&type); 305 } 306 if (signers == NULL) { 307 printf("unsigned\n"); 308 } else { 309 printf("signers:\n"); 310 hx509_certs_iter_f(context, signers, hx509_ci_print_names, stdout); 311 } 312 313 hx509_verify_destroy_ctx(ctx); 314 315 hx509_certs_free(&store); 316 hx509_certs_free(&signers); 317 hx509_certs_free(&anchors); 318 319 hx509_lock_free(lock); 320 321 if (argc > 1) { 322 ret = _hx509_write_file(argv[1], c.data, c.length); 323 if (ret) 324 errx(1, "hx509_write_file: %d", ret); 325 } 326 327 der_free_octet_string(&c); 328 329 if (sd) 330 _hx509_unmap_file_os(sd); 331 332 return 0; 333 } 334 335 static int 336 print_signer(hx509_context contextp, void *ctx, hx509_cert cert) 337 { 338 hx509_pem_header **header = ctx; 339 char *signer_name = NULL; 340 hx509_name name; 341 int ret; 342 343 ret = hx509_cert_get_subject(cert, &name); 344 if (ret) 345 errx(1, "hx509_cert_get_subject"); 346 347 ret = hx509_name_to_string(name, &signer_name); 348 hx509_name_free(&name); 349 if (ret) 350 errx(1, "hx509_name_to_string"); 351 352 hx509_pem_add_header(header, "Signer", signer_name); 353 354 free(signer_name); 355 return 0; 356 } 357 358 int 359 cms_create_sd(struct cms_create_sd_options *opt, int argc, char **argv) 360 { 361 heim_oid contentType; 362 hx509_peer_info peer = NULL; 363 heim_octet_string o; 364 hx509_query *q; 365 hx509_lock lock; 366 hx509_certs store, pool, anchors, signer = NULL; 367 size_t sz; 368 void *p; 369 int ret, flags = 0; 370 char *infile, *outfile = NULL; 371 372 memset(&contentType, 0, sizeof(contentType)); 373 374 infile = argv[0]; 375 376 if (argc < 2) { 377 asprintf(&outfile, "%s.%s", infile, 378 opt->pem_flag ? "pem" : "cms-signeddata"); 379 if (outfile == NULL) 380 errx(1, "out of memory"); 381 } else 382 outfile = argv[1]; 383 384 hx509_lock_init(context, &lock); 385 lock_strings(lock, &opt->pass_strings); 386 387 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &store); 388 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 389 ret = hx509_certs_init(context, "MEMORY:cert-pool", 0, NULL, &pool); 390 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 391 392 certs_strings(context, "store", store, lock, &opt->certificate_strings); 393 certs_strings(context, "pool", pool, lock, &opt->pool_strings); 394 395 if (opt->anchors_strings.num_strings) { 396 ret = hx509_certs_init(context, "MEMORY:cert-anchors", 397 0, NULL, &anchors); 398 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 399 certs_strings(context, "anchors", anchors, lock, &opt->anchors_strings); 400 } else 401 anchors = NULL; 402 403 if (opt->detached_signature_flag) 404 flags |= HX509_CMS_SIGNATURE_DETACHED; 405 if (opt->id_by_name_flag) 406 flags |= HX509_CMS_SIGNATURE_ID_NAME; 407 if (!opt->signer_flag) { 408 flags |= HX509_CMS_SIGNATURE_NO_SIGNER; 409 410 } 411 412 if (opt->signer_flag) { 413 ret = hx509_query_alloc(context, &q); 414 if (ret) 415 errx(1, "hx509_query_alloc: %d", ret); 416 417 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); 418 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE); 419 420 if (opt->signer_string) 421 hx509_query_match_friendly_name(q, opt->signer_string); 422 423 ret = hx509_certs_filter(context, store, q, &signer); 424 hx509_query_free(context, q); 425 if (ret) 426 hx509_err(context, 1, ret, "hx509_certs_find"); 427 } 428 if (!opt->embedded_certs_flag) 429 flags |= HX509_CMS_SIGNATURE_NO_CERTS; 430 if (opt->embed_leaf_only_flag) 431 flags |= HX509_CMS_SIGNATURE_LEAF_ONLY; 432 433 ret = rk_undumpdata(infile, &p, &sz); 434 if (ret) 435 err(1, "map_file: %s: %d", infile, ret); 436 437 if (opt->peer_alg_strings.num_strings) 438 peer_strings(context, &peer, &opt->peer_alg_strings); 439 440 parse_oid(opt->content_type_string, &asn1_oid_id_pkcs7_data, &contentType); 441 442 ret = hx509_cms_create_signed(context, 443 flags, 444 &contentType, 445 p, 446 sz, 447 NULL, 448 signer, 449 peer, 450 anchors, 451 pool, 452 &o); 453 if (ret) 454 hx509_err(context, 1, ret, "hx509_cms_create_signed: %d", ret); 455 456 hx509_certs_free(&anchors); 457 hx509_certs_free(&pool); 458 hx509_certs_free(&store); 459 rk_xfree(p); 460 hx509_lock_free(lock); 461 hx509_peer_info_free(peer); 462 der_free_oid(&contentType); 463 464 if (opt->content_info_flag) { 465 heim_octet_string wo; 466 467 ret = hx509_cms_wrap_ContentInfo(&asn1_oid_id_pkcs7_signedData, &o, &wo); 468 if (ret) 469 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret); 470 471 der_free_octet_string(&o); 472 o = wo; 473 } 474 475 if (opt->pem_flag) { 476 hx509_pem_header *header = NULL; 477 FILE *f; 478 479 hx509_pem_add_header(&header, "Content-disposition", 480 opt->detached_signature_flag ? 481 "detached" : "inline"); 482 if (signer) { 483 ret = hx509_certs_iter_f(context, signer, print_signer, header); 484 if (ret) 485 hx509_err(context, 1, ret, "print signer"); 486 } 487 488 f = fopen(outfile, "w"); 489 if (f == NULL) 490 err(1, "open %s", outfile); 491 492 ret = hx509_pem_write(context, "CMS SIGNEDDATA", header, f, 493 o.data, o.length); 494 fclose(f); 495 hx509_pem_free_header(header); 496 if (ret) 497 errx(1, "hx509_pem_write: %d", ret); 498 499 } else { 500 ret = _hx509_write_file(outfile, o.data, o.length); 501 if (ret) 502 errx(1, "hx509_write_file: %d", ret); 503 } 504 505 hx509_certs_free(&signer); 506 free(o.data); 507 508 return 0; 509 } 510 511 int 512 cms_unenvelope(struct cms_unenvelope_options *opt, int argc, char **argv) 513 { 514 heim_oid contentType = { 0, NULL }; 515 heim_octet_string o, co; 516 hx509_certs certs; 517 size_t sz; 518 void *p; 519 int ret; 520 hx509_lock lock; 521 int flags = 0; 522 523 hx509_lock_init(context, &lock); 524 lock_strings(lock, &opt->pass_strings); 525 526 ret = rk_undumpdata(argv[0], &p, &sz); 527 if (ret) 528 err(1, "map_file: %s: %d", argv[0], ret); 529 530 co.data = p; 531 co.length = sz; 532 533 if (opt->content_info_flag) { 534 heim_octet_string uwco; 535 heim_oid oid; 536 537 ret = hx509_cms_unwrap_ContentInfo(&co, &oid, &uwco, NULL); 538 if (ret) 539 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret); 540 541 if (der_heim_oid_cmp(&oid, &asn1_oid_id_pkcs7_envelopedData) != 0) 542 errx(1, "Content is not SignedData"); 543 der_free_oid(&oid); 544 545 co = uwco; 546 } 547 548 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &certs); 549 if (ret) 550 errx(1, "hx509_certs_init: MEMORY: %d", ret); 551 552 certs_strings(context, "store", certs, lock, &opt->certificate_strings); 553 554 if (opt->allow_weak_crypto_flag) 555 flags |= HX509_CMS_UE_ALLOW_WEAK; 556 557 ret = hx509_cms_unenvelope(context, certs, flags, co.data, co.length, 558 NULL, 0, &contentType, &o); 559 if (co.data != p) 560 der_free_octet_string(&co); 561 if (ret) 562 hx509_err(context, 1, ret, "hx509_cms_unenvelope"); 563 564 rk_xfree(p); 565 hx509_lock_free(lock); 566 hx509_certs_free(&certs); 567 der_free_oid(&contentType); 568 569 ret = _hx509_write_file(argv[1], o.data, o.length); 570 if (ret) 571 errx(1, "hx509_write_file: %d", ret); 572 573 der_free_octet_string(&o); 574 575 return 0; 576 } 577 578 int 579 cms_create_enveloped(struct cms_envelope_options *opt, int argc, char **argv) 580 { 581 heim_oid contentType; 582 heim_octet_string o; 583 const heim_oid *enctype = NULL; 584 hx509_query *q; 585 hx509_certs certs; 586 hx509_cert cert; 587 int ret; 588 size_t sz; 589 void *p; 590 hx509_lock lock; 591 int flags = 0; 592 593 memset(&contentType, 0, sizeof(contentType)); 594 595 hx509_lock_init(context, &lock); 596 lock_strings(lock, &opt->pass_strings); 597 598 ret = rk_undumpdata(argv[0], &p, &sz); 599 if (ret) 600 err(1, "map_file: %s: %d", argv[0], ret); 601 602 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &certs); 603 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 604 605 certs_strings(context, "store", certs, lock, &opt->certificate_strings); 606 607 if (opt->allow_weak_crypto_flag) 608 flags |= HX509_CMS_EV_ALLOW_WEAK; 609 610 if (opt->encryption_type_string) { 611 enctype = hx509_crypto_enctype_by_name(opt->encryption_type_string); 612 if (enctype == NULL) 613 errx(1, "encryption type: %s no found", 614 opt->encryption_type_string); 615 } 616 617 ret = hx509_query_alloc(context, &q); 618 if (ret) 619 errx(1, "hx509_query_alloc: %d", ret); 620 621 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_ENCIPHERMENT); 622 623 ret = hx509_certs_find(context, certs, q, &cert); 624 hx509_query_free(context, q); 625 if (ret) 626 errx(1, "hx509_certs_find: %d", ret); 627 628 parse_oid(opt->content_type_string, &asn1_oid_id_pkcs7_data, &contentType); 629 630 ret = hx509_cms_envelope_1(context, flags, cert, p, sz, enctype, 631 &contentType, &o); 632 if (ret) 633 errx(1, "hx509_cms_envelope_1: %d", ret); 634 635 hx509_cert_free(cert); 636 hx509_certs_free(&certs); 637 rk_xfree(p); 638 der_free_oid(&contentType); 639 640 if (opt->content_info_flag) { 641 heim_octet_string wo; 642 643 ret = hx509_cms_wrap_ContentInfo(&asn1_oid_id_pkcs7_envelopedData, &o, &wo); 644 if (ret) 645 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret); 646 647 der_free_octet_string(&o); 648 o = wo; 649 } 650 651 hx509_lock_free(lock); 652 653 ret = _hx509_write_file(argv[1], o.data, o.length); 654 if (ret) 655 errx(1, "hx509_write_file: %d", ret); 656 657 der_free_octet_string(&o); 658 659 return 0; 660 } 661 662 static void 663 print_certificate(hx509_context hxcontext, hx509_cert cert, int verbose) 664 { 665 const char *fn; 666 int ret; 667 668 fn = hx509_cert_get_friendly_name(cert); 669 if (fn) 670 printf(" friendly name: %s\n", fn); 671 printf(" private key: %s\n", 672 _hx509_cert_private_key(cert) ? "yes" : "no"); 673 674 ret = hx509_print_cert(hxcontext, cert, NULL); 675 if (ret) 676 errx(1, "failed to print cert"); 677 678 if (verbose) { 679 hx509_validate_ctx vctx; 680 681 hx509_validate_ctx_init(hxcontext, &vctx); 682 hx509_validate_ctx_set_print(vctx, hx509_print_stdout, stdout); 683 hx509_validate_ctx_add_flags(vctx, HX509_VALIDATE_F_VALIDATE); 684 hx509_validate_ctx_add_flags(vctx, HX509_VALIDATE_F_VERBOSE); 685 686 hx509_validate_cert(hxcontext, vctx, cert); 687 688 hx509_validate_ctx_free(vctx); 689 } 690 } 691 692 693 struct print_s { 694 int counter; 695 int verbose; 696 }; 697 698 static int 699 print_f(hx509_context hxcontext, void *ctx, hx509_cert cert) 700 { 701 struct print_s *s = ctx; 702 703 printf("cert: %d\n", s->counter++); 704 print_certificate(context, cert, s->verbose); 705 706 return 0; 707 } 708 709 int 710 pcert_print(struct print_options *opt, int argc, char **argv) 711 { 712 hx509_certs certs; 713 hx509_lock lock; 714 struct print_s s; 715 716 s.counter = 0; 717 s.verbose = opt->content_flag; 718 719 hx509_lock_init(context, &lock); 720 lock_strings(lock, &opt->pass_strings); 721 722 while(argc--) { 723 int ret; 724 ret = hx509_certs_init(context, argv[0], 0, lock, &certs); 725 if (ret) { 726 if (opt->never_fail_flag) { 727 printf("ignoreing failure: %d\n", ret); 728 continue; 729 } 730 hx509_err(context, 1, ret, "hx509_certs_init"); 731 } 732 if (opt->info_flag) 733 hx509_certs_info(context, certs, NULL, NULL); 734 hx509_certs_iter_f(context, certs, print_f, &s); 735 hx509_certs_free(&certs); 736 argv++; 737 } 738 739 hx509_lock_free(lock); 740 741 return 0; 742 } 743 744 745 static int 746 validate_f(hx509_context hxcontext, void *ctx, hx509_cert c) 747 { 748 hx509_validate_cert(hxcontext, ctx, c); 749 return 0; 750 } 751 752 int 753 pcert_validate(struct validate_options *opt, int argc, char **argv) 754 { 755 hx509_validate_ctx ctx; 756 hx509_certs certs; 757 hx509_lock lock; 758 759 hx509_lock_init(context, &lock); 760 lock_strings(lock, &opt->pass_strings); 761 762 hx509_validate_ctx_init(context, &ctx); 763 hx509_validate_ctx_set_print(ctx, hx509_print_stdout, stdout); 764 hx509_validate_ctx_add_flags(ctx, HX509_VALIDATE_F_VALIDATE); 765 766 while(argc--) { 767 int ret; 768 ret = hx509_certs_init(context, argv[0], 0, lock, &certs); 769 if (ret) 770 errx(1, "hx509_certs_init: %d", ret); 771 hx509_certs_iter_f(context, certs, validate_f, ctx); 772 hx509_certs_free(&certs); 773 argv++; 774 } 775 hx509_validate_ctx_free(ctx); 776 777 hx509_lock_free(lock); 778 779 return 0; 780 } 781 782 int 783 certificate_copy(struct certificate_copy_options *opt, int argc, char **argv) 784 { 785 hx509_certs certs; 786 hx509_lock inlock, outlock = NULL; 787 int ret; 788 789 hx509_lock_init(context, &inlock); 790 lock_strings(inlock, &opt->in_pass_strings); 791 792 if (opt->out_pass_string) { 793 hx509_lock_init(context, &outlock); 794 ret = hx509_lock_command_string(outlock, opt->out_pass_string); 795 if (ret) 796 errx(1, "hx509_lock_command_string: %s: %d", 797 opt->out_pass_string, ret); 798 } 799 800 ret = hx509_certs_init(context, argv[argc - 1], 801 HX509_CERTS_CREATE, inlock, &certs); 802 if (ret) 803 hx509_err(context, 1, ret, "hx509_certs_init"); 804 805 while(argc-- > 1) { 806 int retx; 807 retx = hx509_certs_append(context, certs, inlock, argv[0]); 808 if (retx) 809 hx509_err(context, 1, retx, "hx509_certs_append"); 810 argv++; 811 } 812 813 ret = hx509_certs_store(context, certs, 0, outlock); 814 if (ret) 815 hx509_err(context, 1, ret, "hx509_certs_store"); 816 817 hx509_certs_free(&certs); 818 hx509_lock_free(inlock); 819 hx509_lock_free(outlock); 820 821 return 0; 822 } 823 824 struct verify { 825 hx509_verify_ctx ctx; 826 hx509_certs chain; 827 const char *hostname; 828 int errors; 829 int count; 830 }; 831 832 static int 833 verify_f(hx509_context hxcontext, void *ctx, hx509_cert c) 834 { 835 struct verify *v = ctx; 836 int ret; 837 838 ret = hx509_verify_path(hxcontext, v->ctx, c, v->chain); 839 if (ret) { 840 char *s = hx509_get_error_string(hxcontext, ret); 841 printf("verify_path: %s: %d\n", s, ret); 842 hx509_free_error_string(s); 843 v->errors++; 844 } else { 845 v->count++; 846 printf("path ok\n"); 847 } 848 849 if (v->hostname) { 850 ret = hx509_verify_hostname(hxcontext, c, 0, HX509_HN_HOSTNAME, 851 v->hostname, NULL, 0); 852 if (ret) { 853 printf("verify_hostname: %d\n", ret); 854 v->errors++; 855 } 856 } 857 858 return 0; 859 } 860 861 int 862 pcert_verify(struct verify_options *opt, int argc, char **argv) 863 { 864 hx509_certs anchors, chain, certs; 865 hx509_revoke_ctx revoke_ctx; 866 hx509_verify_ctx ctx; 867 struct verify v; 868 int ret; 869 870 memset(&v, 0, sizeof(v)); 871 872 if (opt->missing_revoke_flag) 873 hx509_context_set_missing_revoke(context, 1); 874 875 ret = hx509_verify_init_ctx(context, &ctx); 876 if (ret) 877 hx509_err(context, 1, ret, "hx509_verify_init_ctx"); 878 ret = hx509_certs_init(context, "MEMORY:anchors", 0, NULL, &anchors); 879 if (ret) 880 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 881 ret = hx509_certs_init(context, "MEMORY:chain", 0, NULL, &chain); 882 if (ret) 883 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 884 ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &certs); 885 if (ret) 886 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 887 888 if (opt->allow_proxy_certificate_flag) 889 hx509_verify_set_proxy_certificate(ctx, 1); 890 891 if (opt->time_string) { 892 const char *p; 893 struct tm tm; 894 time_t t; 895 896 memset(&tm, 0, sizeof(tm)); 897 898 p = strptime (opt->time_string, "%Y-%m-%d", &tm); 899 if (p == NULL) 900 errx(1, "Failed to parse time %s, need to be on format %%Y-%%m-%%d", 901 opt->time_string); 902 903 t = tm2time (tm, 0); 904 905 hx509_verify_set_time(ctx, t); 906 } 907 908 if (opt->hostname_string) 909 v.hostname = opt->hostname_string; 910 if (opt->max_depth_integer) 911 hx509_verify_set_max_depth(ctx, opt->max_depth_integer); 912 913 ret = hx509_revoke_init(context, &revoke_ctx); 914 if (ret) 915 errx(1, "hx509_revoke_init: %d", ret); 916 917 while(argc--) { 918 char *s = *argv++; 919 920 if (strncmp(s, "chain:", 6) == 0) { 921 s += 6; 922 923 ret = hx509_certs_append(context, chain, NULL, s); 924 if (ret) 925 hx509_err(context, 1, ret, "hx509_certs_append: chain: %s: %d", s, ret); 926 927 } else if (strncmp(s, "anchor:", 7) == 0) { 928 s += 7; 929 930 ret = hx509_certs_append(context, anchors, NULL, s); 931 if (ret) 932 hx509_err(context, 1, ret, "hx509_certs_append: anchor: %s: %d", s, ret); 933 934 } else if (strncmp(s, "cert:", 5) == 0) { 935 s += 5; 936 937 ret = hx509_certs_append(context, certs, NULL, s); 938 if (ret) 939 hx509_err(context, 1, ret, "hx509_certs_append: certs: %s: %d", 940 s, ret); 941 942 } else if (strncmp(s, "crl:", 4) == 0) { 943 s += 4; 944 945 ret = hx509_revoke_add_crl(context, revoke_ctx, s); 946 if (ret) 947 errx(1, "hx509_revoke_add_crl: %s: %d", s, ret); 948 949 } else if (strncmp(s, "ocsp:", 4) == 0) { 950 s += 5; 951 952 ret = hx509_revoke_add_ocsp(context, revoke_ctx, s); 953 if (ret) 954 errx(1, "hx509_revoke_add_ocsp: %s: %d", s, ret); 955 956 } else { 957 errx(1, "unknown option to verify: `%s'\n", s); 958 } 959 } 960 961 hx509_verify_attach_anchors(ctx, anchors); 962 hx509_verify_attach_revoke(ctx, revoke_ctx); 963 964 v.ctx = ctx; 965 v.chain = chain; 966 967 hx509_certs_iter_f(context, certs, verify_f, &v); 968 969 hx509_verify_destroy_ctx(ctx); 970 971 hx509_certs_free(&certs); 972 hx509_certs_free(&chain); 973 hx509_certs_free(&anchors); 974 975 hx509_revoke_free(&revoke_ctx); 976 977 978 if (v.count == 0) { 979 printf("no certs verify at all\n"); 980 return 1; 981 } 982 983 if (v.errors) { 984 printf("failed verifing %d checks\n", v.errors); 985 return 1; 986 } 987 988 return 0; 989 } 990 991 int 992 query(struct query_options *opt, int argc, char **argv) 993 { 994 hx509_lock lock; 995 hx509_query *q; 996 hx509_certs certs; 997 hx509_cert c; 998 int ret; 999 1000 ret = hx509_query_alloc(context, &q); 1001 if (ret) 1002 errx(1, "hx509_query_alloc: %d", ret); 1003 1004 hx509_lock_init(context, &lock); 1005 lock_strings(lock, &opt->pass_strings); 1006 1007 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &certs); 1008 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 1009 1010 while (argc > 0) { 1011 1012 ret = hx509_certs_append(context, certs, lock, argv[0]); 1013 if (ret) 1014 errx(1, "hx509_certs_append: %s: %d", argv[0], ret); 1015 1016 argc--; 1017 argv++; 1018 } 1019 1020 if (opt->friendlyname_string) 1021 hx509_query_match_friendly_name(q, opt->friendlyname_string); 1022 1023 if (opt->eku_string) { 1024 heim_oid oid; 1025 1026 parse_oid(opt->eku_string, NULL, &oid); 1027 1028 ret = hx509_query_match_eku(q, &oid); 1029 if (ret) 1030 errx(1, "hx509_query_match_eku: %d", ret); 1031 der_free_oid(&oid); 1032 } 1033 1034 if (opt->private_key_flag) 1035 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); 1036 1037 if (opt->keyEncipherment_flag) 1038 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_ENCIPHERMENT); 1039 1040 if (opt->digitalSignature_flag) 1041 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE); 1042 1043 if (opt->expr_string) 1044 hx509_query_match_expr(context, q, opt->expr_string); 1045 1046 ret = hx509_certs_find(context, certs, q, &c); 1047 hx509_query_free(context, q); 1048 if (ret) 1049 printf("no match found (%d)\n", ret); 1050 else { 1051 printf("match found\n"); 1052 if (opt->print_flag) 1053 print_certificate(context, c, 0); 1054 } 1055 1056 hx509_cert_free(c); 1057 hx509_certs_free(&certs); 1058 1059 hx509_lock_free(lock); 1060 1061 return ret; 1062 } 1063 1064 int 1065 ocsp_fetch(struct ocsp_fetch_options *opt, int argc, char **argv) 1066 { 1067 hx509_certs reqcerts, pool; 1068 heim_octet_string req, nonce_data, *nonce = &nonce_data; 1069 hx509_lock lock; 1070 int i, ret; 1071 char *file; 1072 const char *url = "/"; 1073 1074 memset(&nonce, 0, sizeof(nonce)); 1075 1076 hx509_lock_init(context, &lock); 1077 lock_strings(lock, &opt->pass_strings); 1078 1079 /* no nonce */ 1080 if (!opt->nonce_flag) 1081 nonce = NULL; 1082 1083 if (opt->url_path_string) 1084 url = opt->url_path_string; 1085 1086 ret = hx509_certs_init(context, "MEMORY:ocsp-pool", 0, NULL, &pool); 1087 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 1088 1089 certs_strings(context, "ocsp-pool", pool, lock, &opt->pool_strings); 1090 1091 file = argv[0]; 1092 1093 ret = hx509_certs_init(context, "MEMORY:ocsp-req", 0, NULL, &reqcerts); 1094 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 1095 1096 for (i = 1; i < argc; i++) { 1097 ret = hx509_certs_append(context, reqcerts, lock, argv[i]); 1098 if (ret) 1099 errx(1, "hx509_certs_append: req: %s: %d", argv[i], ret); 1100 } 1101 1102 ret = hx509_ocsp_request(context, reqcerts, pool, NULL, NULL, &req, nonce); 1103 if (ret) 1104 errx(1, "hx509_ocsp_request: req: %d", ret); 1105 1106 { 1107 FILE *f; 1108 1109 f = fopen(file, "w"); 1110 if (f == NULL) 1111 abort(); 1112 1113 fprintf(f, 1114 "POST %s HTTP/1.0\r\n" 1115 "Content-Type: application/ocsp-request\r\n" 1116 "Content-Length: %ld\r\n" 1117 "\r\n", 1118 url, 1119 (unsigned long)req.length); 1120 fwrite(req.data, req.length, 1, f); 1121 fclose(f); 1122 } 1123 1124 if (nonce) 1125 der_free_octet_string(nonce); 1126 1127 hx509_certs_free(&reqcerts); 1128 hx509_certs_free(&pool); 1129 1130 return 0; 1131 } 1132 1133 int 1134 ocsp_print(struct ocsp_print_options *opt, int argc, char **argv) 1135 { 1136 hx509_revoke_ocsp_print(context, argv[0], stdout); 1137 return 0; 1138 } 1139 1140 /* 1141 * 1142 */ 1143 1144 static int 1145 verify_o(hx509_context hxcontext, void *ctx, hx509_cert c) 1146 { 1147 heim_octet_string *os = ctx; 1148 time_t expiration; 1149 int ret; 1150 1151 ret = hx509_ocsp_verify(context, 0, c, 0, 1152 os->data, os->length, &expiration); 1153 if (ret) { 1154 char *s = hx509_get_error_string(hxcontext, ret); 1155 printf("ocsp_verify: %s: %d\n", s, ret); 1156 hx509_free_error_string(s); 1157 } else 1158 printf("expire: %d\n", (int)expiration); 1159 1160 return ret; 1161 } 1162 1163 1164 int 1165 ocsp_verify(struct ocsp_verify_options *opt, int argc, char **argv) 1166 { 1167 hx509_lock lock; 1168 hx509_certs certs; 1169 int ret, i; 1170 heim_octet_string os; 1171 1172 hx509_lock_init(context, &lock); 1173 1174 if (opt->ocsp_file_string == NULL) 1175 errx(1, "no ocsp file given"); 1176 1177 ret = _hx509_map_file_os(opt->ocsp_file_string, &os); 1178 if (ret) 1179 err(1, "map_file: %s: %d", argv[0], ret); 1180 1181 ret = hx509_certs_init(context, "MEMORY:test-certs", 0, NULL, &certs); 1182 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 1183 1184 for (i = 0; i < argc; i++) { 1185 ret = hx509_certs_append(context, certs, lock, argv[i]); 1186 if (ret) 1187 hx509_err(context, 1, ret, "hx509_certs_append: %s", argv[i]); 1188 } 1189 1190 ret = hx509_certs_iter_f(context, certs, verify_o, &os); 1191 1192 hx509_certs_free(&certs); 1193 _hx509_unmap_file_os(&os); 1194 hx509_lock_free(lock); 1195 1196 return ret; 1197 } 1198 1199 static int 1200 read_private_key(const char *fn, hx509_private_key *key) 1201 { 1202 hx509_private_key *keys; 1203 hx509_certs certs; 1204 int ret; 1205 1206 *key = NULL; 1207 1208 ret = hx509_certs_init(context, fn, 0, NULL, &certs); 1209 if (ret) 1210 hx509_err(context, 1, ret, "hx509_certs_init: %s", fn); 1211 1212 ret = _hx509_certs_keys_get(context, certs, &keys); 1213 hx509_certs_free(&certs); 1214 if (ret) 1215 hx509_err(context, 1, ret, "hx509_certs_keys_get"); 1216 if (keys[0] == NULL) 1217 errx(1, "no keys in key store: %s", fn); 1218 1219 *key = _hx509_private_key_ref(keys[0]); 1220 _hx509_certs_keys_free(context, keys); 1221 1222 return 0; 1223 } 1224 1225 static void 1226 get_key(const char *fn, const char *type, int optbits, 1227 hx509_private_key *signer) 1228 { 1229 int ret; 1230 1231 if (type) { 1232 BIGNUM *e; 1233 RSA *rsa; 1234 unsigned char *p0, *p; 1235 size_t len; 1236 int bits = 1024; 1237 1238 if (fn == NULL) 1239 errx(1, "no key argument, don't know here to store key"); 1240 1241 if (strcasecmp(type, "rsa") != 0) 1242 errx(1, "can only handle rsa keys for now"); 1243 1244 e = BN_new(); 1245 BN_set_word(e, 0x10001); 1246 1247 if (optbits) 1248 bits = optbits; 1249 1250 rsa = RSA_new(); 1251 if(rsa == NULL) 1252 errx(1, "RSA_new failed"); 1253 1254 ret = RSA_generate_key_ex(rsa, bits, e, NULL); 1255 if(ret != 1) 1256 errx(1, "RSA_new failed"); 1257 1258 BN_free(e); 1259 1260 len = i2d_RSAPrivateKey(rsa, NULL); 1261 1262 p0 = p = malloc(len); 1263 if (p == NULL) 1264 errx(1, "out of memory"); 1265 1266 i2d_RSAPrivateKey(rsa, &p); 1267 1268 rk_dumpdata(fn, p0, len); 1269 memset(p0, 0, len); 1270 free(p0); 1271 1272 RSA_free(rsa); 1273 1274 } else if (fn == NULL) 1275 err(1, "no private key"); 1276 1277 ret = read_private_key(fn, signer); 1278 if (ret) 1279 err(1, "read_private_key"); 1280 } 1281 1282 int 1283 request_create(struct request_create_options *opt, int argc, char **argv) 1284 { 1285 heim_octet_string request; 1286 hx509_request req; 1287 int ret, i; 1288 hx509_private_key signer; 1289 SubjectPublicKeyInfo key; 1290 const char *outfile = argv[0]; 1291 1292 memset(&key, 0, sizeof(key)); 1293 1294 get_key(opt->key_string, 1295 opt->generate_key_string, 1296 opt->key_bits_integer, 1297 &signer); 1298 1299 hx509_request_init(context, &req); 1300 1301 if (opt->subject_string) { 1302 hx509_name name = NULL; 1303 1304 ret = hx509_parse_name(context, opt->subject_string, &name); 1305 if (ret) 1306 errx(1, "hx509_parse_name: %d\n", ret); 1307 hx509_request_set_name(context, req, name); 1308 1309 if (opt->verbose_flag) { 1310 char *s; 1311 hx509_name_to_string(name, &s); 1312 printf("%s\n", s); 1313 } 1314 hx509_name_free(&name); 1315 } 1316 1317 for (i = 0; i < opt->email_strings.num_strings; i++) { 1318 ret = _hx509_request_add_email(context, req, 1319 opt->email_strings.strings[i]); 1320 if (ret) 1321 hx509_err(context, 1, ret, "hx509_request_add_email"); 1322 } 1323 1324 for (i = 0; i < opt->dnsname_strings.num_strings; i++) { 1325 ret = _hx509_request_add_dns_name(context, req, 1326 opt->dnsname_strings.strings[i]); 1327 if (ret) 1328 hx509_err(context, 1, ret, "hx509_request_add_dns_name"); 1329 } 1330 1331 1332 ret = hx509_private_key2SPKI(context, signer, &key); 1333 if (ret) 1334 errx(1, "hx509_private_key2SPKI: %d\n", ret); 1335 1336 ret = hx509_request_set_SubjectPublicKeyInfo(context, 1337 req, 1338 &key); 1339 free_SubjectPublicKeyInfo(&key); 1340 if (ret) 1341 hx509_err(context, 1, ret, "hx509_request_set_SubjectPublicKeyInfo"); 1342 1343 ret = _hx509_request_to_pkcs10(context, 1344 req, 1345 signer, 1346 &request); 1347 if (ret) 1348 hx509_err(context, 1, ret, "_hx509_request_to_pkcs10"); 1349 1350 hx509_private_key_free(&signer); 1351 hx509_request_free(&req); 1352 1353 if (ret == 0) 1354 rk_dumpdata(outfile, request.data, request.length); 1355 der_free_octet_string(&request); 1356 1357 return 0; 1358 } 1359 1360 int 1361 request_print(struct request_print_options *opt, int argc, char **argv) 1362 { 1363 int ret, i; 1364 1365 printf("request print\n"); 1366 1367 for (i = 0; i < argc; i++) { 1368 hx509_request req; 1369 1370 ret = _hx509_request_parse(context, argv[i], &req); 1371 if (ret) 1372 hx509_err(context, 1, ret, "parse_request: %s", argv[i]); 1373 1374 ret = _hx509_request_print(context, req, stdout); 1375 hx509_request_free(&req); 1376 if (ret) 1377 hx509_err(context, 1, ret, "Failed to print file %s", argv[i]); 1378 } 1379 1380 return 0; 1381 } 1382 1383 int 1384 info(void *opt, int argc, char **argv) 1385 { 1386 1387 ENGINE_add_conf_module(); 1388 1389 { 1390 const RSA_METHOD *m = RSA_get_default_method(); 1391 if (m != NULL) 1392 printf("rsa: %s\n", m->name); 1393 } 1394 { 1395 const DH_METHOD *m = DH_get_default_method(); 1396 if (m != NULL) 1397 printf("dh: %s\n", m->name); 1398 } 1399 #ifdef HAVE_OPENSSL 1400 { 1401 printf("ecdsa: ECDSA_METHOD-not-export\n"); 1402 } 1403 #else 1404 { 1405 printf("ecdsa: hcrypto null\n"); 1406 } 1407 #endif 1408 { 1409 int ret = RAND_status(); 1410 printf("rand: %s\n", ret == 1 ? "ok" : "not available"); 1411 } 1412 1413 return 0; 1414 } 1415 1416 int 1417 random_data(void *opt, int argc, char **argv) 1418 { 1419 void *ptr; 1420 int len, ret; 1421 1422 len = parse_bytes(argv[0], "byte"); 1423 if (len <= 0) { 1424 fprintf(stderr, "bad argument to random-data\n"); 1425 return 1; 1426 } 1427 1428 ptr = malloc(len); 1429 if (ptr == NULL) { 1430 fprintf(stderr, "out of memory\n"); 1431 return 1; 1432 } 1433 1434 ret = RAND_bytes(ptr, len); 1435 if (ret != 1) { 1436 free(ptr); 1437 fprintf(stderr, "did not get cryptographic strong random\n"); 1438 return 1; 1439 } 1440 1441 fwrite(ptr, len, 1, stdout); 1442 fflush(stdout); 1443 1444 free(ptr); 1445 1446 return 0; 1447 } 1448 1449 int 1450 crypto_available(struct crypto_available_options *opt, int argc, char **argv) 1451 { 1452 AlgorithmIdentifier *val; 1453 unsigned int len, i; 1454 int ret, type = HX509_SELECT_ALL; 1455 1456 if (opt->type_string) { 1457 if (strcmp(opt->type_string, "all") == 0) 1458 type = HX509_SELECT_ALL; 1459 else if (strcmp(opt->type_string, "digest") == 0) 1460 type = HX509_SELECT_DIGEST; 1461 else if (strcmp(opt->type_string, "public-sig") == 0) 1462 type = HX509_SELECT_PUBLIC_SIG; 1463 else if (strcmp(opt->type_string, "secret") == 0) 1464 type = HX509_SELECT_SECRET_ENC; 1465 else 1466 errx(1, "unknown type: %s", opt->type_string); 1467 } 1468 1469 ret = hx509_crypto_available(context, type, NULL, &val, &len); 1470 if (ret) 1471 errx(1, "hx509_crypto_available"); 1472 1473 for (i = 0; i < len; i++) { 1474 char *s; 1475 der_print_heim_oid (&val[i].algorithm, '.', &s); 1476 printf("%s\n", s); 1477 free(s); 1478 } 1479 1480 hx509_crypto_free_algs(val, len); 1481 1482 return 0; 1483 } 1484 1485 int 1486 crypto_select(struct crypto_select_options *opt, int argc, char **argv) 1487 { 1488 hx509_peer_info peer = NULL; 1489 AlgorithmIdentifier selected; 1490 int ret, type = HX509_SELECT_DIGEST; 1491 char *s; 1492 1493 if (opt->type_string) { 1494 if (strcmp(opt->type_string, "digest") == 0) 1495 type = HX509_SELECT_DIGEST; 1496 else if (strcmp(opt->type_string, "public-sig") == 0) 1497 type = HX509_SELECT_PUBLIC_SIG; 1498 else if (strcmp(opt->type_string, "secret") == 0) 1499 type = HX509_SELECT_SECRET_ENC; 1500 else 1501 errx(1, "unknown type: %s", opt->type_string); 1502 } 1503 1504 if (opt->peer_cmstype_strings.num_strings) 1505 peer_strings(context, &peer, &opt->peer_cmstype_strings); 1506 1507 ret = hx509_crypto_select(context, type, NULL, peer, &selected); 1508 if (ret) 1509 errx(1, "hx509_crypto_available"); 1510 1511 der_print_heim_oid (&selected.algorithm, '.', &s); 1512 printf("%s\n", s); 1513 free(s); 1514 free_AlgorithmIdentifier(&selected); 1515 1516 hx509_peer_info_free(peer); 1517 1518 return 0; 1519 } 1520 1521 int 1522 hxtool_hex(struct hex_options *opt, int argc, char **argv) 1523 { 1524 1525 if (opt->decode_flag) { 1526 char buf[1024], buf2[1024], *p; 1527 ssize_t len; 1528 1529 while(fgets(buf, sizeof(buf), stdin) != NULL) { 1530 buf[strcspn(buf, "\r\n")] = '\0'; 1531 p = buf; 1532 while(isspace(*(unsigned char *)p)) 1533 p++; 1534 len = hex_decode(p, buf2, strlen(p)); 1535 if (len < 0) 1536 errx(1, "hex_decode failed"); 1537 if (fwrite(buf2, 1, len, stdout) != (size_t)len) 1538 errx(1, "fwrite failed"); 1539 } 1540 } else { 1541 char buf[28], *p; 1542 ssize_t len; 1543 1544 while((len = fread(buf, 1, sizeof(buf), stdin)) != 0) { 1545 len = hex_encode(buf, len, &p); 1546 if (len < 0) 1547 continue; 1548 fprintf(stdout, "%s\n", p); 1549 free(p); 1550 } 1551 } 1552 return 0; 1553 } 1554 1555 struct cert_type_opt { 1556 int pkinit; 1557 }; 1558 1559 1560 static int 1561 https_server(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt) 1562 { 1563 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_serverAuth); 1564 } 1565 1566 static int 1567 https_client(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt) 1568 { 1569 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_clientAuth); 1570 } 1571 1572 static int 1573 peap_server(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt) 1574 { 1575 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_serverAuth); 1576 } 1577 1578 static int 1579 pkinit_kdc(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt) 1580 { 1581 opt->pkinit++; 1582 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkkdcekuoid); 1583 } 1584 1585 static int 1586 pkinit_client(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt) 1587 { 1588 int ret; 1589 1590 opt->pkinit++; 1591 1592 ret = hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkekuoid); 1593 if (ret) 1594 return ret; 1595 1596 ret = hx509_ca_tbs_add_eku(context, tbs, &asn1_oid_id_ms_client_authentication); 1597 if (ret) 1598 return ret; 1599 1600 return hx509_ca_tbs_add_eku(context, tbs, &asn1_oid_id_pkinit_ms_eku); 1601 } 1602 1603 static int 1604 email_client(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt) 1605 { 1606 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_emailProtection); 1607 } 1608 1609 struct { 1610 const char *type; 1611 const char *desc; 1612 int (*eval)(hx509_context, hx509_ca_tbs, struct cert_type_opt *); 1613 } certtypes[] = { 1614 { 1615 "https-server", 1616 "Used for HTTPS server and many other TLS server certificate types", 1617 https_server 1618 }, 1619 { 1620 "https-client", 1621 "Used for HTTPS client certificates", 1622 https_client 1623 }, 1624 { 1625 "email-client", 1626 "Certificate will be use for email", 1627 email_client 1628 }, 1629 { 1630 "pkinit-client", 1631 "Certificate used for Kerberos PK-INIT client certificates", 1632 pkinit_client 1633 }, 1634 { 1635 "pkinit-kdc", 1636 "Certificates used for Kerberos PK-INIT KDC certificates", 1637 pkinit_kdc 1638 }, 1639 { 1640 "peap-server", 1641 "Certificate used for Radius PEAP (Protected EAP)", 1642 peap_server 1643 } 1644 }; 1645 1646 static void 1647 print_eval_types(FILE *out) 1648 { 1649 rtbl_t table; 1650 unsigned i; 1651 1652 table = rtbl_create(); 1653 rtbl_add_column_by_id (table, 0, "Name", 0); 1654 rtbl_add_column_by_id (table, 1, "Description", 0); 1655 1656 for (i = 0; i < sizeof(certtypes)/sizeof(certtypes[0]); i++) { 1657 rtbl_add_column_entry_by_id(table, 0, certtypes[i].type); 1658 rtbl_add_column_entry_by_id(table, 1, certtypes[i].desc); 1659 } 1660 1661 rtbl_format (table, out); 1662 rtbl_destroy (table); 1663 } 1664 1665 static int 1666 eval_types(hx509_context contextp, 1667 hx509_ca_tbs tbs, 1668 const struct certificate_sign_options *opt) 1669 { 1670 struct cert_type_opt ctopt; 1671 int i; 1672 size_t j; 1673 int ret; 1674 1675 memset(&ctopt, 0, sizeof(ctopt)); 1676 1677 for (i = 0; i < opt->type_strings.num_strings; i++) { 1678 const char *type = opt->type_strings.strings[i]; 1679 1680 for (j = 0; j < sizeof(certtypes)/sizeof(certtypes[0]); j++) { 1681 if (strcasecmp(type, certtypes[j].type) == 0) { 1682 ret = (*certtypes[j].eval)(contextp, tbs, &ctopt); 1683 if (ret) 1684 hx509_err(contextp, 1, ret, 1685 "Failed to evaluate cert type %s", type); 1686 break; 1687 } 1688 } 1689 if (j >= sizeof(certtypes)/sizeof(certtypes[0])) { 1690 fprintf(stderr, "Unknown certificate type %s\n\n", type); 1691 fprintf(stderr, "Available types:\n"); 1692 print_eval_types(stderr); 1693 exit(1); 1694 } 1695 } 1696 1697 if (opt->pk_init_principal_string) { 1698 if (!ctopt.pkinit) 1699 errx(1, "pk-init principal given but no pk-init oid"); 1700 1701 ret = hx509_ca_tbs_add_san_pkinit(contextp, tbs, 1702 opt->pk_init_principal_string); 1703 if (ret) 1704 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_pkinit"); 1705 } 1706 1707 if (opt->ms_upn_string) { 1708 if (!ctopt.pkinit) 1709 errx(1, "MS upn given but no pk-init oid"); 1710 1711 ret = hx509_ca_tbs_add_san_ms_upn(contextp, tbs, opt->ms_upn_string); 1712 if (ret) 1713 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_ms_upn"); 1714 } 1715 1716 1717 for (i = 0; i < opt->hostname_strings.num_strings; i++) { 1718 const char *hostname = opt->hostname_strings.strings[i]; 1719 1720 ret = hx509_ca_tbs_add_san_hostname(contextp, tbs, hostname); 1721 if (ret) 1722 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_hostname"); 1723 } 1724 1725 for (i = 0; i < opt->email_strings.num_strings; i++) { 1726 const char *email = opt->email_strings.strings[i]; 1727 1728 ret = hx509_ca_tbs_add_san_rfc822name(contextp, tbs, email); 1729 if (ret) 1730 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_hostname"); 1731 1732 ret = hx509_ca_tbs_add_eku(contextp, tbs, 1733 &asn1_oid_id_pkix_kp_emailProtection); 1734 if (ret) 1735 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_eku"); 1736 } 1737 1738 if (opt->jid_string) { 1739 ret = hx509_ca_tbs_add_san_jid(contextp, tbs, opt->jid_string); 1740 if (ret) 1741 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_jid"); 1742 } 1743 1744 return 0; 1745 } 1746 1747 int 1748 hxtool_ca(struct certificate_sign_options *opt, int argc, char **argv) 1749 { 1750 int ret; 1751 hx509_ca_tbs tbs; 1752 hx509_cert signer = NULL, cert = NULL; 1753 hx509_private_key private_key = NULL; 1754 hx509_private_key cert_key = NULL; 1755 hx509_name subject = NULL; 1756 SubjectPublicKeyInfo spki; 1757 int delta = 0; 1758 1759 memset(&spki, 0, sizeof(spki)); 1760 1761 if (opt->ca_certificate_string == NULL && !opt->self_signed_flag) 1762 errx(1, "--ca-certificate argument missing (not using --self-signed)"); 1763 if (opt->ca_private_key_string == NULL && opt->generate_key_string == NULL && opt->self_signed_flag) 1764 errx(1, "--ca-private-key argument missing (using --self-signed)"); 1765 if (opt->certificate_string == NULL) 1766 errx(1, "--certificate argument missing"); 1767 1768 if (opt->template_certificate_string) { 1769 if (opt->template_fields_string == NULL) 1770 errx(1, "--template-certificate not no --template-fields"); 1771 } 1772 1773 if (opt->lifetime_string) { 1774 delta = parse_time(opt->lifetime_string, "day"); 1775 if (delta < 0) 1776 errx(1, "Invalid lifetime: %s", opt->lifetime_string); 1777 } 1778 1779 if (opt->ca_certificate_string) { 1780 hx509_certs cacerts = NULL; 1781 hx509_query *q; 1782 1783 ret = hx509_certs_init(context, opt->ca_certificate_string, 0, 1784 NULL, &cacerts); 1785 if (ret) 1786 hx509_err(context, 1, ret, 1787 "hx509_certs_init: %s", opt->ca_certificate_string); 1788 1789 ret = hx509_query_alloc(context, &q); 1790 if (ret) 1791 errx(1, "hx509_query_alloc: %d", ret); 1792 1793 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); 1794 if (!opt->issue_proxy_flag) 1795 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_KEYCERTSIGN); 1796 1797 ret = hx509_certs_find(context, cacerts, q, &signer); 1798 hx509_query_free(context, q); 1799 hx509_certs_free(&cacerts); 1800 if (ret) 1801 hx509_err(context, 1, ret, "no CA certificate found"); 1802 } else if (opt->self_signed_flag) { 1803 if (opt->generate_key_string == NULL 1804 && opt->ca_private_key_string == NULL) 1805 errx(1, "no signing private key"); 1806 1807 if (opt->req_string) 1808 errx(1, "can't be self-signing and have a request at the same time"); 1809 } else 1810 errx(1, "missing ca key"); 1811 1812 if (opt->ca_private_key_string) { 1813 1814 ret = read_private_key(opt->ca_private_key_string, &private_key); 1815 if (ret) 1816 err(1, "read_private_key"); 1817 1818 ret = hx509_private_key2SPKI(context, private_key, &spki); 1819 if (ret) 1820 errx(1, "hx509_private_key2SPKI: %d\n", ret); 1821 1822 if (opt->self_signed_flag) 1823 cert_key = private_key; 1824 } 1825 1826 if (opt->req_string) { 1827 hx509_request req; 1828 1829 ret = _hx509_request_parse(context, opt->req_string, &req); 1830 if (ret) 1831 hx509_err(context, 1, ret, "parse_request: %s", opt->req_string); 1832 ret = hx509_request_get_name(context, req, &subject); 1833 if (ret) 1834 hx509_err(context, 1, ret, "get name"); 1835 ret = hx509_request_get_SubjectPublicKeyInfo(context, req, &spki); 1836 if (ret) 1837 hx509_err(context, 1, ret, "get spki"); 1838 hx509_request_free(&req); 1839 } 1840 1841 if (opt->generate_key_string) { 1842 struct hx509_generate_private_context *keyctx; 1843 1844 ret = _hx509_generate_private_key_init(context, 1845 &asn1_oid_id_pkcs1_rsaEncryption, 1846 &keyctx); 1847 if (ret) 1848 hx509_err(context, 1, ret, "generate private key"); 1849 1850 if (opt->issue_ca_flag) 1851 _hx509_generate_private_key_is_ca(context, keyctx); 1852 1853 if (opt->key_bits_integer) 1854 _hx509_generate_private_key_bits(context, keyctx, 1855 opt->key_bits_integer); 1856 1857 ret = _hx509_generate_private_key(context, keyctx, 1858 &cert_key); 1859 _hx509_generate_private_key_free(&keyctx); 1860 if (ret) 1861 hx509_err(context, 1, ret, "generate private key"); 1862 1863 ret = hx509_private_key2SPKI(context, cert_key, &spki); 1864 if (ret) 1865 errx(1, "hx509_private_key2SPKI: %d\n", ret); 1866 1867 if (opt->self_signed_flag) 1868 private_key = cert_key; 1869 } 1870 1871 if (opt->certificate_private_key_string) { 1872 ret = read_private_key(opt->certificate_private_key_string, &cert_key); 1873 if (ret) 1874 err(1, "read_private_key for certificate"); 1875 } 1876 1877 if (opt->subject_string) { 1878 if (subject) 1879 hx509_name_free(&subject); 1880 ret = hx509_parse_name(context, opt->subject_string, &subject); 1881 if (ret) 1882 hx509_err(context, 1, ret, "hx509_parse_name"); 1883 } 1884 1885 /* 1886 * 1887 */ 1888 1889 ret = hx509_ca_tbs_init(context, &tbs); 1890 if (ret) 1891 hx509_err(context, 1, ret, "hx509_ca_tbs_init"); 1892 1893 if (opt->template_certificate_string) { 1894 hx509_cert template; 1895 hx509_certs tcerts; 1896 int flags; 1897 1898 ret = hx509_certs_init(context, opt->template_certificate_string, 0, 1899 NULL, &tcerts); 1900 if (ret) 1901 hx509_err(context, 1, ret, 1902 "hx509_certs_init: %s", opt->template_certificate_string); 1903 1904 ret = hx509_get_one_cert(context, tcerts, &template); 1905 1906 hx509_certs_free(&tcerts); 1907 if (ret) 1908 hx509_err(context, 1, ret, "no template certificate found"); 1909 1910 flags = parse_units(opt->template_fields_string, 1911 hx509_ca_tbs_template_units(), ""); 1912 1913 ret = hx509_ca_tbs_set_template(context, tbs, flags, template); 1914 if (ret) 1915 hx509_err(context, 1, ret, "hx509_ca_tbs_set_template"); 1916 1917 hx509_cert_free(template); 1918 } 1919 1920 if (opt->serial_number_string) { 1921 heim_integer serialNumber; 1922 1923 ret = der_parse_hex_heim_integer(opt->serial_number_string, 1924 &serialNumber); 1925 if (ret) 1926 err(1, "der_parse_hex_heim_integer"); 1927 ret = hx509_ca_tbs_set_serialnumber(context, tbs, &serialNumber); 1928 if (ret) 1929 hx509_err(context, 1, ret, "hx509_ca_tbs_init"); 1930 der_free_heim_integer(&serialNumber); 1931 } 1932 1933 if (spki.subjectPublicKey.length) { 1934 ret = hx509_ca_tbs_set_spki(context, tbs, &spki); 1935 if (ret) 1936 hx509_err(context, 1, ret, "hx509_ca_tbs_set_spki"); 1937 } 1938 1939 if (subject) { 1940 ret = hx509_ca_tbs_set_subject(context, tbs, subject); 1941 if (ret) 1942 hx509_err(context, 1, ret, "hx509_ca_tbs_set_subject"); 1943 } 1944 1945 if (opt->crl_uri_string) { 1946 ret = hx509_ca_tbs_add_crl_dp_uri(context, tbs, 1947 opt->crl_uri_string, NULL); 1948 if (ret) 1949 hx509_err(context, 1, ret, "hx509_ca_tbs_add_crl_dp_uri"); 1950 } 1951 1952 eval_types(context, tbs, opt); 1953 1954 if (opt->issue_ca_flag) { 1955 ret = hx509_ca_tbs_set_ca(context, tbs, opt->path_length_integer); 1956 if (ret) 1957 hx509_err(context, 1, ret, "hx509_ca_tbs_set_ca"); 1958 } 1959 if (opt->issue_proxy_flag) { 1960 ret = hx509_ca_tbs_set_proxy(context, tbs, opt->path_length_integer); 1961 if (ret) 1962 hx509_err(context, 1, ret, "hx509_ca_tbs_set_proxy"); 1963 } 1964 if (opt->domain_controller_flag) { 1965 hx509_ca_tbs_set_domaincontroller(context, tbs); 1966 if (ret) 1967 hx509_err(context, 1, ret, "hx509_ca_tbs_set_domaincontroller"); 1968 } 1969 1970 if (delta) { 1971 ret = hx509_ca_tbs_set_notAfter_lifetime(context, tbs, delta); 1972 if (ret) 1973 hx509_err(context, 1, ret, "hx509_ca_tbs_set_notAfter_lifetime"); 1974 } 1975 1976 if (opt->self_signed_flag) { 1977 ret = hx509_ca_sign_self(context, tbs, private_key, &cert); 1978 if (ret) 1979 hx509_err(context, 1, ret, "hx509_ca_sign_self"); 1980 } else { 1981 ret = hx509_ca_sign(context, tbs, signer, &cert); 1982 if (ret) 1983 hx509_err(context, 1, ret, "hx509_ca_sign"); 1984 } 1985 1986 if (cert_key) { 1987 ret = _hx509_cert_assign_key(cert, cert_key); 1988 if (ret) 1989 hx509_err(context, 1, ret, "_hx509_cert_assign_key"); 1990 } 1991 1992 { 1993 hx509_certs certs; 1994 1995 ret = hx509_certs_init(context, opt->certificate_string, 1996 HX509_CERTS_CREATE, NULL, &certs); 1997 if (ret) 1998 hx509_err(context, 1, ret, "hx509_certs_init"); 1999 2000 ret = hx509_certs_add(context, certs, cert); 2001 if (ret) 2002 hx509_err(context, 1, ret, "hx509_certs_add"); 2003 2004 ret = hx509_certs_store(context, certs, 0, NULL); 2005 if (ret) 2006 hx509_err(context, 1, ret, "hx509_certs_store"); 2007 2008 hx509_certs_free(&certs); 2009 } 2010 2011 if (subject) 2012 hx509_name_free(&subject); 2013 if (signer) 2014 hx509_cert_free(signer); 2015 hx509_cert_free(cert); 2016 free_SubjectPublicKeyInfo(&spki); 2017 2018 if (private_key != cert_key) 2019 hx509_private_key_free(&private_key); 2020 hx509_private_key_free(&cert_key); 2021 2022 hx509_ca_tbs_free(&tbs); 2023 2024 return 0; 2025 } 2026 2027 static int 2028 test_one_cert(hx509_context hxcontext, void *ctx, hx509_cert cert) 2029 { 2030 heim_octet_string sd, c; 2031 hx509_verify_ctx vctx = ctx; 2032 hx509_certs signer = NULL; 2033 heim_oid type; 2034 int ret; 2035 2036 if (_hx509_cert_private_key(cert) == NULL) 2037 return 0; 2038 2039 ret = hx509_cms_create_signed_1(context, 0, NULL, NULL, 0, 2040 NULL, cert, NULL, NULL, NULL, &sd); 2041 if (ret) 2042 errx(1, "hx509_cms_create_signed_1"); 2043 2044 ret = hx509_cms_verify_signed(context, vctx, 0, sd.data, sd.length, 2045 NULL, NULL, &type, &c, &signer); 2046 free(sd.data); 2047 if (ret) 2048 hx509_err(context, 1, ret, "hx509_cms_verify_signed"); 2049 2050 printf("create-signature verify-sigature done\n"); 2051 2052 free(c.data); 2053 2054 return 0; 2055 } 2056 2057 int 2058 test_crypto(struct test_crypto_options *opt, int argc, char ** argv) 2059 { 2060 hx509_verify_ctx vctx; 2061 hx509_certs certs; 2062 hx509_lock lock; 2063 int i, ret; 2064 2065 hx509_lock_init(context, &lock); 2066 lock_strings(lock, &opt->pass_strings); 2067 2068 ret = hx509_certs_init(context, "MEMORY:test-crypto", 0, NULL, &certs); 2069 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY"); 2070 2071 for (i = 0; i < argc; i++) { 2072 ret = hx509_certs_append(context, certs, lock, argv[i]); 2073 if (ret) 2074 hx509_err(context, 1, ret, "hx509_certs_append"); 2075 } 2076 2077 ret = hx509_verify_init_ctx(context, &vctx); 2078 if (ret) 2079 hx509_err(context, 1, ret, "hx509_verify_init_ctx"); 2080 2081 hx509_verify_attach_anchors(vctx, certs); 2082 2083 ret = hx509_certs_iter_f(context, certs, test_one_cert, vctx); 2084 if (ret) 2085 hx509_err(context, 1, ret, "hx509_cert_iter"); 2086 2087 hx509_certs_free(&certs); 2088 2089 return 0; 2090 } 2091 2092 int 2093 statistic_print(struct statistic_print_options*opt, int argc, char **argv) 2094 { 2095 int type = 0; 2096 2097 if (stat_file_string == NULL) 2098 errx(1, "no stat file"); 2099 2100 if (opt->type_integer) 2101 type = opt->type_integer; 2102 2103 hx509_query_unparse_stats(context, type, stdout); 2104 return 0; 2105 } 2106 2107 /* 2108 * 2109 */ 2110 2111 int 2112 crl_sign(struct crl_sign_options *opt, int argc, char **argv) 2113 { 2114 hx509_crl crl; 2115 heim_octet_string os; 2116 hx509_cert signer = NULL; 2117 hx509_lock lock; 2118 int ret; 2119 2120 hx509_lock_init(context, &lock); 2121 lock_strings(lock, &opt->pass_strings); 2122 2123 ret = hx509_crl_alloc(context, &crl); 2124 if (ret) 2125 errx(1, "crl alloc"); 2126 2127 if (opt->signer_string == NULL) 2128 errx(1, "signer missing"); 2129 2130 { 2131 hx509_certs certs = NULL; 2132 hx509_query *q; 2133 2134 ret = hx509_certs_init(context, opt->signer_string, 0, 2135 NULL, &certs); 2136 if (ret) 2137 hx509_err(context, 1, ret, 2138 "hx509_certs_init: %s", opt->signer_string); 2139 2140 ret = hx509_query_alloc(context, &q); 2141 if (ret) 2142 hx509_err(context, 1, ret, "hx509_query_alloc: %d", ret); 2143 2144 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); 2145 2146 ret = hx509_certs_find(context, certs, q, &signer); 2147 hx509_query_free(context, q); 2148 hx509_certs_free(&certs); 2149 if (ret) 2150 hx509_err(context, 1, ret, "no signer certificate found"); 2151 } 2152 2153 if (opt->lifetime_string) { 2154 int delta; 2155 2156 delta = parse_time(opt->lifetime_string, "day"); 2157 if (delta < 0) 2158 errx(1, "Invalid lifetime: %s", opt->lifetime_string); 2159 2160 hx509_crl_lifetime(context, crl, delta); 2161 } 2162 2163 { 2164 hx509_certs revoked = NULL; 2165 int i; 2166 2167 ret = hx509_certs_init(context, "MEMORY:revoked-certs", 0, 2168 NULL, &revoked); 2169 if (ret) 2170 hx509_err(context, 1, ret, 2171 "hx509_certs_init: MEMORY cert"); 2172 2173 for (i = 0; i < argc; i++) { 2174 ret = hx509_certs_append(context, revoked, lock, argv[i]); 2175 if (ret) 2176 hx509_err(context, 1, ret, "hx509_certs_append: %s", argv[i]); 2177 } 2178 2179 hx509_crl_add_revoked_certs(context, crl, revoked); 2180 hx509_certs_free(&revoked); 2181 } 2182 2183 hx509_crl_sign(context, signer, crl, &os); 2184 2185 if (opt->crl_file_string) 2186 rk_dumpdata(opt->crl_file_string, os.data, os.length); 2187 2188 free(os.data); 2189 2190 hx509_crl_free(context, &crl); 2191 hx509_cert_free(signer); 2192 hx509_lock_free(lock); 2193 2194 return 0; 2195 } 2196 2197 /* 2198 * 2199 */ 2200 2201 int 2202 help(void *opt, int argc, char **argv) 2203 { 2204 sl_slc_help(commands, argc, argv); 2205 return 0; 2206 } 2207 2208 int 2209 main(int argc, char **argv) 2210 { 2211 int ret, optidx = 0; 2212 2213 setprogname (argv[0]); 2214 2215 if(getarg(args, num_args, argc, argv, &optidx)) 2216 usage(1); 2217 if(help_flag) 2218 usage(0); 2219 if(version_flag) { 2220 print_version(NULL); 2221 exit(0); 2222 } 2223 argv += optidx; 2224 argc -= optidx; 2225 2226 if (argc == 0) 2227 usage(1); 2228 2229 ret = hx509_context_init(&context); 2230 if (ret) 2231 errx(1, "hx509_context_init failed with %d", ret); 2232 2233 if (stat_file_string) 2234 hx509_query_statistic_file(context, stat_file_string); 2235 2236 ret = sl_command(commands, argc, argv); 2237 if(ret == -1) 2238 warnx ("unrecognized command: %s", argv[0]); 2239 2240 hx509_context_free(&context); 2241 2242 return ret; 2243 } 2244