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
35 __RCSID("$Heimdal: hxtool.c 22333 2007-12-17 01:03:43Z lha $"
38 #include <hxtool-commands.h>
40 #include <parse_time.h>
42 static hx509_context context
;
44 static char *stat_file_string
;
45 static int version_flag
;
48 struct getargs args
[] = {
49 { "statistic-file", 0, arg_string
, &stat_file_string
},
50 { "version", 0, arg_flag
, &version_flag
},
51 { "help", 0, arg_flag
, &help_flag
}
53 int num_args
= sizeof(args
) / sizeof(args
[0]);
58 arg_printusage(args
, num_args
, NULL
, "command");
59 printf("Use \"%s help\" to get more help\n", getprogname());
68 lock_strings(hx509_lock lock
, getarg_strings
*pass
)
71 for (i
= 0; i
< pass
->num_strings
; i
++) {
72 int ret
= hx509_lock_command_string(lock
, pass
->strings
[i
]);
74 errx(1, "hx509_lock_command_string: %s: %d",
75 pass
->strings
[i
], ret
);
84 certs_strings(hx509_context context
, const char *type
, hx509_certs certs
,
85 hx509_lock lock
, const getarg_strings
*s
)
89 for (i
= 0; i
< s
->num_strings
; i
++) {
90 ret
= hx509_certs_append(context
, certs
, lock
, s
->strings
[i
]);
92 hx509_err(context
, 1, ret
,
93 "hx509_certs_append: %s %s", type
, s
->strings
[i
]);
102 parse_oid(const char *str
, const heim_oid
*def
, heim_oid
*oid
)
106 ret
= der_parse_heim_oid (str
, " .", oid
);
108 ret
= der_copy_oid(def
, oid
);
110 errx(1, "parse_oid failed for: %s", str
? str
: "default oid");
118 peer_strings(hx509_context context
,
119 hx509_peer_info
*peer
,
120 const getarg_strings
*s
)
122 AlgorithmIdentifier
*val
;
125 ret
= hx509_peer_info_alloc(context
, peer
);
127 hx509_err(context
, 1, ret
, "hx509_peer_info_alloc");
129 val
= calloc(s
->num_strings
, sizeof(*val
));
133 for (i
= 0; i
< s
->num_strings
; i
++)
134 parse_oid(s
->strings
[i
], NULL
, &val
[i
].algorithm
);
136 ret
= hx509_peer_info_set_cms_algs(context
, *peer
, val
, s
->num_strings
);
138 hx509_err(context
, 1, ret
, "hx509_peer_info_set_cms_algs");
140 for (i
= 0; i
< s
->num_strings
; i
++)
141 free_AlgorithmIdentifier(&val
[i
]);
150 cms_verify_sd(struct cms_verify_sd_options
*opt
, int argc
, char **argv
)
152 hx509_verify_ctx ctx
= NULL
;
154 heim_octet_string c
, co
, signeddata
, *sd
= NULL
;
155 hx509_certs store
= NULL
;
156 hx509_certs signers
= NULL
;
157 hx509_certs anchors
= NULL
;
164 if (opt
->missing_revoke_flag
)
165 hx509_context_set_missing_revoke(context
, 1);
167 hx509_lock_init(context
, &lock
);
168 lock_strings(lock
, &opt
->pass_strings
);
170 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
172 err(1, "map_file: %s: %d", argv
[0], ret
);
174 if (opt
->signed_content_string
) {
175 ret
= _hx509_map_file_os(opt
->signed_content_string
, &signeddata
, NULL
);
177 err(1, "map_file: %s: %d", opt
->signed_content_string
, ret
);
181 ret
= hx509_verify_init_ctx(context
, &ctx
);
183 ret
= hx509_certs_init(context
, "MEMORY:cms-anchors", 0, NULL
, &anchors
);
184 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &store
);
186 certs_strings(context
, "anchors", anchors
, lock
, &opt
->anchors_strings
);
187 certs_strings(context
, "store", store
, lock
, &opt
->certificate_strings
);
192 if (opt
->content_info_flag
) {
193 heim_octet_string uwco
;
196 ret
= hx509_cms_unwrap_ContentInfo(&co
, &oid
, &uwco
, NULL
);
198 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret
);
200 if (der_heim_oid_cmp(&oid
, oid_id_pkcs7_signedData()) != 0)
201 errx(1, "Content is not SignedData");
207 hx509_verify_attach_anchors(ctx
, anchors
);
209 ret
= hx509_cms_verify_signed(context
, ctx
, co
.data
, co
.length
, sd
,
210 store
, &type
, &c
, &signers
);
212 der_free_octet_string(&co
);
214 hx509_err(context
, 1, ret
, "hx509_cms_verify_signed");
218 der_print_heim_oid(&type
, '.', &str
);
219 printf("type: %s\n", str
);
223 printf("signers:\n");
224 hx509_certs_iter(context
, signers
, hx509_ci_print_names
, stdout
);
226 hx509_verify_destroy_ctx(ctx
);
228 hx509_certs_free(&store
);
229 hx509_certs_free(&signers
);
230 hx509_certs_free(&anchors
);
232 hx509_lock_free(lock
);
234 ret
= _hx509_write_file(argv
[1], c
.data
, c
.length
);
236 errx(1, "hx509_write_file: %d", ret
);
238 der_free_octet_string(&c
);
239 _hx509_unmap_file(p
, sz
);
241 _hx509_unmap_file_os(sd
);
247 cms_create_sd(struct cms_create_sd_options
*opt
, int argc
, char **argv
)
249 heim_oid contentType
;
250 hx509_peer_info peer
= NULL
;
254 hx509_certs store
, pool
, anchors
;
259 char *signer_name
= NULL
;
261 memset(&contentType
, 0, sizeof(contentType
));
266 hx509_lock_init(context
, &lock
);
267 lock_strings(lock
, &opt
->pass_strings
);
269 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &store
);
270 ret
= hx509_certs_init(context
, "MEMORY:cert-pool", 0, NULL
, &pool
);
272 certs_strings(context
, "store", store
, lock
, &opt
->certificate_strings
);
273 certs_strings(context
, "pool", pool
, lock
, &opt
->pool_strings
);
275 if (opt
->anchors_strings
.num_strings
) {
276 ret
= hx509_certs_init(context
, "MEMORY:cert-anchors",
278 certs_strings(context
, "anchors", anchors
, lock
, &opt
->anchors_strings
);
282 if (opt
->detached_signature_flag
)
283 flags
|= HX509_CMS_SIGATURE_DETACHED
;
284 if (opt
->id_by_name_flag
)
285 flags
|= HX509_CMS_SIGATURE_ID_NAME
;
287 ret
= hx509_query_alloc(context
, &q
);
289 errx(1, "hx509_query_alloc: %d", ret
);
291 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
292 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE
);
294 if (opt
->signer_string
)
295 hx509_query_match_friendly_name(q
, opt
->signer_string
);
297 ret
= hx509_certs_find(context
, store
, q
, &cert
);
298 hx509_query_free(context
, q
);
300 hx509_err(context
, 1, ret
, "hx509_certs_find");
302 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
304 err(1, "map_file: %s: %d", argv
[0], ret
);
306 if (opt
->peer_alg_strings
.num_strings
)
307 peer_strings(context
, &peer
, &opt
->peer_alg_strings
);
309 parse_oid(opt
->content_type_string
, oid_id_pkcs7_data(), &contentType
);
311 ret
= hx509_cms_create_signed_1(context
,
323 errx(1, "hx509_cms_create_signed: %d", ret
);
328 ret
= hx509_cert_get_subject(cert
, &name
);
330 errx(1, "hx509_cert_get_subject");
332 ret
= hx509_name_to_string(name
, &signer_name
);
333 hx509_name_free(&name
);
335 errx(1, "hx509_name_to_string");
339 hx509_certs_free(&anchors
);
340 hx509_certs_free(&pool
);
341 hx509_cert_free(cert
);
342 hx509_certs_free(&store
);
343 _hx509_unmap_file(p
, sz
);
344 hx509_lock_free(lock
);
345 hx509_peer_info_free(peer
);
346 der_free_oid(&contentType
);
348 if (opt
->content_info_flag
) {
349 heim_octet_string wo
;
351 ret
= hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &o
, &wo
);
353 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret
);
355 der_free_octet_string(&o
);
360 hx509_pem_header
*header
= NULL
;
363 hx509_pem_add_header(&header
, "Content-disposition",
364 opt
->detached_signature_flag
? "detached" : "inline");
365 hx509_pem_add_header(&header
, "Signer", signer_name
);
367 f
= fopen(argv
[1], "w");
369 err(1, "open %s", argv
[1]);
371 ret
= hx509_pem_write(context
, "CMS SIGNEDDATA", header
, f
,
374 hx509_pem_free_header(header
);
376 errx(1, "hx509_pem_write: %d", ret
);
379 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
381 errx(1, "hx509_write_file: %d", ret
);
391 cms_unenvelope(struct cms_unenvelope_options
*opt
, int argc
, char **argv
)
393 heim_oid contentType
= { 0, NULL
};
394 heim_octet_string o
, co
;
401 hx509_lock_init(context
, &lock
);
402 lock_strings(lock
, &opt
->pass_strings
);
404 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
406 err(1, "map_file: %s: %d", argv
[0], ret
);
411 if (opt
->content_info_flag
) {
412 heim_octet_string uwco
;
415 ret
= hx509_cms_unwrap_ContentInfo(&co
, &oid
, &uwco
, NULL
);
417 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret
);
419 if (der_heim_oid_cmp(&oid
, oid_id_pkcs7_envelopedData()) != 0)
420 errx(1, "Content is not SignedData");
426 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
428 errx(1, "hx509_certs_init: MEMORY: %d", ret
);
430 certs_strings(context
, "store", certs
, lock
, &opt
->certificate_strings
);
432 ret
= hx509_cms_unenvelope(context
, certs
, 0, co
.data
, co
.length
,
433 NULL
, &contentType
, &o
);
435 der_free_octet_string(&co
);
437 hx509_err(context
, 1, ret
, "hx509_cms_unenvelope");
439 _hx509_unmap_file(p
, sz
);
440 hx509_lock_free(lock
);
441 hx509_certs_free(&certs
);
442 der_free_oid(&contentType
);
444 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
446 errx(1, "hx509_write_file: %d", ret
);
448 der_free_octet_string(&o
);
454 cms_create_enveloped(struct cms_envelope_options
*opt
, int argc
, char **argv
)
456 heim_oid contentType
;
458 const heim_oid
*enctype
= NULL
;
467 memset(&contentType
, 0, sizeof(contentType
));
469 hx509_lock_init(context
, &lock
);
470 lock_strings(lock
, &opt
->pass_strings
);
472 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
474 err(1, "map_file: %s: %d", argv
[0], ret
);
476 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
478 certs_strings(context
, "store", certs
, lock
, &opt
->certificate_strings
);
480 if (opt
->encryption_type_string
) {
481 enctype
= hx509_crypto_enctype_by_name(opt
->encryption_type_string
);
483 errx(1, "encryption type: %s no found",
484 opt
->encryption_type_string
);
487 ret
= hx509_query_alloc(context
, &q
);
489 errx(1, "hx509_query_alloc: %d", ret
);
491 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_ENCIPHERMENT
);
493 ret
= hx509_certs_find(context
, certs
, q
, &cert
);
494 hx509_query_free(context
, q
);
496 errx(1, "hx509_certs_find: %d", ret
);
498 parse_oid(opt
->content_type_string
, oid_id_pkcs7_data(), &contentType
);
500 ret
= hx509_cms_envelope_1(context
, 0, cert
, p
, sz
, enctype
,
503 errx(1, "hx509_cms_envelope_1: %d", ret
);
505 hx509_cert_free(cert
);
506 hx509_certs_free(&certs
);
507 _hx509_unmap_file(p
, sz
);
508 der_free_oid(&contentType
);
510 if (opt
->content_info_flag
) {
511 heim_octet_string wo
;
513 ret
= hx509_cms_wrap_ContentInfo(oid_id_pkcs7_envelopedData(), &o
, &wo
);
515 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret
);
517 der_free_octet_string(&o
);
521 hx509_lock_free(lock
);
523 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
525 errx(1, "hx509_write_file: %d", ret
);
527 der_free_octet_string(&o
);
533 print_certificate(hx509_context hxcontext
, hx509_cert cert
, int verbose
)
540 fn
= hx509_cert_get_friendly_name(cert
);
542 printf(" friendly name: %s\n", fn
);
543 printf(" private key: %s\n",
544 _hx509_cert_private_key(cert
) ? "yes" : "no");
546 ret
= hx509_cert_get_issuer(cert
, &name
);
547 hx509_name_to_string(name
, &str
);
548 hx509_name_free(&name
);
549 printf(" issuer: \"%s\"\n", str
);
552 ret
= hx509_cert_get_subject(cert
, &name
);
553 hx509_name_to_string(name
, &str
);
554 hx509_name_free(&name
);
555 printf(" subject: \"%s\"\n", str
);
559 heim_integer serialNumber
;
561 hx509_cert_get_serialnumber(cert
, &serialNumber
);
562 der_print_hex_heim_integer(&serialNumber
, &str
);
563 der_free_heim_integer(&serialNumber
);
564 printf(" serial: %s\n", str
);
568 printf(" keyusage: ");
569 ret
= hx509_cert_keyusage_print(hxcontext
, cert
, &str
);
577 hx509_validate_ctx vctx
;
579 hx509_validate_ctx_init(hxcontext
, &vctx
);
580 hx509_validate_ctx_set_print(vctx
, hx509_print_stdout
, stdout
);
581 hx509_validate_ctx_add_flags(vctx
, HX509_VALIDATE_F_VALIDATE
);
582 hx509_validate_ctx_add_flags(vctx
, HX509_VALIDATE_F_VERBOSE
);
584 hx509_validate_cert(hxcontext
, vctx
, cert
);
586 hx509_validate_ctx_free(vctx
);
597 print_f(hx509_context hxcontext
, void *ctx
, hx509_cert cert
)
599 struct print_s
*s
= ctx
;
601 printf("cert: %d\n", s
->counter
++);
602 print_certificate(context
, cert
, s
->verbose
);
608 pcert_print(struct print_options
*opt
, int argc
, char **argv
)
615 s
.verbose
= opt
->content_flag
;
617 hx509_lock_init(context
, &lock
);
618 lock_strings(lock
, &opt
->pass_strings
);
622 ret
= hx509_certs_init(context
, argv
[0], 0, lock
, &certs
);
624 hx509_err(context
, 1, ret
, "hx509_certs_init");
626 hx509_certs_info(context
, certs
, NULL
, NULL
);
627 hx509_certs_iter(context
, certs
, print_f
, &s
);
628 hx509_certs_free(&certs
);
632 hx509_lock_free(lock
);
639 validate_f(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
641 hx509_validate_cert(hxcontext
, ctx
, c
);
646 pcert_validate(struct validate_options
*opt
, int argc
, char **argv
)
648 hx509_validate_ctx ctx
;
652 hx509_lock_init(context
, &lock
);
653 lock_strings(lock
, &opt
->pass_strings
);
655 hx509_validate_ctx_init(context
, &ctx
);
656 hx509_validate_ctx_set_print(ctx
, hx509_print_stdout
, stdout
);
657 hx509_validate_ctx_add_flags(ctx
, HX509_VALIDATE_F_VALIDATE
);
661 ret
= hx509_certs_init(context
, argv
[0], 0, lock
, &certs
);
663 errx(1, "hx509_certs_init: %d", ret
);
664 hx509_certs_iter(context
, certs
, validate_f
, ctx
);
665 hx509_certs_free(&certs
);
668 hx509_validate_ctx_free(ctx
);
670 hx509_lock_free(lock
);
676 certificate_copy(struct certificate_copy_options
*opt
, int argc
, char **argv
)
682 hx509_lock_init(context
, &lock
);
683 lock_strings(lock
, &opt
->in_pass_strings
);
685 ret
= hx509_certs_init(context
, argv
[argc
- 1],
686 HX509_CERTS_CREATE
, lock
, &certs
);
688 hx509_err(context
, 1, ret
, "hx509_certs_init");
692 ret
= hx509_certs_append(context
, certs
, lock
, argv
[0]);
694 hx509_err(context
, 1, ret
, "hx509_certs_append");
698 ret
= hx509_certs_store(context
, certs
, 0, NULL
);
700 hx509_err(context
, 1, ret
, "hx509_certs_store");
702 hx509_certs_free(&certs
);
703 hx509_lock_free(lock
);
709 hx509_verify_ctx ctx
;
711 const char *hostname
;
716 verify_f(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
718 struct verify
*v
= ctx
;
721 ret
= hx509_verify_path(hxcontext
, v
->ctx
, c
, v
->chain
);
723 char *s
= hx509_get_error_string(hxcontext
, ret
);
724 printf("verify_path: %s: %d\n", s
, ret
);
725 hx509_free_error_string(s
);
731 ret
= hx509_verify_hostname(hxcontext
, c
, 0, HX509_HN_HOSTNAME
,
732 v
->hostname
, NULL
, 0);
734 printf("verify_hostname: %d\n", ret
);
743 pcert_verify(struct verify_options
*opt
, int argc
, char **argv
)
745 hx509_certs anchors
, chain
, certs
;
746 hx509_revoke_ctx revoke_ctx
;
747 hx509_verify_ctx ctx
;
751 memset(&v
, 0, sizeof(v
));
753 if (opt
->missing_revoke_flag
)
754 hx509_context_set_missing_revoke(context
, 1);
756 ret
= hx509_verify_init_ctx(context
, &ctx
);
757 ret
= hx509_certs_init(context
, "MEMORY:anchors", 0, NULL
, &anchors
);
758 ret
= hx509_certs_init(context
, "MEMORY:chain", 0, NULL
, &chain
);
759 ret
= hx509_certs_init(context
, "MEMORY:certs", 0, NULL
, &certs
);
761 if (opt
->allow_proxy_certificate_flag
)
762 hx509_verify_set_proxy_certificate(ctx
, 1);
764 if (opt
->time_string
) {
769 memset(&tm
, 0, sizeof(tm
));
771 p
= strptime (opt
->time_string
, "%Y-%m-%d", &tm
);
773 errx(1, "Failed to parse time %s, need to be on format %%Y-%%m-%%d",
778 hx509_verify_set_time(ctx
, t
);
781 if (opt
->hostname_string
)
782 v
.hostname
= opt
->hostname_string
;
783 if (opt
->max_depth_integer
)
784 hx509_verify_set_max_depth(ctx
, opt
->max_depth_integer
);
786 ret
= hx509_revoke_init(context
, &revoke_ctx
);
788 errx(1, "hx509_revoke_init: %d", ret
);
793 if (strncmp(s
, "chain:", 6) == 0) {
796 ret
= hx509_certs_append(context
, chain
, NULL
, s
);
798 hx509_err(context
, 1, ret
, "hx509_certs_append: chain: %s: %d", s
, ret
);
800 } else if (strncmp(s
, "anchor:", 7) == 0) {
803 ret
= hx509_certs_append(context
, anchors
, NULL
, s
);
805 hx509_err(context
, 1, ret
, "hx509_certs_append: anchor: %s: %d", s
, ret
);
807 } else if (strncmp(s
, "cert:", 5) == 0) {
810 ret
= hx509_certs_append(context
, certs
, NULL
, s
);
812 hx509_err(context
, 1, ret
, "hx509_certs_append: certs: %s: %d",
815 } else if (strncmp(s
, "crl:", 4) == 0) {
818 ret
= hx509_revoke_add_crl(context
, revoke_ctx
, s
);
820 errx(1, "hx509_revoke_add_crl: %s: %d", s
, ret
);
822 } else if (strncmp(s
, "ocsp:", 4) == 0) {
825 ret
= hx509_revoke_add_ocsp(context
, revoke_ctx
, s
);
827 errx(1, "hx509_revoke_add_ocsp: %s: %d", s
, ret
);
830 errx(1, "unknown option to verify: `%s'\n", s
);
834 hx509_verify_attach_anchors(ctx
, anchors
);
835 hx509_verify_attach_revoke(ctx
, revoke_ctx
);
840 hx509_certs_iter(context
, certs
, verify_f
, &v
);
842 hx509_verify_destroy_ctx(ctx
);
844 hx509_certs_free(&certs
);
845 hx509_certs_free(&chain
);
846 hx509_certs_free(&anchors
);
848 hx509_revoke_free(&revoke_ctx
);
851 printf("failed verifing %d checks\n", v
.errors
);
859 query(struct query_options
*opt
, int argc
, char **argv
)
867 ret
= hx509_query_alloc(context
, &q
);
869 errx(1, "hx509_query_alloc: %d", ret
);
871 hx509_lock_init(context
, &lock
);
872 lock_strings(lock
, &opt
->pass_strings
);
874 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
878 ret
= hx509_certs_append(context
, certs
, lock
, argv
[0]);
880 errx(1, "hx509_certs_append: %s: %d", argv
[0], ret
);
886 if (opt
->friendlyname_string
)
887 hx509_query_match_friendly_name(q
, opt
->friendlyname_string
);
889 if (opt
->private_key_flag
)
890 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
892 if (opt
->keyEncipherment_flag
)
893 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_ENCIPHERMENT
);
895 if (opt
->digitalSignature_flag
)
896 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE
);
898 ret
= hx509_certs_find(context
, certs
, q
, &c
);
899 hx509_query_free(context
, q
);
901 printf("no match found (%d)\n", ret
);
903 printf("match found\n");
905 print_certificate(context
, c
, 0);
909 hx509_certs_free(&certs
);
911 hx509_lock_free(lock
);
917 ocsp_fetch(struct ocsp_fetch_options
*opt
, int argc
, char **argv
)
919 hx509_certs reqcerts
, pool
;
920 heim_octet_string req
, nonce_data
, *nonce
= &nonce_data
;
924 const char *url
= "/";
926 memset(&nonce
, 0, sizeof(nonce
));
928 hx509_lock_init(context
, &lock
);
929 lock_strings(lock
, &opt
->pass_strings
);
932 if (!opt
->nonce_flag
)
935 if (opt
->url_path_string
)
936 url
= opt
->url_path_string
;
938 ret
= hx509_certs_init(context
, "MEMORY:ocsp-pool", 0, NULL
, &pool
);
940 certs_strings(context
, "ocsp-pool", pool
, lock
, &opt
->pool_strings
);
944 ret
= hx509_certs_init(context
, "MEMORY:ocsp-req", 0, NULL
, &reqcerts
);
946 for (i
= 1; i
< argc
; i
++) {
947 ret
= hx509_certs_append(context
, reqcerts
, lock
, argv
[i
]);
949 errx(1, "hx509_certs_append: req: %s: %d", argv
[i
], ret
);
952 ret
= hx509_ocsp_request(context
, reqcerts
, pool
, NULL
, NULL
, &req
, nonce
);
954 errx(1, "hx509_ocsp_request: req: %d", ret
);
959 f
= fopen(file
, "w");
964 "POST %s HTTP/1.0\r\n"
965 "Content-Type: application/ocsp-request\r\n"
966 "Content-Length: %ld\r\n"
969 (unsigned long)req
.length
);
970 fwrite(req
.data
, req
.length
, 1, f
);
975 der_free_octet_string(nonce
);
977 hx509_certs_free(&reqcerts
);
978 hx509_certs_free(&pool
);
984 ocsp_print(struct ocsp_print_options
*opt
, int argc
, char **argv
)
986 hx509_revoke_ocsp_print(context
, argv
[0], stdout
);
995 verify_o(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
997 heim_octet_string
*os
= ctx
;
1001 ret
= hx509_ocsp_verify(context
, 0, c
, 0,
1002 os
->data
, os
->length
, &expiration
);
1004 char *s
= hx509_get_error_string(hxcontext
, ret
);
1005 printf("ocsp_verify: %s: %d\n", s
, ret
);
1006 hx509_free_error_string(s
);
1008 printf("expire: %d\n", (int)expiration
);
1015 ocsp_verify(struct ocsp_verify_options
*opt
, int argc
, char **argv
)
1020 heim_octet_string os
;
1022 hx509_lock_init(context
, &lock
);
1024 if (opt
->ocsp_file_string
== NULL
)
1025 errx(1, "no ocsp file given");
1027 ret
= _hx509_map_file(opt
->ocsp_file_string
, &os
.data
, &os
.length
, NULL
);
1029 err(1, "map_file: %s: %d", argv
[0], ret
);
1031 ret
= hx509_certs_init(context
, "MEMORY:test-certs", 0, NULL
, &certs
);
1033 for (i
= 0; i
< argc
; i
++) {
1034 ret
= hx509_certs_append(context
, certs
, lock
, argv
[i
]);
1036 hx509_err(context
, 1, ret
, "hx509_certs_append: %s", argv
[i
]);
1039 ret
= hx509_certs_iter(context
, certs
, verify_o
, &os
);
1041 hx509_certs_free(&certs
);
1042 _hx509_unmap_file(os
.data
, os
.length
);
1043 hx509_lock_free(lock
);
1049 read_private_key(const char *fn
, hx509_private_key
*key
)
1051 hx509_private_key
*keys
;
1057 ret
= hx509_certs_init(context
, fn
, 0, NULL
, &certs
);
1059 hx509_err(context
, 1, ret
, "hx509_certs_init: %s", fn
);
1061 ret
= _hx509_certs_keys_get(context
, certs
, &keys
);
1062 hx509_certs_free(&certs
);
1064 hx509_err(context
, 1, ret
, "hx509_certs_keys_get");
1065 if (keys
[0] == NULL
)
1066 errx(1, "no keys in key store: %s", fn
);
1068 *key
= _hx509_private_key_ref(keys
[0]);
1069 _hx509_certs_keys_free(context
, keys
);
1075 get_key(const char *fn
, const char *type
, int optbits
,
1076 hx509_private_key
*signer
)
1083 unsigned char *p0
, *p
;
1088 errx(1, "no key argument, don't know here to store key");
1090 if (strcasecmp(type
, "rsa") != 0)
1091 errx(1, "can only handle rsa keys for now");
1094 BN_set_word(e
, 0x10001);
1101 errx(1, "RSA_new failed");
1103 ret
= RSA_generate_key_ex(rsa
, bits
, e
, NULL
);
1105 errx(1, "RSA_new failed");
1109 len
= i2d_RSAPrivateKey(rsa
, NULL
);
1111 p0
= p
= malloc(len
);
1113 errx(1, "out of memory");
1115 i2d_RSAPrivateKey(rsa
, &p
);
1117 rk_dumpdata(fn
, p0
, len
);
1123 } else if (fn
== NULL
)
1124 err(1, "no private key");
1126 ret
= read_private_key(fn
, signer
);
1128 err(1, "read_private_key");
1132 request_create(struct request_create_options
*opt
, int argc
, char **argv
)
1134 heim_octet_string request
;
1137 hx509_private_key signer
;
1138 SubjectPublicKeyInfo key
;
1139 const char *outfile
= argv
[0];
1141 memset(&key
, 0, sizeof(key
));
1143 get_key(opt
->key_string
,
1144 opt
->generate_key_string
,
1145 opt
->key_bits_integer
,
1148 _hx509_request_init(context
, &req
);
1150 if (opt
->subject_string
) {
1151 hx509_name name
= NULL
;
1153 ret
= hx509_parse_name(context
, opt
->subject_string
, &name
);
1155 errx(1, "hx509_parse_name: %d\n", ret
);
1156 _hx509_request_set_name(context
, req
, name
);
1158 if (opt
->verbose_flag
) {
1160 hx509_name_to_string(name
, &s
);
1163 hx509_name_free(&name
);
1166 for (i
= 0; i
< opt
->email_strings
.num_strings
; i
++) {
1167 ret
= _hx509_request_add_email(context
, req
,
1168 opt
->email_strings
.strings
[i
]);
1171 for (i
= 0; i
< opt
->dnsname_strings
.num_strings
; i
++) {
1172 ret
= _hx509_request_add_dns_name(context
, req
,
1173 opt
->dnsname_strings
.strings
[i
]);
1177 ret
= _hx509_private_key2SPKI(context
, signer
, &key
);
1179 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1181 ret
= _hx509_request_set_SubjectPublicKeyInfo(context
,
1184 free_SubjectPublicKeyInfo(&key
);
1186 hx509_err(context
, 1, ret
, "_hx509_request_set_SubjectPublicKeyInfo");
1188 ret
= _hx509_request_to_pkcs10(context
,
1193 hx509_err(context
, 1, ret
, "_hx509_request_to_pkcs10");
1195 _hx509_private_key_free(&signer
);
1196 _hx509_request_free(&req
);
1199 rk_dumpdata(outfile
, request
.data
, request
.length
);
1200 der_free_octet_string(&request
);
1206 request_print(struct request_print_options
*opt
, int argc
, char **argv
)
1210 printf("request print\n");
1212 for (i
= 0; i
< argc
; i
++) {
1215 ret
= _hx509_request_parse(context
, argv
[i
], &req
);
1217 hx509_err(context
, 1, ret
, "parse_request: %s", argv
[i
]);
1219 ret
= _hx509_request_print(context
, req
, stdout
);
1220 _hx509_request_free(&req
);
1222 hx509_err(context
, 1, ret
, "Failed to print file %s", argv
[i
]);
1229 info(void *opt
, int argc
, char **argv
)
1232 ENGINE_add_conf_module();
1235 const RSA_METHOD
*m
= RSA_get_default_method();
1237 printf("rsa: %s\n", m
->name
);
1240 const DH_METHOD
*m
= DH_get_default_method();
1242 printf("dh: %s\n", m
->name
);
1245 int ret
= RAND_status();
1246 printf("rand: %s\n", ret
== 1 ? "ok" : "not available");
1253 random_data(void *opt
, int argc
, char **argv
)
1258 len
= parse_bytes(argv
[0], "byte");
1260 fprintf(stderr
, "bad argument to random-data\n");
1266 fprintf(stderr
, "out of memory\n");
1270 ret
= RAND_bytes(ptr
, len
);
1273 fprintf(stderr
, "did not get cryptographic strong random\n");
1277 fwrite(ptr
, len
, 1, stdout
);
1286 crypto_available(struct crypto_available_options
*opt
, int argc
, char **argv
)
1288 AlgorithmIdentifier
*val
;
1289 unsigned int len
, i
;
1292 if (opt
->type_string
) {
1293 if (strcmp(opt
->type_string
, "all") == 0)
1294 type
= HX509_SELECT_ALL
;
1295 else if (strcmp(opt
->type_string
, "digest") == 0)
1296 type
= HX509_SELECT_DIGEST
;
1297 else if (strcmp(opt
->type_string
, "public-sig") == 0)
1298 type
= HX509_SELECT_PUBLIC_SIG
;
1299 else if (strcmp(opt
->type_string
, "secret") == 0)
1300 type
= HX509_SELECT_SECRET_ENC
;
1302 errx(1, "unknown type: %s", opt
->type_string
);
1304 type
= HX509_SELECT_ALL
;
1306 ret
= hx509_crypto_available(context
, type
, NULL
, &val
, &len
);
1308 errx(1, "hx509_crypto_available");
1310 for (i
= 0; i
< len
; i
++) {
1312 der_print_heim_oid (&val
[i
].algorithm
, '.', &s
);
1317 hx509_crypto_free_algs(val
, len
);
1323 crypto_select(struct crypto_select_options
*opt
, int argc
, char **argv
)
1325 hx509_peer_info peer
= NULL
;
1326 AlgorithmIdentifier selected
;
1330 if (opt
->type_string
) {
1331 if (strcmp(opt
->type_string
, "digest") == 0)
1332 type
= HX509_SELECT_DIGEST
;
1333 else if (strcmp(opt
->type_string
, "public-sig") == 0)
1334 type
= HX509_SELECT_PUBLIC_SIG
;
1335 else if (strcmp(opt
->type_string
, "secret") == 0)
1336 type
= HX509_SELECT_SECRET_ENC
;
1338 errx(1, "unknown type: %s", opt
->type_string
);
1340 type
= HX509_SELECT_DIGEST
;
1342 if (opt
->peer_cmstype_strings
.num_strings
)
1343 peer_strings(context
, &peer
, &opt
->peer_cmstype_strings
);
1345 ret
= hx509_crypto_select(context
, type
, NULL
, peer
, &selected
);
1347 errx(1, "hx509_crypto_available");
1349 der_print_heim_oid (&selected
.algorithm
, '.', &s
);
1352 free_AlgorithmIdentifier(&selected
);
1354 hx509_peer_info_free(peer
);
1360 hxtool_hex(struct hex_options
*opt
, int argc
, char **argv
)
1363 if (opt
->decode_flag
) {
1364 char buf
[1024], buf2
[1024], *p
;
1367 while(fgets(buf
, sizeof(buf
), stdin
) != NULL
) {
1368 buf
[strcspn(buf
, "\r\n")] = '\0';
1370 while(isspace(*(unsigned char *)p
))
1372 len
= hex_decode(p
, buf2
, strlen(p
));
1374 errx(1, "hex_decode failed");
1375 if (fwrite(buf2
, 1, len
, stdout
) != len
)
1376 errx(1, "fwrite failed");
1382 while((len
= fread(buf
, 1, sizeof(buf
), stdin
)) != 0) {
1383 len
= hex_encode(buf
, len
, &p
);
1384 fprintf(stdout
, "%s\n", p
);
1392 eval_types(hx509_context context
,
1394 const struct certificate_sign_options
*opt
)
1399 for (i
= 0; i
< opt
->type_strings
.num_strings
; i
++) {
1400 const char *type
= opt
->type_strings
.strings
[i
];
1402 if (strcmp(type
, "https-server") == 0) {
1403 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1404 oid_id_pkix_kp_serverAuth());
1406 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1407 } else if (strcmp(type
, "https-client") == 0) {
1408 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1409 oid_id_pkix_kp_clientAuth());
1411 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1412 } else if (strcmp(type
, "peap-server") == 0) {
1413 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1414 oid_id_pkix_kp_serverAuth());
1416 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1417 } else if (strcmp(type
, "pkinit-kdc") == 0) {
1419 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1420 oid_id_pkkdcekuoid());
1422 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1423 } else if (strcmp(type
, "pkinit-client") == 0) {
1425 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1428 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1430 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1431 oid_id_ms_client_authentication());
1433 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1435 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1436 oid_id_pkinit_ms_eku());
1438 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1440 } else if (strcmp(type
, "email") == 0) {
1441 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1442 oid_id_pkix_kp_emailProtection());
1444 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1446 errx(1, "unknown type %s", type
);
1450 errx(1, "More the one PK-INIT type given");
1452 if (opt
->pk_init_principal_string
) {
1454 errx(1, "pk-init principal given but no pk-init oid");
1456 ret
= hx509_ca_tbs_add_san_pkinit(context
, tbs
,
1457 opt
->pk_init_principal_string
);
1459 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_pkinit");
1462 if (opt
->ms_upn_string
) {
1464 errx(1, "MS up given but no pk-init oid");
1466 ret
= hx509_ca_tbs_add_san_ms_upn(context
, tbs
, opt
->ms_upn_string
);
1468 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_ms_upn");
1472 for (i
= 0; i
< opt
->hostname_strings
.num_strings
; i
++) {
1473 const char *hostname
= opt
->hostname_strings
.strings
[i
];
1475 ret
= hx509_ca_tbs_add_san_hostname(context
, tbs
, hostname
);
1477 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_hostname");
1480 for (i
= 0; i
< opt
->email_strings
.num_strings
; i
++) {
1481 const char *email
= opt
->email_strings
.strings
[i
];
1483 ret
= hx509_ca_tbs_add_san_rfc822name(context
, tbs
, email
);
1485 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_hostname");
1487 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1488 oid_id_pkix_kp_emailProtection());
1490 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1493 if (opt
->jid_string
) {
1494 ret
= hx509_ca_tbs_add_san_jid(context
, tbs
, opt
->jid_string
);
1496 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_jid");
1503 hxtool_ca(struct certificate_sign_options
*opt
, int argc
, char **argv
)
1507 hx509_cert signer
= NULL
, cert
= NULL
;
1508 hx509_private_key private_key
= NULL
;
1509 hx509_private_key cert_key
= NULL
;
1510 hx509_name subject
= NULL
;
1511 SubjectPublicKeyInfo spki
;
1514 memset(&spki
, 0, sizeof(spki
));
1516 if (opt
->ca_certificate_string
== NULL
&& !opt
->self_signed_flag
)
1517 errx(1, "--ca-certificate argument missing (not using --self-signed)");
1518 if (opt
->ca_private_key_string
== NULL
&& opt
->generate_key_string
== NULL
&& opt
->self_signed_flag
)
1519 errx(1, "--ca-private-key argument missing (using --self-signed)");
1520 if (opt
->certificate_string
== NULL
)
1521 errx(1, "--certificate argument missing");
1523 if (opt
->template_certificate_string
) {
1524 if (opt
->template_fields_string
== NULL
)
1525 errx(1, "--template-certificate not no --template-fields");
1528 if (opt
->lifetime_string
) {
1529 delta
= parse_time(opt
->lifetime_string
, "day");
1531 errx(1, "Invalid lifetime: %s", opt
->lifetime_string
);
1534 if (opt
->ca_certificate_string
) {
1535 hx509_certs cacerts
= NULL
;
1538 ret
= hx509_certs_init(context
, opt
->ca_certificate_string
, 0,
1541 hx509_err(context
, 1, ret
,
1542 "hx509_certs_init: %s", opt
->ca_certificate_string
);
1544 ret
= hx509_query_alloc(context
, &q
);
1546 errx(1, "hx509_query_alloc: %d", ret
);
1548 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
1549 if (!opt
->issue_proxy_flag
)
1550 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_KEYCERTSIGN
);
1552 ret
= hx509_certs_find(context
, cacerts
, q
, &signer
);
1553 hx509_query_free(context
, q
);
1554 hx509_certs_free(&cacerts
);
1556 hx509_err(context
, 1, ret
, "no CA certificate found");
1557 } else if (opt
->self_signed_flag
) {
1558 if (opt
->generate_key_string
== NULL
1559 && opt
->ca_private_key_string
== NULL
)
1560 errx(1, "no signing private key");
1562 errx(1, "missing ca key");
1564 if (opt
->ca_private_key_string
) {
1566 ret
= read_private_key(opt
->ca_private_key_string
, &private_key
);
1568 err(1, "read_private_key");
1570 ret
= _hx509_private_key2SPKI(context
, private_key
, &spki
);
1572 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1574 if (opt
->self_signed_flag
)
1575 cert_key
= private_key
;
1578 if (opt
->req_string
) {
1581 ret
= _hx509_request_parse(context
, opt
->req_string
, &req
);
1583 hx509_err(context
, 1, ret
, "parse_request: %s", opt
->req_string
);
1584 ret
= _hx509_request_get_name(context
, req
, &subject
);
1586 hx509_err(context
, 1, ret
, "get name");
1587 ret
= _hx509_request_get_SubjectPublicKeyInfo(context
, req
, &spki
);
1589 hx509_err(context
, 1, ret
, "get spki");
1590 _hx509_request_free(&req
);
1593 if (opt
->generate_key_string
) {
1594 struct hx509_generate_private_context
*keyctx
;
1596 ret
= _hx509_generate_private_key_init(context
,
1597 oid_id_pkcs1_rsaEncryption(),
1600 if (opt
->issue_ca_flag
)
1601 _hx509_generate_private_key_is_ca(context
, keyctx
);
1603 if (opt
->key_bits_integer
)
1604 _hx509_generate_private_key_bits(context
, keyctx
,
1605 opt
->key_bits_integer
);
1607 ret
= _hx509_generate_private_key(context
, keyctx
,
1609 _hx509_generate_private_key_free(&keyctx
);
1611 hx509_err(context
, 1, ret
, "generate private key");
1613 ret
= _hx509_private_key2SPKI(context
, cert_key
, &spki
);
1615 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1617 if (opt
->self_signed_flag
)
1618 private_key
= cert_key
;
1621 if (opt
->certificate_private_key_string
) {
1622 ret
= read_private_key(opt
->certificate_private_key_string
, &cert_key
);
1624 err(1, "read_private_key for certificate");
1627 if (opt
->subject_string
) {
1629 hx509_name_free(&subject
);
1630 ret
= hx509_parse_name(context
, opt
->subject_string
, &subject
);
1632 hx509_err(context
, 1, ret
, "hx509_parse_name");
1639 ret
= hx509_ca_tbs_init(context
, &tbs
);
1641 hx509_err(context
, 1, ret
, "hx509_ca_tbs_init");
1643 if (opt
->template_certificate_string
) {
1644 hx509_cert
template;
1648 ret
= hx509_certs_init(context
, opt
->template_certificate_string
, 0,
1651 hx509_err(context
, 1, ret
,
1652 "hx509_certs_init: %s", opt
->template_certificate_string
);
1654 ret
= hx509_get_one_cert(context
, tcerts
, &template);
1656 hx509_certs_free(&tcerts
);
1658 hx509_err(context
, 1, ret
, "no template certificate found");
1660 flags
= parse_units(opt
->template_fields_string
,
1661 hx509_ca_tbs_template_units(), "");
1663 ret
= hx509_ca_tbs_set_template(context
, tbs
, flags
, template);
1665 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_template");
1667 hx509_cert_free(template);
1670 if (opt
->serial_number_string
) {
1671 heim_integer serialNumber
;
1673 ret
= der_parse_hex_heim_integer(opt
->serial_number_string
,
1676 err(1, "der_parse_hex_heim_integer");
1677 ret
= hx509_ca_tbs_set_serialnumber(context
, tbs
, &serialNumber
);
1679 hx509_err(context
, 1, ret
, "hx509_ca_tbs_init");
1680 der_free_heim_integer(&serialNumber
);
1683 if (spki
.subjectPublicKey
.length
) {
1684 ret
= hx509_ca_tbs_set_spki(context
, tbs
, &spki
);
1686 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_spki");
1690 ret
= hx509_ca_tbs_set_subject(context
, tbs
, subject
);
1692 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_subject");
1695 if (opt
->crl_uri_string
) {
1696 ret
= hx509_ca_tbs_add_crl_dp_uri(context
, tbs
,
1697 opt
->crl_uri_string
, NULL
);
1699 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_crl_dp_uri");
1702 eval_types(context
, tbs
, opt
);
1704 if (opt
->issue_ca_flag
) {
1705 ret
= hx509_ca_tbs_set_ca(context
, tbs
, opt
->path_length_integer
);
1707 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_ca");
1709 if (opt
->issue_proxy_flag
) {
1710 ret
= hx509_ca_tbs_set_proxy(context
, tbs
, opt
->path_length_integer
);
1712 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_proxy");
1714 if (opt
->domain_controller_flag
) {
1715 hx509_ca_tbs_set_domaincontroller(context
, tbs
);
1717 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_domaincontroller");
1721 ret
= hx509_ca_tbs_set_notAfter_lifetime(context
, tbs
, delta
);
1723 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_notAfter_lifetime");
1726 if (opt
->self_signed_flag
) {
1727 ret
= hx509_ca_sign_self(context
, tbs
, private_key
, &cert
);
1729 hx509_err(context
, 1, ret
, "hx509_ca_sign_self");
1731 ret
= hx509_ca_sign(context
, tbs
, signer
, &cert
);
1733 hx509_err(context
, 1, ret
, "hx509_ca_sign");
1737 ret
= _hx509_cert_assign_key(cert
, cert_key
);
1739 hx509_err(context
, 1, ret
, "_hx509_cert_assign_key");
1745 ret
= hx509_certs_init(context
, opt
->certificate_string
,
1746 HX509_CERTS_CREATE
, NULL
, &certs
);
1748 hx509_err(context
, 1, ret
, "hx509_certs_init");
1750 ret
= hx509_certs_add(context
, certs
, cert
);
1752 hx509_err(context
, 1, ret
, "hx509_certs_add");
1754 ret
= hx509_certs_store(context
, certs
, 0, NULL
);
1756 hx509_err(context
, 1, ret
, "hx509_certs_store");
1758 hx509_certs_free(&certs
);
1762 hx509_name_free(&subject
);
1764 hx509_cert_free(signer
);
1765 hx509_cert_free(cert
);
1766 free_SubjectPublicKeyInfo(&spki
);
1768 if (private_key
!= cert_key
)
1769 _hx509_private_key_free(&private_key
);
1770 _hx509_private_key_free(&cert_key
);
1772 hx509_ca_tbs_free(&tbs
);
1778 test_one_cert(hx509_context hxcontext
, void *ctx
, hx509_cert cert
)
1780 heim_octet_string sd
, c
;
1781 hx509_verify_ctx vctx
= ctx
;
1782 hx509_certs signer
= NULL
;
1786 if (_hx509_cert_private_key(cert
) == NULL
)
1789 ret
= hx509_cms_create_signed_1(context
, 0, NULL
, NULL
, 0,
1790 NULL
, cert
, NULL
, NULL
, NULL
, &sd
);
1792 errx(1, "hx509_cms_create_signed_1");
1794 ret
= hx509_cms_verify_signed(context
, vctx
, sd
.data
, sd
.length
,
1795 NULL
, NULL
, &type
, &c
, &signer
);
1798 hx509_err(context
, 1, ret
, "hx509_cms_verify_signed");
1800 printf("create-signature verify-sigature done\n");
1808 test_crypto(struct test_crypto_options
*opt
, int argc
, char ** argv
)
1810 hx509_verify_ctx vctx
;
1815 hx509_lock_init(context
, &lock
);
1816 lock_strings(lock
, &opt
->pass_strings
);
1818 ret
= hx509_certs_init(context
, "MEMORY:test-crypto", 0, NULL
, &certs
);
1820 for (i
= 0; i
< argc
; i
++) {
1821 ret
= hx509_certs_append(context
, certs
, lock
, argv
[i
]);
1823 hx509_err(context
, 1, ret
, "hx509_certs_append");
1826 ret
= hx509_verify_init_ctx(context
, &vctx
);
1828 hx509_err(context
, 1, ret
, "hx509_verify_init_ctx");
1830 hx509_verify_attach_anchors(vctx
, certs
);
1832 ret
= hx509_certs_iter(context
, certs
, test_one_cert
, vctx
);
1834 hx509_certs_free(&certs
);
1840 statistic_print(struct statistic_print_options
*opt
, int argc
, char **argv
)
1844 if (stat_file_string
== NULL
)
1845 errx(1, "no stat file");
1847 if (opt
->type_integer
)
1848 type
= opt
->type_integer
;
1850 hx509_query_unparse_stats(context
, type
, stdout
);
1859 crl_sign(struct crl_sign_options
*opt
, int argc
, char **argv
)
1862 heim_octet_string os
;
1863 hx509_cert signer
= NULL
;
1867 hx509_lock_init(context
, &lock
);
1868 lock_strings(lock
, &opt
->pass_strings
);
1870 ret
= hx509_crl_alloc(context
, &crl
);
1872 errx(1, "crl alloc");
1874 if (opt
->signer_string
== NULL
)
1875 errx(1, "signer missing");
1878 hx509_certs certs
= NULL
;
1881 ret
= hx509_certs_init(context
, opt
->signer_string
, 0,
1884 hx509_err(context
, 1, ret
,
1885 "hx509_certs_init: %s", opt
->signer_string
);
1887 ret
= hx509_query_alloc(context
, &q
);
1889 hx509_err(context
, 1, ret
, "hx509_query_alloc: %d", ret
);
1891 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
1893 ret
= hx509_certs_find(context
, certs
, q
, &signer
);
1894 hx509_query_free(context
, q
);
1895 hx509_certs_free(&certs
);
1897 hx509_err(context
, 1, ret
, "no signer certificate found");
1900 if (opt
->lifetime_string
) {
1903 delta
= parse_time(opt
->lifetime_string
, "day");
1905 errx(1, "Invalid lifetime: %s", opt
->lifetime_string
);
1907 hx509_crl_lifetime(context
, crl
, delta
);
1911 hx509_certs revoked
= NULL
;
1914 ret
= hx509_certs_init(context
, "MEMORY:revoked-certs", 0,
1917 for (i
= 0; i
< argc
; i
++) {
1918 ret
= hx509_certs_append(context
, revoked
, lock
, argv
[i
]);
1920 hx509_err(context
, 1, ret
, "hx509_certs_append: %s", argv
[i
]);
1923 hx509_crl_add_revoked_certs(context
, crl
, revoked
);
1924 hx509_certs_free(&revoked
);
1927 hx509_crl_sign(context
, signer
, crl
, &os
);
1929 if (opt
->crl_file_string
)
1930 rk_dumpdata(opt
->crl_file_string
, os
.data
, os
.length
);
1934 hx509_crl_free(context
, &crl
);
1935 hx509_cert_free(signer
);
1936 hx509_lock_free(lock
);
1946 help(void *opt
, int argc
, char **argv
)
1948 sl_slc_help(commands
, argc
, argv
);
1953 main(int argc
, char **argv
)
1955 int ret
, optidx
= 0;
1957 setprogname (argv
[0]);
1959 if(getarg(args
, num_args
, argc
, argv
, &optidx
))
1964 print_version(NULL
);
1973 ret
= hx509_context_init(&context
);
1975 errx(1, "hx509_context_init failed with %d", ret
);
1977 if (stat_file_string
)
1978 hx509_query_statistic_file(context
, stat_file_string
);
1980 ret
= sl_command(commands
, argc
, argv
);
1982 warnx ("unrecognized command: %s", argv
[0]);
1984 hx509_context_free(&context
);