xref: /openbsd-src/usr.bin/openssl/x509.c (revision 53555c846a0a6f917dbd0a191f826da995ab1c42)
1 /* $OpenBSD: x509.c,v 1.40 2024/12/04 08:14:34 tb Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <assert.h>
60 #include <limits.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 
65 #include "apps.h"
66 
67 #include <openssl/asn1.h>
68 #include <openssl/bio.h>
69 #include <openssl/bn.h>
70 #include <openssl/dsa.h>
71 #include <openssl/err.h>
72 #include <openssl/evp.h>
73 #include <openssl/objects.h>
74 #include <openssl/pem.h>
75 #include <openssl/rsa.h>
76 #include <openssl/x509.h>
77 #include <openssl/x509v3.h>
78 
79 #define	POSTFIX	".srl"
80 #define DEF_DAYS	30
81 
82 static int callb(int ok, X509_STORE_CTX *ctx);
83 static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
84     const EVP_MD *digest, CONF *conf, char *section, X509_NAME *issuer,
85     char *force_pubkey);
86 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
87     X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
88     char *serial, int create, int days, int clrext, CONF *conf, char *section,
89     ASN1_INTEGER *sno, X509_NAME *issuer);
90 static int purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt);
91 
92 static struct {
93 	char *alias;
94 	int aliasout;
95 	int badops;
96 	int C;
97 	int CA_createserial;
98 	int CA_flag;
99 	char *CAfile;
100 	int CAformat;
101 	char *CAkeyfile;
102 	int CAkeyformat;
103 	char *CAserial;
104 	unsigned long certflag;
105 	int checkend;
106 	int checkoffset;
107 	unsigned long chtype;
108 	int clrext;
109 	int clrreject;
110 	int clrtrust;
111 	int days;
112 	const EVP_MD *digest;
113 	int email;
114 	int enddate;
115 	char *extfile;
116 	char *extsect;
117 	int fingerprint;
118 	char *force_pubkey;
119 	char *infile;
120 	int informat;
121 	int issuer;
122 	int issuer_hash;
123 #ifndef OPENSSL_NO_MD5
124 	int issuer_hash_old;
125 #endif
126 	char *keyfile;
127 	int keyformat;
128 	const EVP_MD *md_alg;
129 	int modulus;
130 	int multirdn;
131 	int new;
132 	int next_serial;
133 	unsigned long nmflag;
134 	int noout;
135 	int num;
136 	int ocspid;
137 	ASN1_OBJECT *objtmp;
138 	int ocsp_uri;
139 	char *outfile;
140 	int outformat;
141 	char *passargin;
142 	int pprint;
143 	int pubkey;
144 	STACK_OF(ASN1_OBJECT) *reject;
145 	int reqfile;
146 	int serial;
147 	char *set_issuer;
148 	char *set_subject;
149 	int sign_flag;
150 	STACK_OF(OPENSSL_STRING) *sigopts;
151 	ASN1_INTEGER *sno;
152 	int startdate;
153 	int subject;
154 	int subject_hash;
155 #ifndef OPENSSL_NO_MD5
156 	int subject_hash_old;
157 #endif
158 	int text;
159 	STACK_OF(ASN1_OBJECT) *trust;
160 	int trustout;
161 	int x509req;
162 } cfg;
163 
164 static int
165 x509_opt_addreject(char *arg)
166 {
167 	if ((cfg.objtmp = OBJ_txt2obj(arg, 0)) == NULL) {
168 		BIO_printf(bio_err, "Invalid reject object value %s\n", arg);
169 		return (1);
170 	}
171 
172 	if (cfg.reject == NULL &&
173 	    (cfg.reject = sk_ASN1_OBJECT_new_null()) == NULL)
174 		return (1);
175 
176 	if (!sk_ASN1_OBJECT_push(cfg.reject, cfg.objtmp))
177 		return (1);
178 
179 	cfg.trustout = 1;
180 	return (0);
181 }
182 
183 static int
184 x509_opt_addtrust(char *arg)
185 {
186 	if ((cfg.objtmp = OBJ_txt2obj(arg, 0)) == NULL) {
187 		BIO_printf(bio_err, "Invalid trust object value %s\n", arg);
188 		return (1);
189 	}
190 
191 	if (cfg.trust == NULL &&
192 	    (cfg.trust = sk_ASN1_OBJECT_new_null()) == NULL)
193 		return (1);
194 
195 	if (!sk_ASN1_OBJECT_push(cfg.trust, cfg.objtmp))
196 		return (1);
197 
198 	cfg.trustout = 1;
199 	return (0);
200 }
201 
202 static int
203 x509_opt_ca(char *arg)
204 {
205 	cfg.CAfile = arg;
206 	cfg.CA_flag = ++cfg.num;
207 	return (0);
208 }
209 
210 static int
211 x509_opt_certopt(char *arg)
212 {
213 	if (!set_cert_ex(&cfg.certflag, arg))
214 		return (1);
215 
216 	return (0);
217 }
218 
219 static int
220 x509_opt_checkend(char *arg)
221 {
222 	const char *errstr;
223 
224 	cfg.checkoffset = strtonum(arg, 0, INT_MAX, &errstr);
225 	if (errstr != NULL) {
226 		BIO_printf(bio_err, "checkend unusable: %s\n", errstr);
227 		return (1);
228 	}
229 	cfg.checkend = 1;
230 	return (0);
231 }
232 
233 static int
234 x509_opt_dates(void)
235 {
236 	cfg.startdate = ++cfg.num;
237 	cfg.enddate = ++cfg.num;
238 	return (0);
239 }
240 
241 static int
242 x509_opt_days(char *arg)
243 {
244 	const char *errstr;
245 
246 	cfg.days = strtonum(arg, 1, INT_MAX, &errstr);
247 	if (errstr != NULL) {
248 		BIO_printf(bio_err, "bad number of days: %s\n", errstr);
249 		return (1);
250 	}
251 	return (0);
252 }
253 
254 static int
255 x509_opt_digest(int argc, char **argv, int *argsused)
256 {
257 	char *name = argv[0];
258 
259 	if (*name++ != '-')
260 		return (1);
261 
262 	if ((cfg.md_alg = EVP_get_digestbyname(name)) != NULL) {
263 		cfg.digest = cfg.md_alg;
264 	} else {
265 		BIO_printf(bio_err, "unknown option %s\n", *argv);
266 		cfg.badops = 1;
267 		return (1);
268 	}
269 
270 	*argsused = 1;
271 	return (0);
272 }
273 
274 static int
275 x509_opt_nameopt(char *arg)
276 {
277 	if (!set_name_ex(&cfg.nmflag, arg))
278 		return (1);
279 
280 	return (0);
281 }
282 
283 static int
284 x509_opt_set_serial(char *arg)
285 {
286 	ASN1_INTEGER_free(cfg.sno);
287 	if ((cfg.sno = s2i_ASN1_INTEGER(NULL, arg)) == NULL)
288 		return (1);
289 
290 	return (0);
291 }
292 
293 static int
294 x509_opt_setalias(char *arg)
295 {
296 	cfg.alias = arg;
297 	cfg.trustout = 1;
298 	return (0);
299 }
300 
301 static int
302 x509_opt_signkey(char *arg)
303 {
304 	cfg.keyfile = arg;
305 	cfg.sign_flag = ++cfg.num;
306 	return (0);
307 }
308 
309 static int
310 x509_opt_sigopt(char *arg)
311 {
312 	if (cfg.sigopts == NULL &&
313 	    (cfg.sigopts = sk_OPENSSL_STRING_new_null()) == NULL)
314 		return (1);
315 
316 	if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
317 		return (1);
318 
319 	return (0);
320 }
321 
322 static int
323 x509_opt_utf8(void)
324 {
325 	cfg.chtype = MBSTRING_UTF8;
326 	return (0);
327 }
328 
329 static const struct option x509_options[] = {
330 	{
331 		.name = "C",
332 		.desc = "Convert the certificate into C code",
333 		.type = OPTION_ORDER,
334 		.opt.order = &cfg.C,
335 		.order = &cfg.num,
336 	},
337 	{
338 		.name = "addreject",
339 		.argname = "arg",
340 		.desc = "Reject certificate for a given purpose",
341 		.type = OPTION_ARG_FUNC,
342 		.opt.argfunc = x509_opt_addreject,
343 	},
344 	{
345 		.name = "addtrust",
346 		.argname = "arg",
347 		.desc = "Trust certificate for a given purpose",
348 		.type = OPTION_ARG_FUNC,
349 		.opt.argfunc = x509_opt_addtrust,
350 	},
351 	{
352 		.name = "alias",
353 		.desc = "Output certificate alias",
354 		.type = OPTION_ORDER,
355 		.opt.order = &cfg.aliasout,
356 		.order = &cfg.num,
357 	},
358 	{
359 		.name = "CA",
360 		.argname = "file",
361 		.desc = "CA certificate in PEM format unless -CAform is specified",
362 		.type = OPTION_ARG_FUNC,
363 		.opt.argfunc = x509_opt_ca,
364 	},
365 	{
366 		.name = "CAcreateserial",
367 		.desc = "Create serial number file if it does not exist",
368 		.type = OPTION_ORDER,
369 		.opt.order = &cfg.CA_createserial,
370 		.order = &cfg.num,
371 	},
372 	{
373 		.name = "CAform",
374 		.argname = "fmt",
375 		.desc = "CA format - default PEM",
376 		.type = OPTION_ARG_FORMAT,
377 		.opt.value = &cfg.CAformat,
378 	},
379 	{
380 		.name = "CAkey",
381 		.argname = "file",
382 		.desc = "CA key in PEM format unless -CAkeyform is specified\n"
383 			"if omitted, the key is assumed to be in the CA file",
384 		.type = OPTION_ARG,
385 		.opt.arg = &cfg.CAkeyfile,
386 	},
387 	{
388 		.name = "CAkeyform",
389 		.argname = "fmt",
390 		.desc = "CA key format - default PEM",
391 		.type = OPTION_ARG_FORMAT,
392 		.opt.value = &cfg.CAkeyformat,
393 	},
394 	{
395 		.name = "CAserial",
396 		.argname = "file",
397 		.desc = "Serial file",
398 		.type = OPTION_ARG,
399 		.opt.arg = &cfg.CAserial,
400 	},
401 	{
402 		.name = "certopt",
403 		.argname = "option",
404 		.desc = "Various certificate text options",
405 		.type = OPTION_ARG_FUNC,
406 		.opt.argfunc = x509_opt_certopt,
407 	},
408 	{
409 		.name = "checkend",
410 		.argname = "arg",
411 		.desc = "Check whether the cert expires in the next arg seconds\n"
412 			"exit 1 if so, 0 if not",
413 		.type = OPTION_ARG_FUNC,
414 		.opt.argfunc = x509_opt_checkend,
415 	},
416 	{
417 		.name = "clrext",
418 		.desc = "Clear all extensions",
419 		.type = OPTION_FLAG,
420 		.opt.flag = &cfg.clrext,
421 	},
422 	{
423 		.name = "clrreject",
424 		.desc = "Clear all rejected purposes",
425 		.type = OPTION_ORDER,
426 		.opt.order = &cfg.clrreject,
427 		.order = &cfg.num,
428 	},
429 	{
430 		.name = "clrtrust",
431 		.desc = "Clear all trusted purposes",
432 		.type = OPTION_ORDER,
433 		.opt.order = &cfg.clrtrust,
434 		.order = &cfg.num,
435 	},
436 	{
437 		.name = "dates",
438 		.desc = "Both Before and After dates",
439 		.type = OPTION_FUNC,
440 		.opt.func = x509_opt_dates,
441 	},
442 	{
443 		.name = "days",
444 		.argname = "arg",
445 		.desc = "How long till expiry of a signed certificate - def 30 days",
446 		.type = OPTION_ARG_FUNC,
447 		.opt.argfunc = x509_opt_days,
448 	},
449 	{
450 		.name = "email",
451 		.desc = "Print email address(es)",
452 		.type = OPTION_ORDER,
453 		.opt.order = &cfg.email,
454 		.order = &cfg.num,
455 	},
456 	{
457 		.name = "enddate",
458 		.desc = "Print notAfter field",
459 		.type = OPTION_ORDER,
460 		.opt.order = &cfg.enddate,
461 		.order = &cfg.num,
462 	},
463 	{
464 		.name = "extensions",
465 		.argname = "section",
466 		.desc = "Section from config file with X509V3 extensions to add",
467 		.type = OPTION_ARG,
468 		.opt.arg = &cfg.extsect,
469 	},
470 	{
471 		.name = "extfile",
472 		.argname = "file",
473 		.desc = "Configuration file with X509V3 extensions to add",
474 		.type = OPTION_ARG,
475 		.opt.arg = &cfg.extfile,
476 	},
477 	{
478 		.name = "fingerprint",
479 		.desc = "Print the certificate fingerprint",
480 		.type = OPTION_ORDER,
481 		.opt.order = &cfg.fingerprint,
482 		.order = &cfg.num,
483 	},
484 	{
485 		.name = "force_pubkey",
486 		.argname = "key",
487 		.desc = "Force the public key to be put in the certificate",
488 		.type = OPTION_ARG,
489 		.opt.arg = &cfg.force_pubkey,
490 	},
491 	{
492 		.name = "hash",
493 		.desc = "Synonym for -subject_hash",
494 		.type = OPTION_ORDER,
495 		.opt.order = &cfg.subject_hash,
496 		.order = &cfg.num,
497 	},
498 	{
499 		.name = "in",
500 		.argname = "file",
501 		.desc = "Input file - default stdin",
502 		.type = OPTION_ARG,
503 		.opt.arg = &cfg.infile,
504 	},
505 	{
506 		.name = "inform",
507 		.argname = "fmt",
508 		.desc = "Input format - default PEM (one of DER, NET or PEM)",
509 		.type = OPTION_ARG_FORMAT,
510 		.opt.value = &cfg.informat,
511 	},
512 	{
513 		.name = "issuer",
514 		.desc = "Print issuer name",
515 		.type = OPTION_ORDER,
516 		.opt.order = &cfg.issuer,
517 		.order = &cfg.num,
518 	},
519 	{
520 		.name = "issuer_hash",
521 		.desc = "Print issuer hash value",
522 		.type = OPTION_ORDER,
523 		.opt.order = &cfg.issuer_hash,
524 		.order = &cfg.num,
525 	},
526 #ifndef OPENSSL_NO_MD5
527 	{
528 		.name = "issuer_hash_old",
529 		.desc = "Print old-style (MD5) issuer hash value",
530 		.type = OPTION_ORDER,
531 		.opt.order = &cfg.issuer_hash_old,
532 		.order = &cfg.num,
533 	},
534 #endif
535 	{
536 		.name = "key",
537 		.argname = "file",
538 		.type = OPTION_ARG_FUNC,
539 		.opt.argfunc = x509_opt_signkey,
540 	},
541 	{
542 		.name = "keyform",
543 		.argname = "fmt",
544 		.desc = "Private key format - default PEM",
545 		.type = OPTION_ARG_FORMAT,
546 		.opt.value = &cfg.keyformat,
547 	},
548 	{
549 		.name = "modulus",
550 		.desc = "Print the RSA key modulus",
551 		.type = OPTION_ORDER,
552 		.opt.order = &cfg.modulus,
553 		.order = &cfg.num,
554 	},
555 	{
556 		.name = "multivalue-rdn",
557 		.desc = "Enable support for multivalued RDNs",
558 		.type = OPTION_FLAG,
559 		.opt.flag = &cfg.multirdn,
560 	},
561 	{
562 		.name = "nameopt",
563 		.argname = "option",
564 		.desc = "Various certificate name options",
565 		.type = OPTION_ARG_FUNC,
566 		.opt.argfunc = x509_opt_nameopt,
567 	},
568 	{
569 		.name = "new",
570 		.desc = "Generate a new certificate",
571 		.type = OPTION_FLAG,
572 		.opt.flag = &cfg.new,
573 	},
574 	{
575 		.name = "next_serial",
576 		.desc = "Print the next serial number",
577 		.type = OPTION_ORDER,
578 		.opt.order = &cfg.next_serial,
579 		.order = &cfg.num,
580 	},
581 	{
582 		.name = "noout",
583 		.desc = "No certificate output",
584 		.type = OPTION_ORDER,
585 		.opt.order = &cfg.noout,
586 		.order = &cfg.num,
587 	},
588 	{
589 		.name = "ocsp_uri",
590 		.desc = "Print OCSP Responder URL(s)",
591 		.type = OPTION_ORDER,
592 		.opt.order = &cfg.ocsp_uri,
593 		.order = &cfg.num,
594 	},
595 	{
596 		.name = "ocspid",
597 		.desc = "Print OCSP hash values for the subject name and public key",
598 		.type = OPTION_ORDER,
599 		.opt.order = &cfg.ocspid,
600 		.order = &cfg.num,
601 	},
602 	{
603 		.name = "out",
604 		.argname = "file",
605 		.desc = "Output file - default stdout",
606 		.type = OPTION_ARG,
607 		.opt.arg = &cfg.outfile,
608 	},
609 	{
610 		.name = "outform",
611 		.argname = "fmt",
612 		.desc = "Output format - default PEM (one of DER, NET or PEM)",
613 		.type = OPTION_ARG_FORMAT,
614 		.opt.value = &cfg.outformat,
615 	},
616 	{
617 		.name = "passin",
618 		.argname = "src",
619 		.desc = "Private key password source",
620 		.type = OPTION_ARG,
621 		.opt.arg = &cfg.passargin,
622 	},
623 	{
624 		.name = "pubkey",
625 		.desc = "Output the public key",
626 		.type = OPTION_ORDER,
627 		.opt.order = &cfg.pubkey,
628 		.order = &cfg.num,
629 	},
630 	{
631 		.name = "purpose",
632 		.desc = "Print out certificate purposes",
633 		.type = OPTION_ORDER,
634 		.opt.order = &cfg.pprint,
635 		.order = &cfg.num,
636 	},
637 	{
638 		.name = "req",
639 		.desc = "Input is a certificate request, sign and output",
640 		.type = OPTION_FLAG,
641 		.opt.flag = &cfg.reqfile,
642 	},
643 	{
644 		.name = "serial",
645 		.desc = "Print serial number value",
646 		.type = OPTION_ORDER,
647 		.opt.order = &cfg.serial,
648 		.order = &cfg.num,
649 	},
650 	{
651 		.name = "set_issuer",
652 		.argname = "name",
653 		.desc = "Set the issuer name",
654 		.type = OPTION_ARG,
655 		.opt.arg = &cfg.set_issuer,
656 	},
657 	{
658 		.name = "set_serial",
659 		.argname = "n",
660 		.desc = "Serial number to use",
661 		.type = OPTION_ARG_FUNC,
662 		.opt.argfunc = x509_opt_set_serial,
663 	},
664 	{
665 		.name = "set_subject",
666 		.argname = "name",
667 		.desc = "Set the subject name",
668 		.type = OPTION_ARG,
669 		.opt.arg = &cfg.set_subject,
670 	},
671 	{
672 		.name = "setalias",
673 		.argname = "arg",
674 		.desc = "Set certificate alias",
675 		.type = OPTION_ARG_FUNC,
676 		.opt.argfunc = x509_opt_setalias,
677 	},
678 	{
679 		.name = "signkey",
680 		.argname = "file",
681 		.desc = "Self sign cert with arg",
682 		.type = OPTION_ARG_FUNC,
683 		.opt.argfunc = x509_opt_signkey,
684 	},
685 	{
686 		.name = "sigopt",
687 		.argname = "nm:v",
688 		.desc = "Various signature algorithm options",
689 		.type = OPTION_ARG_FUNC,
690 		.opt.argfunc = x509_opt_sigopt,
691 	},
692 	{
693 		.name = "startdate",
694 		.desc = "Print notBefore field",
695 		.type = OPTION_ORDER,
696 		.opt.order = &cfg.startdate,
697 		.order = &cfg.num,
698 	},
699 	{
700 		.name = "subj",
701 		.type = OPTION_ARG,
702 		.opt.arg = &cfg.set_subject,
703 	},
704 	{
705 		.name = "subject",
706 		.desc = "Print subject name",
707 		.type = OPTION_ORDER,
708 		.opt.order = &cfg.subject,
709 		.order = &cfg.num,
710 	},
711 	{
712 		.name = "subject_hash",
713 		.desc = "Print subject hash value",
714 		.type = OPTION_ORDER,
715 		.opt.order = &cfg.subject_hash,
716 		.order = &cfg.num,
717 	},
718 #ifndef OPENSSL_NO_MD5
719 	{
720 		.name = "subject_hash_old",
721 		.desc = "Print old-style (MD5) subject hash value",
722 		.type = OPTION_ORDER,
723 		.opt.order = &cfg.subject_hash_old,
724 		.order = &cfg.num,
725 	},
726 #endif
727 	{
728 		.name = "text",
729 		.desc = "Print the certificate in text form",
730 		.type = OPTION_ORDER,
731 		.opt.order = &cfg.text,
732 		.order = &cfg.num,
733 	},
734 	{
735 		.name = "trustout",
736 		.desc = "Output a trusted certificate",
737 		.type = OPTION_FLAG,
738 		.opt.flag = &cfg.trustout,
739 	},
740 	{
741 		.name = "utf8",
742 		.desc = "Input characters are in UTF-8 (default ASCII)",
743 		.type = OPTION_FUNC,
744 		.opt.func = x509_opt_utf8,
745 	},
746 	{
747 		.name = "x509toreq",
748 		.desc = "Output a certification request object",
749 		.type = OPTION_ORDER,
750 		.opt.order = &cfg.x509req,
751 		.order = &cfg.num,
752 	},
753 	{
754 		.name = NULL,
755 		.desc = "",
756 		.type = OPTION_ARGV_FUNC,
757 		.opt.argvfunc = x509_opt_digest,
758 	},
759 	{ NULL },
760 };
761 
762 static void
763 x509_usage(void)
764 {
765 	fprintf(stderr, "usage: x509 "
766 	    "[-C] [-addreject arg] [-addtrust arg] [-alias] [-CA file]\n"
767 	    "    [-CAcreateserial] [-CAform der | pem] [-CAkey file]\n"
768 	    "    [-CAkeyform der | pem] [-CAserial file] [-certopt option]\n"
769 	    "    [-checkend arg] [-clrext] [-clrreject] [-clrtrust] [-dates]\n"
770 	    "    [-days arg] [-email] [-enddate] [-extensions section]\n"
771 	    "    [-extfile file] [-fingerprint] [-force_pubkey key] [-hash]\n"
772 	    "    [-in file] [-inform der | net | pem] [-issuer]\n"
773 	    "    [-issuer_hash] [-issuer_hash_old] [-keyform der | pem]\n"
774 	    "    [-md5 | -sha1] [-modulus] [-multivalue-rdn]\n"
775 	    "    [-nameopt option] [-new] [-next_serial] [-noout] [-ocsp_uri]\n"
776 	    "    [-ocspid] [-out file] [-outform der | net | pem]\n"
777 	    "    [-passin arg] [-pubkey] [-purpose] [-req] [-serial]\n"
778 	    "    [-set_issuer name] [-set_serial n] [-set_subject name]\n"
779 	    "    [-setalias arg] [-signkey file] [-sigopt nm:v] [-startdate]\n"
780 	    "    [-subject] [-subject_hash] [-subject_hash_old] [-text]\n"
781 	    "    [-trustout] [-utf8] [-x509toreq]\n");
782 	fprintf(stderr, "\n");
783 	options_usage(x509_options);
784 	fprintf(stderr, "\n");
785 }
786 
787 int
788 x509_main(int argc, char **argv)
789 {
790 	int ret = 1;
791 	X509_REQ *req = NULL;
792 	X509 *x = NULL, *xca = NULL;
793 	X509_NAME *iname = NULL, *sname = NULL;
794 	EVP_PKEY *Fpkey = NULL, *Upkey = NULL, *CApkey = NULL;
795 	EVP_PKEY *pkey;
796 	int i;
797 	BIO *out = NULL;
798 	BIO *STDout = NULL;
799 	X509_STORE *ctx = NULL;
800 	X509_REQ *rq = NULL;
801 	char buf[256];
802 	CONF *extconf = NULL;
803 	char *passin = NULL;
804 
805 	if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
806 		perror("pledge");
807 		exit(1);
808 	}
809 
810 	memset(&cfg, 0, sizeof(cfg));
811 	cfg.chtype = MBSTRING_ASC;
812 	cfg.days = DEF_DAYS;
813 	cfg.informat = FORMAT_PEM;
814 	cfg.outformat = FORMAT_PEM;
815 	cfg.keyformat = FORMAT_PEM;
816 	cfg.CAformat = FORMAT_PEM;
817 	cfg.CAkeyformat = FORMAT_PEM;
818 
819 	STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
820 
821 	ctx = X509_STORE_new();
822 	if (ctx == NULL)
823 		goto end;
824 	X509_STORE_set_verify_cb(ctx, callb);
825 
826 	if (options_parse(argc, argv, x509_options, NULL, NULL) != 0)
827 		goto bad;
828 
829 	if (cfg.badops) {
830  bad:
831 		x509_usage();
832 		goto end;
833 	}
834 
835 	if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
836 		BIO_printf(bio_err, "Error getting password\n");
837 		goto end;
838 	}
839 	if (!X509_STORE_set_default_paths(ctx)) {
840 		ERR_print_errors(bio_err);
841 		goto end;
842 	}
843 	if (cfg.CAkeyfile == NULL && cfg.CA_flag && cfg.CAformat == FORMAT_PEM) {
844 		cfg.CAkeyfile = cfg.CAfile;
845 	} else if (cfg.CA_flag && cfg.CAkeyfile == NULL) {
846 		BIO_printf(bio_err,
847 		    "need to specify a CAkey if using the CA command\n");
848 		goto end;
849 	}
850 	if (cfg.extfile != NULL) {
851 		long errorline = -1;
852 		X509V3_CTX ctx2;
853 		extconf = NCONF_new(NULL);
854 		if (!NCONF_load(extconf, cfg.extfile, &errorline)) {
855 			if (errorline <= 0)
856 				BIO_printf(bio_err,
857 				    "error loading the config file '%s'\n",
858 				    cfg.extfile);
859 			else
860 				BIO_printf(bio_err,
861 				    "error on line %ld of config file '%s'\n",
862 				    errorline, cfg.extfile);
863 			goto end;
864 		}
865 		if (cfg.extsect == NULL) {
866 			cfg.extsect = NCONF_get_string(extconf, "default",
867 			    "extensions");
868 			if (cfg.extsect == NULL) {
869 				ERR_clear_error();
870 				cfg.extsect = "default";
871 			}
872 		}
873 		X509V3_set_ctx_test(&ctx2);
874 		X509V3_set_nconf(&ctx2, extconf);
875 		if (!X509V3_EXT_add_nconf(extconf, &ctx2, cfg.extsect, NULL)) {
876 			BIO_printf(bio_err,
877 			    "Error Loading extension section %s\n", cfg.extsect);
878 			ERR_print_errors(bio_err);
879 			goto end;
880 		}
881 	}
882 	if (cfg.force_pubkey != NULL) {
883 		if ((Fpkey = load_pubkey(bio_err, cfg.force_pubkey,
884 		    cfg.keyformat, 0, NULL, "Forced key")) == NULL)
885 			goto end;
886 	}
887 	if (cfg.new) {
888 		if (cfg.infile != NULL) {
889 			BIO_printf(bio_err, "Can't combine -new and -in\n");
890 			goto end;
891 		}
892 		if (cfg.reqfile) {
893 			BIO_printf(bio_err, "Can't combine -new and -req\n");
894 			goto end;
895 		}
896 		if (cfg.set_subject == NULL) {
897 			BIO_printf(bio_err, "Must use -set_subject with -new\n");
898 			goto end;
899 		}
900 		if (cfg.keyfile == NULL) {
901 			BIO_printf(bio_err, "Must use -signkey with -new\n");
902 			goto end;
903 		}
904 		if ((Upkey = load_key(bio_err, cfg.keyfile, cfg.keyformat, 0,
905 		    passin, "Private key")) == NULL)
906 			goto end;
907 	}
908 	if (cfg.reqfile) {
909 		BIO *in;
910 
911 		if (!cfg.sign_flag && !cfg.CA_flag) {
912 			BIO_printf(bio_err,
913 			    "We need a private key to sign with\n");
914 			goto end;
915 		}
916 		in = BIO_new(BIO_s_file());
917 		if (in == NULL) {
918 			ERR_print_errors(bio_err);
919 			goto end;
920 		}
921 		if (cfg.infile == NULL)
922 			BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
923 		else {
924 			if (BIO_read_filename(in, cfg.infile) <= 0) {
925 				perror(cfg.infile);
926 				BIO_free(in);
927 				goto end;
928 			}
929 		}
930 		req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
931 		BIO_free(in);
932 
933 		if (req == NULL) {
934 			ERR_print_errors(bio_err);
935 			goto end;
936 		}
937 		if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
938 			BIO_printf(bio_err, "error unpacking public key\n");
939 			goto end;
940 		}
941 		i = X509_REQ_verify(req, pkey);
942 		if (i < 0) {
943 			BIO_printf(bio_err, "Signature verification error\n");
944 			ERR_print_errors(bio_err);
945 			goto end;
946 		}
947 		if (i == 0) {
948 			BIO_printf(bio_err,
949 			    "Signature did not match the certificate request\n");
950 			goto end;
951 		} else
952 			BIO_printf(bio_err, "Signature ok\n");
953 
954 		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
955 		    cfg.nmflag);
956 
957 	}
958 	if (cfg.reqfile || cfg.new) {
959 		if ((x = X509_new()) == NULL)
960 			goto end;
961 
962 		if (cfg.sno == NULL) {
963 			cfg.sno = ASN1_INTEGER_new();
964 			if (cfg.sno == NULL || !rand_serial(NULL, cfg.sno))
965 				goto end;
966 			if (!X509_set_serialNumber(x, cfg.sno))
967 				goto end;
968 			ASN1_INTEGER_free(cfg.sno);
969 			cfg.sno = NULL;
970 		} else if (!X509_set_serialNumber(x, cfg.sno))
971 			goto end;
972 
973 		if (cfg.set_issuer != NULL) {
974 			iname = parse_name(cfg.set_issuer, cfg.chtype,
975 			    cfg.multirdn);
976 			if (iname == NULL)
977 				goto end;
978 		}
979 
980 		if (cfg.set_subject != NULL)
981 			sname = parse_name(cfg.set_subject, cfg.chtype,
982 			    cfg.multirdn);
983 		else
984 			sname = X509_NAME_dup(X509_REQ_get_subject_name(req));
985 		if (sname == NULL)
986 			goto end;
987 		if (!X509_set_subject_name(x, sname))
988 			goto end;
989 
990 		if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
991 			goto end;
992 		if (X509_time_adj_ex(X509_get_notAfter(x), cfg.days, 0,
993 		    NULL) == NULL)
994 			goto end;
995 
996 		if ((pkey = Fpkey) == NULL)
997 			pkey = X509_REQ_get0_pubkey(req);
998 		if (pkey == NULL)
999 			pkey = Upkey;
1000 		if (pkey == NULL)
1001 			goto end;
1002 		if (!X509_set_pubkey(x, pkey))
1003 			goto end;
1004 	} else {
1005 		x = load_cert(bio_err, cfg.infile, cfg.informat, NULL,
1006 		    "Certificate");
1007 	}
1008 	if (x == NULL)
1009 		goto end;
1010 
1011 	if (cfg.CA_flag) {
1012 		xca = load_cert(bio_err, cfg.CAfile, cfg.CAformat, NULL,
1013 		    "CA Certificate");
1014 		if (xca == NULL)
1015 			goto end;
1016 	}
1017 	if (!cfg.noout || cfg.text || cfg.next_serial) {
1018 		OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
1019 
1020 		out = BIO_new(BIO_s_file());
1021 		if (out == NULL) {
1022 			ERR_print_errors(bio_err);
1023 			goto end;
1024 		}
1025 		if (cfg.outfile == NULL) {
1026 			BIO_set_fp(out, stdout, BIO_NOCLOSE);
1027 		} else {
1028 			if (BIO_write_filename(out, cfg.outfile) <= 0) {
1029 				perror(cfg.outfile);
1030 				goto end;
1031 			}
1032 		}
1033 	}
1034 	if (cfg.alias != NULL) {
1035 		if (!X509_alias_set1(x, (unsigned char *)cfg.alias, -1))
1036 			goto end;
1037 	}
1038 
1039 	if (cfg.clrtrust)
1040 		X509_trust_clear(x);
1041 	if (cfg.clrreject)
1042 		X509_reject_clear(x);
1043 
1044 	if (cfg.trust != NULL) {
1045 		for (i = 0; i < sk_ASN1_OBJECT_num(cfg.trust); i++) {
1046 			cfg.objtmp = sk_ASN1_OBJECT_value(cfg.trust, i);
1047 			if (!X509_add1_trust_object(x, cfg.objtmp))
1048 				goto end;
1049 		}
1050 	}
1051 	if (cfg.reject != NULL) {
1052 		for (i = 0; i < sk_ASN1_OBJECT_num(cfg.reject); i++) {
1053 			cfg.objtmp = sk_ASN1_OBJECT_value(cfg.reject, i);
1054 			if (!X509_add1_reject_object(x, cfg.objtmp))
1055 				goto end;
1056 		}
1057 	}
1058 	if (cfg.num) {
1059 		for (i = 1; i <= cfg.num; i++) {
1060 			if (cfg.issuer == i) {
1061 				print_name(STDout, "issuer= ",
1062 				    X509_get_issuer_name(x), cfg.nmflag);
1063 			} else if (cfg.subject == i) {
1064 				print_name(STDout, "subject= ",
1065 				    X509_get_subject_name(x), cfg.nmflag);
1066 			} else if (cfg.serial == i) {
1067 				BIO_printf(STDout, "serial=");
1068 				i2a_ASN1_INTEGER(STDout,
1069 				    X509_get_serialNumber(x));
1070 				BIO_printf(STDout, "\n");
1071 			} else if (cfg.next_serial == i) {
1072 				BIGNUM *bnser;
1073 				ASN1_INTEGER *ser;
1074 
1075 				ser = X509_get_serialNumber(x);
1076 				if (ser == NULL)
1077 					goto end;
1078 				bnser = ASN1_INTEGER_to_BN(ser, NULL);
1079 				if (bnser == NULL)
1080 					goto end;
1081 				if (!BN_add_word(bnser, 1)) {
1082 					BN_free(bnser);
1083 					goto end;
1084 				}
1085 				ser = BN_to_ASN1_INTEGER(bnser, NULL);
1086 				if (ser == NULL) {
1087 					BN_free(bnser);
1088 					goto end;
1089 				}
1090 				BN_free(bnser);
1091 				i2a_ASN1_INTEGER(out, ser);
1092 				ASN1_INTEGER_free(ser);
1093 				BIO_puts(out, "\n");
1094 			} else if (cfg.email == i || cfg.ocsp_uri == i) {
1095 				STACK_OF(OPENSSL_STRING) *emlst;
1096 				int j;
1097 
1098 				if (cfg.email == i)
1099 					emlst = X509_get1_email(x);
1100 				else
1101 					emlst = X509_get1_ocsp(x);
1102 				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
1103 					BIO_printf(STDout, "%s\n",
1104 					    sk_OPENSSL_STRING_value(emlst, j));
1105 				X509_email_free(emlst);
1106 			} else if (cfg.aliasout == i) {
1107 				unsigned char *albuf;
1108 				int buflen;
1109 				albuf = X509_alias_get0(x, &buflen);
1110 				if (albuf != NULL)
1111 					BIO_printf(STDout, "%.*s\n",
1112 					    buflen, albuf);
1113 				else
1114 					BIO_puts(STDout, "<No Alias>\n");
1115 			} else if (cfg.subject_hash == i) {
1116 				BIO_printf(STDout, "%08lx\n",
1117 				    X509_subject_name_hash(x));
1118 			}
1119 #ifndef OPENSSL_NO_MD5
1120 			else if (cfg.subject_hash_old == i) {
1121 				BIO_printf(STDout, "%08lx\n",
1122 				    X509_subject_name_hash_old(x));
1123 			}
1124 #endif
1125 			else if (cfg.issuer_hash == i) {
1126 				BIO_printf(STDout, "%08lx\n",
1127 				    X509_issuer_name_hash(x));
1128 			}
1129 #ifndef OPENSSL_NO_MD5
1130 			else if (cfg.issuer_hash_old == i) {
1131 				BIO_printf(STDout, "%08lx\n",
1132 				    X509_issuer_name_hash_old(x));
1133 			}
1134 #endif
1135 			else if (cfg.pprint == i) {
1136 				const X509_PURPOSE *ptmp;
1137 				int j;
1138 
1139 				BIO_printf(STDout, "Certificate purposes:\n");
1140 				for (j = 0; j < X509_PURPOSE_get_count(); j++) {
1141 					ptmp = X509_PURPOSE_get0(j);
1142 					purpose_print(STDout, x, ptmp);
1143 				}
1144 			} else if (cfg.modulus == i) {
1145 				EVP_PKEY *pubkey;
1146 
1147 				if ((pubkey = X509_get0_pubkey(x)) == NULL) {
1148 					BIO_printf(bio_err,
1149 					    "Modulus=unavailable\n");
1150 					ERR_print_errors(bio_err);
1151 					goto end;
1152 				}
1153 				BIO_printf(STDout, "Modulus=");
1154 				if (EVP_PKEY_id(pubkey) == EVP_PKEY_RSA) {
1155 					RSA *rsa = EVP_PKEY_get0_RSA(pubkey);
1156 					const BIGNUM *n = NULL;
1157 
1158 					RSA_get0_key(rsa, &n, NULL, NULL);
1159 					BN_print(STDout, n);
1160 				} else if (EVP_PKEY_id(pubkey) == EVP_PKEY_DSA) {
1161 					DSA *dsa = EVP_PKEY_get0_DSA(pubkey);
1162 					const BIGNUM *dsa_pub_key = NULL;
1163 
1164 					DSA_get0_key(dsa, &dsa_pub_key, NULL);
1165 
1166 					BN_print(STDout, dsa_pub_key);
1167 				} else
1168 					BIO_printf(STDout,
1169 					    "Wrong Algorithm type");
1170 				BIO_printf(STDout, "\n");
1171 			} else if (cfg.pubkey == i) {
1172 				EVP_PKEY *pubkey;
1173 
1174 				if ((pubkey = X509_get0_pubkey(x)) == NULL) {
1175 					BIO_printf(bio_err,
1176 					    "Error getting public key\n");
1177 					ERR_print_errors(bio_err);
1178 					goto end;
1179 				}
1180 				PEM_write_bio_PUBKEY(STDout, pubkey);
1181 			} else if (cfg.C == i) {
1182 				unsigned char *d;
1183 				char *m;
1184 				int y, z;
1185 
1186 				m = X509_NAME_oneline(X509_get_subject_name(x),
1187 				    buf, sizeof buf);
1188 				if (m == NULL)
1189 					goto end;
1190 				BIO_printf(STDout, "/* subject:%s */\n", buf);
1191 				m = X509_NAME_oneline(X509_get_issuer_name(x),
1192 				    buf, sizeof buf);
1193 				if (m == NULL)
1194 					goto end;
1195 				BIO_printf(STDout, "/* issuer :%s */\n", buf);
1196 
1197 				z = i2d_X509(x, NULL);
1198 				if (z < 0)
1199 					goto end;
1200 
1201 				m = malloc(z);
1202 				if (m == NULL) {
1203 					BIO_printf(bio_err, "out of mem\n");
1204 					goto end;
1205 				}
1206 
1207 				d = (unsigned char *) m;
1208 				z = i2d_X509_NAME(X509_get_subject_name(x), &d);
1209 				if (z < 0) {
1210 					free(m);
1211 					goto end;
1212 				}
1213 				BIO_printf(STDout,
1214 				    "unsigned char XXX_subject_name[%d]={\n", z);
1215 				d = (unsigned char *) m;
1216 				for (y = 0; y < z; y++) {
1217 					BIO_printf(STDout, "0x%02X,", d[y]);
1218 					if ((y & 0x0f) == 0x0f)
1219 						BIO_printf(STDout, "\n");
1220 				}
1221 				if (y % 16 != 0)
1222 					BIO_printf(STDout, "\n");
1223 				BIO_printf(STDout, "};\n");
1224 
1225 				z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
1226 				if (z < 0) {
1227 					free(m);
1228 					goto end;
1229 				}
1230 				BIO_printf(STDout,
1231 				    "unsigned char XXX_public_key[%d]={\n", z);
1232 				d = (unsigned char *) m;
1233 				for (y = 0; y < z; y++) {
1234 					BIO_printf(STDout, "0x%02X,", d[y]);
1235 					if ((y & 0x0f) == 0x0f)
1236 						BIO_printf(STDout, "\n");
1237 				}
1238 				if (y % 16 != 0)
1239 					BIO_printf(STDout, "\n");
1240 				BIO_printf(STDout, "};\n");
1241 
1242 				z = i2d_X509(x, &d);
1243 				if (z < 0) {
1244 					free(m);
1245 					goto end;
1246 				}
1247 				BIO_printf(STDout,
1248 				    "unsigned char XXX_certificate[%d]={\n", z);
1249 				d = (unsigned char *) m;
1250 				for (y = 0; y < z; y++) {
1251 					BIO_printf(STDout, "0x%02X,", d[y]);
1252 					if ((y & 0x0f) == 0x0f)
1253 						BIO_printf(STDout, "\n");
1254 				}
1255 				if (y % 16 != 0)
1256 					BIO_printf(STDout, "\n");
1257 				BIO_printf(STDout, "};\n");
1258 
1259 				free(m);
1260 			} else if (cfg.text == i) {
1261 				if(!X509_print_ex(STDout, x, cfg.nmflag,
1262 				    cfg.certflag))
1263 					goto end;
1264 			} else if (cfg.startdate == i) {
1265 				ASN1_TIME *nB = X509_get_notBefore(x);
1266 
1267 				BIO_puts(STDout, "notBefore=");
1268 				if (!ASN1_TIME_to_tm(nB, NULL))
1269 					BIO_puts(STDout,
1270 					    "INVALID RFC5280 TIME");
1271 				else
1272 					ASN1_TIME_print(STDout, nB);
1273 				BIO_puts(STDout, "\n");
1274 			} else if (cfg.enddate == i) {
1275 				ASN1_TIME *nA = X509_get_notAfter(x);
1276 
1277 				BIO_puts(STDout, "notAfter=");
1278 				if (!ASN1_TIME_to_tm(nA, NULL))
1279 					BIO_puts(STDout,
1280 					    "INVALID RFC5280 TIME");
1281 				else
1282 					ASN1_TIME_print(STDout, nA);
1283 				BIO_puts(STDout, "\n");
1284 			} else if (cfg.fingerprint == i) {
1285 				int j;
1286 				unsigned int n;
1287 				unsigned char md[EVP_MAX_MD_SIZE];
1288 				const EVP_MD *fdig = cfg.digest;
1289 
1290 				if (fdig == NULL)
1291 					fdig = EVP_sha256();
1292 
1293 				if (!X509_digest(x, fdig, md, &n)) {
1294 					BIO_printf(bio_err, "out of memory\n");
1295 					goto end;
1296 				}
1297 				BIO_printf(STDout, "%s Fingerprint=",
1298 				    OBJ_nid2sn(EVP_MD_type(fdig)));
1299 				for (j = 0; j < (int) n; j++) {
1300 					BIO_printf(STDout, "%02X%c", md[j],
1301 					    (j + 1 == (int)n) ? '\n' : ':');
1302 				}
1303 			} else if (cfg.sign_flag == i && cfg.x509req == 0) {
1304 				if (Upkey == NULL) {
1305 					Upkey = load_key(bio_err, cfg.keyfile,
1306 					    cfg.keyformat, 0, passin,
1307 					    "Private key");
1308 					if (Upkey == NULL)
1309 						goto end;
1310 				}
1311 				if (!sign(x, Upkey, cfg.days,
1312 				    cfg.clrext, cfg.digest,
1313 				    extconf, cfg.extsect, iname,
1314 				    cfg.force_pubkey))
1315 					goto end;
1316 			} else if (cfg.CA_flag == i) {
1317 				if (cfg.CAkeyfile != NULL) {
1318 					CApkey = load_key(bio_err, cfg.CAkeyfile,
1319 					    cfg.CAkeyformat, 0, passin,
1320 					    "CA Private Key");
1321 					if (CApkey == NULL)
1322 						goto end;
1323 				}
1324 				if (!x509_certify(ctx, cfg.CAfile, cfg.digest,
1325 				    x, xca, CApkey, cfg.sigopts, cfg.CAserial,
1326 				    cfg.CA_createserial, cfg.days, cfg.clrext,
1327 				    extconf, cfg.extsect, cfg.sno, iname))
1328 					goto end;
1329 			} else if (cfg.x509req == i) {
1330 				EVP_PKEY *pk;
1331 
1332 				BIO_printf(bio_err,
1333 				    "Getting request Private Key\n");
1334 				if (cfg.keyfile == NULL) {
1335 					BIO_printf(bio_err,
1336 					    "no request key file specified\n");
1337 					goto end;
1338 				} else {
1339 					pk = load_key(bio_err, cfg.keyfile,
1340 					    cfg.keyformat, 0, passin,
1341 					    "request key");
1342 					if (pk == NULL)
1343 						goto end;
1344 				}
1345 
1346 				BIO_printf(bio_err,
1347 				    "Generating certificate request\n");
1348 
1349 				rq = X509_to_X509_REQ(x, pk, cfg.digest);
1350 				EVP_PKEY_free(pk);
1351 				if (rq == NULL) {
1352 					ERR_print_errors(bio_err);
1353 					goto end;
1354 				}
1355 				if (!cfg.noout) {
1356 					if (!X509_REQ_print(out, rq))
1357 						goto end;
1358 					if (!PEM_write_bio_X509_REQ(out, rq))
1359 						goto end;
1360 				}
1361 				cfg.noout = 1;
1362 			} else if (cfg.ocspid == i) {
1363 				if (!X509_ocspid_print(out, x))
1364 					goto end;
1365 			}
1366 		}
1367 	}
1368 	if (cfg.checkend) {
1369 		time_t tcheck = time(NULL) + cfg.checkoffset;
1370 		int timecheck = X509_cmp_time(X509_get_notAfter(x), &tcheck);
1371 		if (timecheck == 0) {
1372 			BIO_printf(out, "Certificate expiry time is invalid\n");
1373 			ret = 1;
1374 		} else if (timecheck < 0) {
1375 			BIO_printf(out, "Certificate will expire\n");
1376 			ret = 1;
1377 		} else {
1378 			BIO_printf(out, "Certificate will not expire\n");
1379 			ret = 0;
1380 		}
1381 		goto end;
1382 	}
1383 	if (cfg.noout) {
1384 		ret = 0;
1385 		goto end;
1386 	}
1387 	if (cfg.outformat == FORMAT_ASN1)
1388 		i = i2d_X509_bio(out, x);
1389 	else if (cfg.outformat == FORMAT_PEM) {
1390 		if (cfg.trustout)
1391 			i = PEM_write_bio_X509_AUX(out, x);
1392 		else
1393 			i = PEM_write_bio_X509(out, x);
1394 	} else {
1395 		BIO_printf(bio_err,
1396 		    "bad output format specified for outfile\n");
1397 		goto end;
1398 	}
1399 	if (!i) {
1400 		BIO_printf(bio_err, "unable to write certificate\n");
1401 		ERR_print_errors(bio_err);
1402 		goto end;
1403 	}
1404 	ret = 0;
1405 
1406  end:
1407 	OBJ_cleanup();
1408 	NCONF_free(extconf);
1409 	BIO_free_all(out);
1410 	BIO_free_all(STDout);
1411 	X509_NAME_free(iname);
1412 	X509_NAME_free(sname);
1413 	X509_STORE_free(ctx);
1414 	X509_REQ_free(req);
1415 	X509_free(x);
1416 	X509_free(xca);
1417 	EVP_PKEY_free(Fpkey);
1418 	EVP_PKEY_free(Upkey);
1419 	EVP_PKEY_free(CApkey);
1420 	sk_OPENSSL_STRING_free(cfg.sigopts);
1421 	X509_REQ_free(rq);
1422 	ASN1_INTEGER_free(cfg.sno);
1423 	sk_ASN1_OBJECT_pop_free(cfg.trust, ASN1_OBJECT_free);
1424 	sk_ASN1_OBJECT_pop_free(cfg.reject, ASN1_OBJECT_free);
1425 	free(passin);
1426 
1427 	return (ret);
1428 }
1429 
1430 static ASN1_INTEGER *
1431 x509_load_serial(char *CAfile, char *serialfile, int create)
1432 {
1433 	char *buf = NULL, *p;
1434 	ASN1_INTEGER *bs = NULL;
1435 	BIGNUM *serial = NULL;
1436 	size_t len;
1437 
1438 	len = ((serialfile == NULL) ? (strlen(CAfile) + strlen(POSTFIX) + 1) :
1439 	    (strlen(serialfile))) + 1;
1440 	buf = malloc(len);
1441 	if (buf == NULL) {
1442 		BIO_printf(bio_err, "out of mem\n");
1443 		goto end;
1444 	}
1445 	if (serialfile == NULL) {
1446 		strlcpy(buf, CAfile, len);
1447 		for (p = buf; *p; p++)
1448 			if (*p == '.') {
1449 				*p = '\0';
1450 				break;
1451 			}
1452 		strlcat(buf, POSTFIX, len);
1453 	} else
1454 		strlcpy(buf, serialfile, len);
1455 
1456 	serial = load_serial(buf, create, NULL);
1457 	if (serial == NULL)
1458 		goto end;
1459 
1460 	if (!BN_add_word(serial, 1)) {
1461 		BIO_printf(bio_err, "add_word failure\n");
1462 		goto end;
1463 	}
1464 	if (!save_serial(buf, NULL, serial, &bs))
1465 		goto end;
1466 
1467  end:
1468 	free(buf);
1469 	BN_free(serial);
1470 
1471 	return bs;
1472 }
1473 
1474 static int
1475 x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x,
1476     X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
1477     char *serialfile, int create, int days, int clrext, CONF *conf,
1478     char *section, ASN1_INTEGER *sno, X509_NAME *issuer)
1479 {
1480 	int ret = 0;
1481 	ASN1_INTEGER *bs = NULL;
1482 	X509_STORE_CTX *xsc = NULL;
1483 	EVP_PKEY *upkey;
1484 
1485 	upkey = X509_get0_pubkey(xca);
1486 	if (upkey == NULL)
1487 		goto end;
1488 	EVP_PKEY_copy_parameters(upkey, pkey);
1489 
1490 	if ((xsc = X509_STORE_CTX_new()) == NULL)
1491 		goto end;
1492 	if (!X509_STORE_CTX_init(xsc, ctx, x, NULL)) {
1493 		BIO_printf(bio_err, "Error initialising X509 store\n");
1494 		goto end;
1495 	}
1496 	if (sno != NULL)
1497 		bs = sno;
1498 	else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)
1499 		goto end;
1500 
1501 /*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/
1502 
1503 	/*
1504 	 * NOTE: this certificate can/should be self signed, unless it was a
1505 	 * certificate request in which case it is not.
1506 	 */
1507 	X509_STORE_CTX_set_cert(xsc, x);
1508 	X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
1509 	if (!cfg.reqfile && X509_verify_cert(xsc) <= 0)
1510 		goto end;
1511 
1512 	if (!X509_check_private_key(xca, pkey)) {
1513 		BIO_printf(bio_err,
1514 		    "CA certificate and CA private key do not match\n");
1515 		goto end;
1516 	}
1517 
1518 	if (issuer == NULL)
1519 		issuer = X509_get_subject_name(xca);
1520 	if (issuer == NULL)
1521 		goto end;
1522 	if (!X509_set_issuer_name(x, issuer))
1523 		goto end;
1524 
1525 	if (!X509_set_serialNumber(x, bs))
1526 		goto end;
1527 
1528 	if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
1529 		goto end;
1530 
1531 	/* hardwired expired */
1532 	if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
1533 		goto end;
1534 
1535 	if (clrext) {
1536 		while (X509_get_ext_count(x) > 0) {
1537 			if (X509_delete_ext(x, 0) == NULL)
1538 				goto end;
1539 		}
1540 	}
1541 	if (conf != NULL) {
1542 		X509V3_CTX ctx2;
1543 		if (!X509_set_version(x, 2))	/* version 3 certificate */
1544 			goto end;
1545 		X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
1546 		X509V3_set_nconf(&ctx2, conf);
1547 		if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
1548 			goto end;
1549 	}
1550 	if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
1551 		goto end;
1552 
1553 	ret = 1;
1554  end:
1555 	X509_STORE_CTX_free(xsc);
1556 	if (!ret)
1557 		ERR_print_errors(bio_err);
1558 	if (sno == NULL)
1559 		ASN1_INTEGER_free(bs);
1560 	return ret;
1561 }
1562 
1563 static int
1564 callb(int ok, X509_STORE_CTX *ctx)
1565 {
1566 	int err;
1567 	X509 *err_cert;
1568 
1569 	/*
1570 	 * it is ok to use a self signed certificate This case will catch
1571 	 * both the initial ok == 0 and the final ok == 1 calls to this
1572 	 * function
1573 	 */
1574 	err = X509_STORE_CTX_get_error(ctx);
1575 	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
1576 		return 1;
1577 
1578 	/*
1579 	 * BAD we should have gotten an error.  Normally if everything worked
1580 	 * X509_STORE_CTX_get_error(ctx) will still be set to
1581 	 * DEPTH_ZERO_SELF_....
1582 	 */
1583 	if (ok) {
1584 		BIO_printf(bio_err,
1585 		    "error with certificate to be certified - should be self signed\n");
1586 		return 0;
1587 	} else {
1588 		err_cert = X509_STORE_CTX_get_current_cert(ctx);
1589 		print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
1590 		BIO_printf(bio_err,
1591 		    "error with certificate - error %d at depth %d\n%s\n",
1592 		    err, X509_STORE_CTX_get_error_depth(ctx),
1593 		    X509_verify_cert_error_string(err));
1594 		return 1;
1595 	}
1596 }
1597 
1598 static int
1599 key_identifier_hash(EVP_PKEY *pkey, unsigned char *md, unsigned int *md_len)
1600 {
1601 	X509_PUBKEY *x509_pubkey = NULL;
1602 	const unsigned char *der;
1603 	int der_len;
1604 	int ret = 0;
1605 
1606 	if (*md_len < SHA_DIGEST_LENGTH)
1607 		goto err;
1608 
1609 	if (!X509_PUBKEY_set(&x509_pubkey, pkey))
1610 		goto err;
1611 	if (!X509_PUBKEY_get0_param(NULL, &der, &der_len, NULL, x509_pubkey))
1612 		goto err;
1613 	if (!EVP_Digest(der, der_len, md, md_len, EVP_sha1(), NULL))
1614 		goto err;
1615 
1616 	ret = 1;
1617 
1618  err:
1619 	X509_PUBKEY_free(x509_pubkey);
1620 
1621 	return ret;
1622 }
1623 
1624 static ASN1_OCTET_STRING *
1625 compute_key_identifier(EVP_PKEY *pkey)
1626 {
1627 	ASN1_OCTET_STRING *ki = NULL;
1628 	unsigned char md[EVP_MAX_MD_SIZE];
1629 	unsigned int md_len = EVP_MAX_MD_SIZE;
1630 
1631 	if (!key_identifier_hash(pkey, md, &md_len))
1632 		goto err;
1633 
1634 	if ((ki = ASN1_OCTET_STRING_new()) == NULL)
1635 		goto err;
1636 	if (!ASN1_STRING_set(ki, md, md_len))
1637 		goto err;
1638 
1639 	return ki;
1640 
1641  err:
1642 	ASN1_OCTET_STRING_free(ki);
1643 
1644 	return NULL;
1645 }
1646 
1647 static ASN1_OCTET_STRING *
1648 compute_subject_key_identifier(EVP_PKEY *subject_key)
1649 {
1650 	return compute_key_identifier(subject_key);
1651 }
1652 
1653 static AUTHORITY_KEYID *
1654 compute_authority_key_identifier(EVP_PKEY *issuer_key)
1655 {
1656 	AUTHORITY_KEYID *aki = NULL;
1657 
1658 	if ((aki = AUTHORITY_KEYID_new()) == NULL)
1659 		goto err;
1660 	if ((aki->keyid = compute_key_identifier(issuer_key)) == NULL)
1661 		goto err;
1662 
1663 	return aki;
1664 
1665  err:
1666 	AUTHORITY_KEYID_free(aki);
1667 
1668 	return NULL;
1669 }
1670 
1671 static int
1672 set_key_identifiers(X509 *cert, EVP_PKEY *issuer_key)
1673 {
1674 	EVP_PKEY *subject_key;
1675 	ASN1_OCTET_STRING *ski = NULL;
1676 	AUTHORITY_KEYID *aki = NULL;
1677 	int ret = 0;
1678 
1679 	if ((subject_key = X509_get0_pubkey(cert)) == NULL)
1680 		goto err;
1681 
1682 	if ((ski = compute_subject_key_identifier(subject_key)) == NULL)
1683 		goto err;
1684 	if (!X509_add1_ext_i2d(cert, NID_subject_key_identifier, ski, 0,
1685 	    X509V3_ADD_REPLACE))
1686 		goto err;
1687 
1688 	/*
1689 	 * Historical OpenSSL behavior: don't set AKI if we're self-signing.
1690 	 * RFC 5280 says we MAY omit it, so this is ok.
1691 	 */
1692 	if (EVP_PKEY_cmp(subject_key, issuer_key) == 1)
1693 		goto done;
1694 
1695 	if ((aki = compute_authority_key_identifier(issuer_key)) == NULL)
1696 		goto err;
1697 	if (!X509_add1_ext_i2d(cert, NID_authority_key_identifier, aki, 0,
1698 	    X509V3_ADD_REPLACE))
1699 		goto err;
1700 
1701  done:
1702 	ret = 1;
1703 
1704  err:
1705 	ASN1_OCTET_STRING_free(ski);
1706 	AUTHORITY_KEYID_free(aki);
1707 
1708 	return ret;
1709 }
1710 
1711 static int
1712 sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
1713     CONF *conf, char *section, X509_NAME *issuer, char *force_pubkey)
1714 {
1715 	EVP_PKEY *pktmp;
1716 
1717 	pktmp = X509_get0_pubkey(x);
1718 	if (pktmp == NULL)
1719 		goto err;
1720 	EVP_PKEY_copy_parameters(pktmp, pkey);
1721 	EVP_PKEY_save_parameters(pktmp, 1);
1722 
1723 	if (issuer == NULL)
1724 		issuer = X509_get_subject_name(x);
1725 	if (issuer == NULL)
1726 		goto err;
1727 	if (!X509_set_issuer_name(x, issuer))
1728 		goto err;
1729 	if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
1730 		goto err;
1731 
1732 	if (X509_gmtime_adj(X509_get_notAfter(x), 60L * 60 * 24 * days) == NULL)
1733 		goto err;
1734 
1735 	if (force_pubkey == NULL) {
1736 		if (!X509_set_pubkey(x, pkey))
1737 			goto err;
1738 	}
1739 	if (clrext) {
1740 		while (X509_get_ext_count(x) > 0) {
1741 			if (X509_delete_ext(x, 0) == NULL)
1742 				goto err;
1743 		}
1744 	}
1745 	if (conf != NULL) {
1746 		X509V3_CTX ctx;
1747 
1748 		if (!X509_set_version(x, 2))	/* version 3 certificate */
1749 			goto err;
1750 		X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
1751 		X509V3_set_nconf(&ctx, conf);
1752 		if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
1753 			goto err;
1754 		if (force_pubkey != NULL) {
1755 			/*
1756 			 * Set or fix up SKI and AKI.
1757 			 *
1758 			 * XXX - Doing this in a fully OpenSSL 3 compatible way
1759 			 * is extremely nasty: they hang an issuer_pubkey off
1760 			 * the X509V3_CTX and adjusted v2i_AUTHORITY_KEYID().
1761 			 * Punt on this and make things work in the specific
1762 			 * situation we're interested in. Like OpenSSL, we only
1763 			 * support the keyid form of the AKI, which is what
1764 			 * RFC 5280 recommends, but unlike OpenSSL we replace
1765 			 * existing SKI and AKI rather than honoring the most
1766 			 * likely outdated ones already present in the cert.
1767 			 */
1768 			if (!set_key_identifiers(x, pkey))
1769 				goto err;
1770 		}
1771 	}
1772 	if (!X509_sign(x, pkey, digest))
1773 		goto err;
1774 
1775 	return 1;
1776 
1777  err:
1778 	ERR_print_errors(bio_err);
1779 	return 0;
1780 }
1781 
1782 static int
1783 purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt)
1784 {
1785 	int id, i, idret;
1786 	const char *pname;
1787 
1788 	id = X509_PURPOSE_get_id(pt);
1789 	pname = X509_PURPOSE_get0_name(pt);
1790 	for (i = 0; i < 2; i++) {
1791 		idret = X509_check_purpose(cert, id, i);
1792 		BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
1793 		if (idret == 1)
1794 			BIO_printf(bio, "Yes\n");
1795 		else if (idret == 0)
1796 			BIO_printf(bio, "No\n");
1797 		else
1798 			BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
1799 	}
1800 	return 1;
1801 }
1802