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 cms_verify_sd(struct cms_verify_sd_options
*opt
, int argc
, char **argv
)
151 hx509_verify_ctx ctx
= NULL
;
153 heim_octet_string c
, co
, signeddata
, *sd
= NULL
;
154 hx509_certs store
= NULL
;
155 hx509_certs signers
= NULL
;
156 hx509_certs anchors
= NULL
;
163 if (opt
->missing_revoke_flag
)
164 hx509_context_set_missing_revoke(context
, 1);
166 hx509_lock_init(context
, &lock
);
167 lock_strings(lock
, &opt
->pass_strings
);
169 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
171 err(1, "map_file: %s: %d", argv
[0], ret
);
173 if (opt
->signed_content_string
) {
174 ret
= _hx509_map_file_os(opt
->signed_content_string
, &signeddata
, NULL
);
176 err(1, "map_file: %s: %d", opt
->signed_content_string
, ret
);
180 ret
= hx509_verify_init_ctx(context
, &ctx
);
182 ret
= hx509_certs_init(context
, "MEMORY:cms-anchors", 0, NULL
, &anchors
);
183 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &store
);
185 certs_strings(context
, "anchors", anchors
, lock
, &opt
->anchors_strings
);
186 certs_strings(context
, "store", store
, lock
, &opt
->certificate_strings
);
191 if (opt
->content_info_flag
) {
192 heim_octet_string uwco
;
195 ret
= hx509_cms_unwrap_ContentInfo(&co
, &oid
, &uwco
, NULL
);
197 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret
);
199 if (der_heim_oid_cmp(&oid
, oid_id_pkcs7_signedData()) != 0)
200 errx(1, "Content is not SignedData");
206 hx509_verify_attach_anchors(ctx
, anchors
);
208 ret
= hx509_cms_verify_signed(context
, ctx
, co
.data
, co
.length
, sd
,
209 store
, &type
, &c
, &signers
);
211 der_free_octet_string(&co
);
213 hx509_err(context
, 1, ret
, "hx509_cms_verify_signed");
217 der_print_heim_oid(&type
, '.', &str
);
218 printf("type: %s\n", str
);
222 printf("signers:\n");
223 hx509_certs_iter(context
, signers
, hx509_ci_print_names
, stdout
);
225 hx509_verify_destroy_ctx(ctx
);
227 hx509_certs_free(&store
);
228 hx509_certs_free(&signers
);
229 hx509_certs_free(&anchors
);
231 hx509_lock_free(lock
);
233 ret
= _hx509_write_file(argv
[1], c
.data
, c
.length
);
235 errx(1, "hx509_write_file: %d", ret
);
237 der_free_octet_string(&c
);
238 _hx509_unmap_file(p
, sz
);
240 _hx509_unmap_file_os(sd
);
246 cms_create_sd(struct cms_create_sd_options
*opt
, int argc
, char **argv
)
248 heim_oid contentType
;
249 hx509_peer_info peer
= NULL
;
253 hx509_certs store
, pool
, anchors
;
258 char *signer_name
= NULL
;
260 memset(&contentType
, 0, sizeof(contentType
));
265 hx509_lock_init(context
, &lock
);
266 lock_strings(lock
, &opt
->pass_strings
);
268 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &store
);
269 ret
= hx509_certs_init(context
, "MEMORY:cert-pool", 0, NULL
, &pool
);
271 certs_strings(context
, "store", store
, lock
, &opt
->certificate_strings
);
272 certs_strings(context
, "pool", pool
, lock
, &opt
->pool_strings
);
274 if (opt
->anchors_strings
.num_strings
) {
275 ret
= hx509_certs_init(context
, "MEMORY:cert-anchors",
277 certs_strings(context
, "anchors", anchors
, lock
, &opt
->anchors_strings
);
281 if (opt
->detached_signature_flag
)
282 flags
|= HX509_CMS_SIGATURE_DETACHED
;
283 if (opt
->id_by_name_flag
)
284 flags
|= HX509_CMS_SIGATURE_ID_NAME
;
286 ret
= hx509_query_alloc(context
, &q
);
288 errx(1, "hx509_query_alloc: %d", ret
);
290 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
291 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE
);
293 if (opt
->signer_string
)
294 hx509_query_match_friendly_name(q
, opt
->signer_string
);
296 ret
= hx509_certs_find(context
, store
, q
, &cert
);
297 hx509_query_free(context
, q
);
299 hx509_err(context
, 1, ret
, "hx509_certs_find");
301 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
303 err(1, "map_file: %s: %d", argv
[0], ret
);
305 if (opt
->peer_alg_strings
.num_strings
)
306 peer_strings(context
, &peer
, &opt
->peer_alg_strings
);
308 parse_oid(opt
->content_type_string
, oid_id_pkcs7_data(), &contentType
);
310 ret
= hx509_cms_create_signed_1(context
,
322 errx(1, "hx509_cms_create_signed: %d", ret
);
327 ret
= hx509_cert_get_subject(cert
, &name
);
329 errx(1, "hx509_cert_get_subject");
331 ret
= hx509_name_to_string(name
, &signer_name
);
332 hx509_name_free(&name
);
334 errx(1, "hx509_name_to_string");
338 hx509_certs_free(&anchors
);
339 hx509_certs_free(&pool
);
340 hx509_cert_free(cert
);
341 hx509_certs_free(&store
);
342 _hx509_unmap_file(p
, sz
);
343 hx509_lock_free(lock
);
344 hx509_peer_info_free(peer
);
345 der_free_oid(&contentType
);
347 if (opt
->content_info_flag
) {
348 heim_octet_string wo
;
350 ret
= hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &o
, &wo
);
352 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret
);
354 der_free_octet_string(&o
);
359 hx509_pem_header
*header
= NULL
;
362 hx509_pem_add_header(&header
, "Content-disposition",
363 opt
->detached_signature_flag
? "detached" : "inline");
364 hx509_pem_add_header(&header
, "Signer", signer_name
);
366 f
= fopen(argv
[1], "w");
368 err(1, "open %s", argv
[1]);
370 ret
= hx509_pem_write(context
, "CMS SIGNEDDATA", header
, f
,
373 hx509_pem_free_header(header
);
375 errx(1, "hx509_pem_write: %d", ret
);
378 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
380 errx(1, "hx509_write_file: %d", ret
);
390 cms_unenvelope(struct cms_unenvelope_options
*opt
, int argc
, char **argv
)
392 heim_oid contentType
= { 0, NULL
};
393 heim_octet_string o
, co
;
400 hx509_lock_init(context
, &lock
);
401 lock_strings(lock
, &opt
->pass_strings
);
403 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
405 err(1, "map_file: %s: %d", argv
[0], ret
);
410 if (opt
->content_info_flag
) {
411 heim_octet_string uwco
;
414 ret
= hx509_cms_unwrap_ContentInfo(&co
, &oid
, &uwco
, NULL
);
416 errx(1, "hx509_cms_unwrap_ContentInfo: %d", ret
);
418 if (der_heim_oid_cmp(&oid
, oid_id_pkcs7_envelopedData()) != 0)
419 errx(1, "Content is not SignedData");
425 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
427 errx(1, "hx509_certs_init: MEMORY: %d", ret
);
429 certs_strings(context
, "store", certs
, lock
, &opt
->certificate_strings
);
431 ret
= hx509_cms_unenvelope(context
, certs
, 0, co
.data
, co
.length
,
432 NULL
, &contentType
, &o
);
434 der_free_octet_string(&co
);
436 hx509_err(context
, 1, ret
, "hx509_cms_unenvelope");
438 _hx509_unmap_file(p
, sz
);
439 hx509_lock_free(lock
);
440 hx509_certs_free(&certs
);
441 der_free_oid(&contentType
);
443 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
445 errx(1, "hx509_write_file: %d", ret
);
447 der_free_octet_string(&o
);
453 cms_create_enveloped(struct cms_envelope_options
*opt
, int argc
, char **argv
)
455 heim_oid contentType
;
457 const heim_oid
*enctype
= NULL
;
466 memset(&contentType
, 0, sizeof(contentType
));
468 hx509_lock_init(context
, &lock
);
469 lock_strings(lock
, &opt
->pass_strings
);
471 ret
= _hx509_map_file(argv
[0], &p
, &sz
, NULL
);
473 err(1, "map_file: %s: %d", argv
[0], ret
);
475 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
477 certs_strings(context
, "store", certs
, lock
, &opt
->certificate_strings
);
479 if (opt
->encryption_type_string
) {
480 enctype
= hx509_crypto_enctype_by_name(opt
->encryption_type_string
);
482 errx(1, "encryption type: %s no found",
483 opt
->encryption_type_string
);
486 ret
= hx509_query_alloc(context
, &q
);
488 errx(1, "hx509_query_alloc: %d", ret
);
490 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_ENCIPHERMENT
);
492 ret
= hx509_certs_find(context
, certs
, q
, &cert
);
493 hx509_query_free(context
, q
);
495 errx(1, "hx509_certs_find: %d", ret
);
497 parse_oid(opt
->content_type_string
, oid_id_pkcs7_data(), &contentType
);
499 ret
= hx509_cms_envelope_1(context
, 0, cert
, p
, sz
, enctype
,
502 errx(1, "hx509_cms_envelope_1: %d", ret
);
504 hx509_cert_free(cert
);
505 hx509_certs_free(&certs
);
506 _hx509_unmap_file(p
, sz
);
507 der_free_oid(&contentType
);
509 if (opt
->content_info_flag
) {
510 heim_octet_string wo
;
512 ret
= hx509_cms_wrap_ContentInfo(oid_id_pkcs7_envelopedData(), &o
, &wo
);
514 errx(1, "hx509_cms_wrap_ContentInfo: %d", ret
);
516 der_free_octet_string(&o
);
520 hx509_lock_free(lock
);
522 ret
= _hx509_write_file(argv
[1], o
.data
, o
.length
);
524 errx(1, "hx509_write_file: %d", ret
);
526 der_free_octet_string(&o
);
532 print_certificate(hx509_context hxcontext
, hx509_cert cert
, int verbose
)
539 fn
= hx509_cert_get_friendly_name(cert
);
541 printf(" friendly name: %s\n", fn
);
542 printf(" private key: %s\n",
543 _hx509_cert_private_key(cert
) ? "yes" : "no");
545 ret
= hx509_cert_get_issuer(cert
, &name
);
546 hx509_name_to_string(name
, &str
);
547 hx509_name_free(&name
);
548 printf(" issuer: \"%s\"\n", str
);
551 ret
= hx509_cert_get_subject(cert
, &name
);
552 hx509_name_to_string(name
, &str
);
553 hx509_name_free(&name
);
554 printf(" subject: \"%s\"\n", str
);
558 heim_integer serialNumber
;
560 hx509_cert_get_serialnumber(cert
, &serialNumber
);
561 der_print_hex_heim_integer(&serialNumber
, &str
);
562 der_free_heim_integer(&serialNumber
);
563 printf(" serial: %s\n", str
);
567 printf(" keyusage: ");
568 ret
= hx509_cert_keyusage_print(hxcontext
, cert
, &str
);
576 hx509_validate_ctx vctx
;
578 hx509_validate_ctx_init(hxcontext
, &vctx
);
579 hx509_validate_ctx_set_print(vctx
, hx509_print_stdout
, stdout
);
580 hx509_validate_ctx_add_flags(vctx
, HX509_VALIDATE_F_VALIDATE
);
581 hx509_validate_ctx_add_flags(vctx
, HX509_VALIDATE_F_VERBOSE
);
583 hx509_validate_cert(hxcontext
, vctx
, cert
);
585 hx509_validate_ctx_free(vctx
);
596 print_f(hx509_context hxcontext
, void *ctx
, hx509_cert cert
)
598 struct print_s
*s
= ctx
;
600 printf("cert: %d\n", s
->counter
++);
601 print_certificate(context
, cert
, s
->verbose
);
607 pcert_print(struct print_options
*opt
, int argc
, char **argv
)
614 s
.verbose
= opt
->content_flag
;
616 hx509_lock_init(context
, &lock
);
617 lock_strings(lock
, &opt
->pass_strings
);
621 ret
= hx509_certs_init(context
, argv
[0], 0, lock
, &certs
);
623 hx509_err(context
, 1, ret
, "hx509_certs_init");
625 hx509_certs_info(context
, certs
, NULL
, NULL
);
626 hx509_certs_iter(context
, certs
, print_f
, &s
);
627 hx509_certs_free(&certs
);
631 hx509_lock_free(lock
);
638 validate_f(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
640 hx509_validate_cert(hxcontext
, ctx
, c
);
645 pcert_validate(struct validate_options
*opt
, int argc
, char **argv
)
647 hx509_validate_ctx ctx
;
651 hx509_lock_init(context
, &lock
);
652 lock_strings(lock
, &opt
->pass_strings
);
654 hx509_validate_ctx_init(context
, &ctx
);
655 hx509_validate_ctx_set_print(ctx
, hx509_print_stdout
, stdout
);
656 hx509_validate_ctx_add_flags(ctx
, HX509_VALIDATE_F_VALIDATE
);
660 ret
= hx509_certs_init(context
, argv
[0], 0, lock
, &certs
);
662 errx(1, "hx509_certs_init: %d", ret
);
663 hx509_certs_iter(context
, certs
, validate_f
, ctx
);
664 hx509_certs_free(&certs
);
667 hx509_validate_ctx_free(ctx
);
669 hx509_lock_free(lock
);
675 certificate_copy(struct certificate_copy_options
*opt
, int argc
, char **argv
)
681 hx509_lock_init(context
, &lock
);
682 lock_strings(lock
, &opt
->in_pass_strings
);
684 ret
= hx509_certs_init(context
, argv
[argc
- 1],
685 HX509_CERTS_CREATE
, lock
, &certs
);
687 hx509_err(context
, 1, ret
, "hx509_certs_init");
691 ret
= hx509_certs_append(context
, certs
, lock
, argv
[0]);
693 hx509_err(context
, 1, ret
, "hx509_certs_append");
697 ret
= hx509_certs_store(context
, certs
, 0, NULL
);
699 hx509_err(context
, 1, ret
, "hx509_certs_store");
701 hx509_certs_free(&certs
);
702 hx509_lock_free(lock
);
708 hx509_verify_ctx ctx
;
710 const char *hostname
;
715 verify_f(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
717 struct verify
*v
= ctx
;
720 ret
= hx509_verify_path(hxcontext
, v
->ctx
, c
, v
->chain
);
722 char *s
= hx509_get_error_string(hxcontext
, ret
);
723 printf("verify_path: %s: %d\n", s
, ret
);
724 hx509_free_error_string(s
);
730 ret
= hx509_verify_hostname(hxcontext
, c
, 0, HX509_HN_HOSTNAME
,
731 v
->hostname
, NULL
, 0);
733 printf("verify_hostname: %d\n", ret
);
742 pcert_verify(struct verify_options
*opt
, int argc
, char **argv
)
744 hx509_certs anchors
, chain
, certs
;
745 hx509_revoke_ctx revoke_ctx
;
746 hx509_verify_ctx ctx
;
750 memset(&v
, 0, sizeof(v
));
752 if (opt
->missing_revoke_flag
)
753 hx509_context_set_missing_revoke(context
, 1);
755 ret
= hx509_verify_init_ctx(context
, &ctx
);
756 ret
= hx509_certs_init(context
, "MEMORY:anchors", 0, NULL
, &anchors
);
757 ret
= hx509_certs_init(context
, "MEMORY:chain", 0, NULL
, &chain
);
758 ret
= hx509_certs_init(context
, "MEMORY:certs", 0, NULL
, &certs
);
760 if (opt
->allow_proxy_certificate_flag
)
761 hx509_verify_set_proxy_certificate(ctx
, 1);
763 if (opt
->time_string
) {
768 memset(&tm
, 0, sizeof(tm
));
770 p
= strptime (opt
->time_string
, "%Y-%m-%d", &tm
);
772 errx(1, "Failed to parse time %s, need to be on format %%Y-%%m-%%d",
777 hx509_verify_set_time(ctx
, t
);
780 if (opt
->hostname_string
)
781 v
.hostname
= opt
->hostname_string
;
782 if (opt
->max_depth_integer
)
783 hx509_verify_set_max_depth(ctx
, opt
->max_depth_integer
);
785 ret
= hx509_revoke_init(context
, &revoke_ctx
);
787 errx(1, "hx509_revoke_init: %d", ret
);
792 if (strncmp(s
, "chain:", 6) == 0) {
795 ret
= hx509_certs_append(context
, chain
, NULL
, s
);
797 hx509_err(context
, 1, ret
, "hx509_certs_append: chain: %s: %d", s
, ret
);
799 } else if (strncmp(s
, "anchor:", 7) == 0) {
802 ret
= hx509_certs_append(context
, anchors
, NULL
, s
);
804 hx509_err(context
, 1, ret
, "hx509_certs_append: anchor: %s: %d", s
, ret
);
806 } else if (strncmp(s
, "cert:", 5) == 0) {
809 ret
= hx509_certs_append(context
, certs
, NULL
, s
);
811 hx509_err(context
, 1, ret
, "hx509_certs_append: certs: %s: %d",
814 } else if (strncmp(s
, "crl:", 4) == 0) {
817 ret
= hx509_revoke_add_crl(context
, revoke_ctx
, s
);
819 errx(1, "hx509_revoke_add_crl: %s: %d", s
, ret
);
821 } else if (strncmp(s
, "ocsp:", 4) == 0) {
824 ret
= hx509_revoke_add_ocsp(context
, revoke_ctx
, s
);
826 errx(1, "hx509_revoke_add_ocsp: %s: %d", s
, ret
);
829 errx(1, "unknown option to verify: `%s'\n", s
);
833 hx509_verify_attach_anchors(ctx
, anchors
);
834 hx509_verify_attach_revoke(ctx
, revoke_ctx
);
839 hx509_certs_iter(context
, certs
, verify_f
, &v
);
841 hx509_verify_destroy_ctx(ctx
);
843 hx509_certs_free(&certs
);
844 hx509_certs_free(&chain
);
845 hx509_certs_free(&anchors
);
847 hx509_revoke_free(&revoke_ctx
);
850 printf("failed verifing %d checks\n", v
.errors
);
858 query(struct query_options
*opt
, int argc
, char **argv
)
866 ret
= hx509_query_alloc(context
, &q
);
868 errx(1, "hx509_query_alloc: %d", ret
);
870 hx509_lock_init(context
, &lock
);
871 lock_strings(lock
, &opt
->pass_strings
);
873 ret
= hx509_certs_init(context
, "MEMORY:cert-store", 0, NULL
, &certs
);
877 ret
= hx509_certs_append(context
, certs
, lock
, argv
[0]);
879 errx(1, "hx509_certs_append: %s: %d", argv
[0], ret
);
885 if (opt
->friendlyname_string
)
886 hx509_query_match_friendly_name(q
, opt
->friendlyname_string
);
888 if (opt
->private_key_flag
)
889 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
891 if (opt
->keyEncipherment_flag
)
892 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_ENCIPHERMENT
);
894 if (opt
->digitalSignature_flag
)
895 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE
);
897 ret
= hx509_certs_find(context
, certs
, q
, &c
);
898 hx509_query_free(context
, q
);
900 printf("no match found (%d)\n", ret
);
902 printf("match found\n");
904 print_certificate(context
, c
, 0);
908 hx509_certs_free(&certs
);
910 hx509_lock_free(lock
);
916 ocsp_fetch(struct ocsp_fetch_options
*opt
, int argc
, char **argv
)
918 hx509_certs reqcerts
, pool
;
919 heim_octet_string req
, nonce_data
, *nonce
= &nonce_data
;
923 const char *url
= "/";
925 memset(&nonce
, 0, sizeof(nonce
));
927 hx509_lock_init(context
, &lock
);
928 lock_strings(lock
, &opt
->pass_strings
);
931 if (!opt
->nonce_flag
)
934 if (opt
->url_path_string
)
935 url
= opt
->url_path_string
;
937 ret
= hx509_certs_init(context
, "MEMORY:ocsp-pool", 0, NULL
, &pool
);
939 certs_strings(context
, "ocsp-pool", pool
, lock
, &opt
->pool_strings
);
943 ret
= hx509_certs_init(context
, "MEMORY:ocsp-req", 0, NULL
, &reqcerts
);
945 for (i
= 1; i
< argc
; i
++) {
946 ret
= hx509_certs_append(context
, reqcerts
, lock
, argv
[i
]);
948 errx(1, "hx509_certs_append: req: %s: %d", argv
[i
], ret
);
951 ret
= hx509_ocsp_request(context
, reqcerts
, pool
, NULL
, NULL
, &req
, nonce
);
953 errx(1, "hx509_ocsp_request: req: %d", ret
);
958 f
= fopen(file
, "w");
963 "POST %s HTTP/1.0\r\n"
964 "Content-Type: application/ocsp-request\r\n"
965 "Content-Length: %ld\r\n"
968 (unsigned long)req
.length
);
969 fwrite(req
.data
, req
.length
, 1, f
);
974 der_free_octet_string(nonce
);
976 hx509_certs_free(&reqcerts
);
977 hx509_certs_free(&pool
);
983 ocsp_print(struct ocsp_print_options
*opt
, int argc
, char **argv
)
985 hx509_revoke_ocsp_print(context
, argv
[0], stdout
);
994 verify_o(hx509_context hxcontext
, void *ctx
, hx509_cert c
)
996 heim_octet_string
*os
= ctx
;
1000 ret
= hx509_ocsp_verify(context
, 0, c
, 0,
1001 os
->data
, os
->length
, &expiration
);
1003 char *s
= hx509_get_error_string(hxcontext
, ret
);
1004 printf("ocsp_verify: %s: %d\n", s
, ret
);
1005 hx509_free_error_string(s
);
1007 printf("expire: %d\n", (int)expiration
);
1014 ocsp_verify(struct ocsp_verify_options
*opt
, int argc
, char **argv
)
1019 heim_octet_string os
;
1021 hx509_lock_init(context
, &lock
);
1023 if (opt
->ocsp_file_string
== NULL
)
1024 errx(1, "no ocsp file given");
1026 ret
= _hx509_map_file(opt
->ocsp_file_string
, &os
.data
, &os
.length
, NULL
);
1028 err(1, "map_file: %s: %d", argv
[0], ret
);
1030 ret
= hx509_certs_init(context
, "MEMORY:test-certs", 0, NULL
, &certs
);
1032 for (i
= 0; i
< argc
; i
++) {
1033 ret
= hx509_certs_append(context
, certs
, lock
, argv
[i
]);
1035 hx509_err(context
, 1, ret
, "hx509_certs_append: %s", argv
[i
]);
1038 ret
= hx509_certs_iter(context
, certs
, verify_o
, &os
);
1040 hx509_certs_free(&certs
);
1041 _hx509_unmap_file(os
.data
, os
.length
);
1042 hx509_lock_free(lock
);
1048 read_private_key(const char *fn
, hx509_private_key
*key
)
1050 hx509_private_key
*keys
;
1056 ret
= hx509_certs_init(context
, fn
, 0, NULL
, &certs
);
1058 hx509_err(context
, 1, ret
, "hx509_certs_init: %s", fn
);
1060 ret
= _hx509_certs_keys_get(context
, certs
, &keys
);
1061 hx509_certs_free(&certs
);
1063 hx509_err(context
, 1, ret
, "hx509_certs_keys_get");
1064 if (keys
[0] == NULL
)
1065 errx(1, "no keys in key store: %s", fn
);
1067 *key
= _hx509_private_key_ref(keys
[0]);
1068 _hx509_certs_keys_free(context
, keys
);
1074 get_key(const char *fn
, const char *type
, int optbits
,
1075 hx509_private_key
*signer
)
1082 unsigned char *p0
, *p
;
1087 errx(1, "no key argument, don't know here to store key");
1089 if (strcasecmp(type
, "rsa") != 0)
1090 errx(1, "can only handle rsa keys for now");
1093 BN_set_word(e
, 0x10001);
1100 errx(1, "RSA_new failed");
1102 ret
= RSA_generate_key_ex(rsa
, bits
, e
, NULL
);
1104 errx(1, "RSA_new failed");
1108 len
= i2d_RSAPrivateKey(rsa
, NULL
);
1110 p0
= p
= malloc(len
);
1112 errx(1, "out of memory");
1114 i2d_RSAPrivateKey(rsa
, &p
);
1116 rk_dumpdata(fn
, p0
, len
);
1122 } else if (fn
== NULL
)
1123 err(1, "no private key");
1125 ret
= read_private_key(fn
, signer
);
1127 err(1, "read_private_key");
1131 request_create(struct request_create_options
*opt
, int argc
, char **argv
)
1133 heim_octet_string request
;
1136 hx509_private_key signer
;
1137 SubjectPublicKeyInfo key
;
1138 const char *outfile
= argv
[0];
1140 memset(&key
, 0, sizeof(key
));
1142 get_key(opt
->key_string
,
1143 opt
->generate_key_string
,
1144 opt
->key_bits_integer
,
1147 _hx509_request_init(context
, &req
);
1149 if (opt
->subject_string
) {
1150 hx509_name name
= NULL
;
1152 ret
= hx509_parse_name(context
, opt
->subject_string
, &name
);
1154 errx(1, "hx509_parse_name: %d\n", ret
);
1155 _hx509_request_set_name(context
, req
, name
);
1157 if (opt
->verbose_flag
) {
1159 hx509_name_to_string(name
, &s
);
1162 hx509_name_free(&name
);
1165 for (i
= 0; i
< opt
->email_strings
.num_strings
; i
++) {
1166 ret
= _hx509_request_add_email(context
, req
,
1167 opt
->email_strings
.strings
[i
]);
1170 for (i
= 0; i
< opt
->dnsname_strings
.num_strings
; i
++) {
1171 ret
= _hx509_request_add_dns_name(context
, req
,
1172 opt
->dnsname_strings
.strings
[i
]);
1176 ret
= _hx509_private_key2SPKI(context
, signer
, &key
);
1178 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1180 ret
= _hx509_request_set_SubjectPublicKeyInfo(context
,
1183 free_SubjectPublicKeyInfo(&key
);
1185 hx509_err(context
, 1, ret
, "_hx509_request_set_SubjectPublicKeyInfo");
1187 ret
= _hx509_request_to_pkcs10(context
,
1192 hx509_err(context
, 1, ret
, "_hx509_request_to_pkcs10");
1194 _hx509_private_key_free(&signer
);
1195 _hx509_request_free(&req
);
1198 rk_dumpdata(outfile
, request
.data
, request
.length
);
1199 der_free_octet_string(&request
);
1205 request_print(struct request_print_options
*opt
, int argc
, char **argv
)
1209 printf("request print\n");
1211 for (i
= 0; i
< argc
; i
++) {
1214 ret
= _hx509_request_parse(context
, argv
[i
], &req
);
1216 hx509_err(context
, 1, ret
, "parse_request: %s", argv
[i
]);
1218 ret
= _hx509_request_print(context
, req
, stdout
);
1219 _hx509_request_free(&req
);
1221 hx509_err(context
, 1, ret
, "Failed to print file %s", argv
[i
]);
1228 info(void *opt
, int argc
, char **argv
)
1231 ENGINE_add_conf_module();
1234 const RSA_METHOD
*m
= RSA_get_default_method();
1236 printf("rsa: %s\n", m
->name
);
1239 const DH_METHOD
*m
= DH_get_default_method();
1241 printf("dh: %s\n", m
->name
);
1244 int ret
= RAND_status();
1245 printf("rand: %s\n", ret
== 1 ? "ok" : "not available");
1252 random_data(void *opt
, int argc
, char **argv
)
1257 len
= parse_bytes(argv
[0], "byte");
1259 fprintf(stderr
, "bad argument to random-data\n");
1265 fprintf(stderr
, "out of memory\n");
1269 ret
= RAND_bytes(ptr
, len
);
1272 fprintf(stderr
, "did not get cryptographic strong random\n");
1276 fwrite(ptr
, len
, 1, stdout
);
1285 crypto_available(struct crypto_available_options
*opt
, int argc
, char **argv
)
1287 AlgorithmIdentifier
*val
;
1288 unsigned int len
, i
;
1291 if (opt
->type_string
) {
1292 if (strcmp(opt
->type_string
, "all") == 0)
1293 type
= HX509_SELECT_ALL
;
1294 else if (strcmp(opt
->type_string
, "digest") == 0)
1295 type
= HX509_SELECT_DIGEST
;
1296 else if (strcmp(opt
->type_string
, "public-sig") == 0)
1297 type
= HX509_SELECT_PUBLIC_SIG
;
1298 else if (strcmp(opt
->type_string
, "secret") == 0)
1299 type
= HX509_SELECT_SECRET_ENC
;
1301 errx(1, "unknown type: %s", opt
->type_string
);
1303 type
= HX509_SELECT_ALL
;
1305 ret
= hx509_crypto_available(context
, type
, NULL
, &val
, &len
);
1307 errx(1, "hx509_crypto_available");
1309 for (i
= 0; i
< len
; i
++) {
1311 der_print_heim_oid (&val
[i
].algorithm
, '.', &s
);
1316 hx509_crypto_free_algs(val
, len
);
1322 crypto_select(struct crypto_select_options
*opt
, int argc
, char **argv
)
1324 hx509_peer_info peer
= NULL
;
1325 AlgorithmIdentifier selected
;
1329 if (opt
->type_string
) {
1330 if (strcmp(opt
->type_string
, "digest") == 0)
1331 type
= HX509_SELECT_DIGEST
;
1332 else if (strcmp(opt
->type_string
, "public-sig") == 0)
1333 type
= HX509_SELECT_PUBLIC_SIG
;
1334 else if (strcmp(opt
->type_string
, "secret") == 0)
1335 type
= HX509_SELECT_SECRET_ENC
;
1337 errx(1, "unknown type: %s", opt
->type_string
);
1339 type
= HX509_SELECT_DIGEST
;
1341 if (opt
->peer_cmstype_strings
.num_strings
)
1342 peer_strings(context
, &peer
, &opt
->peer_cmstype_strings
);
1344 ret
= hx509_crypto_select(context
, type
, NULL
, peer
, &selected
);
1346 errx(1, "hx509_crypto_available");
1348 der_print_heim_oid (&selected
.algorithm
, '.', &s
);
1351 free_AlgorithmIdentifier(&selected
);
1353 hx509_peer_info_free(peer
);
1359 hxtool_hex(struct hex_options
*opt
, int argc
, char **argv
)
1362 if (opt
->decode_flag
) {
1363 char buf
[1024], buf2
[1024], *p
;
1366 while(fgets(buf
, sizeof(buf
), stdin
) != NULL
) {
1367 buf
[strcspn(buf
, "\r\n")] = '\0';
1369 while(isspace(*(unsigned char *)p
))
1371 len
= hex_decode(p
, buf2
, strlen(p
));
1373 errx(1, "hex_decode failed");
1374 if (fwrite(buf2
, 1, len
, stdout
) != len
)
1375 errx(1, "fwrite failed");
1381 while((len
= fread(buf
, 1, sizeof(buf
), stdin
)) != 0) {
1382 len
= hex_encode(buf
, len
, &p
);
1383 fprintf(stdout
, "%s\n", p
);
1391 eval_types(hx509_context context
,
1393 const struct certificate_sign_options
*opt
)
1398 for (i
= 0; i
< opt
->type_strings
.num_strings
; i
++) {
1399 const char *type
= opt
->type_strings
.strings
[i
];
1401 if (strcmp(type
, "https-server") == 0) {
1402 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1403 oid_id_pkix_kp_serverAuth());
1405 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1406 } else if (strcmp(type
, "https-client") == 0) {
1407 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1408 oid_id_pkix_kp_clientAuth());
1410 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1411 } else if (strcmp(type
, "peap-server") == 0) {
1412 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1413 oid_id_pkix_kp_serverAuth());
1415 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1416 } else if (strcmp(type
, "pkinit-kdc") == 0) {
1418 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1419 oid_id_pkkdcekuoid());
1421 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1422 } else if (strcmp(type
, "pkinit-client") == 0) {
1424 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1427 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1429 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1430 oid_id_ms_client_authentication());
1432 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1434 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1435 oid_id_pkinit_ms_eku());
1437 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1439 } else if (strcmp(type
, "email") == 0) {
1440 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1441 oid_id_pkix_kp_emailProtection());
1443 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1445 errx(1, "unknown type %s", type
);
1449 errx(1, "More the one PK-INIT type given");
1451 if (opt
->pk_init_principal_string
) {
1453 errx(1, "pk-init principal given but no pk-init oid");
1455 ret
= hx509_ca_tbs_add_san_pkinit(context
, tbs
,
1456 opt
->pk_init_principal_string
);
1458 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_pkinit");
1461 if (opt
->ms_upn_string
) {
1463 errx(1, "MS up given but no pk-init oid");
1465 ret
= hx509_ca_tbs_add_san_ms_upn(context
, tbs
, opt
->ms_upn_string
);
1467 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_ms_upn");
1471 for (i
= 0; i
< opt
->hostname_strings
.num_strings
; i
++) {
1472 const char *hostname
= opt
->hostname_strings
.strings
[i
];
1474 ret
= hx509_ca_tbs_add_san_hostname(context
, tbs
, hostname
);
1476 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_hostname");
1479 for (i
= 0; i
< opt
->email_strings
.num_strings
; i
++) {
1480 const char *email
= opt
->email_strings
.strings
[i
];
1482 ret
= hx509_ca_tbs_add_san_rfc822name(context
, tbs
, email
);
1484 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_hostname");
1486 ret
= hx509_ca_tbs_add_eku(context
, tbs
,
1487 oid_id_pkix_kp_emailProtection());
1489 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_eku");
1492 if (opt
->jid_string
) {
1493 ret
= hx509_ca_tbs_add_san_jid(context
, tbs
, opt
->jid_string
);
1495 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_san_jid");
1502 hxtool_ca(struct certificate_sign_options
*opt
, int argc
, char **argv
)
1506 hx509_cert signer
= NULL
, cert
= NULL
;
1507 hx509_private_key private_key
= NULL
;
1508 hx509_private_key cert_key
= NULL
;
1509 hx509_name subject
= NULL
;
1510 SubjectPublicKeyInfo spki
;
1513 memset(&spki
, 0, sizeof(spki
));
1515 if (opt
->ca_certificate_string
== NULL
&& !opt
->self_signed_flag
)
1516 errx(1, "--ca-certificate argument missing (not using --self-signed)");
1517 if (opt
->ca_private_key_string
== NULL
&& opt
->generate_key_string
== NULL
&& opt
->self_signed_flag
)
1518 errx(1, "--ca-private-key argument missing (using --self-signed)");
1519 if (opt
->certificate_string
== NULL
)
1520 errx(1, "--certificate argument missing");
1522 if (opt
->template_certificate_string
) {
1523 if (opt
->template_fields_string
== NULL
)
1524 errx(1, "--template-certificate not no --template-fields");
1527 if (opt
->lifetime_string
) {
1528 delta
= parse_time(opt
->lifetime_string
, "day");
1530 errx(1, "Invalid lifetime: %s", opt
->lifetime_string
);
1533 if (opt
->ca_certificate_string
) {
1534 hx509_certs cacerts
= NULL
;
1537 ret
= hx509_certs_init(context
, opt
->ca_certificate_string
, 0,
1540 hx509_err(context
, 1, ret
,
1541 "hx509_certs_init: %s", opt
->ca_certificate_string
);
1543 ret
= hx509_query_alloc(context
, &q
);
1545 errx(1, "hx509_query_alloc: %d", ret
);
1547 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
1548 if (!opt
->issue_proxy_flag
)
1549 hx509_query_match_option(q
, HX509_QUERY_OPTION_KU_KEYCERTSIGN
);
1551 ret
= hx509_certs_find(context
, cacerts
, q
, &signer
);
1552 hx509_query_free(context
, q
);
1553 hx509_certs_free(&cacerts
);
1555 hx509_err(context
, 1, ret
, "no CA certificate found");
1556 } else if (opt
->self_signed_flag
) {
1557 if (opt
->generate_key_string
== NULL
1558 && opt
->ca_private_key_string
== NULL
)
1559 errx(1, "no signing private key");
1561 errx(1, "missing ca key");
1563 if (opt
->ca_private_key_string
) {
1565 ret
= read_private_key(opt
->ca_private_key_string
, &private_key
);
1567 err(1, "read_private_key");
1569 ret
= _hx509_private_key2SPKI(context
, private_key
, &spki
);
1571 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1573 if (opt
->self_signed_flag
)
1574 cert_key
= private_key
;
1577 if (opt
->req_string
) {
1580 ret
= _hx509_request_parse(context
, opt
->req_string
, &req
);
1582 hx509_err(context
, 1, ret
, "parse_request: %s", opt
->req_string
);
1583 ret
= _hx509_request_get_name(context
, req
, &subject
);
1585 hx509_err(context
, 1, ret
, "get name");
1586 ret
= _hx509_request_get_SubjectPublicKeyInfo(context
, req
, &spki
);
1588 hx509_err(context
, 1, ret
, "get spki");
1589 _hx509_request_free(&req
);
1592 if (opt
->generate_key_string
) {
1593 struct hx509_generate_private_context
*keyctx
;
1595 ret
= _hx509_generate_private_key_init(context
,
1596 oid_id_pkcs1_rsaEncryption(),
1599 if (opt
->issue_ca_flag
)
1600 _hx509_generate_private_key_is_ca(context
, keyctx
);
1602 if (opt
->key_bits_integer
)
1603 _hx509_generate_private_key_bits(context
, keyctx
,
1604 opt
->key_bits_integer
);
1606 ret
= _hx509_generate_private_key(context
, keyctx
,
1608 _hx509_generate_private_key_free(&keyctx
);
1610 hx509_err(context
, 1, ret
, "generate private key");
1612 ret
= _hx509_private_key2SPKI(context
, cert_key
, &spki
);
1614 errx(1, "_hx509_private_key2SPKI: %d\n", ret
);
1616 if (opt
->self_signed_flag
)
1617 private_key
= cert_key
;
1620 if (opt
->certificate_private_key_string
) {
1621 ret
= read_private_key(opt
->certificate_private_key_string
, &cert_key
);
1623 err(1, "read_private_key for certificate");
1626 if (opt
->subject_string
) {
1628 hx509_name_free(&subject
);
1629 ret
= hx509_parse_name(context
, opt
->subject_string
, &subject
);
1631 hx509_err(context
, 1, ret
, "hx509_parse_name");
1638 ret
= hx509_ca_tbs_init(context
, &tbs
);
1640 hx509_err(context
, 1, ret
, "hx509_ca_tbs_init");
1642 if (opt
->template_certificate_string
) {
1643 hx509_cert
template;
1647 ret
= hx509_certs_init(context
, opt
->template_certificate_string
, 0,
1650 hx509_err(context
, 1, ret
,
1651 "hx509_certs_init: %s", opt
->template_certificate_string
);
1653 ret
= hx509_get_one_cert(context
, tcerts
, &template);
1655 hx509_certs_free(&tcerts
);
1657 hx509_err(context
, 1, ret
, "no template certificate found");
1659 flags
= parse_units(opt
->template_fields_string
,
1660 hx509_ca_tbs_template_units(), "");
1662 ret
= hx509_ca_tbs_set_template(context
, tbs
, flags
, template);
1664 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_template");
1666 hx509_cert_free(template);
1669 if (opt
->serial_number_string
) {
1670 heim_integer serialNumber
;
1672 ret
= der_parse_hex_heim_integer(opt
->serial_number_string
,
1675 err(1, "der_parse_hex_heim_integer");
1676 ret
= hx509_ca_tbs_set_serialnumber(context
, tbs
, &serialNumber
);
1678 hx509_err(context
, 1, ret
, "hx509_ca_tbs_init");
1679 der_free_heim_integer(&serialNumber
);
1682 if (spki
.subjectPublicKey
.length
) {
1683 ret
= hx509_ca_tbs_set_spki(context
, tbs
, &spki
);
1685 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_spki");
1689 ret
= hx509_ca_tbs_set_subject(context
, tbs
, subject
);
1691 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_subject");
1694 if (opt
->crl_uri_string
) {
1695 ret
= hx509_ca_tbs_add_crl_dp_uri(context
, tbs
,
1696 opt
->crl_uri_string
, NULL
);
1698 hx509_err(context
, 1, ret
, "hx509_ca_tbs_add_crl_dp_uri");
1701 eval_types(context
, tbs
, opt
);
1703 if (opt
->issue_ca_flag
) {
1704 ret
= hx509_ca_tbs_set_ca(context
, tbs
, opt
->path_length_integer
);
1706 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_ca");
1708 if (opt
->issue_proxy_flag
) {
1709 ret
= hx509_ca_tbs_set_proxy(context
, tbs
, opt
->path_length_integer
);
1711 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_proxy");
1713 if (opt
->domain_controller_flag
) {
1714 hx509_ca_tbs_set_domaincontroller(context
, tbs
);
1716 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_domaincontroller");
1720 ret
= hx509_ca_tbs_set_notAfter_lifetime(context
, tbs
, delta
);
1722 hx509_err(context
, 1, ret
, "hx509_ca_tbs_set_notAfter_lifetime");
1725 if (opt
->self_signed_flag
) {
1726 ret
= hx509_ca_sign_self(context
, tbs
, private_key
, &cert
);
1728 hx509_err(context
, 1, ret
, "hx509_ca_sign_self");
1730 ret
= hx509_ca_sign(context
, tbs
, signer
, &cert
);
1732 hx509_err(context
, 1, ret
, "hx509_ca_sign");
1736 ret
= _hx509_cert_assign_key(cert
, cert_key
);
1738 hx509_err(context
, 1, ret
, "_hx509_cert_assign_key");
1744 ret
= hx509_certs_init(context
, opt
->certificate_string
,
1745 HX509_CERTS_CREATE
, NULL
, &certs
);
1747 hx509_err(context
, 1, ret
, "hx509_certs_init");
1749 ret
= hx509_certs_add(context
, certs
, cert
);
1751 hx509_err(context
, 1, ret
, "hx509_certs_add");
1753 ret
= hx509_certs_store(context
, certs
, 0, NULL
);
1755 hx509_err(context
, 1, ret
, "hx509_certs_store");
1757 hx509_certs_free(&certs
);
1761 hx509_name_free(&subject
);
1763 hx509_cert_free(signer
);
1764 hx509_cert_free(cert
);
1765 free_SubjectPublicKeyInfo(&spki
);
1767 if (private_key
!= cert_key
)
1768 _hx509_private_key_free(&private_key
);
1769 _hx509_private_key_free(&cert_key
);
1771 hx509_ca_tbs_free(&tbs
);
1777 test_one_cert(hx509_context hxcontext
, void *ctx
, hx509_cert cert
)
1779 heim_octet_string sd
, c
;
1780 hx509_verify_ctx vctx
= ctx
;
1781 hx509_certs signer
= NULL
;
1785 if (_hx509_cert_private_key(cert
) == NULL
)
1788 ret
= hx509_cms_create_signed_1(context
, 0, NULL
, NULL
, 0,
1789 NULL
, cert
, NULL
, NULL
, NULL
, &sd
);
1791 errx(1, "hx509_cms_create_signed_1");
1793 ret
= hx509_cms_verify_signed(context
, vctx
, sd
.data
, sd
.length
,
1794 NULL
, NULL
, &type
, &c
, &signer
);
1797 hx509_err(context
, 1, ret
, "hx509_cms_verify_signed");
1799 printf("create-signature verify-sigature done\n");
1807 test_crypto(struct test_crypto_options
*opt
, int argc
, char ** argv
)
1809 hx509_verify_ctx vctx
;
1814 hx509_lock_init(context
, &lock
);
1815 lock_strings(lock
, &opt
->pass_strings
);
1817 ret
= hx509_certs_init(context
, "MEMORY:test-crypto", 0, NULL
, &certs
);
1819 for (i
= 0; i
< argc
; i
++) {
1820 ret
= hx509_certs_append(context
, certs
, lock
, argv
[i
]);
1822 hx509_err(context
, 1, ret
, "hx509_certs_append");
1825 ret
= hx509_verify_init_ctx(context
, &vctx
);
1827 hx509_err(context
, 1, ret
, "hx509_verify_init_ctx");
1829 hx509_verify_attach_anchors(vctx
, certs
);
1831 ret
= hx509_certs_iter(context
, certs
, test_one_cert
, vctx
);
1833 hx509_certs_free(&certs
);
1839 statistic_print(struct statistic_print_options
*opt
, int argc
, char **argv
)
1843 if (stat_file_string
== NULL
)
1844 errx(1, "no stat file");
1846 if (opt
->type_integer
)
1847 type
= opt
->type_integer
;
1849 hx509_query_unparse_stats(context
, type
, stdout
);
1858 crl_sign(struct crl_sign_options
*opt
, int argc
, char **argv
)
1861 heim_octet_string os
;
1862 hx509_cert signer
= NULL
;
1866 hx509_lock_init(context
, &lock
);
1867 lock_strings(lock
, &opt
->pass_strings
);
1869 ret
= hx509_crl_alloc(context
, &crl
);
1871 errx(1, "crl alloc");
1873 if (opt
->signer_string
== NULL
)
1874 errx(1, "signer missing");
1877 hx509_certs certs
= NULL
;
1880 ret
= hx509_certs_init(context
, opt
->signer_string
, 0,
1883 hx509_err(context
, 1, ret
,
1884 "hx509_certs_init: %s", opt
->signer_string
);
1886 ret
= hx509_query_alloc(context
, &q
);
1888 hx509_err(context
, 1, ret
, "hx509_query_alloc: %d", ret
);
1890 hx509_query_match_option(q
, HX509_QUERY_OPTION_PRIVATE_KEY
);
1892 ret
= hx509_certs_find(context
, certs
, q
, &signer
);
1893 hx509_query_free(context
, q
);
1894 hx509_certs_free(&certs
);
1896 hx509_err(context
, 1, ret
, "no signer certificate found");
1899 if (opt
->lifetime_string
) {
1902 delta
= parse_time(opt
->lifetime_string
, "day");
1904 errx(1, "Invalid lifetime: %s", opt
->lifetime_string
);
1906 hx509_crl_lifetime(context
, crl
, delta
);
1910 hx509_certs revoked
= NULL
;
1913 ret
= hx509_certs_init(context
, "MEMORY:revoked-certs", 0,
1916 for (i
= 0; i
< argc
; i
++) {
1917 ret
= hx509_certs_append(context
, revoked
, lock
, argv
[i
]);
1919 hx509_err(context
, 1, ret
, "hx509_certs_append: %s", argv
[i
]);
1922 hx509_crl_add_revoked_certs(context
, crl
, revoked
);
1923 hx509_certs_free(&revoked
);
1926 hx509_crl_sign(context
, signer
, crl
, &os
);
1928 if (opt
->crl_file_string
)
1929 rk_dumpdata(opt
->crl_file_string
, os
.data
, os
.length
);
1933 hx509_crl_free(context
, &crl
);
1934 hx509_cert_free(signer
);
1935 hx509_lock_free(lock
);
1945 help(void *opt
, int argc
, char **argv
)
1947 sl_slc_help(commands
, argc
, argv
);
1952 main(int argc
, char **argv
)
1954 int ret
, optidx
= 0;
1956 setprogname (argv
[0]);
1958 if(getarg(args
, num_args
, argc
, argv
, &optidx
))
1963 print_version(NULL
);
1972 ret
= hx509_context_init(&context
);
1974 errx(1, "hx509_context_init failed with %d", ret
);
1976 if (stat_file_string
)
1977 hx509_query_statistic_file(context
, stat_file_string
);
1979 ret
= sl_command(commands
, argc
, argv
);
1981 warnx ("unrecognized command: %s", argv
[0]);
1983 hx509_context_free(&context
);