2 * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
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.
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
36 #include <hxtool-commands.h>
39 #include <parse_time.h>
41 static hx509_context context;
43 static char *stat_file_string;
44 static int version_flag;
47 struct getargs args[] = {
48 { "statistic-file", 0, arg_string, &stat_file_string, NULL, NULL },
49 { "version", 0, arg_flag, &version_flag, NULL, NULL },
50 { "help", 0, arg_flag, &help_flag, NULL, NULL }
52 int num_args = sizeof(args) / sizeof(args[0]);
57 arg_printusage(args, num_args, NULL, "command");
58 printf("Use \"%s help\" to get more help\n", getprogname());
67 lock_strings(hx509_lock lock, getarg_strings *pass)
70 for (i = 0; i < pass->num_strings; i++) {
71 int ret = hx509_lock_command_string(lock, pass->strings[i]);
73 errx(1, "hx509_lock_command_string: %s: %d",
74 pass->strings[i], ret);
83 certs_strings(hx509_context contextp, const char *type, hx509_certs certs,
84 hx509_lock lock, const getarg_strings *s)
88 for (i = 0; i < s->num_strings; i++) {
89 ret = hx509_certs_append(contextp, certs, lock, s->strings[i]);
91 hx509_err(contextp, 1, ret,
92 "hx509_certs_append: %s %s", type, s->strings[i]);
101 parse_oid(const char *str, const heim_oid *def, heim_oid *oid)
105 ret = der_parse_heim_oid (str, " .", oid);
107 ret = der_copy_oid(def, oid);
109 errx(1, "parse_oid failed for: %s", str ? str : "default oid");
117 peer_strings(hx509_context contextp,
118 hx509_peer_info *peer,
119 const getarg_strings *s)
121 AlgorithmIdentifier *val;
124 ret = hx509_peer_info_alloc(contextp, peer);
126 hx509_err(contextp, 1, ret, "hx509_peer_info_alloc");
128 val = calloc(s->num_strings, sizeof(*val));
132 for (i = 0; i < s->num_strings; i++)
133 parse_oid(s->strings[i], NULL, &val[i].algorithm);
135 ret = hx509_peer_info_set_cms_algs(contextp, *peer, val, s->num_strings);
137 hx509_err(contextp, 1, ret, "hx509_peer_info_set_cms_algs");
139 for (i = 0; i < s->num_strings; i++)
140 free_AlgorithmIdentifier(&val[i]);
149 heim_octet_string *os;
154 pem_reader(hx509_context contextp, const char *type,
155 const hx509_pem_header *headers,
156 const void *data , size_t length, void *ctx)
158 struct pem_data *p = (struct pem_data *)ctx;
161 p->os->data = malloc(length);
162 if (p->os->data == NULL)
164 memcpy(p->os->data, data, length);
165 p->os->length = length;
167 h = hx509_pem_find_header(headers, "Content-disposition");
168 if (h && strcasecmp(h, "detached") == 0)
169 p->detached_data = 1;
179 cms_verify_sd(struct cms_verify_sd_options *opt, int argc, char **argv)
181 hx509_verify_ctx ctx = NULL;
183 heim_octet_string c, co, signeddata, *sd = NULL;
184 hx509_certs store = NULL;
185 hx509_certs signers = NULL;
186 hx509_certs anchors = NULL;
193 if (opt->missing_revoke_flag)
194 hx509_context_set_missing_revoke(context, 1);
196 hx509_lock_init(context, &lock);
197 lock_strings(lock, &opt->pass_strings);
199 ret = hx509_verify_init_ctx(context, &ctx);
201 hx509_err(context, 1, ret, "hx509_verify_init_ctx");
203 ret = hx509_certs_init(context, "MEMORY:cms-anchors", 0, NULL, &anchors);
205 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
206 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &store);
208 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
210 certs_strings(context, "anchors", anchors, lock, &opt->anchors_strings);
211 certs_strings(context, "store", store, lock, &opt->certificate_strings);
218 pd.detached_data = 0;
220 f = fopen(argv[0], "r");
222 err(1, "Failed to open file %s", argv[0]);
224 ret = hx509_pem_read(context, f, pem_reader, &pd);
227 errx(1, "PEM reader failed: %d", ret);
229 if (pd.detached_data && opt->signed_content_string == NULL) {
230 char *r = strrchr(argv[0], '.');
231 if (r && strcasecmp(r, ".pem") == 0) {
232 char *s = strdup(argv[0]);
234 errx(1, "malloc: out of memory");
235 s[r - argv[0]] = '\0';
236 ret = _hx509_map_file_os(s, &signeddata);
238 errx(1, "map_file: %s: %d", s, ret);
245 ret = rk_undumpdata(argv[0], &p, &sz);
247 err(1, "map_file: %s: %d", argv[0], ret);
253 if (opt->signed_content_string) {
254 ret = _hx509_map_file_os(opt->signed_content_string, &signeddata);
256 errx(1, "map_file: %s: %d", opt->signed_content_string, ret);
260 if (opt->content_info_flag) {
261 heim_octet_string uwco;
264 ret = hx509_cms_unwrap_ContentInfo(&co, &oid, &uwco, NULL);
266 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret);
268 if (der_heim_oid_cmp(&oid, &asn1_oid_id_pkcs7_signedData) != 0)
269 errx(1, "Content is not SignedData");
273 der_free_octet_string(&co);
281 hx509_verify_attach_anchors(ctx, anchors);
283 if (!opt->signer_allowed_flag)
284 flags |= HX509_CMS_VS_ALLOW_ZERO_SIGNER;
285 if (opt->allow_wrong_oid_flag)
286 flags |= HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH;
288 ret = hx509_cms_verify_signed(context, ctx, flags, co.data, co.length, sd,
289 store, &type, &c, &signers);
291 der_free_octet_string(&co);
295 hx509_err(context, 1, ret, "hx509_cms_verify_signed");
299 der_print_heim_oid(&type, '.', &str);
300 printf("type: %s\n", str);
304 if (signers == NULL) {
305 printf("unsigned\n");
307 printf("signers:\n");
308 hx509_certs_iter_f(context, signers, hx509_ci_print_names, stdout);
311 hx509_verify_destroy_ctx(ctx);
313 hx509_certs_free(&store);
314 hx509_certs_free(&signers);
315 hx509_certs_free(&anchors);
317 hx509_lock_free(lock);
320 ret = _hx509_write_file(argv[1], c.data, c.length);
322 errx(1, "hx509_write_file: %d", ret);
325 der_free_octet_string(&c);
328 _hx509_unmap_file_os(sd);
334 print_signer(hx509_context contextp, void *ctx, hx509_cert cert)
336 hx509_pem_header **header = ctx;
337 char *signer_name = NULL;
341 ret = hx509_cert_get_subject(cert, &name);
343 errx(1, "hx509_cert_get_subject");
345 ret = hx509_name_to_string(name, &signer_name);
346 hx509_name_free(&name);
348 errx(1, "hx509_name_to_string");
350 hx509_pem_add_header(header, "Signer", signer_name);
357 cms_create_sd(struct cms_create_sd_options *opt, int argc, char **argv)
359 heim_oid contentType;
360 hx509_peer_info peer = NULL;
364 hx509_certs store, pool, anchors, signer = NULL;
368 char *infile, *outfile = NULL;
370 memset(&contentType, 0, sizeof(contentType));
375 asprintf(&outfile, "%s.%s", infile,
376 opt->pem_flag ? "pem" : "cms-signeddata");
378 errx(1, "out of memory");
382 hx509_lock_init(context, &lock);
383 lock_strings(lock, &opt->pass_strings);
385 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &store);
386 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
387 ret = hx509_certs_init(context, "MEMORY:cert-pool", 0, NULL, &pool);
388 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
390 certs_strings(context, "store", store, lock, &opt->certificate_strings);
391 certs_strings(context, "pool", pool, lock, &opt->pool_strings);
393 if (opt->anchors_strings.num_strings) {
394 ret = hx509_certs_init(context, "MEMORY:cert-anchors",
396 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
397 certs_strings(context, "anchors", anchors, lock, &opt->anchors_strings);
401 if (opt->detached_signature_flag)
402 flags |= HX509_CMS_SIGNATURE_DETACHED;
403 if (opt->id_by_name_flag)
404 flags |= HX509_CMS_SIGNATURE_ID_NAME;
405 if (!opt->signer_flag) {
406 flags |= HX509_CMS_SIGNATURE_NO_SIGNER;
410 if (opt->signer_flag) {
411 ret = hx509_query_alloc(context, &q);
413 errx(1, "hx509_query_alloc: %d", ret);
415 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
416 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
418 if (opt->signer_string)
419 hx509_query_match_friendly_name(q, opt->signer_string);
421 ret = hx509_certs_filter(context, store, q, &signer);
422 hx509_query_free(context, q);
424 hx509_err(context, 1, ret, "hx509_certs_find");
426 if (!opt->embedded_certs_flag)
427 flags |= HX509_CMS_SIGNATURE_NO_CERTS;
428 if (opt->embed_leaf_only_flag)
429 flags |= HX509_CMS_SIGNATURE_LEAF_ONLY;
431 ret = rk_undumpdata(infile, &p, &sz);
433 err(1, "map_file: %s: %d", infile, ret);
435 if (opt->peer_alg_strings.num_strings)
436 peer_strings(context, &peer, &opt->peer_alg_strings);
438 parse_oid(opt->content_type_string, &asn1_oid_id_pkcs7_data, &contentType);
440 ret = hx509_cms_create_signed(context,
452 hx509_err(context, 1, ret, "hx509_cms_create_signed: %d", ret);
454 hx509_certs_free(&anchors);
455 hx509_certs_free(&pool);
456 hx509_certs_free(&store);
458 hx509_lock_free(lock);
459 hx509_peer_info_free(peer);
460 der_free_oid(&contentType);
462 if (opt->content_info_flag) {
463 heim_octet_string wo;
465 ret = hx509_cms_wrap_ContentInfo(&asn1_oid_id_pkcs7_signedData, &o, &wo);
467 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret);
469 der_free_octet_string(&o);
474 hx509_pem_header *header = NULL;
477 hx509_pem_add_header(&header, "Content-disposition",
478 opt->detached_signature_flag ?
479 "detached" : "inline");
481 ret = hx509_certs_iter_f(context, signer, print_signer, header);
483 hx509_err(context, 1, ret, "print signer");
486 f = fopen(outfile, "w");
488 err(1, "open %s", outfile);
490 ret = hx509_pem_write(context, "CMS SIGNEDDATA", header, f,
493 hx509_pem_free_header(header);
495 errx(1, "hx509_pem_write: %d", ret);
498 ret = _hx509_write_file(outfile, o.data, o.length);
500 errx(1, "hx509_write_file: %d", ret);
503 hx509_certs_free(&signer);
510 cms_unenvelope(struct cms_unenvelope_options *opt, int argc, char **argv)
512 heim_oid contentType = { 0, NULL };
513 heim_octet_string o, co;
521 hx509_lock_init(context, &lock);
522 lock_strings(lock, &opt->pass_strings);
524 ret = rk_undumpdata(argv[0], &p, &sz);
526 err(1, "map_file: %s: %d", argv[0], ret);
531 if (opt->content_info_flag) {
532 heim_octet_string uwco;
535 ret = hx509_cms_unwrap_ContentInfo(&co, &oid, &uwco, NULL);
537 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret);
539 if (der_heim_oid_cmp(&oid, &asn1_oid_id_pkcs7_envelopedData) != 0)
540 errx(1, "Content is not SignedData");
546 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &certs);
548 errx(1, "hx509_certs_init: MEMORY: %d", ret);
550 certs_strings(context, "store", certs, lock, &opt->certificate_strings);
552 if (opt->allow_weak_crypto_flag)
553 flags |= HX509_CMS_UE_ALLOW_WEAK;
555 ret = hx509_cms_unenvelope(context, certs, flags, co.data, co.length,
556 NULL, 0, &contentType, &o);
558 der_free_octet_string(&co);
560 hx509_err(context, 1, ret, "hx509_cms_unenvelope");
563 hx509_lock_free(lock);
564 hx509_certs_free(&certs);
565 der_free_oid(&contentType);
567 ret = _hx509_write_file(argv[1], o.data, o.length);
569 errx(1, "hx509_write_file: %d", ret);
571 der_free_octet_string(&o);
577 cms_create_enveloped(struct cms_envelope_options *opt, int argc, char **argv)
579 heim_oid contentType;
581 const heim_oid *enctype = NULL;
591 memset(&contentType, 0, sizeof(contentType));
593 hx509_lock_init(context, &lock);
594 lock_strings(lock, &opt->pass_strings);
596 ret = rk_undumpdata(argv[0], &p, &sz);
598 err(1, "map_file: %s: %d", argv[0], ret);
600 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &certs);
601 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
603 certs_strings(context, "store", certs, lock, &opt->certificate_strings);
605 if (opt->allow_weak_crypto_flag)
606 flags |= HX509_CMS_EV_ALLOW_WEAK;
608 if (opt->encryption_type_string) {
609 enctype = hx509_crypto_enctype_by_name(opt->encryption_type_string);
611 errx(1, "encryption type: %s no found",
612 opt->encryption_type_string);
615 ret = hx509_query_alloc(context, &q);
617 errx(1, "hx509_query_alloc: %d", ret);
619 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_ENCIPHERMENT);
621 ret = hx509_certs_find(context, certs, q, &cert);
622 hx509_query_free(context, q);
624 errx(1, "hx509_certs_find: %d", ret);
626 parse_oid(opt->content_type_string, &asn1_oid_id_pkcs7_data, &contentType);
628 ret = hx509_cms_envelope_1(context, flags, cert, p, sz, enctype,
631 errx(1, "hx509_cms_envelope_1: %d", ret);
633 hx509_cert_free(cert);
634 hx509_certs_free(&certs);
636 der_free_oid(&contentType);
638 if (opt->content_info_flag) {
639 heim_octet_string wo;
641 ret = hx509_cms_wrap_ContentInfo(&asn1_oid_id_pkcs7_envelopedData, &o, &wo);
643 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret);
645 der_free_octet_string(&o);
649 hx509_lock_free(lock);
651 ret = _hx509_write_file(argv[1], o.data, o.length);
653 errx(1, "hx509_write_file: %d", ret);
655 der_free_octet_string(&o);
661 print_certificate(hx509_context hxcontext, hx509_cert cert, int verbose)
666 fn = hx509_cert_get_friendly_name(cert);
668 printf(" friendly name: %s\n", fn);
669 printf(" private key: %s\n",
670 _hx509_cert_private_key(cert) ? "yes" : "no");
672 ret = hx509_print_cert(hxcontext, cert, NULL);
674 errx(1, "failed to print cert");
677 hx509_validate_ctx vctx;
679 hx509_validate_ctx_init(hxcontext, &vctx);
680 hx509_validate_ctx_set_print(vctx, hx509_print_stdout, stdout);
681 hx509_validate_ctx_add_flags(vctx, HX509_VALIDATE_F_VALIDATE);
682 hx509_validate_ctx_add_flags(vctx, HX509_VALIDATE_F_VERBOSE);
684 hx509_validate_cert(hxcontext, vctx, cert);
686 hx509_validate_ctx_free(vctx);
697 print_f(hx509_context hxcontext, void *ctx, hx509_cert cert)
699 struct print_s *s = ctx;
701 printf("cert: %d\n", s->counter++);
702 print_certificate(context, cert, s->verbose);
708 pcert_print(struct print_options *opt, int argc, char **argv)
715 s.verbose = opt->content_flag;
717 hx509_lock_init(context, &lock);
718 lock_strings(lock, &opt->pass_strings);
722 ret = hx509_certs_init(context, argv[0], 0, lock, &certs);
724 if (opt->never_fail_flag) {
725 printf("ignoreing failure: %d\n", ret);
728 hx509_err(context, 1, ret, "hx509_certs_init");
731 hx509_certs_info(context, certs, NULL, NULL);
732 hx509_certs_iter_f(context, certs, print_f, &s);
733 hx509_certs_free(&certs);
737 hx509_lock_free(lock);
744 validate_f(hx509_context hxcontext, void *ctx, hx509_cert c)
746 hx509_validate_cert(hxcontext, ctx, c);
751 pcert_validate(struct validate_options *opt, int argc, char **argv)
753 hx509_validate_ctx ctx;
757 hx509_lock_init(context, &lock);
758 lock_strings(lock, &opt->pass_strings);
760 hx509_validate_ctx_init(context, &ctx);
761 hx509_validate_ctx_set_print(ctx, hx509_print_stdout, stdout);
762 hx509_validate_ctx_add_flags(ctx, HX509_VALIDATE_F_VALIDATE);
766 ret = hx509_certs_init(context, argv[0], 0, lock, &certs);
768 errx(1, "hx509_certs_init: %d", ret);
769 hx509_certs_iter_f(context, certs, validate_f, ctx);
770 hx509_certs_free(&certs);
773 hx509_validate_ctx_free(ctx);
775 hx509_lock_free(lock);
781 certificate_copy(struct certificate_copy_options *opt, int argc, char **argv)
784 hx509_lock inlock, outlock = NULL;
787 hx509_lock_init(context, &inlock);
788 lock_strings(inlock, &opt->in_pass_strings);
790 if (opt->out_pass_string) {
791 hx509_lock_init(context, &outlock);
792 ret = hx509_lock_command_string(outlock, opt->out_pass_string);
794 errx(1, "hx509_lock_command_string: %s: %d",
795 opt->out_pass_string, ret);
798 ret = hx509_certs_init(context, argv[argc - 1],
799 HX509_CERTS_CREATE, inlock, &certs);
801 hx509_err(context, 1, ret, "hx509_certs_init");
805 retx = hx509_certs_append(context, certs, inlock, argv[0]);
807 hx509_err(context, 1, retx, "hx509_certs_append");
811 ret = hx509_certs_store(context, certs, 0, outlock);
813 hx509_err(context, 1, ret, "hx509_certs_store");
815 hx509_certs_free(&certs);
816 hx509_lock_free(inlock);
817 hx509_lock_free(outlock);
823 hx509_verify_ctx ctx;
825 const char *hostname;
831 verify_f(hx509_context hxcontext, void *ctx, hx509_cert c)
833 struct verify *v = ctx;
836 ret = hx509_verify_path(hxcontext, v->ctx, c, v->chain);
838 char *s = hx509_get_error_string(hxcontext, ret);
839 printf("verify_path: %s: %d\n", s, ret);
840 hx509_free_error_string(s);
848 ret = hx509_verify_hostname(hxcontext, c, 0, HX509_HN_HOSTNAME,
849 v->hostname, NULL, 0);
851 printf("verify_hostname: %d\n", ret);
860 pcert_verify(struct verify_options *opt, int argc, char **argv)
862 hx509_certs anchors, chain, certs;
863 hx509_revoke_ctx revoke_ctx;
864 hx509_verify_ctx ctx;
868 memset(&v, 0, sizeof(v));
870 if (opt->missing_revoke_flag)
871 hx509_context_set_missing_revoke(context, 1);
873 ret = hx509_verify_init_ctx(context, &ctx);
875 hx509_err(context, 1, ret, "hx509_verify_init_ctx");
876 ret = hx509_certs_init(context, "MEMORY:anchors", 0, NULL, &anchors);
878 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
879 ret = hx509_certs_init(context, "MEMORY:chain", 0, NULL, &chain);
881 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
882 ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &certs);
884 hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
886 if (opt->allow_proxy_certificate_flag)
887 hx509_verify_set_proxy_certificate(ctx, 1);
889 if (opt->time_string) {
894 memset(&tm, 0, sizeof(tm));
896 p = strptime (opt->time_string, "%Y-%m-%d", &tm);
898 errx(1, "Failed to parse time %s, need to be on format %%Y-%%m-%%d",
903 hx509_verify_set_time(ctx, t);
906 if (opt->hostname_string)
907 v.hostname = opt->hostname_string;
908 if (opt->max_depth_integer)
909 hx509_verify_set_max_depth(ctx, opt->max_depth_integer);
911 ret = hx509_revoke_init(context, &revoke_ctx);
913 errx(1, "hx509_revoke_init: %d", ret);
918 if (strncmp(s, "chain:", 6) == 0) {
921 ret = hx509_certs_append(context, chain, NULL, s);
923 hx509_err(context, 1, ret, "hx509_certs_append: chain: %s: %d", s, ret);
925 } else if (strncmp(s, "anchor:", 7) == 0) {
928 ret = hx509_certs_append(context, anchors, NULL, s);
930 hx509_err(context, 1, ret, "hx509_certs_append: anchor: %s: %d", s, ret);
932 } else if (strncmp(s, "cert:", 5) == 0) {
935 ret = hx509_certs_append(context, certs, NULL, s);
937 hx509_err(context, 1, ret, "hx509_certs_append: certs: %s: %d",
940 } else if (strncmp(s, "crl:", 4) == 0) {
943 ret = hx509_revoke_add_crl(context, revoke_ctx, s);
945 errx(1, "hx509_revoke_add_crl: %s: %d", s, ret);
947 } else if (strncmp(s, "ocsp:", 4) == 0) {
950 ret = hx509_revoke_add_ocsp(context, revoke_ctx, s);
952 errx(1, "hx509_revoke_add_ocsp: %s: %d", s, ret);
955 errx(1, "unknown option to verify: `%s'\n", s);
959 hx509_verify_attach_anchors(ctx, anchors);
960 hx509_verify_attach_revoke(ctx, revoke_ctx);
965 hx509_certs_iter_f(context, certs, verify_f, &v);
967 hx509_verify_destroy_ctx(ctx);
969 hx509_certs_free(&certs);
970 hx509_certs_free(&chain);
971 hx509_certs_free(&anchors);
973 hx509_revoke_free(&revoke_ctx);
977 printf("no certs verify at all\n");
982 printf("failed verifing %d checks\n", v.errors);
990 query(struct query_options *opt, int argc, char **argv)
998 ret = hx509_query_alloc(context, &q);
1000 errx(1, "hx509_query_alloc: %d", ret);
1002 hx509_lock_init(context, &lock);
1003 lock_strings(lock, &opt->pass_strings);
1005 ret = hx509_certs_init(context, "MEMORY:cert-store", 0, NULL, &certs);
1006 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
1010 ret = hx509_certs_append(context, certs, lock, argv[0]);
1012 errx(1, "hx509_certs_append: %s: %d", argv[0], ret);
1018 if (opt->friendlyname_string)
1019 hx509_query_match_friendly_name(q, opt->friendlyname_string);
1021 if (opt->eku_string) {
1024 parse_oid(opt->eku_string, NULL, &oid);
1026 ret = hx509_query_match_eku(q, &oid);
1028 errx(1, "hx509_query_match_eku: %d", ret);
1032 if (opt->private_key_flag)
1033 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
1035 if (opt->keyEncipherment_flag)
1036 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_ENCIPHERMENT);
1038 if (opt->digitalSignature_flag)
1039 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
1041 if (opt->expr_string)
1042 hx509_query_match_expr(context, q, opt->expr_string);
1044 ret = hx509_certs_find(context, certs, q, &c);
1045 hx509_query_free(context, q);
1047 printf("no match found (%d)\n", ret);
1049 printf("match found\n");
1050 if (opt->print_flag)
1051 print_certificate(context, c, 0);
1055 hx509_certs_free(&certs);
1057 hx509_lock_free(lock);
1063 ocsp_fetch(struct ocsp_fetch_options *opt, int argc, char **argv)
1065 hx509_certs reqcerts, pool;
1066 heim_octet_string req, nonce_data, *nonce = &nonce_data;
1070 const char *url = "/";
1072 memset(&nonce, 0, sizeof(nonce));
1074 hx509_lock_init(context, &lock);
1075 lock_strings(lock, &opt->pass_strings);
1078 if (!opt->nonce_flag)
1081 if (opt->url_path_string)
1082 url = opt->url_path_string;
1084 ret = hx509_certs_init(context, "MEMORY:ocsp-pool", 0, NULL, &pool);
1085 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
1087 certs_strings(context, "ocsp-pool", pool, lock, &opt->pool_strings);
1091 ret = hx509_certs_init(context, "MEMORY:ocsp-req", 0, NULL, &reqcerts);
1092 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
1094 for (i = 1; i < argc; i++) {
1095 ret = hx509_certs_append(context, reqcerts, lock, argv[i]);
1097 errx(1, "hx509_certs_append: req: %s: %d", argv[i], ret);
1100 ret = hx509_ocsp_request(context, reqcerts, pool, NULL, NULL, &req, nonce);
1102 errx(1, "hx509_ocsp_request: req: %d", ret);
1107 f = fopen(file, "w");
1112 "POST %s HTTP/1.0\r\n"
1113 "Content-Type: application/ocsp-request\r\n"
1114 "Content-Length: %ld\r\n"
1117 (unsigned long)req.length);
1118 fwrite(req.data, req.length, 1, f);
1123 der_free_octet_string(nonce);
1125 hx509_certs_free(&reqcerts);
1126 hx509_certs_free(&pool);
1132 ocsp_print(struct ocsp_print_options *opt, int argc, char **argv)
1134 hx509_revoke_ocsp_print(context, argv[0], stdout);
1143 verify_o(hx509_context hxcontext, void *ctx, hx509_cert c)
1145 heim_octet_string *os = ctx;
1149 ret = hx509_ocsp_verify(context, 0, c, 0,
1150 os->data, os->length, &expiration);
1152 char *s = hx509_get_error_string(hxcontext, ret);
1153 printf("ocsp_verify: %s: %d\n", s, ret);
1154 hx509_free_error_string(s);
1156 printf("expire: %d\n", (int)expiration);
1163 ocsp_verify(struct ocsp_verify_options *opt, int argc, char **argv)
1168 heim_octet_string os;
1170 hx509_lock_init(context, &lock);
1172 if (opt->ocsp_file_string == NULL)
1173 errx(1, "no ocsp file given");
1175 ret = _hx509_map_file_os(opt->ocsp_file_string, &os);
1177 err(1, "map_file: %s: %d", argv[0], ret);
1179 ret = hx509_certs_init(context, "MEMORY:test-certs", 0, NULL, &certs);
1180 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
1182 for (i = 0; i < argc; i++) {
1183 ret = hx509_certs_append(context, certs, lock, argv[i]);
1185 hx509_err(context, 1, ret, "hx509_certs_append: %s", argv[i]);
1188 ret = hx509_certs_iter_f(context, certs, verify_o, &os);
1190 hx509_certs_free(&certs);
1191 _hx509_unmap_file_os(&os);
1192 hx509_lock_free(lock);
1198 read_private_key(const char *fn, hx509_private_key *key)
1200 hx509_private_key *keys;
1206 ret = hx509_certs_init(context, fn, 0, NULL, &certs);
1208 hx509_err(context, 1, ret, "hx509_certs_init: %s", fn);
1210 ret = _hx509_certs_keys_get(context, certs, &keys);
1211 hx509_certs_free(&certs);
1213 hx509_err(context, 1, ret, "hx509_certs_keys_get");
1214 if (keys[0] == NULL)
1215 errx(1, "no keys in key store: %s", fn);
1217 *key = _hx509_private_key_ref(keys[0]);
1218 _hx509_certs_keys_free(context, keys);
1224 get_key(const char *fn, const char *type, int optbits,
1225 hx509_private_key *signer)
1232 unsigned char *p0, *p;
1237 errx(1, "no key argument, don't know here to store key");
1239 if (strcasecmp(type, "rsa") != 0)
1240 errx(1, "can only handle rsa keys for now");
1243 BN_set_word(e, 0x10001);
1250 errx(1, "RSA_new failed");
1252 ret = RSA_generate_key_ex(rsa, bits, e, NULL);
1254 errx(1, "RSA_new failed");
1258 len = i2d_RSAPrivateKey(rsa, NULL);
1260 p0 = p = malloc(len);
1262 errx(1, "out of memory");
1264 i2d_RSAPrivateKey(rsa, &p);
1266 rk_dumpdata(fn, p0, len);
1272 } else if (fn == NULL)
1273 err(1, "no private key");
1275 ret = read_private_key(fn, signer);
1277 err(1, "read_private_key");
1281 request_create(struct request_create_options *opt, int argc, char **argv)
1283 heim_octet_string request;
1286 hx509_private_key signer;
1287 SubjectPublicKeyInfo key;
1288 const char *outfile = argv[0];
1290 memset(&key, 0, sizeof(key));
1292 get_key(opt->key_string,
1293 opt->generate_key_string,
1294 opt->key_bits_integer,
1297 hx509_request_init(context, &req);
1299 if (opt->subject_string) {
1300 hx509_name name = NULL;
1302 ret = hx509_parse_name(context, opt->subject_string, &name);
1304 errx(1, "hx509_parse_name: %d\n", ret);
1305 hx509_request_set_name(context, req, name);
1307 if (opt->verbose_flag) {
1309 hx509_name_to_string(name, &s);
1312 hx509_name_free(&name);
1315 for (i = 0; i < opt->email_strings.num_strings; i++) {
1316 ret = _hx509_request_add_email(context, req,
1317 opt->email_strings.strings[i]);
1319 hx509_err(context, 1, ret, "hx509_request_add_email");
1322 for (i = 0; i < opt->dnsname_strings.num_strings; i++) {
1323 ret = _hx509_request_add_dns_name(context, req,
1324 opt->dnsname_strings.strings[i]);
1326 hx509_err(context, 1, ret, "hx509_request_add_dns_name");
1330 ret = hx509_private_key2SPKI(context, signer, &key);
1332 errx(1, "hx509_private_key2SPKI: %d\n", ret);
1334 ret = hx509_request_set_SubjectPublicKeyInfo(context,
1337 free_SubjectPublicKeyInfo(&key);
1339 hx509_err(context, 1, ret, "hx509_request_set_SubjectPublicKeyInfo");
1341 ret = _hx509_request_to_pkcs10(context,
1346 hx509_err(context, 1, ret, "_hx509_request_to_pkcs10");
1348 hx509_private_key_free(&signer);
1349 hx509_request_free(&req);
1352 rk_dumpdata(outfile, request.data, request.length);
1353 der_free_octet_string(&request);
1359 request_print(struct request_print_options *opt, int argc, char **argv)
1363 printf("request print\n");
1365 for (i = 0; i < argc; i++) {
1368 ret = _hx509_request_parse(context, argv[i], &req);
1370 hx509_err(context, 1, ret, "parse_request: %s", argv[i]);
1372 ret = _hx509_request_print(context, req, stdout);
1373 hx509_request_free(&req);
1375 hx509_err(context, 1, ret, "Failed to print file %s", argv[i]);
1382 info(void *opt, int argc, char **argv)
1385 ENGINE_add_conf_module();
1388 const RSA_METHOD *m = RSA_get_default_method();
1390 printf("rsa: %s\n", m->name);
1393 const DH_METHOD *m = DH_get_default_method();
1395 printf("dh: %s\n", m->name);
1399 printf("ecdsa: ECDSA_METHOD-not-export\n");
1403 printf("ecdsa: hcrypto null\n");
1407 int ret = RAND_status();
1408 printf("rand: %s\n", ret == 1 ? "ok" : "not available");
1415 random_data(void *opt, int argc, char **argv)
1420 len = parse_bytes(argv[0], "byte");
1422 fprintf(stderr, "bad argument to random-data\n");
1428 fprintf(stderr, "out of memory\n");
1432 ret = RAND_bytes(ptr, len);
1435 fprintf(stderr, "did not get cryptographic strong random\n");
1439 fwrite(ptr, len, 1, stdout);
1448 crypto_available(struct crypto_available_options *opt, int argc, char **argv)
1450 AlgorithmIdentifier *val;
1451 unsigned int len, i;
1452 int ret, type = HX509_SELECT_ALL;
1454 if (opt->type_string) {
1455 if (strcmp(opt->type_string, "all") == 0)
1456 type = HX509_SELECT_ALL;
1457 else if (strcmp(opt->type_string, "digest") == 0)
1458 type = HX509_SELECT_DIGEST;
1459 else if (strcmp(opt->type_string, "public-sig") == 0)
1460 type = HX509_SELECT_PUBLIC_SIG;
1461 else if (strcmp(opt->type_string, "secret") == 0)
1462 type = HX509_SELECT_SECRET_ENC;
1464 errx(1, "unknown type: %s", opt->type_string);
1467 ret = hx509_crypto_available(context, type, NULL, &val, &len);
1469 errx(1, "hx509_crypto_available");
1471 for (i = 0; i < len; i++) {
1473 der_print_heim_oid (&val[i].algorithm, '.', &s);
1478 hx509_crypto_free_algs(val, len);
1484 crypto_select(struct crypto_select_options *opt, int argc, char **argv)
1486 hx509_peer_info peer = NULL;
1487 AlgorithmIdentifier selected;
1488 int ret, type = HX509_SELECT_DIGEST;
1491 if (opt->type_string) {
1492 if (strcmp(opt->type_string, "digest") == 0)
1493 type = HX509_SELECT_DIGEST;
1494 else if (strcmp(opt->type_string, "public-sig") == 0)
1495 type = HX509_SELECT_PUBLIC_SIG;
1496 else if (strcmp(opt->type_string, "secret") == 0)
1497 type = HX509_SELECT_SECRET_ENC;
1499 errx(1, "unknown type: %s", opt->type_string);
1502 if (opt->peer_cmstype_strings.num_strings)
1503 peer_strings(context, &peer, &opt->peer_cmstype_strings);
1505 ret = hx509_crypto_select(context, type, NULL, peer, &selected);
1507 errx(1, "hx509_crypto_available");
1509 der_print_heim_oid (&selected.algorithm, '.', &s);
1512 free_AlgorithmIdentifier(&selected);
1514 hx509_peer_info_free(peer);
1520 hxtool_hex(struct hex_options *opt, int argc, char **argv)
1523 if (opt->decode_flag) {
1524 char buf[1024], buf2[1024], *p;
1527 while(fgets(buf, sizeof(buf), stdin) != NULL) {
1528 buf[strcspn(buf, "\r\n")] = '\0';
1530 while(isspace(*(unsigned char *)p))
1532 len = hex_decode(p, buf2, strlen(p));
1534 errx(1, "hex_decode failed");
1535 if (fwrite(buf2, 1, len, stdout) != (size_t)len)
1536 errx(1, "fwrite failed");
1542 while((len = fread(buf, 1, sizeof(buf), stdin)) != 0) {
1543 len = hex_encode(buf, len, &p);
1546 fprintf(stdout, "%s\n", p);
1553 struct cert_type_opt {
1559 https_server(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt)
1561 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_serverAuth);
1565 https_client(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt)
1567 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_clientAuth);
1571 peap_server(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt)
1573 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_serverAuth);
1577 pkinit_kdc(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt)
1580 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkkdcekuoid);
1584 pkinit_client(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt)
1590 ret = hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkekuoid);
1594 ret = hx509_ca_tbs_add_eku(context, tbs, &asn1_oid_id_ms_client_authentication);
1598 return hx509_ca_tbs_add_eku(context, tbs, &asn1_oid_id_pkinit_ms_eku);
1602 email_client(hx509_context contextp, hx509_ca_tbs tbs, struct cert_type_opt *opt)
1604 return hx509_ca_tbs_add_eku(contextp, tbs, &asn1_oid_id_pkix_kp_emailProtection);
1610 int (*eval)(hx509_context, hx509_ca_tbs, struct cert_type_opt *);
1614 "Used for HTTPS server and many other TLS server certificate types",
1619 "Used for HTTPS client certificates",
1624 "Certificate will be use for email",
1629 "Certificate used for Kerberos PK-INIT client certificates",
1634 "Certificates used for Kerberos PK-INIT KDC certificates",
1639 "Certificate used for Radius PEAP (Protected EAP)",
1645 print_eval_types(FILE *out)
1650 table = rtbl_create();
1651 rtbl_add_column_by_id (table, 0, "Name", 0);
1652 rtbl_add_column_by_id (table, 1, "Description", 0);
1654 for (i = 0; i < sizeof(certtypes)/sizeof(certtypes[0]); i++) {
1655 rtbl_add_column_entry_by_id(table, 0, certtypes[i].type);
1656 rtbl_add_column_entry_by_id(table, 1, certtypes[i].desc);
1659 rtbl_format (table, out);
1660 rtbl_destroy (table);
1664 eval_types(hx509_context contextp,
1666 const struct certificate_sign_options *opt)
1668 struct cert_type_opt ctopt;
1673 memset(&ctopt, 0, sizeof(ctopt));
1675 for (i = 0; i < opt->type_strings.num_strings; i++) {
1676 const char *type = opt->type_strings.strings[i];
1678 for (j = 0; j < sizeof(certtypes)/sizeof(certtypes[0]); j++) {
1679 if (strcasecmp(type, certtypes[j].type) == 0) {
1680 ret = (*certtypes[j].eval)(contextp, tbs, &ctopt);
1682 hx509_err(contextp, 1, ret,
1683 "Failed to evaluate cert type %s", type);
1687 if (j >= sizeof(certtypes)/sizeof(certtypes[0])) {
1688 fprintf(stderr, "Unknown certificate type %s\n\n", type);
1689 fprintf(stderr, "Available types:\n");
1690 print_eval_types(stderr);
1695 if (opt->pk_init_principal_string) {
1697 errx(1, "pk-init principal given but no pk-init oid");
1699 ret = hx509_ca_tbs_add_san_pkinit(contextp, tbs,
1700 opt->pk_init_principal_string);
1702 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_pkinit");
1705 if (opt->ms_upn_string) {
1707 errx(1, "MS upn given but no pk-init oid");
1709 ret = hx509_ca_tbs_add_san_ms_upn(contextp, tbs, opt->ms_upn_string);
1711 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_ms_upn");
1715 for (i = 0; i < opt->hostname_strings.num_strings; i++) {
1716 const char *hostname = opt->hostname_strings.strings[i];
1718 ret = hx509_ca_tbs_add_san_hostname(contextp, tbs, hostname);
1720 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_hostname");
1723 for (i = 0; i < opt->email_strings.num_strings; i++) {
1724 const char *email = opt->email_strings.strings[i];
1726 ret = hx509_ca_tbs_add_san_rfc822name(contextp, tbs, email);
1728 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_hostname");
1730 ret = hx509_ca_tbs_add_eku(contextp, tbs,
1731 &asn1_oid_id_pkix_kp_emailProtection);
1733 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_eku");
1736 if (opt->jid_string) {
1737 ret = hx509_ca_tbs_add_san_jid(contextp, tbs, opt->jid_string);
1739 hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_jid");
1746 hxtool_ca(struct certificate_sign_options *opt, int argc, char **argv)
1750 hx509_cert signer = NULL, cert = NULL;
1751 hx509_private_key private_key = NULL;
1752 hx509_private_key cert_key = NULL;
1753 hx509_name subject = NULL;
1754 SubjectPublicKeyInfo spki;
1757 memset(&spki, 0, sizeof(spki));
1759 if (opt->ca_certificate_string == NULL && !opt->self_signed_flag)
1760 errx(1, "--ca-certificate argument missing (not using --self-signed)");
1761 if (opt->ca_private_key_string == NULL && opt->generate_key_string == NULL && opt->self_signed_flag)
1762 errx(1, "--ca-private-key argument missing (using --self-signed)");
1763 if (opt->certificate_string == NULL)
1764 errx(1, "--certificate argument missing");
1766 if (opt->template_certificate_string) {
1767 if (opt->template_fields_string == NULL)
1768 errx(1, "--template-certificate not no --template-fields");
1771 if (opt->lifetime_string) {
1772 delta = parse_time(opt->lifetime_string, "day");
1774 errx(1, "Invalid lifetime: %s", opt->lifetime_string);
1777 if (opt->ca_certificate_string) {
1778 hx509_certs cacerts = NULL;
1781 ret = hx509_certs_init(context, opt->ca_certificate_string, 0,
1784 hx509_err(context, 1, ret,
1785 "hx509_certs_init: %s", opt->ca_certificate_string);
1787 ret = hx509_query_alloc(context, &q);
1789 errx(1, "hx509_query_alloc: %d", ret);
1791 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
1792 if (!opt->issue_proxy_flag)
1793 hx509_query_match_option(q, HX509_QUERY_OPTION_KU_KEYCERTSIGN);
1795 ret = hx509_certs_find(context, cacerts, q, &signer);
1796 hx509_query_free(context, q);
1797 hx509_certs_free(&cacerts);
1799 hx509_err(context, 1, ret, "no CA certificate found");
1800 } else if (opt->self_signed_flag) {
1801 if (opt->generate_key_string == NULL
1802 && opt->ca_private_key_string == NULL)
1803 errx(1, "no signing private key");
1805 if (opt->req_string)
1806 errx(1, "can't be self-signing and have a request at the same time");
1808 errx(1, "missing ca key");
1810 if (opt->ca_private_key_string) {
1812 ret = read_private_key(opt->ca_private_key_string, &private_key);
1814 err(1, "read_private_key");
1816 ret = hx509_private_key2SPKI(context, private_key, &spki);
1818 errx(1, "hx509_private_key2SPKI: %d\n", ret);
1820 if (opt->self_signed_flag)
1821 cert_key = private_key;
1824 if (opt->req_string) {
1827 ret = _hx509_request_parse(context, opt->req_string, &req);
1829 hx509_err(context, 1, ret, "parse_request: %s", opt->req_string);
1830 ret = hx509_request_get_name(context, req, &subject);
1832 hx509_err(context, 1, ret, "get name");
1833 ret = hx509_request_get_SubjectPublicKeyInfo(context, req, &spki);
1835 hx509_err(context, 1, ret, "get spki");
1836 hx509_request_free(&req);
1839 if (opt->generate_key_string) {
1840 struct hx509_generate_private_context *keyctx;
1842 ret = _hx509_generate_private_key_init(context,
1843 &asn1_oid_id_pkcs1_rsaEncryption,
1846 hx509_err(context, 1, ret, "generate private key");
1848 if (opt->issue_ca_flag)
1849 _hx509_generate_private_key_is_ca(context, keyctx);
1851 if (opt->key_bits_integer)
1852 _hx509_generate_private_key_bits(context, keyctx,
1853 opt->key_bits_integer);
1855 ret = _hx509_generate_private_key(context, keyctx,
1857 _hx509_generate_private_key_free(&keyctx);
1859 hx509_err(context, 1, ret, "generate private key");
1861 ret = hx509_private_key2SPKI(context, cert_key, &spki);
1863 errx(1, "hx509_private_key2SPKI: %d\n", ret);
1865 if (opt->self_signed_flag)
1866 private_key = cert_key;
1869 if (opt->certificate_private_key_string) {
1870 ret = read_private_key(opt->certificate_private_key_string, &cert_key);
1872 err(1, "read_private_key for certificate");
1875 if (opt->subject_string) {
1877 hx509_name_free(&subject);
1878 ret = hx509_parse_name(context, opt->subject_string, &subject);
1880 hx509_err(context, 1, ret, "hx509_parse_name");
1887 ret = hx509_ca_tbs_init(context, &tbs);
1889 hx509_err(context, 1, ret, "hx509_ca_tbs_init");
1891 if (opt->template_certificate_string) {
1892 hx509_cert template;
1896 ret = hx509_certs_init(context, opt->template_certificate_string, 0,
1899 hx509_err(context, 1, ret,
1900 "hx509_certs_init: %s", opt->template_certificate_string);
1902 ret = hx509_get_one_cert(context, tcerts, &template);
1904 hx509_certs_free(&tcerts);
1906 hx509_err(context, 1, ret, "no template certificate found");
1908 flags = parse_units(opt->template_fields_string,
1909 hx509_ca_tbs_template_units(), "");
1911 ret = hx509_ca_tbs_set_template(context, tbs, flags, template);
1913 hx509_err(context, 1, ret, "hx509_ca_tbs_set_template");
1915 hx509_cert_free(template);
1918 if (opt->serial_number_string) {
1919 heim_integer serialNumber;
1921 ret = der_parse_hex_heim_integer(opt->serial_number_string,
1924 err(1, "der_parse_hex_heim_integer");
1925 ret = hx509_ca_tbs_set_serialnumber(context, tbs, &serialNumber);
1927 hx509_err(context, 1, ret, "hx509_ca_tbs_init");
1928 der_free_heim_integer(&serialNumber);
1931 if (spki.subjectPublicKey.length) {
1932 ret = hx509_ca_tbs_set_spki(context, tbs, &spki);
1934 hx509_err(context, 1, ret, "hx509_ca_tbs_set_spki");
1938 ret = hx509_ca_tbs_set_subject(context, tbs, subject);
1940 hx509_err(context, 1, ret, "hx509_ca_tbs_set_subject");
1943 if (opt->crl_uri_string) {
1944 ret = hx509_ca_tbs_add_crl_dp_uri(context, tbs,
1945 opt->crl_uri_string, NULL);
1947 hx509_err(context, 1, ret, "hx509_ca_tbs_add_crl_dp_uri");
1950 eval_types(context, tbs, opt);
1952 if (opt->issue_ca_flag) {
1953 ret = hx509_ca_tbs_set_ca(context, tbs, opt->path_length_integer);
1955 hx509_err(context, 1, ret, "hx509_ca_tbs_set_ca");
1957 if (opt->issue_proxy_flag) {
1958 ret = hx509_ca_tbs_set_proxy(context, tbs, opt->path_length_integer);
1960 hx509_err(context, 1, ret, "hx509_ca_tbs_set_proxy");
1962 if (opt->domain_controller_flag) {
1963 hx509_ca_tbs_set_domaincontroller(context, tbs);
1965 hx509_err(context, 1, ret, "hx509_ca_tbs_set_domaincontroller");
1969 ret = hx509_ca_tbs_set_notAfter_lifetime(context, tbs, delta);
1971 hx509_err(context, 1, ret, "hx509_ca_tbs_set_notAfter_lifetime");
1974 if (opt->self_signed_flag) {
1975 ret = hx509_ca_sign_self(context, tbs, private_key, &cert);
1977 hx509_err(context, 1, ret, "hx509_ca_sign_self");
1979 ret = hx509_ca_sign(context, tbs, signer, &cert);
1981 hx509_err(context, 1, ret, "hx509_ca_sign");
1985 ret = _hx509_cert_assign_key(cert, cert_key);
1987 hx509_err(context, 1, ret, "_hx509_cert_assign_key");
1993 ret = hx509_certs_init(context, opt->certificate_string,
1994 HX509_CERTS_CREATE, NULL, &certs);
1996 hx509_err(context, 1, ret, "hx509_certs_init");
1998 ret = hx509_certs_add(context, certs, cert);
2000 hx509_err(context, 1, ret, "hx509_certs_add");
2002 ret = hx509_certs_store(context, certs, 0, NULL);
2004 hx509_err(context, 1, ret, "hx509_certs_store");
2006 hx509_certs_free(&certs);
2010 hx509_name_free(&subject);
2012 hx509_cert_free(signer);
2013 hx509_cert_free(cert);
2014 free_SubjectPublicKeyInfo(&spki);
2016 if (private_key != cert_key)
2017 hx509_private_key_free(&private_key);
2018 hx509_private_key_free(&cert_key);
2020 hx509_ca_tbs_free(&tbs);
2026 test_one_cert(hx509_context hxcontext, void *ctx, hx509_cert cert)
2028 heim_octet_string sd, c;
2029 hx509_verify_ctx vctx = ctx;
2030 hx509_certs signer = NULL;
2034 if (_hx509_cert_private_key(cert) == NULL)
2037 ret = hx509_cms_create_signed_1(context, 0, NULL, NULL, 0,
2038 NULL, cert, NULL, NULL, NULL, &sd);
2040 errx(1, "hx509_cms_create_signed_1");
2042 ret = hx509_cms_verify_signed(context, vctx, 0, sd.data, sd.length,
2043 NULL, NULL, &type, &c, &signer);
2046 hx509_err(context, 1, ret, "hx509_cms_verify_signed");
2048 printf("create-signature verify-sigature done\n");
2056 test_crypto(struct test_crypto_options *opt, int argc, char ** argv)
2058 hx509_verify_ctx vctx;
2063 hx509_lock_init(context, &lock);
2064 lock_strings(lock, &opt->pass_strings);
2066 ret = hx509_certs_init(context, "MEMORY:test-crypto", 0, NULL, &certs);
2067 if (ret) hx509_err(context, 1, ret, "hx509_certs_init: MEMORY");
2069 for (i = 0; i < argc; i++) {
2070 ret = hx509_certs_append(context, certs, lock, argv[i]);
2072 hx509_err(context, 1, ret, "hx509_certs_append");
2075 ret = hx509_verify_init_ctx(context, &vctx);
2077 hx509_err(context, 1, ret, "hx509_verify_init_ctx");
2079 hx509_verify_attach_anchors(vctx, certs);
2081 ret = hx509_certs_iter_f(context, certs, test_one_cert, vctx);
2083 hx509_err(context, 1, ret, "hx509_cert_iter");
2085 hx509_certs_free(&certs);
2091 statistic_print(struct statistic_print_options*opt, int argc, char **argv)
2095 if (stat_file_string == NULL)
2096 errx(1, "no stat file");
2098 if (opt->type_integer)
2099 type = opt->type_integer;
2101 hx509_query_unparse_stats(context, type, stdout);
2110 crl_sign(struct crl_sign_options *opt, int argc, char **argv)
2113 heim_octet_string os;
2114 hx509_cert signer = NULL;
2118 hx509_lock_init(context, &lock);
2119 lock_strings(lock, &opt->pass_strings);
2121 ret = hx509_crl_alloc(context, &crl);
2123 errx(1, "crl alloc");
2125 if (opt->signer_string == NULL)
2126 errx(1, "signer missing");
2129 hx509_certs certs = NULL;
2132 ret = hx509_certs_init(context, opt->signer_string, 0,
2135 hx509_err(context, 1, ret,
2136 "hx509_certs_init: %s", opt->signer_string);
2138 ret = hx509_query_alloc(context, &q);
2140 hx509_err(context, 1, ret, "hx509_query_alloc: %d", ret);
2142 hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
2144 ret = hx509_certs_find(context, certs, q, &signer);
2145 hx509_query_free(context, q);
2146 hx509_certs_free(&certs);
2148 hx509_err(context, 1, ret, "no signer certificate found");
2151 if (opt->lifetime_string) {
2154 delta = parse_time(opt->lifetime_string, "day");
2156 errx(1, "Invalid lifetime: %s", opt->lifetime_string);
2158 hx509_crl_lifetime(context, crl, delta);
2162 hx509_certs revoked = NULL;
2165 ret = hx509_certs_init(context, "MEMORY:revoked-certs", 0,
2168 hx509_err(context, 1, ret,
2169 "hx509_certs_init: MEMORY cert");
2171 for (i = 0; i < argc; i++) {
2172 ret = hx509_certs_append(context, revoked, lock, argv[i]);
2174 hx509_err(context, 1, ret, "hx509_certs_append: %s", argv[i]);
2177 hx509_crl_add_revoked_certs(context, crl, revoked);
2178 hx509_certs_free(&revoked);
2181 hx509_crl_sign(context, signer, crl, &os);
2183 if (opt->crl_file_string)
2184 rk_dumpdata(opt->crl_file_string, os.data, os.length);
2188 hx509_crl_free(context, &crl);
2189 hx509_cert_free(signer);
2190 hx509_lock_free(lock);
2200 help(void *opt, int argc, char **argv)
2202 sl_slc_help(commands, argc, argv);
2207 main(int argc, char **argv)
2209 int ret, optidx = 0;
2211 setprogname (argv[0]);
2213 if(getarg(args, num_args, argc, argv, &optidx))
2218 print_version(NULL);
2227 ret = hx509_context_init(&context);
2229 errx(1, "hx509_context_init failed with %d", ret);
2231 if (stat_file_string)
2232 hx509_query_statistic_file(context, stat_file_string);
2234 ret = sl_command(commands, argc, argv);
2236 warnx ("unrecognized command: %s", argv[0]);
2238 hx509_context_free(&context);