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