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