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
37 #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
},
49 { "version", 0, arg_flag
, &version_flag
},
50 { "help", 0, arg_flag
, &help_flag
}
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 context
, 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(context
, certs
, lock
, s
->strings
[i
]);
91 hx509_err(context
, 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 context
,
118 hx509_peer_info
*peer
,
119 const getarg_strings
*s
)
121 AlgorithmIdentifier
*val
;
124 ret
= hx509_peer_info_alloc(context
, peer
);
126 hx509_err(context
, 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(context
, *peer
, val
, s
->num_strings
);
137 hx509_err(context
, 1, ret
, "hx509_peer_info_set_cms_algs");
139 for (i
= 0; i
< s
->num_strings
; i
++)
140 free_AlgorithmIdentifier(&val
[i
]);
149 pem_reader(hx509_context context
, const char *type
,
150 const hx509_pem_header
*headers
,
151 const void *data
, size_t length
, void *ctx
)
153 heim_octet_string
*c
= (heim_octet_string
*)ctx
;
155 c
->data
= malloc(length
);
158 memcpy(c
->data
, data
, length
);
169 cms_verify_sd(struct cms_verify_sd_options
*opt
, int argc
, char **argv
)
171 hx509_verify_ctx ctx
= NULL
;
173 heim_octet_string c
, co
, signeddata
, *sd
= NULL
;
174 hx509_certs store
= NULL
;
175 hx509_certs signers
= NULL
;
176 hx509_certs anchors
= NULL
;
183 if (opt
->missing_revoke_flag
)
184 hx509_context_set_missing_revoke(context
, 1);
186 hx509_lock_init(context
, &lock
);
187 lock_strings(lock
, &opt
->pass_strings
);
189 ret
= hx509_verify_init_ctx(context
, &ctx
);
191 ret
= hx509_certs_init(context
, "MEMORY:cms-anchors", 0, NULL
, &anchors
);
192 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &store
);
194 certs_strings(context
, "anchors", anchors
, lock
, &opt
->anchors_strings
);
195 certs_strings(context
, "store", store
, lock
, &opt
->certificate_strings
);
200 f
= fopen(argv
[0], "r");
202 err(1, "Failed to open file %s", argv
[0]);
204 ret
= hx509_pem_read(context
, f
, pem_reader
, &co
);
207 errx(1, "PEM reader failed: %d", ret
);
209 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
211 err(1, "map_file: %s: %d", argv
[0], ret
);
217 if (opt
->signed_content_string
) {
218 ret
= _hx509_map_file_os(opt
->signed_content_string
, &signeddata
, NULL
);
220 errx(1, "map_file: %s: %d", opt
->signed_content_string
, ret
);
224 if (opt
->content_info_flag
) {
225 heim_octet_string uwco
;
228 ret
= hx509_cms_unwrap_ContentInfo(&co
, &oid
, &uwco
, NULL
);
230 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret
);
232 if (der_heim_oid_cmp(&oid
, oid_id_pkcs7_signedData()) != 0)
233 errx(1, "Content is not SignedData");
239 hx509_verify_attach_anchors(ctx
, anchors
);
241 ret
= hx509_cms_verify_signed(context
, ctx
, co
.data
, co
.length
, sd
,
242 store
, &type
, &c
, &signers
);
244 der_free_octet_string(&co
);
246 hx509_err(context
, 1, ret
, "hx509_cms_verify_signed");
250 der_print_heim_oid(&type
, '.', &str
);
251 printf("type: %s\n", str
);
255 printf("signers:\n");
256 hx509_certs_iter(context
, signers
, hx509_ci_print_names
, stdout
);
258 hx509_verify_destroy_ctx(ctx
);
260 hx509_certs_free(&store
);
261 hx509_certs_free(&signers
);
262 hx509_certs_free(&anchors
);
264 hx509_lock_free(lock
);
266 ret
= _hx509_write_file(argv
[1], c
.data
, c
.length
);
268 errx(1, "hx509_write_file: %d", ret
);
270 der_free_octet_string(&c
);
272 der_free_octet_string(&co
);
274 _hx509_unmap_file(p
, sz
);
276 _hx509_unmap_file_os(sd
);
282 cms_create_sd(struct cms_create_sd_options
*opt
, int argc
, char **argv
)
284 heim_oid contentType
;
285 hx509_peer_info peer
= NULL
;
289 hx509_certs store
, pool
, anchors
;
294 char *signer_name
= NULL
;
296 memset(&contentType
, 0, sizeof(contentType
));
301 hx509_lock_init(context
, &lock
);
302 lock_strings(lock
, &opt
->pass_strings
);
304 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &store
);
305 ret
= hx509_certs_init(context
, "MEMORY:cert-pool", 0, NULL
, &pool
);
307 certs_strings(context
, "store", store
, lock
, &opt
->certificate_strings
);
308 certs_strings(context
, "pool", pool
, lock
, &opt
->pool_strings
);
310 if (opt
->anchors_strings
.num_strings
) {
311 ret
= hx509_certs_init(context
, "MEMORY:cert-anchors",
313 certs_strings(context
, "anchors", anchors
, lock
, &opt
->anchors_strings
);
317 if (opt
->detached_signature_flag
)
318 flags
|= HX509_CMS_SIGATURE_DETACHED
;
319 if (opt
->id_by_name_flag
)
320 flags
|= HX509_CMS_SIGATURE_ID_NAME
;
322 ret
= hx509_query_alloc(context
, &q
);
324 errx(1, "hx509_query_alloc: %d", ret
);
326 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
327 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE
);
329 if (opt
->signer_string
)
330 hx509_query_match_friendly_name(q
, opt
->signer_string
);
332 ret
= hx509_certs_find(context
, store
, q
, &cert
);
333 hx509_query_free(context
, q
);
335 hx509_err(context
, 1, ret
, "hx509_certs_find");
337 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
339 err(1, "map_file: %s: %d", argv
[0], ret
);
341 if (opt
->peer_alg_strings
.num_strings
)
342 peer_strings(context
, &peer
, &opt
->peer_alg_strings
);
344 parse_oid(opt
->content_type_string
, oid_id_pkcs7_data(), &contentType
);
346 ret
= hx509_cms_create_signed_1(context
,
358 errx(1, "hx509_cms_create_signed: %d", ret
);
363 ret
= hx509_cert_get_subject(cert
, &name
);
365 errx(1, "hx509_cert_get_subject");
367 ret
= hx509_name_to_string(name
, &signer_name
);
368 hx509_name_free(&name
);
370 errx(1, "hx509_name_to_string");
374 hx509_certs_free(&anchors
);
375 hx509_certs_free(&pool
);
376 hx509_cert_free(cert
);
377 hx509_certs_free(&store
);
378 _hx509_unmap_file(p
, sz
);
379 hx509_lock_free(lock
);
380 hx509_peer_info_free(peer
);
381 der_free_oid(&contentType
);
383 if (opt
->content_info_flag
) {
384 heim_octet_string wo
;
386 ret
= hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &o
, &wo
);
388 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret
);
390 der_free_octet_string(&o
);
395 hx509_pem_header
*header
= NULL
;
398 hx509_pem_add_header(&header
, "Content-disposition",
399 opt
->detached_signature_flag
?
400 "detached" : "inline");
401 hx509_pem_add_header(&header
, "Signer", signer_name
);
403 f
= fopen(argv
[1], "w");
405 err(1, "open %s", argv
[1]);
407 ret
= hx509_pem_write(context
, "CMS SIGNEDDATA", header
, f
,
410 hx509_pem_free_header(header
);
412 errx(1, "hx509_pem_write: %d", ret
);
415 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
417 errx(1, "hx509_write_file: %d", ret
);
427 cms_unenvelope(struct cms_unenvelope_options
*opt
, int argc
, char **argv
)
429 heim_oid contentType
= { 0, NULL
};
430 heim_octet_string o
, co
;
437 hx509_lock_init(context
, &lock
);
438 lock_strings(lock
, &opt
->pass_strings
);
440 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
442 err(1, "map_file: %s: %d", argv
[0], ret
);
447 if (opt
->content_info_flag
) {
448 heim_octet_string uwco
;
451 ret
= hx509_cms_unwrap_ContentInfo(&co
, &oid
, &uwco
, NULL
);
453 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret
);
455 if (der_heim_oid_cmp(&oid
, oid_id_pkcs7_envelopedData()) != 0)
456 errx(1, "Content is not SignedData");
462 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
464 errx(1, "hx509_certs_init: MEMORY: %d", ret
);
466 certs_strings(context
, "store", certs
, lock
, &opt
->certificate_strings
);
468 ret
= hx509_cms_unenvelope(context
, certs
, 0, co
.data
, co
.length
,
469 NULL
, &contentType
, &o
);
471 der_free_octet_string(&co
);
473 hx509_err(context
, 1, ret
, "hx509_cms_unenvelope");
475 _hx509_unmap_file(p
, sz
);
476 hx509_lock_free(lock
);
477 hx509_certs_free(&certs
);
478 der_free_oid(&contentType
);
480 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
482 errx(1, "hx509_write_file: %d", ret
);
484 der_free_octet_string(&o
);
490 cms_create_enveloped(struct cms_envelope_options
*opt
, int argc
, char **argv
)
492 heim_oid contentType
;
494 const heim_oid
*enctype
= NULL
;
503 memset(&contentType
, 0, sizeof(contentType
));
505 hx509_lock_init(context
, &lock
);
506 lock_strings(lock
, &opt
->pass_strings
);
508 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
510 err(1, "map_file: %s: %d", argv
[0], ret
);
512 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
514 certs_strings(context
, "store", certs
, lock
, &opt
->certificate_strings
);
516 if (opt
->encryption_type_string
) {
517 enctype
= hx509_crypto_enctype_by_name(opt
->encryption_type_string
);
519 errx(1, "encryption type: %s no found",
520 opt
->encryption_type_string
);
523 ret
= hx509_query_alloc(context
, &q
);
525 errx(1, "hx509_query_alloc: %d", ret
);
527 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_ENCIPHERMENT
);
529 ret
= hx509_certs_find(context
, certs
, q
, &cert
);
530 hx509_query_free(context
, q
);
532 errx(1, "hx509_certs_find: %d", ret
);
534 parse_oid(opt
->content_type_string
, oid_id_pkcs7_data(), &contentType
);
536 ret
= hx509_cms_envelope_1(context
, 0, cert
, p
, sz
, enctype
,
539 errx(1, "hx509_cms_envelope_1: %d", ret
);
541 hx509_cert_free(cert
);
542 hx509_certs_free(&certs
);
543 _hx509_unmap_file(p
, sz
);
544 der_free_oid(&contentType
);
546 if (opt
->content_info_flag
) {
547 heim_octet_string wo
;
549 ret
= hx509_cms_wrap_ContentInfo(oid_id_pkcs7_envelopedData(), &o
, &wo
);
551 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret
);
553 der_free_octet_string(&o
);
557 hx509_lock_free(lock
);
559 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
561 errx(1, "hx509_write_file: %d", ret
);
563 der_free_octet_string(&o
);
569 print_certificate(hx509_context hxcontext
, hx509_cert cert
, int verbose
)
576 fn
= hx509_cert_get_friendly_name(cert
);
578 printf(" friendly name: %s\n", fn
);
579 printf(" private key: %s\n",
580 _hx509_cert_private_key(cert
) ? "yes" : "no");
582 ret
= hx509_cert_get_issuer(cert
, &name
);
583 hx509_name_to_string(name
, &str
);
584 hx509_name_free(&name
);
585 printf(" issuer: \"%s\"\n", str
);
588 ret
= hx509_cert_get_subject(cert
, &name
);
589 hx509_name_to_string(name
, &str
);
590 hx509_name_free(&name
);
591 printf(" subject: \"%s\"\n", str
);
595 heim_integer serialNumber
;
597 hx509_cert_get_serialnumber(cert
, &serialNumber
);
598 der_print_hex_heim_integer(&serialNumber
, &str
);
599 der_free_heim_integer(&serialNumber
);
600 printf(" serial: %s\n", str
);
604 printf(" keyusage: ");
605 ret
= hx509_cert_keyusage_print(hxcontext
, cert
, &str
);
613 hx509_validate_ctx vctx
;
615 hx509_validate_ctx_init(hxcontext
, &vctx
);
616 hx509_validate_ctx_set_print(vctx
, hx509_print_stdout
, stdout
);
617 hx509_validate_ctx_add_flags(vctx
, HX509_VALIDATE_F_VALIDATE
);
618 hx509_validate_ctx_add_flags(vctx
, HX509_VALIDATE_F_VERBOSE
);
620 hx509_validate_cert(hxcontext
, vctx
, cert
);
622 hx509_validate_ctx_free(vctx
);
633 print_f(hx509_context hxcontext
, void *ctx
, hx509_cert cert
)
635 struct print_s
*s
= ctx
;
637 printf("cert: %d\n", s
->counter
++);
638 print_certificate(context
, cert
, s
->verbose
);
644 pcert_print(struct print_options
*opt
, int argc
, char **argv
)
651 s
.verbose
= opt
->content_flag
;
653 hx509_lock_init(context
, &lock
);
654 lock_strings(lock
, &opt
->pass_strings
);
658 ret
= hx509_certs_init(context
, argv
[0], 0, lock
, &certs
);
660 hx509_err(context
, 1, ret
, "hx509_certs_init");
662 hx509_certs_info(context
, certs
, NULL
, NULL
);
663 hx509_certs_iter(context
, certs
, print_f
, &s
);
664 hx509_certs_free(&certs
);
668 hx509_lock_free(lock
);
675 validate_f(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
677 hx509_validate_cert(hxcontext
, ctx
, c
);
682 pcert_validate(struct validate_options
*opt
, int argc
, char **argv
)
684 hx509_validate_ctx ctx
;
688 hx509_lock_init(context
, &lock
);
689 lock_strings(lock
, &opt
->pass_strings
);
691 hx509_validate_ctx_init(context
, &ctx
);
692 hx509_validate_ctx_set_print(ctx
, hx509_print_stdout
, stdout
);
693 hx509_validate_ctx_add_flags(ctx
, HX509_VALIDATE_F_VALIDATE
);
697 ret
= hx509_certs_init(context
, argv
[0], 0, lock
, &certs
);
699 errx(1, "hx509_certs_init: %d", ret
);
700 hx509_certs_iter(context
, certs
, validate_f
, ctx
);
701 hx509_certs_free(&certs
);
704 hx509_validate_ctx_free(ctx
);
706 hx509_lock_free(lock
);
712 certificate_copy(struct certificate_copy_options
*opt
, int argc
, char **argv
)
718 hx509_lock_init(context
, &lock
);
719 lock_strings(lock
, &opt
->in_pass_strings
);
721 ret
= hx509_certs_init(context
, argv
[argc
- 1],
722 HX509_CERTS_CREATE
, lock
, &certs
);
724 hx509_err(context
, 1, ret
, "hx509_certs_init");
728 ret
= hx509_certs_append(context
, certs
, lock
, argv
[0]);
730 hx509_err(context
, 1, ret
, "hx509_certs_append");
734 ret
= hx509_certs_store(context
, certs
, 0, NULL
);
736 hx509_err(context
, 1, ret
, "hx509_certs_store");
738 hx509_certs_free(&certs
);
739 hx509_lock_free(lock
);
745 hx509_verify_ctx ctx
;
747 const char *hostname
;
752 verify_f(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
754 struct verify
*v
= ctx
;
757 ret
= hx509_verify_path(hxcontext
, v
->ctx
, c
, v
->chain
);
759 char *s
= hx509_get_error_string(hxcontext
, ret
);
760 printf("verify_path: %s: %d\n", s
, ret
);
761 hx509_free_error_string(s
);
767 ret
= hx509_verify_hostname(hxcontext
, c
, 0, HX509_HN_HOSTNAME
,
768 v
->hostname
, NULL
, 0);
770 printf("verify_hostname: %d\n", ret
);
779 pcert_verify(struct verify_options
*opt
, int argc
, char **argv
)
781 hx509_certs anchors
, chain
, certs
;
782 hx509_revoke_ctx revoke_ctx
;
783 hx509_verify_ctx ctx
;
787 memset(&v
, 0, sizeof(v
));
789 if (opt
->missing_revoke_flag
)
790 hx509_context_set_missing_revoke(context
, 1);
792 ret
= hx509_verify_init_ctx(context
, &ctx
);
793 ret
= hx509_certs_init(context
, "MEMORY:anchors", 0, NULL
, &anchors
);
794 ret
= hx509_certs_init(context
, "MEMORY:chain", 0, NULL
, &chain
);
795 ret
= hx509_certs_init(context
, "MEMORY:certs", 0, NULL
, &certs
);
797 if (opt
->allow_proxy_certificate_flag
)
798 hx509_verify_set_proxy_certificate(ctx
, 1);
800 if (opt
->time_string
) {
805 memset(&tm
, 0, sizeof(tm
));
807 p
= strptime (opt
->time_string
, "%Y-%m-%d", &tm
);
809 errx(1, "Failed to parse time %s, need to be on format %%Y-%%m-%%d",
814 hx509_verify_set_time(ctx
, t
);
817 if (opt
->hostname_string
)
818 v
.hostname
= opt
->hostname_string
;
819 if (opt
->max_depth_integer
)
820 hx509_verify_set_max_depth(ctx
, opt
->max_depth_integer
);
822 ret
= hx509_revoke_init(context
, &revoke_ctx
);
824 errx(1, "hx509_revoke_init: %d", ret
);
829 if (strncmp(s
, "chain:", 6) == 0) {
832 ret
= hx509_certs_append(context
, chain
, NULL
, s
);
834 hx509_err(context
, 1, ret
, "hx509_certs_append: chain: %s: %d", s
, ret
);
836 } else if (strncmp(s
, "anchor:", 7) == 0) {
839 ret
= hx509_certs_append(context
, anchors
, NULL
, s
);
841 hx509_err(context
, 1, ret
, "hx509_certs_append: anchor: %s: %d", s
, ret
);
843 } else if (strncmp(s
, "cert:", 5) == 0) {
846 ret
= hx509_certs_append(context
, certs
, NULL
, s
);
848 hx509_err(context
, 1, ret
, "hx509_certs_append: certs: %s: %d",
851 } else if (strncmp(s
, "crl:", 4) == 0) {
854 ret
= hx509_revoke_add_crl(context
, revoke_ctx
, s
);
856 errx(1, "hx509_revoke_add_crl: %s: %d", s
, ret
);
858 } else if (strncmp(s
, "ocsp:", 4) == 0) {
861 ret
= hx509_revoke_add_ocsp(context
, revoke_ctx
, s
);
863 errx(1, "hx509_revoke_add_ocsp: %s: %d", s
, ret
);
866 errx(1, "unknown option to verify: `%s'\n", s
);
870 hx509_verify_attach_anchors(ctx
, anchors
);
871 hx509_verify_attach_revoke(ctx
, revoke_ctx
);
876 hx509_certs_iter(context
, certs
, verify_f
, &v
);
878 hx509_verify_destroy_ctx(ctx
);
880 hx509_certs_free(&certs
);
881 hx509_certs_free(&chain
);
882 hx509_certs_free(&anchors
);
884 hx509_revoke_free(&revoke_ctx
);
887 printf("failed verifing %d checks\n", v
.errors
);
895 query(struct query_options
*opt
, int argc
, char **argv
)
903 ret
= hx509_query_alloc(context
, &q
);
905 errx(1, "hx509_query_alloc: %d", ret
);
907 hx509_lock_init(context
, &lock
);
908 lock_strings(lock
, &opt
->pass_strings
);
910 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
914 ret
= hx509_certs_append(context
, certs
, lock
, argv
[0]);
916 errx(1, "hx509_certs_append: %s: %d", argv
[0], ret
);
922 if (opt
->friendlyname_string
)
923 hx509_query_match_friendly_name(q
, opt
->friendlyname_string
);
925 if (opt
->eku_string
) {
928 parse_oid(opt
->eku_string
, NULL
, &oid
);
930 ret
= hx509_query_match_eku(q
, &oid
);
932 errx(1, "hx509_query_match_eku: %d", ret
);
936 if (opt
->private_key_flag
)
937 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
939 if (opt
->keyEncipherment_flag
)
940 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_ENCIPHERMENT
);
942 if (opt
->digitalSignature_flag
)
943 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE
);
945 if (opt
->expr_string
)
946 hx509_query_match_expr(context
, q
, opt
->expr_string
);
948 ret
= hx509_certs_find(context
, certs
, q
, &c
);
949 hx509_query_free(context
, q
);
951 printf("no match found (%d)\n", ret
);
953 printf("match found\n");
955 print_certificate(context
, c
, 0);
959 hx509_certs_free(&certs
);
961 hx509_lock_free(lock
);
967 ocsp_fetch(struct ocsp_fetch_options
*opt
, int argc
, char **argv
)
969 hx509_certs reqcerts
, pool
;
970 heim_octet_string req
, nonce_data
, *nonce
= &nonce_data
;
974 const char *url
= "/";
976 memset(&nonce
, 0, sizeof(nonce
));
978 hx509_lock_init(context
, &lock
);
979 lock_strings(lock
, &opt
->pass_strings
);
982 if (!opt
->nonce_flag
)
985 if (opt
->url_path_string
)
986 url
= opt
->url_path_string
;
988 ret
= hx509_certs_init(context
, "MEMORY:ocsp-pool", 0, NULL
, &pool
);
990 certs_strings(context
, "ocsp-pool", pool
, lock
, &opt
->pool_strings
);
994 ret
= hx509_certs_init(context
, "MEMORY:ocsp-req", 0, NULL
, &reqcerts
);
996 for (i
= 1; i
< argc
; i
++) {
997 ret
= hx509_certs_append(context
, reqcerts
, lock
, argv
[i
]);
999 errx(1, "hx509_certs_append: req: %s: %d", argv
[i
], ret
);
1002 ret
= hx509_ocsp_request(context
, reqcerts
, pool
, NULL
, NULL
, &req
, nonce
);
1004 errx(1, "hx509_ocsp_request: req: %d", ret
);
1009 f
= fopen(file
, "w");
1014 "POST %s HTTP/1.0\r\n"
1015 "Content-Type: application/ocsp-request\r\n"
1016 "Content-Length: %ld\r\n"
1019 (unsigned long)req
.length
);
1020 fwrite(req
.data
, req
.length
, 1, f
);
1025 der_free_octet_string(nonce
);
1027 hx509_certs_free(&reqcerts
);
1028 hx509_certs_free(&pool
);
1034 ocsp_print(struct ocsp_print_options
*opt
, int argc
, char **argv
)
1036 hx509_revoke_ocsp_print(context
, argv
[0], stdout
);
1045 verify_o(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
1047 heim_octet_string
*os
= ctx
;
1051 ret
= hx509_ocsp_verify(context
, 0, c
, 0,
1052 os
->data
, os
->length
, &expiration
);
1054 char *s
= hx509_get_error_string(hxcontext
, ret
);
1055 printf("ocsp_verify: %s: %d\n", s
, ret
);
1056 hx509_free_error_string(s
);
1058 printf("expire: %d\n", (int)expiration
);
1065 ocsp_verify(struct ocsp_verify_options
*opt
, int argc
, char **argv
)
1070 heim_octet_string os
;
1072 hx509_lock_init(context
, &lock
);
1074 if (opt
->ocsp_file_string
== NULL
)
1075 errx(1, "no ocsp file given");
1077 ret
= _hx509_map_file(opt
->ocsp_file_string
, &os
.data
, &os
.length
, NULL
);
1079 err(1, "map_file: %s: %d", argv
[0], ret
);
1081 ret
= hx509_certs_init(context
, "MEMORY:test-certs", 0, NULL
, &certs
);
1083 for (i
= 0; i
< argc
; i
++) {
1084 ret
= hx509_certs_append(context
, certs
, lock
, argv
[i
]);
1086 hx509_err(context
, 1, ret
, "hx509_certs_append: %s", argv
[i
]);
1089 ret
= hx509_certs_iter(context
, certs
, verify_o
, &os
);
1091 hx509_certs_free(&certs
);
1092 _hx509_unmap_file(os
.data
, os
.length
);
1093 hx509_lock_free(lock
);
1099 read_private_key(const char *fn
, hx509_private_key
*key
)
1101 hx509_private_key
*keys
;
1107 ret
= hx509_certs_init(context
, fn
, 0, NULL
, &certs
);
1109 hx509_err(context
, 1, ret
, "hx509_certs_init: %s", fn
);
1111 ret
= _hx509_certs_keys_get(context
, certs
, &keys
);
1112 hx509_certs_free(&certs
);
1114 hx509_err(context
, 1, ret
, "hx509_certs_keys_get");
1115 if (keys
[0] == NULL
)
1116 errx(1, "no keys in key store: %s", fn
);
1118 *key
= _hx509_private_key_ref(keys
[0]);
1119 _hx509_certs_keys_free(context
, keys
);
1125 get_key(const char *fn
, const char *type
, int optbits
,
1126 hx509_private_key
*signer
)
1133 unsigned char *p0
, *p
;
1138 errx(1, "no key argument, don't know here to store key");
1140 if (strcasecmp(type
, "rsa") != 0)
1141 errx(1, "can only handle rsa keys for now");
1144 BN_set_word(e
, 0x10001);
1151 errx(1, "RSA_new failed");
1153 ret
= RSA_generate_key_ex(rsa
, bits
, e
, NULL
);
1155 errx(1, "RSA_new failed");
1159 len
= i2d_RSAPrivateKey(rsa
, NULL
);
1161 p0
= p
= malloc(len
);
1163 errx(1, "out of memory");
1165 i2d_RSAPrivateKey(rsa
, &p
);
1167 rk_dumpdata(fn
, p0
, len
);
1173 } else if (fn
== NULL
)
1174 err(1, "no private key");
1176 ret
= read_private_key(fn
, signer
);
1178 err(1, "read_private_key");
1182 request_create(struct request_create_options
*opt
, int argc
, char **argv
)
1184 heim_octet_string request
;
1187 hx509_private_key signer
;
1188 SubjectPublicKeyInfo key
;
1189 const char *outfile
= argv
[0];
1191 memset(&key
, 0, sizeof(key
));
1193 get_key(opt
->key_string
,
1194 opt
->generate_key_string
,
1195 opt
->key_bits_integer
,
1198 _hx509_request_init(context
, &req
);
1200 if (opt
->subject_string
) {
1201 hx509_name name
= NULL
;
1203 ret
= hx509_parse_name(context
, opt
->subject_string
, &name
);
1205 errx(1, "hx509_parse_name: %d\n", ret
);
1206 _hx509_request_set_name(context
, req
, name
);
1208 if (opt
->verbose_flag
) {
1210 hx509_name_to_string(name
, &s
);
1213 hx509_name_free(&name
);
1216 for (i
= 0; i
< opt
->email_strings
.num_strings
; i
++) {
1217 ret
= _hx509_request_add_email(context
, req
,
1218 opt
->email_strings
.strings
[i
]);
1221 for (i
= 0; i
< opt
->dnsname_strings
.num_strings
; i
++) {
1222 ret
= _hx509_request_add_dns_name(context
, req
,
1223 opt
->dnsname_strings
.strings
[i
]);
1227 ret
= _hx509_private_key2SPKI(context
, signer
, &key
);
1229 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1231 ret
= _hx509_request_set_SubjectPublicKeyInfo(context
,
1234 free_SubjectPublicKeyInfo(&key
);
1236 hx509_err(context
, 1, ret
, "_hx509_request_set_SubjectPublicKeyInfo");
1238 ret
= _hx509_request_to_pkcs10(context
,
1243 hx509_err(context
, 1, ret
, "_hx509_request_to_pkcs10");
1245 _hx509_private_key_free(&signer
);
1246 _hx509_request_free(&req
);
1249 rk_dumpdata(outfile
, request
.data
, request
.length
);
1250 der_free_octet_string(&request
);
1256 request_print(struct request_print_options
*opt
, int argc
, char **argv
)
1260 printf("request print\n");
1262 for (i
= 0; i
< argc
; i
++) {
1265 ret
= _hx509_request_parse(context
, argv
[i
], &req
);
1267 hx509_err(context
, 1, ret
, "parse_request: %s", argv
[i
]);
1269 ret
= _hx509_request_print(context
, req
, stdout
);
1270 _hx509_request_free(&req
);
1272 hx509_err(context
, 1, ret
, "Failed to print file %s", argv
[i
]);
1279 info(void *opt
, int argc
, char **argv
)
1282 ENGINE_add_conf_module();
1285 const RSA_METHOD
*m
= RSA_get_default_method();
1287 printf("rsa: %s\n", m
->name
);
1290 const DH_METHOD
*m
= DH_get_default_method();
1292 printf("dh: %s\n", m
->name
);
1295 int ret
= RAND_status();
1296 printf("rand: %s\n", ret
== 1 ? "ok" : "not available");
1303 random_data(void *opt
, int argc
, char **argv
)
1308 len
= parse_bytes(argv
[0], "byte");
1310 fprintf(stderr
, "bad argument to random-data\n");
1316 fprintf(stderr
, "out of memory\n");
1320 ret
= RAND_bytes(ptr
, len
);
1323 fprintf(stderr
, "did not get cryptographic strong random\n");
1327 fwrite(ptr
, len
, 1, stdout
);
1336 crypto_available(struct crypto_available_options
*opt
, int argc
, char **argv
)
1338 AlgorithmIdentifier
*val
;
1339 unsigned int len
, i
;
1342 if (opt
->type_string
) {
1343 if (strcmp(opt
->type_string
, "all") == 0)
1344 type
= HX509_SELECT_ALL
;
1345 else if (strcmp(opt
->type_string
, "digest") == 0)
1346 type
= HX509_SELECT_DIGEST
;
1347 else if (strcmp(opt
->type_string
, "public-sig") == 0)
1348 type
= HX509_SELECT_PUBLIC_SIG
;
1349 else if (strcmp(opt
->type_string
, "secret") == 0)
1350 type
= HX509_SELECT_SECRET_ENC
;
1352 errx(1, "unknown type: %s", opt
->type_string
);
1354 type
= HX509_SELECT_ALL
;
1356 ret
= hx509_crypto_available(context
, type
, NULL
, &val
, &len
);
1358 errx(1, "hx509_crypto_available");
1360 for (i
= 0; i
< len
; i
++) {
1362 der_print_heim_oid (&val
[i
].algorithm
, '.', &s
);
1367 hx509_crypto_free_algs(val
, len
);
1373 crypto_select(struct crypto_select_options
*opt
, int argc
, char **argv
)
1375 hx509_peer_info peer
= NULL
;
1376 AlgorithmIdentifier selected
;
1380 if (opt
->type_string
) {
1381 if (strcmp(opt
->type_string
, "digest") == 0)
1382 type
= HX509_SELECT_DIGEST
;
1383 else if (strcmp(opt
->type_string
, "public-sig") == 0)
1384 type
= HX509_SELECT_PUBLIC_SIG
;
1385 else if (strcmp(opt
->type_string
, "secret") == 0)
1386 type
= HX509_SELECT_SECRET_ENC
;
1388 errx(1, "unknown type: %s", opt
->type_string
);
1390 type
= HX509_SELECT_DIGEST
;
1392 if (opt
->peer_cmstype_strings
.num_strings
)
1393 peer_strings(context
, &peer
, &opt
->peer_cmstype_strings
);
1395 ret
= hx509_crypto_select(context
, type
, NULL
, peer
, &selected
);
1397 errx(1, "hx509_crypto_available");
1399 der_print_heim_oid (&selected
.algorithm
, '.', &s
);
1402 free_AlgorithmIdentifier(&selected
);
1404 hx509_peer_info_free(peer
);
1410 hxtool_hex(struct hex_options
*opt
, int argc
, char **argv
)
1413 if (opt
->decode_flag
) {
1414 char buf
[1024], buf2
[1024], *p
;
1417 while(fgets(buf
, sizeof(buf
), stdin
) != NULL
) {
1418 buf
[strcspn(buf
, "\r\n")] = '\0';
1420 while(isspace(*(unsigned char *)p
))
1422 len
= hex_decode(p
, buf2
, strlen(p
));
1424 errx(1, "hex_decode failed");
1425 if (fwrite(buf2
, 1, len
, stdout
) != len
)
1426 errx(1, "fwrite failed");
1432 while((len
= fread(buf
, 1, sizeof(buf
), stdin
)) != 0) {
1433 len
= hex_encode(buf
, len
, &p
);
1434 fprintf(stdout
, "%s\n", p
);
1442 eval_types(hx509_context context
,
1444 const struct certificate_sign_options
*opt
)
1449 for (i
= 0; i
< opt
->type_strings
.num_strings
; i
++) {
1450 const char *type
= opt
->type_strings
.strings
[i
];
1452 if (strcmp(type
, "https-server") == 0) {
1453 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1454 oid_id_pkix_kp_serverAuth());
1456 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1457 } else if (strcmp(type
, "https-client") == 0) {
1458 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1459 oid_id_pkix_kp_clientAuth());
1461 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1462 } else if (strcmp(type
, "peap-server") == 0) {
1463 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1464 oid_id_pkix_kp_serverAuth());
1466 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1467 } else if (strcmp(type
, "pkinit-kdc") == 0) {
1469 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1470 oid_id_pkkdcekuoid());
1472 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1473 } else if (strcmp(type
, "pkinit-client") == 0) {
1475 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1478 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1480 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1481 oid_id_ms_client_authentication());
1483 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1485 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1486 oid_id_pkinit_ms_eku());
1488 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1490 } else if (strcmp(type
, "email") == 0) {
1491 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1492 oid_id_pkix_kp_emailProtection());
1494 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1496 errx(1, "unknown type %s", type
);
1500 errx(1, "More the one PK-INIT type given");
1502 if (opt
->pk_init_principal_string
) {
1504 errx(1, "pk-init principal given but no pk-init oid");
1506 ret
= hx509_ca_tbs_add_san_pkinit(context
, tbs
,
1507 opt
->pk_init_principal_string
);
1509 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_pkinit");
1512 if (opt
->ms_upn_string
) {
1514 errx(1, "MS up given but no pk-init oid");
1516 ret
= hx509_ca_tbs_add_san_ms_upn(context
, tbs
, opt
->ms_upn_string
);
1518 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_ms_upn");
1522 for (i
= 0; i
< opt
->hostname_strings
.num_strings
; i
++) {
1523 const char *hostname
= opt
->hostname_strings
.strings
[i
];
1525 ret
= hx509_ca_tbs_add_san_hostname(context
, tbs
, hostname
);
1527 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_hostname");
1530 for (i
= 0; i
< opt
->email_strings
.num_strings
; i
++) {
1531 const char *email
= opt
->email_strings
.strings
[i
];
1533 ret
= hx509_ca_tbs_add_san_rfc822name(context
, tbs
, email
);
1535 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_hostname");
1537 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1538 oid_id_pkix_kp_emailProtection());
1540 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1543 if (opt
->jid_string
) {
1544 ret
= hx509_ca_tbs_add_san_jid(context
, tbs
, opt
->jid_string
);
1546 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_jid");
1553 hxtool_ca(struct certificate_sign_options
*opt
, int argc
, char **argv
)
1557 hx509_cert signer
= NULL
, cert
= NULL
;
1558 hx509_private_key private_key
= NULL
;
1559 hx509_private_key cert_key
= NULL
;
1560 hx509_name subject
= NULL
;
1561 SubjectPublicKeyInfo spki
;
1564 memset(&spki
, 0, sizeof(spki
));
1566 if (opt
->ca_certificate_string
== NULL
&& !opt
->self_signed_flag
)
1567 errx(1, "--ca-certificate argument missing (not using --self-signed)");
1568 if (opt
->ca_private_key_string
== NULL
&& opt
->generate_key_string
== NULL
&& opt
->self_signed_flag
)
1569 errx(1, "--ca-private-key argument missing (using --self-signed)");
1570 if (opt
->certificate_string
== NULL
)
1571 errx(1, "--certificate argument missing");
1573 if (opt
->template_certificate_string
) {
1574 if (opt
->template_fields_string
== NULL
)
1575 errx(1, "--template-certificate not no --template-fields");
1578 if (opt
->lifetime_string
) {
1579 delta
= parse_time(opt
->lifetime_string
, "day");
1581 errx(1, "Invalid lifetime: %s", opt
->lifetime_string
);
1584 if (opt
->ca_certificate_string
) {
1585 hx509_certs cacerts
= NULL
;
1588 ret
= hx509_certs_init(context
, opt
->ca_certificate_string
, 0,
1591 hx509_err(context
, 1, ret
,
1592 "hx509_certs_init: %s", opt
->ca_certificate_string
);
1594 ret
= hx509_query_alloc(context
, &q
);
1596 errx(1, "hx509_query_alloc: %d", ret
);
1598 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
1599 if (!opt
->issue_proxy_flag
)
1600 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_KEYCERTSIGN
);
1602 ret
= hx509_certs_find(context
, cacerts
, q
, &signer
);
1603 hx509_query_free(context
, q
);
1604 hx509_certs_free(&cacerts
);
1606 hx509_err(context
, 1, ret
, "no CA certificate found");
1607 } else if (opt
->self_signed_flag
) {
1608 if (opt
->generate_key_string
== NULL
1609 && opt
->ca_private_key_string
== NULL
)
1610 errx(1, "no signing private key");
1612 errx(1, "missing ca key");
1614 if (opt
->ca_private_key_string
) {
1616 ret
= read_private_key(opt
->ca_private_key_string
, &private_key
);
1618 err(1, "read_private_key");
1620 ret
= _hx509_private_key2SPKI(context
, private_key
, &spki
);
1622 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1624 if (opt
->self_signed_flag
)
1625 cert_key
= private_key
;
1628 if (opt
->req_string
) {
1631 ret
= _hx509_request_parse(context
, opt
->req_string
, &req
);
1633 hx509_err(context
, 1, ret
, "parse_request: %s", opt
->req_string
);
1634 ret
= _hx509_request_get_name(context
, req
, &subject
);
1636 hx509_err(context
, 1, ret
, "get name");
1637 ret
= _hx509_request_get_SubjectPublicKeyInfo(context
, req
, &spki
);
1639 hx509_err(context
, 1, ret
, "get spki");
1640 _hx509_request_free(&req
);
1643 if (opt
->generate_key_string
) {
1644 struct hx509_generate_private_context
*keyctx
;
1646 ret
= _hx509_generate_private_key_init(context
,
1647 oid_id_pkcs1_rsaEncryption(),
1650 if (opt
->issue_ca_flag
)
1651 _hx509_generate_private_key_is_ca(context
, keyctx
);
1653 if (opt
->key_bits_integer
)
1654 _hx509_generate_private_key_bits(context
, keyctx
,
1655 opt
->key_bits_integer
);
1657 ret
= _hx509_generate_private_key(context
, keyctx
,
1659 _hx509_generate_private_key_free(&keyctx
);
1661 hx509_err(context
, 1, ret
, "generate private key");
1663 ret
= _hx509_private_key2SPKI(context
, cert_key
, &spki
);
1665 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1667 if (opt
->self_signed_flag
)
1668 private_key
= cert_key
;
1671 if (opt
->certificate_private_key_string
) {
1672 ret
= read_private_key(opt
->certificate_private_key_string
, &cert_key
);
1674 err(1, "read_private_key for certificate");
1677 if (opt
->subject_string
) {
1679 hx509_name_free(&subject
);
1680 ret
= hx509_parse_name(context
, opt
->subject_string
, &subject
);
1682 hx509_err(context
, 1, ret
, "hx509_parse_name");
1689 ret
= hx509_ca_tbs_init(context
, &tbs
);
1691 hx509_err(context
, 1, ret
, "hx509_ca_tbs_init");
1693 if (opt
->template_certificate_string
) {
1694 hx509_cert
template;
1698 ret
= hx509_certs_init(context
, opt
->template_certificate_string
, 0,
1701 hx509_err(context
, 1, ret
,
1702 "hx509_certs_init: %s", opt
->template_certificate_string
);
1704 ret
= hx509_get_one_cert(context
, tcerts
, &template);
1706 hx509_certs_free(&tcerts
);
1708 hx509_err(context
, 1, ret
, "no template certificate found");
1710 flags
= parse_units(opt
->template_fields_string
,
1711 hx509_ca_tbs_template_units(), "");
1713 ret
= hx509_ca_tbs_set_template(context
, tbs
, flags
, template);
1715 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_template");
1717 hx509_cert_free(template);
1720 if (opt
->serial_number_string
) {
1721 heim_integer serialNumber
;
1723 ret
= der_parse_hex_heim_integer(opt
->serial_number_string
,
1726 err(1, "der_parse_hex_heim_integer");
1727 ret
= hx509_ca_tbs_set_serialnumber(context
, tbs
, &serialNumber
);
1729 hx509_err(context
, 1, ret
, "hx509_ca_tbs_init");
1730 der_free_heim_integer(&serialNumber
);
1733 if (spki
.subjectPublicKey
.length
) {
1734 ret
= hx509_ca_tbs_set_spki(context
, tbs
, &spki
);
1736 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_spki");
1740 ret
= hx509_ca_tbs_set_subject(context
, tbs
, subject
);
1742 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_subject");
1745 if (opt
->crl_uri_string
) {
1746 ret
= hx509_ca_tbs_add_crl_dp_uri(context
, tbs
,
1747 opt
->crl_uri_string
, NULL
);
1749 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_crl_dp_uri");
1752 eval_types(context
, tbs
, opt
);
1754 if (opt
->issue_ca_flag
) {
1755 ret
= hx509_ca_tbs_set_ca(context
, tbs
, opt
->path_length_integer
);
1757 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_ca");
1759 if (opt
->issue_proxy_flag
) {
1760 ret
= hx509_ca_tbs_set_proxy(context
, tbs
, opt
->path_length_integer
);
1762 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_proxy");
1764 if (opt
->domain_controller_flag
) {
1765 hx509_ca_tbs_set_domaincontroller(context
, tbs
);
1767 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_domaincontroller");
1771 ret
= hx509_ca_tbs_set_notAfter_lifetime(context
, tbs
, delta
);
1773 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_notAfter_lifetime");
1776 if (opt
->self_signed_flag
) {
1777 ret
= hx509_ca_sign_self(context
, tbs
, private_key
, &cert
);
1779 hx509_err(context
, 1, ret
, "hx509_ca_sign_self");
1781 ret
= hx509_ca_sign(context
, tbs
, signer
, &cert
);
1783 hx509_err(context
, 1, ret
, "hx509_ca_sign");
1787 ret
= _hx509_cert_assign_key(cert
, cert_key
);
1789 hx509_err(context
, 1, ret
, "_hx509_cert_assign_key");
1795 ret
= hx509_certs_init(context
, opt
->certificate_string
,
1796 HX509_CERTS_CREATE
, NULL
, &certs
);
1798 hx509_err(context
, 1, ret
, "hx509_certs_init");
1800 ret
= hx509_certs_add(context
, certs
, cert
);
1802 hx509_err(context
, 1, ret
, "hx509_certs_add");
1804 ret
= hx509_certs_store(context
, certs
, 0, NULL
);
1806 hx509_err(context
, 1, ret
, "hx509_certs_store");
1808 hx509_certs_free(&certs
);
1812 hx509_name_free(&subject
);
1814 hx509_cert_free(signer
);
1815 hx509_cert_free(cert
);
1816 free_SubjectPublicKeyInfo(&spki
);
1818 if (private_key
!= cert_key
)
1819 _hx509_private_key_free(&private_key
);
1820 _hx509_private_key_free(&cert_key
);
1822 hx509_ca_tbs_free(&tbs
);
1828 test_one_cert(hx509_context hxcontext
, void *ctx
, hx509_cert cert
)
1830 heim_octet_string sd
, c
;
1831 hx509_verify_ctx vctx
= ctx
;
1832 hx509_certs signer
= NULL
;
1836 if (_hx509_cert_private_key(cert
) == NULL
)
1839 ret
= hx509_cms_create_signed_1(context
, 0, NULL
, NULL
, 0,
1840 NULL
, cert
, NULL
, NULL
, NULL
, &sd
);
1842 errx(1, "hx509_cms_create_signed_1");
1844 ret
= hx509_cms_verify_signed(context
, vctx
, sd
.data
, sd
.length
,
1845 NULL
, NULL
, &type
, &c
, &signer
);
1848 hx509_err(context
, 1, ret
, "hx509_cms_verify_signed");
1850 printf("create-signature verify-sigature done\n");
1858 test_crypto(struct test_crypto_options
*opt
, int argc
, char ** argv
)
1860 hx509_verify_ctx vctx
;
1865 hx509_lock_init(context
, &lock
);
1866 lock_strings(lock
, &opt
->pass_strings
);
1868 ret
= hx509_certs_init(context
, "MEMORY:test-crypto", 0, NULL
, &certs
);
1870 for (i
= 0; i
< argc
; i
++) {
1871 ret
= hx509_certs_append(context
, certs
, lock
, argv
[i
]);
1873 hx509_err(context
, 1, ret
, "hx509_certs_append");
1876 ret
= hx509_verify_init_ctx(context
, &vctx
);
1878 hx509_err(context
, 1, ret
, "hx509_verify_init_ctx");
1880 hx509_verify_attach_anchors(vctx
, certs
);
1882 ret
= hx509_certs_iter(context
, certs
, test_one_cert
, vctx
);
1884 hx509_certs_free(&certs
);
1890 statistic_print(struct statistic_print_options
*opt
, int argc
, char **argv
)
1894 if (stat_file_string
== NULL
)
1895 errx(1, "no stat file");
1897 if (opt
->type_integer
)
1898 type
= opt
->type_integer
;
1900 hx509_query_unparse_stats(context
, type
, stdout
);
1909 crl_sign(struct crl_sign_options
*opt
, int argc
, char **argv
)
1912 heim_octet_string os
;
1913 hx509_cert signer
= NULL
;
1917 hx509_lock_init(context
, &lock
);
1918 lock_strings(lock
, &opt
->pass_strings
);
1920 ret
= hx509_crl_alloc(context
, &crl
);
1922 errx(1, "crl alloc");
1924 if (opt
->signer_string
== NULL
)
1925 errx(1, "signer missing");
1928 hx509_certs certs
= NULL
;
1931 ret
= hx509_certs_init(context
, opt
->signer_string
, 0,
1934 hx509_err(context
, 1, ret
,
1935 "hx509_certs_init: %s", opt
->signer_string
);
1937 ret
= hx509_query_alloc(context
, &q
);
1939 hx509_err(context
, 1, ret
, "hx509_query_alloc: %d", ret
);
1941 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
1943 ret
= hx509_certs_find(context
, certs
, q
, &signer
);
1944 hx509_query_free(context
, q
);
1945 hx509_certs_free(&certs
);
1947 hx509_err(context
, 1, ret
, "no signer certificate found");
1950 if (opt
->lifetime_string
) {
1953 delta
= parse_time(opt
->lifetime_string
, "day");
1955 errx(1, "Invalid lifetime: %s", opt
->lifetime_string
);
1957 hx509_crl_lifetime(context
, crl
, delta
);
1961 hx509_certs revoked
= NULL
;
1964 ret
= hx509_certs_init(context
, "MEMORY:revoked-certs", 0,
1967 for (i
= 0; i
< argc
; i
++) {
1968 ret
= hx509_certs_append(context
, revoked
, lock
, argv
[i
]);
1970 hx509_err(context
, 1, ret
, "hx509_certs_append: %s", argv
[i
]);
1973 hx509_crl_add_revoked_certs(context
, crl
, revoked
);
1974 hx509_certs_free(&revoked
);
1977 hx509_crl_sign(context
, signer
, crl
, &os
);
1979 if (opt
->crl_file_string
)
1980 rk_dumpdata(opt
->crl_file_string
, os
.data
, os
.length
);
1984 hx509_crl_free(context
, &crl
);
1985 hx509_cert_free(signer
);
1986 hx509_lock_free(lock
);
1996 help(void *opt
, int argc
, char **argv
)
1998 sl_slc_help(commands
, argc
, argv
);
2003 main(int argc
, char **argv
)
2005 int ret
, optidx
= 0;
2007 setprogname (argv
[0]);
2009 if(getarg(args
, num_args
, argc
, argv
, &optidx
))
2014 print_version(NULL
);
2023 ret
= hx509_context_init(&context
);
2025 errx(1, "hx509_context_init failed with %d", ret
);
2027 if (stat_file_string
)
2028 hx509_query_statistic_file(context
, stat_file_string
);
2030 ret
= sl_command(commands
, argc
, argv
);
2032 warnx ("unrecognized command: %s", argv
[0]);
2034 hx509_context_free(&context
);