xref: /openbsd/usr.bin/openssl/ca.c (revision fd187f8b)
1 /* $OpenBSD: ca.c,v 1.58 2024/02/04 13:08:29 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 /* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
60 
61 #include <sys/types.h>
62 
63 #include <ctype.h>
64 #include <stdio.h>
65 #include <stdlib.h>
66 #include <limits.h>
67 #include <string.h>
68 #include <unistd.h>
69 
70 #include "apps.h"
71 
72 #include <openssl/bio.h>
73 #include <openssl/bn.h>
74 #include <openssl/conf.h>
75 #include <openssl/err.h>
76 #include <openssl/evp.h>
77 #include <openssl/objects.h>
78 #include <openssl/ocsp.h>
79 #include <openssl/pem.h>
80 #include <openssl/txt_db.h>
81 #include <openssl/x509.h>
82 #include <openssl/x509v3.h>
83 
84 #define BASE_SECTION		"ca"
85 
86 #define ENV_DEFAULT_CA		"default_ca"
87 
88 #define STRING_MASK		"string_mask"
89 #define UTF8_IN			"utf8"
90 
91 #define ENV_NEW_CERTS_DIR	"new_certs_dir"
92 #define ENV_CERTIFICATE 	"certificate"
93 #define ENV_SERIAL		"serial"
94 #define ENV_CRLNUMBER		"crlnumber"
95 #define ENV_PRIVATE_KEY		"private_key"
96 #define ENV_DEFAULT_DAYS 	"default_days"
97 #define ENV_DEFAULT_STARTDATE 	"default_startdate"
98 #define ENV_DEFAULT_ENDDATE 	"default_enddate"
99 #define ENV_DEFAULT_CRL_DAYS 	"default_crl_days"
100 #define ENV_DEFAULT_CRL_HOURS 	"default_crl_hours"
101 #define ENV_DEFAULT_MD		"default_md"
102 #define ENV_DEFAULT_EMAIL_DN	"email_in_dn"
103 #define ENV_PRESERVE		"preserve"
104 #define ENV_POLICY      	"policy"
105 #define ENV_EXTENSIONS      	"x509_extensions"
106 #define ENV_CRLEXT      	"crl_extensions"
107 #define ENV_MSIE_HACK		"msie_hack"
108 #define ENV_NAMEOPT		"name_opt"
109 #define ENV_CERTOPT		"cert_opt"
110 #define ENV_EXTCOPY		"copy_extensions"
111 #define ENV_UNIQUE_SUBJECT	"unique_subject"
112 
113 #define ENV_DATABASE		"database"
114 
115 /* Additional revocation information types */
116 
117 #define REV_NONE		0	/* No addditional information */
118 #define REV_CRL_REASON		1	/* Value is CRL reason code */
119 #define REV_HOLD		2	/* Value is hold instruction */
120 #define REV_KEY_COMPROMISE	3	/* Value is cert key compromise time */
121 #define REV_CA_COMPROMISE	4	/* Value is CA key compromise time */
122 
123 static void lookup_fail(const char *name, const char *tag);
124 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
125     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
126     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
127     unsigned long chtype, int multirdn, int email_dn, char *startdate,
128     char *enddate, long days, int batch, char *ext_sect, CONF *conf,
129     int verbose, unsigned long certopt, unsigned long nameopt,
130     int default_op, int ext_copy, int selfsign);
131 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey,
132     X509 *x509, const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
133     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
134     unsigned long chtype, int multirdn, int email_dn, char *startdate,
135     char *enddate, long days, int batch, char *ext_sect, CONF *conf,
136     int verbose, unsigned long certopt, unsigned long nameopt, int default_op,
137     int ext_copy);
138 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey,
139     X509 *x509, const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
140     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
141     unsigned long chtype, int multirdn, int email_dn, char *startdate,
142     char *enddate, long days, char *ext_sect, CONF *conf, int verbose,
143     unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy);
144 static int write_new_certificate(BIO *bp, X509 *x, int output_der,
145     int notext);
146 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
147     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
148     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
149     unsigned long chtype, int multirdn, int email_dn, char *startdate,
150     char *enddate, long days, int batch, int verbose, X509_REQ *req,
151     char *ext_sect, CONF *conf, unsigned long certopt, unsigned long nameopt,
152     int default_op, int ext_copy, int selfsign);
153 static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
154 static int get_certificate_status(const char *serial, CA_DB *db);
155 static int do_updatedb(CA_DB *db);
156 static int check_time_format(const char *str);
157 static char *bin2hex(unsigned char *, size_t);
158 char *make_revocation_str(int rev_type, char *rev_arg);
159 int make_revoked(X509_REVOKED *rev, const char *str);
160 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
161 
162 static CONF *conf = NULL;
163 static CONF *extconf = NULL;
164 
165 static struct {
166 	int batch;
167 	char *certfile;
168 	unsigned long chtype;
169 	char *configfile;
170 	int create_serial;
171 	char *crl_ext;
172 	long crldays;
173 	long crlhours;
174 	long crlsec;
175 	long days;
176 	int dorevoke;
177 	int doupdatedb;
178 	int email_dn;
179 	char *enddate;
180 	char *extensions;
181 	char *extfile;
182 	int gencrl;
183 	char *infile;
184 	char **infiles;
185 	int infiles_num;
186 	char *key;
187 	char *keyfile;
188 	int keyform;
189 	char *md;
190 	int multirdn;
191 	int msie_hack;
192 	int notext;
193 	char *outdir;
194 	char *outfile;
195 	char *passargin;
196 	char *policy;
197 	int preserve;
198 	int req;
199 	char *rev_arg;
200 	int rev_type;
201 	char *serial_status;
202 	char *section;
203 	int selfsign;
204 	STACK_OF(OPENSSL_STRING) *sigopts;
205 	char *spkac_file;
206 	char *ss_cert_file;
207 	char *startdate;
208 	char *subj;
209 	int verbose;
210 } cfg;
211 
212 static int
ca_opt_chtype_utf8(void)213 ca_opt_chtype_utf8(void)
214 {
215 	cfg.chtype = MBSTRING_UTF8;
216 	return (0);
217 }
218 
219 static int
ca_opt_crl_ca_compromise(char * arg)220 ca_opt_crl_ca_compromise(char *arg)
221 {
222 	cfg.rev_arg = arg;
223 	cfg.rev_type = REV_CA_COMPROMISE;
224 	return (0);
225 }
226 
227 static int
ca_opt_crl_compromise(char * arg)228 ca_opt_crl_compromise(char *arg)
229 {
230 	cfg.rev_arg = arg;
231 	cfg.rev_type = REV_KEY_COMPROMISE;
232 	return (0);
233 }
234 
235 static int
ca_opt_crl_hold(char * arg)236 ca_opt_crl_hold(char *arg)
237 {
238 	cfg.rev_arg = arg;
239 	cfg.rev_type = REV_HOLD;
240 	return (0);
241 }
242 
243 static int
ca_opt_crl_reason(char * arg)244 ca_opt_crl_reason(char *arg)
245 {
246 	cfg.rev_arg = arg;
247 	cfg.rev_type = REV_CRL_REASON;
248 	return (0);
249 }
250 
251 static int
ca_opt_in(char * arg)252 ca_opt_in(char *arg)
253 {
254 	cfg.infile = arg;
255 	cfg.req = 1;
256 	return (0);
257 }
258 
259 static int
ca_opt_infiles(int argc,char ** argv,int * argsused)260 ca_opt_infiles(int argc, char **argv, int *argsused)
261 {
262 	cfg.infiles_num = argc - 1;
263 	if (cfg.infiles_num < 1)
264 		return (1);
265 	cfg.infiles = argv + 1;
266 	cfg.req = 1;
267 	*argsused = argc;
268 	return (0);
269 }
270 
271 static int
ca_opt_revoke(char * arg)272 ca_opt_revoke(char *arg)
273 {
274 	cfg.infile = arg;
275 	cfg.dorevoke = 1;
276 	return (0);
277 }
278 
279 static int
ca_opt_sigopt(char * arg)280 ca_opt_sigopt(char *arg)
281 {
282 	if (cfg.sigopts == NULL)
283 		cfg.sigopts = sk_OPENSSL_STRING_new_null();
284 	if (cfg.sigopts == NULL)
285 		return (1);
286 	if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
287 		return (1);
288 	return (0);
289 }
290 
291 static int
ca_opt_spkac(char * arg)292 ca_opt_spkac(char *arg)
293 {
294 	cfg.spkac_file = arg;
295 	cfg.req = 1;
296 	return (0);
297 }
298 
299 static int
ca_opt_ss_cert(char * arg)300 ca_opt_ss_cert(char *arg)
301 {
302 	cfg.ss_cert_file = arg;
303 	cfg.req = 1;
304 	return (0);
305 }
306 
307 static const struct option ca_options[] = {
308 	{
309 		.name = "batch",
310 		.desc = "Operate in batch mode",
311 		.type = OPTION_FLAG,
312 		.opt.flag = &cfg.batch,
313 	},
314 	{
315 		.name = "cert",
316 		.argname = "file",
317 		.desc = "File containing the CA certificate",
318 		.type = OPTION_ARG,
319 		.opt.arg = &cfg.certfile,
320 	},
321 	{
322 		.name = "config",
323 		.argname = "file",
324 		.desc = "Specify an alternative configuration file",
325 		.type = OPTION_ARG,
326 		.opt.arg = &cfg.configfile,
327 	},
328 	{
329 		.name = "create_serial",
330 		.desc = "If reading serial fails, create a new random serial",
331 		.type = OPTION_FLAG,
332 		.opt.flag = &cfg.create_serial,
333 	},
334 	{
335 		.name = "crl_CA_compromise",
336 		.argname = "time",
337 		.desc = "Set the compromise time and the revocation reason to\n"
338 		    "CACompromise",
339 		.type = OPTION_ARG_FUNC,
340 		.opt.argfunc = ca_opt_crl_ca_compromise,
341 	},
342 	{
343 		.name = "crl_compromise",
344 		.argname = "time",
345 		.desc = "Set the compromise time and the revocation reason to\n"
346 		    "keyCompromise",
347 		.type = OPTION_ARG_FUNC,
348 		.opt.argfunc = ca_opt_crl_compromise,
349 	},
350 	{
351 		.name = "crl_hold",
352 		.argname = "instruction",
353 		.desc = "Set the hold instruction and the revocation reason to\n"
354 		    "certificateHold",
355 		.type = OPTION_ARG_FUNC,
356 		.opt.argfunc = ca_opt_crl_hold,
357 	},
358 	{
359 		.name = "crl_reason",
360 		.argname = "reason",
361 		.desc = "Revocation reason",
362 		.type = OPTION_ARG_FUNC,
363 		.opt.argfunc = ca_opt_crl_reason,
364 	},
365 	{
366 		.name = "crldays",
367 		.argname = "days",
368 		.desc = "Number of days before the next CRL is due",
369 		.type = OPTION_ARG_LONG,
370 		.opt.lvalue = &cfg.crldays,
371 	},
372 	{
373 		.name = "crlexts",
374 		.argname = "section",
375 		.desc = "CRL extension section (override value in config file)",
376 		.type = OPTION_ARG,
377 		.opt.arg = &cfg.crl_ext,
378 	},
379 	{
380 		.name = "crlhours",
381 		.argname = "hours",
382 		.desc = "Number of hours before the next CRL is due",
383 		.type = OPTION_ARG_LONG,
384 		.opt.lvalue = &cfg.crlhours,
385 	},
386 	{
387 		.name = "crlsec",
388 		.argname = "seconds",
389 		.desc = "Number of seconds before the next CRL is due",
390 		.type = OPTION_ARG_LONG,
391 		.opt.lvalue = &cfg.crlsec,
392 	},
393 	{
394 		.name = "days",
395 		.argname = "arg",
396 		.desc = "Number of days to certify the certificate for",
397 		.type = OPTION_ARG_LONG,
398 		.opt.lvalue = &cfg.days,
399 	},
400 	{
401 		.name = "enddate",
402 		.argname = "YYMMDDHHMMSSZ",
403 		.desc = "Certificate validity notAfter (overrides -days)",
404 		.type = OPTION_ARG,
405 		.opt.arg = &cfg.enddate,
406 	},
407 	{
408 		.name = "extensions",
409 		.argname = "section",
410 		.desc = "Extension section (override value in config file)",
411 		.type = OPTION_ARG,
412 		.opt.arg = &cfg.extensions,
413 	},
414 	{
415 		.name = "extfile",
416 		.argname = "file",
417 		.desc = "Configuration file with X509v3 extentions to add",
418 		.type = OPTION_ARG,
419 		.opt.arg = &cfg.extfile,
420 	},
421 	{
422 		.name = "gencrl",
423 		.desc = "Generate a new CRL",
424 		.type = OPTION_FLAG,
425 		.opt.flag = &cfg.gencrl,
426 	},
427 	{
428 		.name = "in",
429 		.argname = "file",
430 		.desc = "Input file containing a single certificate request",
431 		.type = OPTION_ARG_FUNC,
432 		.opt.argfunc = ca_opt_in,
433 	},
434 	{
435 		.name = "infiles",
436 		.argname = "...",
437 		.desc = "The last argument, certificate requests to process",
438 		.type = OPTION_ARGV_FUNC,
439 		.opt.argvfunc = ca_opt_infiles,
440 	},
441 	{
442 		.name = "key",
443 		.argname = "password",
444 		.desc = "Key to decode the private key if it is encrypted",
445 		.type = OPTION_ARG,
446 		.opt.arg = &cfg.key,
447 	},
448 	{
449 		.name = "keyfile",
450 		.argname = "file",
451 		.desc = "Private key file",
452 		.type = OPTION_ARG,
453 		.opt.arg = &cfg.keyfile,
454 	},
455 	{
456 		.name = "keyform",
457 		.argname = "fmt",
458 		.desc = "Private key file format (DER or PEM (default))",
459 		.type = OPTION_ARG_FORMAT,
460 		.opt.value = &cfg.keyform,
461 	},
462 	{
463 		.name = "md",
464 		.argname = "alg",
465 		.desc = "Message digest to use",
466 		.type = OPTION_ARG,
467 		.opt.arg = &cfg.md,
468 	},
469 	{
470 		.name = "msie_hack",
471 		.type = OPTION_FLAG,
472 		.opt.flag = &cfg.msie_hack,
473 	},
474 	{
475 		.name = "multivalue-rdn",
476 		.desc = "Enable support for multivalued RDNs",
477 		.type = OPTION_FLAG,
478 		.opt.flag = &cfg.multirdn,
479 	},
480 	{
481 		.name = "name",
482 		.argname = "section",
483 		.desc = "Specifies the configuration file section to use",
484 		.type = OPTION_ARG,
485 		.opt.arg = &cfg.section,
486 	},
487 	{
488 		.name = "noemailDN",
489 		.desc = "Do not add the EMAIL field to the DN",
490 		.type = OPTION_VALUE,
491 		.opt.value = &cfg.email_dn,
492 		.value = 0,
493 	},
494 	{
495 		.name = "notext",
496 		.desc = "Do not print the generated certificate",
497 		.type = OPTION_FLAG,
498 		.opt.flag = &cfg.notext,
499 	},
500 	{
501 		.name = "out",
502 		.argname = "file",
503 		.desc = "Output file (default stdout)",
504 		.type = OPTION_ARG,
505 		.opt.arg = &cfg.outfile,
506 	},
507 	{
508 		.name = "outdir",
509 		.argname = "directory",
510 		.desc = " Directory to output certificates to",
511 		.type = OPTION_ARG,
512 		.opt.arg = &cfg.outdir,
513 	},
514 	{
515 		.name = "passin",
516 		.argname = "src",
517 		.desc = "Private key input password source",
518 		.type = OPTION_ARG,
519 		.opt.arg = &cfg.passargin,
520 	},
521 	{
522 		.name = "policy",
523 		.argname = "name",
524 		.desc = "The CA 'policy' to support",
525 		.type = OPTION_ARG,
526 		.opt.arg = &cfg.policy,
527 	},
528 	{
529 		.name = "preserveDN",
530 		.desc = "Do not re-order the DN",
531 		.type = OPTION_FLAG,
532 		.opt.flag = &cfg.preserve,
533 	},
534 	{
535 		.name = "revoke",
536 		.argname = "file",
537 		.desc = "Revoke a certificate (given in file)",
538 		.type = OPTION_ARG_FUNC,
539 		.opt.argfunc = ca_opt_revoke,
540 	},
541 	{
542 		.name = "selfsign",
543 		.desc = "Sign a certificate using the key associated with it",
544 		.type = OPTION_FLAG,
545 		.opt.flag = &cfg.selfsign,
546 	},
547 	{
548 		.name = "sigopt",
549 		.argname = "nm:v",
550 		.desc = "Signature parameter in nm:v form",
551 		.type = OPTION_ARG_FUNC,
552 		.opt.argfunc = ca_opt_sigopt,
553 	},
554 	{
555 		.name = "spkac",
556 		.argname = "file",
557 		.desc = "File contains DN and signed public key and challenge",
558 		.type = OPTION_ARG_FUNC,
559 		.opt.argfunc = ca_opt_spkac,
560 	},
561 	{
562 		.name = "ss_cert",
563 		.argname = "file",
564 		.desc = "File contains a self signed certificate to sign",
565 		.type = OPTION_ARG_FUNC,
566 		.opt.argfunc = ca_opt_ss_cert,
567 	},
568 	{
569 		.name = "startdate",
570 		.argname = "YYMMDDHHMMSSZ",
571 		.desc = "Certificate validity notBefore",
572 		.type = OPTION_ARG,
573 		.opt.arg = &cfg.startdate,
574 	},
575 	{
576 		.name = "status",
577 		.argname = "serial",
578 		.desc = "Shows certificate status given the serial number",
579 		.type = OPTION_ARG,
580 		.opt.arg = &cfg.serial_status,
581 	},
582 	{
583 		.name = "subj",
584 		.argname = "arg",
585 		.desc = "Use arg instead of request's subject",
586 		.type = OPTION_ARG,
587 		.opt.arg = &cfg.subj,
588 	},
589 	{
590 		.name = "updatedb",
591 		.desc = "Updates db for expired certificates",
592 		.type = OPTION_FLAG,
593 		.opt.flag = &cfg.doupdatedb,
594 	},
595 	{
596 		.name = "utf8",
597 		.desc = "Input characters are in UTF-8 (default ASCII)",
598 		.type = OPTION_FUNC,
599 		.opt.func = ca_opt_chtype_utf8,
600 	},
601 	{
602 		.name = "verbose",
603 		.desc = "Verbose output during processing",
604 		.type = OPTION_FLAG,
605 		.opt.flag = &cfg.verbose,
606 	},
607 	{ NULL },
608 };
609 
610 static void
ca_usage(void)611 ca_usage(void)
612 {
613 	fprintf(stderr,
614 	    "usage: ca  [-batch] [-cert file] [-config file] [-create_serial]\n"
615 	    "    [-crl_CA_compromise time] [-crl_compromise time]\n"
616 	    "    [-crl_hold instruction] [-crl_reason reason] [-crldays days]\n"
617 	    "    [-crlexts section] [-crlhours hours] [-crlsec seconds]\n"
618 	    "    [-days arg] [-enddate date] [-extensions section]\n"
619 	    "    [-extfile file] [-gencrl] [-in file] [-infiles]\n"
620 	    "    [-key password] [-keyfile file] [-keyform pem | der]\n"
621 	    "    [-md alg] [-multivalue-rdn] [-name section]\n"
622 	    "    [-noemailDN] [-notext] [-out file] [-outdir directory]\n"
623 	    "    [-passin arg] [-policy name] [-preserveDN] [-revoke file]\n"
624 	    "    [-selfsign] [-sigopt nm:v] [-spkac file] [-ss_cert file]\n"
625 	    "    [-startdate date] [-status serial] [-subj arg] [-updatedb]\n"
626 	    "    [-utf8] [-verbose]\n\n");
627 	options_usage(ca_options);
628 	fprintf(stderr, "\n");
629 }
630 
631 int
ca_main(int argc,char ** argv)632 ca_main(int argc, char **argv)
633 {
634 	int free_key = 0;
635 	int total = 0;
636 	int total_done = 0;
637 	long errorline = -1;
638 	EVP_PKEY *pkey = NULL;
639 	int output_der = 0;
640 	char *serialfile = NULL;
641 	char *crlnumberfile = NULL;
642 	char *tmp_email_dn = NULL;
643 	BIGNUM *serial = NULL;
644 	BIGNUM *crlnumber = NULL;
645 	unsigned long nameopt = 0, certopt = 0;
646 	int default_op = 1;
647 	int ext_copy = EXT_COPY_NONE;
648 	X509 *x509 = NULL, *x509p = NULL;
649 	X509 *x = NULL;
650 	BIO *in = NULL, *out = NULL, *Sout = NULL, *Cout = NULL;
651 	char *dbfile = NULL;
652 	CA_DB *db = NULL;
653 	X509_CRL *crl = NULL;
654 	X509_REVOKED *r = NULL;
655 	ASN1_TIME *tmptm = NULL;
656 	ASN1_INTEGER *tmpserial;
657 	char *f;
658 	const char *p;
659 	char *const *pp;
660 	int i, j;
661 	const EVP_MD *dgst = NULL;
662 	STACK_OF(CONF_VALUE) *attribs = NULL;
663 	STACK_OF(X509) *cert_sk = NULL;
664 	char *tofree = NULL;
665 	DB_ATTR db_attr;
666 	int default_nid, rv;
667 	int ret = 1;
668 
669 	if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
670 		perror("pledge");
671 		exit(1);
672 	}
673 
674 	memset(&cfg, 0, sizeof(cfg));
675 	cfg.email_dn = 1;
676 	cfg.keyform = FORMAT_PEM;
677 	cfg.chtype = MBSTRING_ASC;
678 	cfg.rev_type = REV_NONE;
679 
680 	conf = NULL;
681 
682 	if (options_parse(argc, argv, ca_options, NULL, NULL) != 0) {
683 		ca_usage();
684 		goto err;
685 	}
686 
687 	/*****************************************************************/
688 	tofree = NULL;
689 	if (cfg.configfile == NULL)
690 		cfg.configfile = getenv("OPENSSL_CONF");
691 	if (cfg.configfile == NULL) {
692 		if ((tofree = make_config_name()) == NULL) {
693 			BIO_printf(bio_err, "error making config file name\n");
694 			goto err;
695 		}
696 		cfg.configfile = tofree;
697 	}
698 	BIO_printf(bio_err, "Using configuration from %s\n",
699 	    cfg.configfile);
700 	conf = NCONF_new(NULL);
701 	if (NCONF_load(conf, cfg.configfile, &errorline) <= 0) {
702 		if (errorline <= 0)
703 			BIO_printf(bio_err,
704 			    "error loading the config file '%s'\n",
705 			    cfg.configfile);
706 		else
707 			BIO_printf(bio_err,
708 			    "error on line %ld of config file '%s'\n",
709 			    errorline, cfg.configfile);
710 		goto err;
711 	}
712 	free(tofree);
713 	tofree = NULL;
714 
715 	/* Lets get the config section we are using */
716 	if (cfg.section == NULL) {
717 		cfg.section = NCONF_get_string(conf, BASE_SECTION,
718 		    ENV_DEFAULT_CA);
719 		if (cfg.section == NULL) {
720 			lookup_fail(BASE_SECTION, ENV_DEFAULT_CA);
721 			goto err;
722 		}
723 	}
724 	if (conf != NULL) {
725 		p = NCONF_get_string(conf, NULL, "oid_file");
726 		if (p == NULL)
727 			ERR_clear_error();
728 		if (p != NULL) {
729 			BIO *oid_bio;
730 
731 			oid_bio = BIO_new_file(p, "r");
732 			if (oid_bio == NULL) {
733 				/*
734 				BIO_printf(bio_err,
735 				    "problems opening %s for extra oid's\n", p);
736 				ERR_print_errors(bio_err);
737 				*/
738 				ERR_clear_error();
739 			} else {
740 				OBJ_create_objects(oid_bio);
741 				BIO_free(oid_bio);
742 			}
743 		}
744 		if (!add_oid_section(bio_err, conf)) {
745 			ERR_print_errors(bio_err);
746 			goto err;
747 		}
748 	}
749 	f = NCONF_get_string(conf, cfg.section, STRING_MASK);
750 	if (f == NULL)
751 		ERR_clear_error();
752 
753 	if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
754 		BIO_printf(bio_err,
755 		    "Invalid global string mask setting %s\n", f);
756 		goto err;
757 	}
758 	if (cfg.chtype != MBSTRING_UTF8) {
759 		f = NCONF_get_string(conf, cfg.section, UTF8_IN);
760 		if (f == NULL)
761 			ERR_clear_error();
762 		else if (strcmp(f, "yes") == 0)
763 			cfg.chtype = MBSTRING_UTF8;
764 	}
765 	db_attr.unique_subject = 1;
766 	p = NCONF_get_string(conf, cfg.section, ENV_UNIQUE_SUBJECT);
767 	if (p != NULL) {
768 		db_attr.unique_subject = parse_yesno(p, 1);
769 	} else
770 		ERR_clear_error();
771 
772 	in = BIO_new(BIO_s_file());
773 	out = BIO_new(BIO_s_file());
774 	Sout = BIO_new(BIO_s_file());
775 	Cout = BIO_new(BIO_s_file());
776 	if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL)) {
777 		ERR_print_errors(bio_err);
778 		goto err;
779 	}
780 	/*****************************************************************/
781 	/* report status of cert with serial number given on command line */
782 	if (cfg.serial_status) {
783 		if ((dbfile = NCONF_get_string(conf, cfg.section,
784 		    ENV_DATABASE)) == NULL) {
785 			lookup_fail(cfg.section, ENV_DATABASE);
786 			goto err;
787 		}
788 		db = load_index(dbfile, &db_attr);
789 		if (db == NULL)
790 			goto err;
791 
792 		if (!index_index(db))
793 			goto err;
794 
795 		if (get_certificate_status(cfg.serial_status, db) != 1)
796 			BIO_printf(bio_err, "Error verifying serial %s!\n",
797 			    cfg.serial_status);
798 		goto err;
799 	}
800 	/*****************************************************************/
801 	/* we definitely need a private key, so let's get it */
802 
803 	if ((cfg.keyfile == NULL) &&
804 	    ((cfg.keyfile = NCONF_get_string(conf, cfg.section,
805 	    ENV_PRIVATE_KEY)) == NULL)) {
806 		lookup_fail(cfg.section, ENV_PRIVATE_KEY);
807 		goto err;
808 	}
809 	if (cfg.key == NULL) {
810 		free_key = 1;
811 		if (!app_passwd(bio_err, cfg.passargin, NULL,
812 		    &cfg.key, NULL)) {
813 			BIO_printf(bio_err, "Error getting password\n");
814 			goto err;
815 		}
816 	}
817 	pkey = load_key(bio_err, cfg.keyfile, cfg.keyform, 0,
818 	    cfg.key, "CA private key");
819 	if (cfg.key != NULL)
820 		explicit_bzero(cfg.key, strlen(cfg.key));
821 	if (pkey == NULL) {
822 		/* load_key() has already printed an appropriate message */
823 		goto err;
824 	}
825 	/*****************************************************************/
826 	/* we need a certificate */
827 	if (!cfg.selfsign || cfg.spkac_file != NULL ||
828 	    cfg.ss_cert_file != NULL || cfg.gencrl) {
829 		if ((cfg.certfile == NULL) &&
830 		    ((cfg.certfile = NCONF_get_string(conf,
831 		    cfg.section, ENV_CERTIFICATE)) == NULL)) {
832 			lookup_fail(cfg.section, ENV_CERTIFICATE);
833 			goto err;
834 		}
835 		x509 = load_cert(bio_err, cfg.certfile, FORMAT_PEM, NULL,
836 		    "CA certificate");
837 		if (x509 == NULL)
838 			goto err;
839 
840 		if (!X509_check_private_key(x509, pkey)) {
841 			BIO_printf(bio_err,
842 			    "CA certificate and CA private key do not match\n");
843 			goto err;
844 		}
845 	}
846 	if (!cfg.selfsign)
847 		x509p = x509;
848 
849 	f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE);
850 	if (f == NULL)
851 		ERR_clear_error();
852 	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
853 		cfg.preserve = 1;
854 	f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK);
855 	if (f == NULL)
856 		ERR_clear_error();
857 	if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
858 		cfg.msie_hack = 1;
859 
860 	f = NCONF_get_string(conf, cfg.section, ENV_NAMEOPT);
861 
862 	if (f != NULL) {
863 		if (!set_name_ex(&nameopt, f)) {
864 			BIO_printf(bio_err,
865 			    "Invalid name options: \"%s\"\n", f);
866 			goto err;
867 		}
868 		default_op = 0;
869 	} else
870 		ERR_clear_error();
871 
872 	f = NCONF_get_string(conf, cfg.section, ENV_CERTOPT);
873 
874 	if (f != NULL) {
875 		if (!set_cert_ex(&certopt, f)) {
876 			BIO_printf(bio_err,
877 			    "Invalid certificate options: \"%s\"\n", f);
878 			goto err;
879 		}
880 		default_op = 0;
881 	} else
882 		ERR_clear_error();
883 
884 	f = NCONF_get_string(conf, cfg.section, ENV_EXTCOPY);
885 
886 	if (f != NULL) {
887 		if (!set_ext_copy(&ext_copy, f)) {
888 			BIO_printf(bio_err,
889 			    "Invalid extension copy option: \"%s\"\n", f);
890 			goto err;
891 		}
892 	} else
893 		ERR_clear_error();
894 
895 	/*****************************************************************/
896 	/* lookup where to write new certificates */
897 	if (cfg.outdir == NULL && cfg.req) {
898 		if ((cfg.outdir = NCONF_get_string(conf,
899 		    cfg.section, ENV_NEW_CERTS_DIR)) == NULL) {
900 			BIO_printf(bio_err, "output directory %s not defined\n",
901 			    ENV_NEW_CERTS_DIR);
902 			goto err;
903 		}
904 	}
905 	/*****************************************************************/
906 	/* we need to load the database file */
907 	if ((dbfile = NCONF_get_string(conf, cfg.section,
908 	    ENV_DATABASE)) == NULL) {
909 		lookup_fail(cfg.section, ENV_DATABASE);
910 		goto err;
911 	}
912 	db = load_index(dbfile, &db_attr);
913 	if (db == NULL)
914 		goto err;
915 
916 	/* Lets check some fields */
917 	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
918 		pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
919 		if ((pp[DB_type][0] != DB_TYPE_REV) &&
920 		    (pp[DB_rev_date][0] != '\0')) {
921 			BIO_printf(bio_err,
922 			    "entry %d: not revoked yet, but has a revocation date\n",
923 			    i + 1);
924 			goto err;
925 		}
926 		if ((pp[DB_type][0] == DB_TYPE_REV) &&
927 		    !make_revoked(NULL, pp[DB_rev_date])) {
928 			BIO_printf(bio_err, " in entry %d\n", i + 1);
929 			goto err;
930 		}
931 		if (!check_time_format((char *) pp[DB_exp_date])) {
932 			BIO_printf(bio_err, "entry %d: invalid expiry date\n",
933 			    i + 1);
934 			goto err;
935 		}
936 		p = pp[DB_serial];
937 		j = strlen(p);
938 		if (*p == '-') {
939 			p++;
940 			j--;
941 		}
942 		if ((j & 1) || (j < 2)) {
943 			BIO_printf(bio_err,
944 			    "entry %d: bad serial number length (%d)\n",
945 			    i + 1, j);
946 			goto err;
947 		}
948 		while (*p) {
949 			if (!(((*p >= '0') && (*p <= '9')) ||
950 			    ((*p >= 'A') && (*p <= 'F')) ||
951 			    ((*p >= 'a') && (*p <= 'f')))) {
952 				BIO_printf(bio_err,
953 				    "entry %d: bad serial number characters, char pos %ld, char is '%c'\n",
954 				    i + 1, (long) (p - pp[DB_serial]), *p);
955 				goto err;
956 			}
957 			p++;
958 		}
959 	}
960 	if (cfg.verbose) {
961 		BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
962 		TXT_DB_write(out, db->db);
963 		BIO_printf(bio_err, "%d entries loaded from the database\n",
964 		    sk_OPENSSL_PSTRING_num(db->db->data));
965 		BIO_printf(bio_err, "generating index\n");
966 	}
967 	if (!index_index(db))
968 		goto err;
969 
970 	/*****************************************************************/
971 	/* Update the db file for expired certificates */
972 	if (cfg.doupdatedb) {
973 		if (cfg.verbose)
974 			BIO_printf(bio_err, "Updating %s ...\n", dbfile);
975 
976 		i = do_updatedb(db);
977 		if (i == -1) {
978 			BIO_printf(bio_err, "Malloc failure\n");
979 			goto err;
980 		} else if (i == 0) {
981 			if (cfg.verbose)
982 				BIO_printf(bio_err,
983 				    "No entries found to mark expired\n");
984 		} else {
985 			if (!save_index(dbfile, "new", db))
986 				goto err;
987 
988 			if (!rotate_index(dbfile, "new", "old"))
989 				goto err;
990 
991 			if (cfg.verbose)
992 				BIO_printf(bio_err,
993 				    "Done. %d entries marked as expired\n", i);
994 		}
995 	}
996 	/*****************************************************************/
997 	/* Read extentions config file                                   */
998 	if (cfg.extfile != NULL) {
999 		extconf = NCONF_new(NULL);
1000 		if (NCONF_load(extconf, cfg.extfile, &errorline) <= 0) {
1001 			if (errorline <= 0)
1002 				BIO_printf(bio_err,
1003 				    "ERROR: loading the config file '%s'\n",
1004 				    cfg.extfile);
1005 			else
1006 				BIO_printf(bio_err,
1007 				    "ERROR: on line %ld of config file '%s'\n",
1008 				    errorline, cfg.extfile);
1009 			ret = 1;
1010 			goto err;
1011 		}
1012 		if (cfg.verbose)
1013 			BIO_printf(bio_err,
1014 			    "Successfully loaded extensions file %s\n",
1015 			    cfg.extfile);
1016 
1017 		/* We can have sections in the ext file */
1018 		if (cfg.extensions == NULL &&
1019 		    (cfg.extensions = NCONF_get_string(extconf, "default",
1020 		    "extensions")) == NULL)
1021 			cfg.extensions = "default";
1022 	}
1023 	/*****************************************************************/
1024 	if (cfg.req || cfg.gencrl) {
1025 		if (cfg.outfile != NULL) {
1026 			if (BIO_write_filename(Sout, cfg.outfile) <= 0) {
1027 				perror(cfg.outfile);
1028 				goto err;
1029 			}
1030 		} else {
1031 			BIO_set_fp(Sout, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
1032 		}
1033 	}
1034 
1035 	rv = EVP_PKEY_get_default_digest_nid(pkey, &default_nid);
1036 	if (rv == 2 && default_nid == NID_undef) {
1037 		/* The digest is required to be EVP_md_null() (EdDSA). */
1038 		dgst = EVP_md_null();
1039 	} else {
1040 		/* Ignore rv unless we need a valid default_nid. */
1041 		if (cfg.md == NULL)
1042 			cfg.md = NCONF_get_string(conf, cfg.section,
1043 			    ENV_DEFAULT_MD);
1044 		if (cfg.md == NULL) {
1045 			lookup_fail(cfg.section, ENV_DEFAULT_MD);
1046 			goto err;
1047 		}
1048 		if (strcmp(cfg.md, "default") == 0) {
1049 			if (rv <= 0) {
1050 				BIO_puts(bio_err, "no default digest\n");
1051 				goto err;
1052 			}
1053 			cfg.md = (char *)OBJ_nid2sn(default_nid);
1054 		}
1055 		if (cfg.md == NULL)
1056 			goto err;
1057 		if ((dgst = EVP_get_digestbyname(cfg.md)) == NULL) {
1058 			BIO_printf(bio_err, "%s is an unsupported "
1059 			    "message digest type\n", cfg.md);
1060 			goto err;
1061 		}
1062 	}
1063 	if (cfg.req) {
1064 		if ((cfg.email_dn == 1) &&
1065 		    ((tmp_email_dn = NCONF_get_string(conf, cfg.section,
1066 		    ENV_DEFAULT_EMAIL_DN)) != NULL)) {
1067 			if (strcmp(tmp_email_dn, "no") == 0)
1068 				cfg.email_dn = 0;
1069 		}
1070 		if (cfg.verbose)
1071 			BIO_printf(bio_err, "message digest is %s\n",
1072 			    OBJ_nid2ln(EVP_MD_type(dgst)));
1073 		if ((cfg.policy == NULL) &&
1074 		    ((cfg.policy = NCONF_get_string(conf,
1075 		    cfg.section, ENV_POLICY)) == NULL)) {
1076 			lookup_fail(cfg.section, ENV_POLICY);
1077 			goto err;
1078 		}
1079 		if (cfg.verbose)
1080 			BIO_printf(bio_err, "policy is %s\n", cfg.policy);
1081 
1082 		if ((serialfile = NCONF_get_string(conf, cfg.section,
1083 		    ENV_SERIAL)) == NULL) {
1084 			lookup_fail(cfg.section, ENV_SERIAL);
1085 			goto err;
1086 		}
1087 		if (extconf == NULL) {
1088 			/*
1089 			 * no '-extfile' option, so we look for extensions in
1090 			 * the main configuration file
1091 			 */
1092 			if (cfg.extensions == NULL) {
1093 				cfg.extensions = NCONF_get_string(conf,
1094 				    cfg.section, ENV_EXTENSIONS);
1095 				if (cfg.extensions == NULL)
1096 					ERR_clear_error();
1097 			}
1098 			if (cfg.extensions != NULL) {
1099 				/* Check syntax of file */
1100 				X509V3_CTX ctx;
1101 				X509V3_set_ctx_test(&ctx);
1102 				X509V3_set_nconf(&ctx, conf);
1103 				if (!X509V3_EXT_add_nconf(conf, &ctx,
1104 				    cfg.extensions, NULL)) {
1105 					BIO_printf(bio_err,
1106 					    "Error Loading extension section %s\n",
1107 					    cfg.extensions);
1108 					ret = 1;
1109 					goto err;
1110 				}
1111 			}
1112 		}
1113 		if (cfg.startdate == NULL) {
1114 			cfg.startdate = NCONF_get_string(conf,
1115 			    cfg.section, ENV_DEFAULT_STARTDATE);
1116 			if (cfg.startdate == NULL)
1117 				ERR_clear_error();
1118 		}
1119 		if (cfg.startdate == NULL)
1120 			cfg.startdate = "today";
1121 
1122 		if (cfg.enddate == NULL) {
1123 			cfg.enddate = NCONF_get_string(conf,
1124 			    cfg.section, ENV_DEFAULT_ENDDATE);
1125 			if (cfg.enddate == NULL)
1126 				ERR_clear_error();
1127 		}
1128 		if (cfg.days == 0 && cfg.enddate == NULL) {
1129 			if (!NCONF_get_number(conf, cfg.section,
1130 				ENV_DEFAULT_DAYS, &cfg.days))
1131 				cfg.days = 0;
1132 		}
1133 		if (cfg.enddate == NULL && cfg.days == 0) {
1134 			BIO_printf(bio_err,
1135 			    "cannot lookup how many days to certify for\n");
1136 			goto err;
1137 		}
1138 		if ((serial = load_serial(serialfile, cfg.create_serial,
1139 		    NULL)) == NULL) {
1140 			BIO_printf(bio_err,
1141 			    "error while loading serial number\n");
1142 			goto err;
1143 		}
1144 		if (cfg.verbose) {
1145 			if (BN_is_zero(serial))
1146 				BIO_printf(bio_err,
1147 				    "next serial number is 00\n");
1148 			else {
1149 				if ((f = BN_bn2hex(serial)) == NULL)
1150 					goto err;
1151 				BIO_printf(bio_err,
1152 				    "next serial number is %s\n", f);
1153 				free(f);
1154 			}
1155 		}
1156 		if ((attribs = NCONF_get_section(conf, cfg.policy)) ==
1157 		    NULL) {
1158 			BIO_printf(bio_err, "unable to find 'section' for %s\n",
1159 			    cfg.policy);
1160 			goto err;
1161 		}
1162 		if ((cert_sk = sk_X509_new_null()) == NULL) {
1163 			BIO_printf(bio_err, "Memory allocation failure\n");
1164 			goto err;
1165 		}
1166 		if (cfg.spkac_file != NULL) {
1167 			total++;
1168 			j = certify_spkac(&x, cfg.spkac_file, pkey, x509,
1169 			    dgst, cfg.sigopts, attribs, db, serial,
1170 			    cfg.subj, cfg.chtype,
1171 			    cfg.multirdn, cfg.email_dn,
1172 			    cfg.startdate, cfg.enddate,
1173 			    cfg.days, cfg.extensions, conf,
1174 			    cfg.verbose, certopt, nameopt, default_op,
1175 			    ext_copy);
1176 			if (j < 0)
1177 				goto err;
1178 			if (j > 0) {
1179 				total_done++;
1180 				BIO_printf(bio_err, "\n");
1181 				if (!BN_add_word(serial, 1))
1182 					goto err;
1183 				if (!sk_X509_push(cert_sk, x)) {
1184 					BIO_printf(bio_err,
1185 					    "Memory allocation failure\n");
1186 					goto err;
1187 				}
1188 				if (cfg.outfile != NULL) {
1189 					output_der = 1;
1190 					cfg.batch = 1;
1191 				}
1192 			}
1193 		}
1194 		if (cfg.ss_cert_file != NULL) {
1195 			total++;
1196 			j = certify_cert(&x, cfg.ss_cert_file, pkey, x509,
1197 			    dgst, cfg.sigopts, attribs, db, serial,
1198 			    cfg.subj, cfg.chtype,
1199 			    cfg.multirdn, cfg.email_dn,
1200 			    cfg.startdate, cfg.enddate,
1201 			    cfg.days, cfg.batch,
1202 			    cfg.extensions, conf, cfg.verbose,
1203 			    certopt, nameopt, default_op, ext_copy);
1204 			if (j < 0)
1205 				goto err;
1206 			if (j > 0) {
1207 				total_done++;
1208 				BIO_printf(bio_err, "\n");
1209 				if (!BN_add_word(serial, 1))
1210 					goto err;
1211 				if (!sk_X509_push(cert_sk, x)) {
1212 					BIO_printf(bio_err,
1213 					    "Memory allocation failure\n");
1214 					goto err;
1215 				}
1216 			}
1217 		}
1218 		if (cfg.infile != NULL) {
1219 			total++;
1220 			j = certify(&x, cfg.infile, pkey, x509p, dgst,
1221 			    cfg.sigopts, attribs, db, serial,
1222 			    cfg.subj, cfg.chtype,
1223 			    cfg.multirdn, cfg.email_dn,
1224 			    cfg.startdate, cfg.enddate,
1225 			    cfg.days, cfg.batch,
1226 			    cfg.extensions, conf, cfg.verbose,
1227 			    certopt, nameopt, default_op, ext_copy,
1228 			    cfg.selfsign);
1229 			if (j < 0)
1230 				goto err;
1231 			if (j > 0) {
1232 				total_done++;
1233 				BIO_printf(bio_err, "\n");
1234 				if (!BN_add_word(serial, 1))
1235 					goto err;
1236 				if (!sk_X509_push(cert_sk, x)) {
1237 					BIO_printf(bio_err,
1238 					    "Memory allocation failure\n");
1239 					goto err;
1240 				}
1241 			}
1242 		}
1243 		for (i = 0; i < cfg.infiles_num; i++) {
1244 			total++;
1245 			j = certify(&x, cfg.infiles[i], pkey, x509p, dgst,
1246 			    cfg.sigopts, attribs, db, serial,
1247 			    cfg.subj, cfg.chtype,
1248 			    cfg.multirdn, cfg.email_dn,
1249 			    cfg.startdate, cfg.enddate,
1250 			    cfg.days, cfg.batch,
1251 			    cfg.extensions, conf, cfg.verbose,
1252 			    certopt, nameopt, default_op, ext_copy,
1253 			    cfg.selfsign);
1254 			if (j < 0)
1255 				goto err;
1256 			if (j > 0) {
1257 				total_done++;
1258 				BIO_printf(bio_err, "\n");
1259 				if (!BN_add_word(serial, 1))
1260 					goto err;
1261 				if (!sk_X509_push(cert_sk, x)) {
1262 					BIO_printf(bio_err,
1263 					    "Memory allocation failure\n");
1264 					goto err;
1265 				}
1266 			}
1267 		}
1268 		/*
1269 		 * we have a stack of newly certified certificates and a data
1270 		 * base and serial number that need updating
1271 		 */
1272 
1273 		if (sk_X509_num(cert_sk) > 0) {
1274 			if (!cfg.batch) {
1275 				char answer[10];
1276 
1277 				BIO_printf(bio_err,
1278 				    "\n%d out of %d certificate requests certified, commit? [y/n]",
1279 				    total_done, total);
1280 				(void) BIO_flush(bio_err);
1281 				if (fgets(answer, sizeof answer - 1, stdin) ==
1282 				    NULL) {
1283 					BIO_printf(bio_err,
1284 					    "CERTIFICATION CANCELED: I/O error\n");
1285 					ret = 0;
1286 					goto err;
1287 				}
1288 				if ((answer[0] != 'y') && (answer[0] != 'Y')) {
1289 					BIO_printf(bio_err,
1290 					    "CERTIFICATION CANCELED\n");
1291 					ret = 0;
1292 					goto err;
1293 				}
1294 			}
1295 			BIO_printf(bio_err,
1296 			    "Write out database with %d new entries\n",
1297 			    sk_X509_num(cert_sk));
1298 
1299 			if (!save_serial(serialfile, "new", serial, NULL))
1300 				goto err;
1301 
1302 			if (!save_index(dbfile, "new", db))
1303 				goto err;
1304 		}
1305 		if (cfg.verbose)
1306 			BIO_printf(bio_err, "writing new certificates\n");
1307 		for (i = 0; i < sk_X509_num(cert_sk); i++) {
1308 			ASN1_INTEGER *serialNumber;
1309 			int k;
1310 			char *serialstr;
1311 			unsigned char *data;
1312 			char pempath[PATH_MAX];
1313 
1314 			x = sk_X509_value(cert_sk, i);
1315 
1316 			serialNumber = X509_get_serialNumber(x);
1317 			j = ASN1_STRING_length(serialNumber);
1318 			data = ASN1_STRING_data(serialNumber);
1319 
1320 			if (j > 0)
1321 				serialstr = bin2hex(data, j);
1322 			else
1323 				serialstr = strdup("00");
1324 			if (serialstr != NULL) {
1325 				k = snprintf(pempath, sizeof(pempath),
1326 				    "%s/%s.pem", cfg.outdir, serialstr);
1327 				free(serialstr);
1328 				if (k < 0 || k >= sizeof(pempath)) {
1329 					BIO_printf(bio_err,
1330 					    "certificate file name too long\n");
1331 					goto err;
1332 				}
1333 			} else {
1334 				BIO_printf(bio_err,
1335 				    "memory allocation failed\n");
1336 				goto err;
1337 			}
1338 			if (cfg.verbose)
1339 				BIO_printf(bio_err, "writing %s\n", pempath);
1340 
1341 			if (BIO_write_filename(Cout, pempath) <= 0) {
1342 				perror(pempath);
1343 				goto err;
1344 			}
1345 			if (!write_new_certificate(Cout, x, 0,
1346 			    cfg.notext))
1347 				goto err;
1348 			if (!write_new_certificate(Sout, x, output_der,
1349 			    cfg.notext))
1350 				goto err;
1351 		}
1352 
1353 		if (sk_X509_num(cert_sk)) {
1354 			/* Rename the database and the serial file */
1355 			if (!rotate_serial(serialfile, "new", "old"))
1356 				goto err;
1357 
1358 			if (!rotate_index(dbfile, "new", "old"))
1359 				goto err;
1360 
1361 			BIO_printf(bio_err, "Data Base Updated\n");
1362 		}
1363 	}
1364 	/*****************************************************************/
1365 	if (cfg.gencrl) {
1366 		int crl_v2 = 0;
1367 		if (cfg.crl_ext == NULL) {
1368 			cfg.crl_ext = NCONF_get_string(conf,
1369 			    cfg.section, ENV_CRLEXT);
1370 			if (cfg.crl_ext == NULL)
1371 				ERR_clear_error();
1372 		}
1373 		if (cfg.crl_ext != NULL) {
1374 			/* Check syntax of file */
1375 			X509V3_CTX ctx;
1376 			X509V3_set_ctx_test(&ctx);
1377 			X509V3_set_nconf(&ctx, conf);
1378 			if (!X509V3_EXT_add_nconf(conf, &ctx, cfg.crl_ext,
1379 			    NULL)) {
1380 				BIO_printf(bio_err,
1381 				    "Error Loading CRL extension section %s\n",
1382 				    cfg.crl_ext);
1383 				ret = 1;
1384 				goto err;
1385 			}
1386 		}
1387 		if ((crlnumberfile = NCONF_get_string(conf, cfg.section,
1388 		    ENV_CRLNUMBER)) != NULL)
1389 			if ((crlnumber = load_serial(crlnumberfile, 0,
1390 			    NULL)) == NULL) {
1391 				BIO_printf(bio_err,
1392 				    "error while loading CRL number\n");
1393 				goto err;
1394 			}
1395 		if (!cfg.crldays && !cfg.crlhours &&
1396 		    !cfg.crlsec) {
1397 			if (!NCONF_get_number(conf, cfg.section,
1398 			    ENV_DEFAULT_CRL_DAYS, &cfg.crldays))
1399 				cfg.crldays = 0;
1400 			if (!NCONF_get_number(conf, cfg.section,
1401 			    ENV_DEFAULT_CRL_HOURS, &cfg.crlhours))
1402 				cfg.crlhours = 0;
1403 			ERR_clear_error();
1404 		}
1405 		if ((cfg.crldays == 0) && (cfg.crlhours == 0) &&
1406 		    (cfg.crlsec == 0)) {
1407 			BIO_printf(bio_err,
1408 			    "cannot lookup how long until the next CRL is issued\n");
1409 			goto err;
1410 		}
1411 		if (cfg.verbose)
1412 			BIO_printf(bio_err, "making CRL\n");
1413 		if ((crl = X509_CRL_new()) == NULL)
1414 			goto err;
1415 		if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509)))
1416 			goto err;
1417 
1418 		if ((tmptm = X509_gmtime_adj(NULL, 0)) == NULL)
1419 			goto err;
1420 		if (!X509_CRL_set_lastUpdate(crl, tmptm))
1421 			goto err;
1422 		if (X509_time_adj_ex(tmptm, cfg.crldays,
1423 		    cfg.crlhours * 60 * 60 + cfg.crlsec, NULL) ==
1424 		    NULL) {
1425 			BIO_puts(bio_err, "error setting CRL nextUpdate\n");
1426 			goto err;
1427 		}
1428 		if (!X509_CRL_set_nextUpdate(crl, tmptm))
1429 			goto err;
1430 		ASN1_TIME_free(tmptm);
1431 		tmptm = NULL;
1432 
1433 		for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
1434 			pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
1435 			if (pp[DB_type][0] == DB_TYPE_REV) {
1436 				if ((r = X509_REVOKED_new()) == NULL)
1437 					goto err;
1438 				j = make_revoked(r, pp[DB_rev_date]);
1439 				if (!j)
1440 					goto err;
1441 				if (j == 2)
1442 					crl_v2 = 1;
1443 				if (!BN_hex2bn(&serial, pp[DB_serial]))
1444 					goto err;
1445 				tmpserial = BN_to_ASN1_INTEGER(serial, NULL);
1446 				BN_free(serial);
1447 				serial = NULL;
1448 				if (tmpserial == NULL)
1449 					goto err;
1450 				if (!X509_REVOKED_set_serialNumber(r, tmpserial)) {
1451 					ASN1_INTEGER_free(tmpserial);
1452 					goto err;
1453 				}
1454 				ASN1_INTEGER_free(tmpserial);
1455 				if (!X509_CRL_add0_revoked(crl, r))
1456 					goto err;
1457 				r = NULL;
1458 			}
1459 		}
1460 
1461 		/*
1462 		 * sort the data so it will be written in serial number order
1463 		 */
1464 		X509_CRL_sort(crl);
1465 
1466 		/* we now have a CRL */
1467 		if (cfg.verbose)
1468 			BIO_printf(bio_err, "signing CRL\n");
1469 
1470 		/* Add any extensions asked for */
1471 
1472 		if (cfg.crl_ext != NULL || crlnumberfile != NULL) {
1473 			X509V3_CTX crlctx;
1474 			X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1475 			X509V3_set_nconf(&crlctx, conf);
1476 
1477 			if (cfg.crl_ext != NULL)
1478 				if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1479 				    cfg.crl_ext, crl))
1480 					goto err;
1481 			if (crlnumberfile != NULL) {
1482 				tmpserial = BN_to_ASN1_INTEGER(crlnumber, NULL);
1483 				if (tmpserial == NULL)
1484 					goto err;
1485 				if (!X509_CRL_add1_ext_i2d(crl, NID_crl_number,
1486 				    tmpserial, 0, 0)) {
1487 					ASN1_INTEGER_free(tmpserial);
1488 					goto err;
1489 				}
1490 				ASN1_INTEGER_free(tmpserial);
1491 				crl_v2 = 1;
1492 				if (!BN_add_word(crlnumber, 1))
1493 					goto err;
1494 			}
1495 		}
1496 		if (cfg.crl_ext != NULL || crl_v2) {
1497 			if (!X509_CRL_set_version(crl, 1))
1498 				goto err;	/* version 2 CRL */
1499 		}
1500 		if (crlnumberfile != NULL)	/* we have a CRL number that
1501 						 * need updating */
1502 			if (!save_serial(crlnumberfile, "new", crlnumber, NULL))
1503 				goto err;
1504 
1505 		BN_free(crlnumber);
1506 		crlnumber = NULL;
1507 
1508 		if (!do_X509_CRL_sign(bio_err, crl, pkey, dgst,
1509 		    cfg.sigopts))
1510 			goto err;
1511 
1512 		if (!PEM_write_bio_X509_CRL(Sout, crl))
1513 			goto err;
1514 
1515 		if (crlnumberfile != NULL)	/* Rename the crlnumber file */
1516 			if (!rotate_serial(crlnumberfile, "new", "old"))
1517 				goto err;
1518 
1519 	}
1520 	/*****************************************************************/
1521 	if (cfg.dorevoke) {
1522 		if (cfg.infile == NULL) {
1523 			BIO_printf(bio_err, "no input files\n");
1524 			goto err;
1525 		} else {
1526 			X509 *revcert;
1527 			revcert = load_cert(bio_err, cfg.infile,
1528 			    FORMAT_PEM, NULL, cfg.infile);
1529 			if (revcert == NULL)
1530 				goto err;
1531 			j = do_revoke(revcert, db, cfg.rev_type,
1532 			    cfg.rev_arg);
1533 			if (j <= 0)
1534 				goto err;
1535 			X509_free(revcert);
1536 
1537 			if (!save_index(dbfile, "new", db))
1538 				goto err;
1539 
1540 			if (!rotate_index(dbfile, "new", "old"))
1541 				goto err;
1542 
1543 			BIO_printf(bio_err, "Data Base Updated\n");
1544 		}
1545 	}
1546 	/*****************************************************************/
1547 	ret = 0;
1548 
1549  err:
1550 	free(tofree);
1551 
1552 	BIO_free_all(Cout);
1553 	BIO_free_all(Sout);
1554 	BIO_free_all(out);
1555 	BIO_free_all(in);
1556 
1557 	sk_X509_pop_free(cert_sk, X509_free);
1558 
1559 	if (ret)
1560 		ERR_print_errors(bio_err);
1561 	if (free_key)
1562 		free(cfg.key);
1563 	BN_free(serial);
1564 	BN_free(crlnumber);
1565 	free_index(db);
1566 	sk_OPENSSL_STRING_free(cfg.sigopts);
1567 	EVP_PKEY_free(pkey);
1568 	X509_free(x509);
1569 	X509_CRL_free(crl);
1570 	X509_REVOKED_free(r);
1571 	ASN1_TIME_free(tmptm);
1572 	NCONF_free(conf);
1573 	NCONF_free(extconf);
1574 	OBJ_cleanup();
1575 
1576 	return (ret);
1577 }
1578 
1579 static void
lookup_fail(const char * name,const char * tag)1580 lookup_fail(const char *name, const char *tag)
1581 {
1582 	BIO_printf(bio_err, "variable lookup failed for %s::%s\n", name, tag);
1583 }
1584 
1585 static int
certify(X509 ** xret,char * infile,EVP_PKEY * pkey,X509 * x509,const EVP_MD * dgst,STACK_OF (OPENSSL_STRING)* sigopts,STACK_OF (CONF_VALUE)* policy,CA_DB * db,BIGNUM * serial,char * subj,unsigned long chtype,int multirdn,int email_dn,char * startdate,char * enddate,long days,int batch,char * ext_sect,CONF * lconf,int verbose,unsigned long certopt,unsigned long nameopt,int default_op,int ext_copy,int selfsign)1586 certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1587     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1588     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1589     unsigned long chtype, int multirdn, int email_dn, char *startdate,
1590     char *enddate, long days, int batch, char *ext_sect, CONF *lconf,
1591     int verbose, unsigned long certopt, unsigned long nameopt, int default_op,
1592     int ext_copy, int selfsign)
1593 {
1594 	X509_REQ *req = NULL;
1595 	BIO *in = NULL;
1596 	EVP_PKEY *pktmp = NULL;
1597 	int ok = -1, i;
1598 
1599 	in = BIO_new(BIO_s_file());
1600 
1601 	if (BIO_read_filename(in, infile) <= 0) {
1602 		perror(infile);
1603 		goto err;
1604 	}
1605 	if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) {
1606 		BIO_printf(bio_err, "Error reading certificate request in %s\n",
1607 		    infile);
1608 		goto err;
1609 	}
1610 	if (verbose) {
1611 		if (!X509_REQ_print(bio_err, req))
1612 			goto err;
1613 	}
1614 
1615 	BIO_printf(bio_err, "Check that the request matches the signature\n");
1616 
1617 	if (selfsign && !X509_REQ_check_private_key(req, pkey)) {
1618 		BIO_printf(bio_err,
1619 		    "Certificate request and CA private key do not match\n");
1620 		ok = 0;
1621 		goto err;
1622 	}
1623 	if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
1624 		BIO_printf(bio_err, "error unpacking public key\n");
1625 		goto err;
1626 	}
1627 	i = X509_REQ_verify(req, pktmp);
1628 	if (i < 0) {
1629 		ok = 0;
1630 		BIO_printf(bio_err, "Signature verification problems....\n");
1631 		goto err;
1632 	}
1633 	if (i == 0) {
1634 		ok = 0;
1635 		BIO_printf(bio_err,
1636 		    "Signature did not match the certificate request\n");
1637 		goto err;
1638 	} else
1639 		BIO_printf(bio_err, "Signature ok\n");
1640 
1641 	ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial,
1642 	    subj, chtype, multirdn, email_dn, startdate, enddate, days, batch,
1643 	    verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
1644 	    ext_copy, selfsign);
1645 
1646  err:
1647 	X509_REQ_free(req);
1648 	BIO_free(in);
1649 
1650 	return (ok);
1651 }
1652 
1653 static int
certify_cert(X509 ** xret,char * infile,EVP_PKEY * pkey,X509 * x509,const EVP_MD * dgst,STACK_OF (OPENSSL_STRING)* sigopts,STACK_OF (CONF_VALUE)* policy,CA_DB * db,BIGNUM * serial,char * subj,unsigned long chtype,int multirdn,int email_dn,char * startdate,char * enddate,long days,int batch,char * ext_sect,CONF * lconf,int verbose,unsigned long certopt,unsigned long nameopt,int default_op,int ext_copy)1654 certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1655     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1656     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1657     unsigned long chtype, int multirdn, int email_dn, char *startdate,
1658     char *enddate, long days, int batch, char *ext_sect, CONF *lconf,
1659     int verbose, unsigned long certopt, unsigned long nameopt, int default_op,
1660     int ext_copy)
1661 {
1662 	X509 *req = NULL;
1663 	X509_REQ *rreq = NULL;
1664 	EVP_PKEY *pktmp = NULL;
1665 	int ok = -1, i;
1666 
1667 	if ((req = load_cert(bio_err, infile, FORMAT_PEM, NULL,
1668 	    infile)) == NULL)
1669 		goto err;
1670 	if (verbose) {
1671 		if (!X509_print(bio_err, req))
1672 			goto err;
1673 	}
1674 
1675 	BIO_printf(bio_err, "Check that the request matches the signature\n");
1676 
1677 	if ((pktmp = X509_get0_pubkey(req)) == NULL) {
1678 		BIO_printf(bio_err, "error unpacking public key\n");
1679 		goto err;
1680 	}
1681 	i = X509_verify(req, pktmp);
1682 	if (i < 0) {
1683 		ok = 0;
1684 		BIO_printf(bio_err, "Signature verification problems....\n");
1685 		goto err;
1686 	}
1687 	if (i == 0) {
1688 		ok = 0;
1689 		BIO_printf(bio_err,
1690 		    "Signature did not match the certificate\n");
1691 		goto err;
1692 	} else
1693 		BIO_printf(bio_err, "Signature ok\n");
1694 
1695 	if ((rreq = X509_to_X509_REQ(req, NULL, EVP_md5())) == NULL)
1696 		goto err;
1697 
1698 	ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial,
1699 	    subj, chtype, multirdn, email_dn, startdate, enddate, days, batch,
1700 	    verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
1701 	    ext_copy, 0);
1702 
1703  err:
1704 	X509_REQ_free(rreq);
1705 	X509_free(req);
1706 
1707 	return (ok);
1708 }
1709 
1710 static int
do_body(X509 ** xret,EVP_PKEY * pkey,X509 * x509,const EVP_MD * dgst,STACK_OF (OPENSSL_STRING)* sigopts,STACK_OF (CONF_VALUE)* policy,CA_DB * db,BIGNUM * serial,char * subj,unsigned long chtype,int multirdn,int email_dn,char * startdate,char * enddate,long days,int batch,int verbose,X509_REQ * req,char * ext_sect,CONF * lconf,unsigned long certopt,unsigned long nameopt,int default_op,int ext_copy,int selfsign)1711 do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1712     STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy,
1713     CA_DB *db, BIGNUM *serial, char *subj, unsigned long chtype, int multirdn,
1714     int email_dn, char *startdate, char *enddate, long days, int batch,
1715     int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1716     unsigned long certopt, unsigned long nameopt, int default_op,
1717     int ext_copy, int selfsign)
1718 {
1719 	X509_NAME *name = NULL, *CAname = NULL;
1720 	X509_NAME *subject = NULL, *dn_subject = NULL;
1721 	ASN1_UTCTIME *tm;
1722 	ASN1_STRING *str, *str2;
1723 	ASN1_OBJECT *obj;
1724 	X509 *ret = NULL;
1725 	X509_NAME_ENTRY *ne;
1726 	X509_NAME_ENTRY *tne, *push;
1727 	EVP_PKEY *pktmp;
1728 	int ok = -1, i, j, last, nid;
1729 	const char *p;
1730 	CONF_VALUE *cv;
1731 	OPENSSL_STRING row[DB_NUMBER];
1732 	OPENSSL_STRING *irow = NULL;
1733 	OPENSSL_STRING *rrow = NULL;
1734 	const STACK_OF(X509_EXTENSION) *exts;
1735 
1736 	*xret = NULL;
1737 
1738 	for (i = 0; i < DB_NUMBER; i++)
1739 		row[i] = NULL;
1740 
1741 	if (subj != NULL) {
1742 		X509_NAME *n = parse_name(subj, chtype, multirdn);
1743 
1744 		if (n == NULL) {
1745 			ERR_print_errors(bio_err);
1746 			goto err;
1747 		}
1748 		if (!X509_REQ_set_subject_name(req, n)) {
1749 			X509_NAME_free(n);
1750 			goto err;
1751 		}
1752 		X509_NAME_free(n);
1753 	}
1754 	if (default_op)
1755 		BIO_printf(bio_err,
1756 		    "The Subject's Distinguished Name is as follows\n");
1757 
1758 	name = X509_REQ_get_subject_name(req);
1759 	for (i = 0; i < X509_NAME_entry_count(name); i++) {
1760 		ne = X509_NAME_get_entry(name, i);
1761 		if (ne == NULL)
1762 			goto err;
1763 		str = X509_NAME_ENTRY_get_data(ne);
1764 		if (str == NULL)
1765 			goto err;
1766 		obj = X509_NAME_ENTRY_get_object(ne);
1767 		if (obj == NULL)
1768 			goto err;
1769 
1770 		if (cfg.msie_hack) {
1771 			/* assume all type should be strings */
1772 			nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
1773 			if (nid == NID_undef)
1774 				goto err;
1775 
1776 			if (str->type == V_ASN1_UNIVERSALSTRING)
1777 				ASN1_UNIVERSALSTRING_to_string(str);
1778 
1779 			if ((str->type == V_ASN1_IA5STRING) &&
1780 			    (nid != NID_pkcs9_emailAddress))
1781 				str->type = V_ASN1_T61STRING;
1782 
1783 			if ((nid == NID_pkcs9_emailAddress) &&
1784 			    (str->type == V_ASN1_PRINTABLESTRING))
1785 				str->type = V_ASN1_IA5STRING;
1786 		}
1787 		/* If no EMAIL is wanted in the subject */
1788 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1789 			continue;
1790 
1791 		/* check some things */
1792 		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1793 		    (str->type != V_ASN1_IA5STRING)) {
1794 			BIO_printf(bio_err,
1795 			    "\nemailAddress type needs to be of type IA5STRING\n");
1796 			goto err;
1797 		}
1798 		if ((str->type != V_ASN1_BMPSTRING) &&
1799 		    (str->type != V_ASN1_UTF8STRING)) {
1800 			j = ASN1_PRINTABLE_type(str->data, str->length);
1801 			if (((j == V_ASN1_T61STRING) &&
1802 			    (str->type != V_ASN1_T61STRING)) ||
1803 			    ((j == V_ASN1_IA5STRING) &&
1804 			    (str->type == V_ASN1_PRINTABLESTRING))) {
1805 				BIO_printf(bio_err,
1806 				    "\nThe string contains characters that are illegal for the ASN.1 type\n");
1807 				goto err;
1808 			}
1809 		}
1810 		if (default_op)
1811 			old_entry_print(bio_err, obj, str);
1812 	}
1813 
1814 	/* Ok, now we check the 'policy' stuff. */
1815 	if ((subject = X509_NAME_new()) == NULL) {
1816 		BIO_printf(bio_err, "Memory allocation failure\n");
1817 		goto err;
1818 	}
1819 	/* take a copy of the issuer name before we mess with it. */
1820 	if (selfsign)
1821 		CAname = X509_NAME_dup(name);
1822 	else
1823 		CAname = X509_NAME_dup(X509_get_subject_name(x509));
1824 	if (CAname == NULL)
1825 		goto err;
1826 	str = str2 = NULL;
1827 
1828 	for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
1829 		cv = sk_CONF_VALUE_value(policy, i);	/* get the object id */
1830 		if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
1831 			BIO_printf(bio_err,
1832 			    "%s:unknown object type in 'policy' configuration\n",
1833 			    cv->name);
1834 			goto err;
1835 		}
1836 		obj = OBJ_nid2obj(j);
1837 		if (obj == NULL)
1838 			goto err;
1839 
1840 		last = -1;
1841 		for (;;) {
1842 			/* lookup the object in the supplied name list */
1843 			j = X509_NAME_get_index_by_OBJ(name, obj, last);
1844 			if (j < 0) {
1845 				if (last != -1)
1846 					break;
1847 				tne = NULL;
1848 			} else {
1849 				tne = X509_NAME_get_entry(name, j);
1850 				if (tne == NULL)
1851 					goto err;
1852 			}
1853 			last = j;
1854 
1855 			/* depending on the 'policy', decide what to do. */
1856 			push = NULL;
1857 			if (strcmp(cv->value, "optional") == 0) {
1858 				if (tne != NULL)
1859 					push = tne;
1860 			} else if (strcmp(cv->value, "supplied") == 0) {
1861 				if (tne == NULL) {
1862 					BIO_printf(bio_err,
1863 					    "The %s field needed to be supplied and was missing\n",
1864 					    cv->name);
1865 					goto err;
1866 				} else
1867 					push = tne;
1868 			} else if (strcmp(cv->value, "match") == 0) {
1869 				int last2;
1870 
1871 				if (tne == NULL) {
1872 					BIO_printf(bio_err,
1873 					    "The mandatory %s field was missing\n",
1874 					    cv->name);
1875 					goto err;
1876 				}
1877 				last2 = -1;
1878 
1879  again2:
1880 				j = X509_NAME_get_index_by_OBJ(CAname, obj,
1881 				    last2);
1882 				if ((j < 0) && (last2 == -1)) {
1883 					BIO_printf(bio_err,
1884 					    "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",
1885 					    cv->name);
1886 					goto err;
1887 				}
1888 				if (j >= 0) {
1889 					push = X509_NAME_get_entry(CAname, j);
1890 					if (push == NULL)
1891 						goto err;
1892 					str = X509_NAME_ENTRY_get_data(tne);
1893 					if (str == NULL)
1894 						goto err;
1895 					str2 = X509_NAME_ENTRY_get_data(push);
1896 					if (str2 == NULL)
1897 						goto err;
1898 					last2 = j;
1899 					if (ASN1_STRING_cmp(str, str2) != 0)
1900 						goto again2;
1901 				}
1902 				if (j < 0) {
1903 					BIO_printf(bio_err,
1904 					    "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",
1905 					    cv->name, ((str2 == NULL) ?
1906 					    "NULL" : (char *) str2->data),
1907 					    ((str == NULL) ?
1908 					    "NULL" : (char *) str->data));
1909 					goto err;
1910 				}
1911 			} else {
1912 				BIO_printf(bio_err,
1913 				    "%s:invalid type in 'policy' configuration\n",
1914 				    cv->value);
1915 				goto err;
1916 			}
1917 
1918 			if (push != NULL) {
1919 				if (!X509_NAME_add_entry(subject, push,
1920 				    -1, 0)) {
1921 					X509_NAME_ENTRY_free(push);
1922 					BIO_printf(bio_err,
1923 					    "Memory allocation failure\n");
1924 					goto err;
1925 				}
1926 			}
1927 			if (j < 0)
1928 				break;
1929 		}
1930 	}
1931 
1932 	if (cfg.preserve) {
1933 		X509_NAME_free(subject);
1934 		/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1935 		subject = X509_NAME_dup(name);
1936 		if (subject == NULL)
1937 			goto err;
1938 	}
1939 
1940 	/* We are now totally happy, lets make and sign the certificate */
1941 	if (verbose)
1942 		BIO_printf(bio_err,
1943 		    "Everything appears to be ok, creating and signing the certificate\n");
1944 
1945 	if ((ret = X509_new()) == NULL)
1946 		goto err;
1947 
1948 #ifdef X509_V3
1949 	/* Make it an X509 v3 certificate. */
1950 	if (!X509_set_version(ret, 2))
1951 		goto err;
1952 #endif
1953 	if (X509_get_serialNumber(ret) == NULL)
1954 		goto err;
1955 	if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
1956 		goto err;
1957 	if (selfsign) {
1958 		if (!X509_set_issuer_name(ret, subject))
1959 			goto err;
1960 	} else {
1961 		if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
1962 			goto err;
1963 	}
1964 
1965 	if (strcmp(startdate, "today") == 0) {
1966 		if (X509_gmtime_adj(X509_get_notBefore(ret), 0) == NULL)
1967 			goto err;
1968 	} else if (!ASN1_TIME_set_string_X509(X509_get_notBefore(ret), startdate)) {
1969 		BIO_printf(bio_err, "Invalid start date %s\n", startdate);
1970 		goto err;
1971 	}
1972 
1973 	if (enddate == NULL) {
1974 		if (X509_time_adj_ex(X509_get_notAfter(ret), days, 0,
1975 		    NULL) == NULL)
1976 			goto err;
1977 	} else if (!ASN1_TIME_set_string_X509(X509_get_notAfter(ret), enddate)) {
1978 		BIO_printf(bio_err, "Invalid end date %s\n", enddate);
1979 		goto err;
1980 	}
1981 
1982 	if (!X509_set_subject_name(ret, subject))
1983 		goto err;
1984 
1985 	if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL)
1986 		goto err;
1987 
1988 	if (!X509_set_pubkey(ret, pktmp))
1989 		goto err;
1990 
1991 	/* Lets add the extensions, if there are any */
1992 	if (ext_sect != NULL) {
1993 		X509V3_CTX ctx;
1994 
1995 		/* Initialize the context structure */
1996 		if (selfsign)
1997 			X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
1998 		else
1999 			X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2000 
2001 		if (extconf != NULL) {
2002 			if (verbose)
2003 				BIO_printf(bio_err,
2004 				    "Extra configuration file found\n");
2005 
2006 			/* Use the extconf configuration db LHASH */
2007 			X509V3_set_nconf(&ctx, extconf);
2008 
2009 			/* Test the structure (needed?) */
2010 			/* X509V3_set_ctx_test(&ctx); */
2011 
2012 			/* Adds exts contained in the configuration file */
2013 			if (!X509V3_EXT_add_nconf(extconf, &ctx,
2014 			    ext_sect, ret)) {
2015 				BIO_printf(bio_err,
2016 				    "ERROR: adding extensions in section %s\n",
2017 				    ext_sect);
2018 				ERR_print_errors(bio_err);
2019 				goto err;
2020 			}
2021 			if (verbose)
2022 				BIO_printf(bio_err,
2023 				    "Successfully added extensions from file.\n");
2024 		} else if (ext_sect != NULL) {
2025 			/* We found extensions to be set from config file */
2026 			X509V3_set_nconf(&ctx, lconf);
2027 
2028 			if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
2029 				BIO_printf(bio_err,
2030 				    "ERROR: adding extensions in section %s\n",
2031 				    ext_sect);
2032 				ERR_print_errors(bio_err);
2033 				goto err;
2034 			}
2035 			if (verbose)
2036 				BIO_printf(bio_err,
2037 				    "Successfully added extensions from config\n");
2038 		}
2039 	}
2040 
2041 	/* Copy extensions from request (if any) */
2042 	if (!copy_extensions(ret, req, ext_copy)) {
2043 		BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2044 		ERR_print_errors(bio_err);
2045 		goto err;
2046 	}
2047 
2048 	exts = X509_get0_extensions(ret);
2049 	if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0) {
2050 		/* Make it an X509 v3 certificate. */
2051 		if (!X509_set_version(ret, 2))
2052 			goto err;
2053 	}
2054 
2055 	if (verbose)
2056 		BIO_printf(bio_err,
2057 		    "The subject name appears to be ok, checking data base for clashes\n");
2058 
2059 	/* Build the correct Subject if no email is wanted in the subject */
2060 	if (!email_dn) {
2061 		X509_NAME_ENTRY *tmpne;
2062 		/*
2063 		 * Its best to dup the subject DN and then delete any email
2064 		 * addresses because this retains its structure.
2065 		 */
2066 		if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
2067 			BIO_printf(bio_err, "Memory allocation failure\n");
2068 			goto err;
2069 		}
2070 		while ((i = X509_NAME_get_index_by_NID(dn_subject,
2071 		    NID_pkcs9_emailAddress, -1)) >= 0) {
2072 			tmpne = X509_NAME_get_entry(dn_subject, i);
2073 			if (tmpne == NULL)
2074 				goto err;
2075 			if (X509_NAME_delete_entry(dn_subject, i) == NULL) {
2076 				X509_NAME_ENTRY_free(tmpne);
2077 				goto err;
2078 			}
2079 			X509_NAME_ENTRY_free(tmpne);
2080 		}
2081 
2082 		if (!X509_set_subject_name(ret, dn_subject))
2083 			goto err;
2084 
2085 		X509_NAME_free(dn_subject);
2086 		dn_subject = NULL;
2087 	}
2088 
2089 	row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
2090 	if (row[DB_name] == NULL) {
2091 		BIO_printf(bio_err, "Memory allocation failure\n");
2092 		goto err;
2093 	}
2094 
2095 	if (BN_is_zero(serial))
2096 		row[DB_serial] = strdup("00");
2097 	else
2098 		row[DB_serial] = BN_bn2hex(serial);
2099 	if (row[DB_serial] == NULL) {
2100 		BIO_printf(bio_err, "Memory allocation failure\n");
2101 		goto err;
2102 	}
2103 
2104 	if (row[DB_name][0] == '\0') {
2105 		/*
2106 		 * An empty subject! We'll use the serial number instead. If
2107 		 * unique_subject is in use then we don't want different
2108 		 * entries with empty subjects matching each other.
2109 		 */
2110 		free(row[DB_name]);
2111 		row[DB_name] = strdup(row[DB_serial]);
2112 		if (row[DB_name] == NULL) {
2113 			BIO_printf(bio_err, "Memory allocation failure\n");
2114 			goto err;
2115 		}
2116 	}
2117 
2118 	if (db->attributes.unique_subject) {
2119 		OPENSSL_STRING *crow = row;
2120 
2121 		rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
2122 		if (rrow != NULL) {
2123 			BIO_printf(bio_err,
2124 			    "ERROR:There is already a certificate for %s\n",
2125 			    row[DB_name]);
2126 		}
2127 	}
2128 	if (rrow == NULL) {
2129 		rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2130 		if (rrow != NULL) {
2131 			BIO_printf(bio_err,
2132 			    "ERROR:Serial number %s has already been issued,\n",
2133 			    row[DB_serial]);
2134 			BIO_printf(bio_err,
2135 			    "      check the database/serial_file for corruption\n");
2136 		}
2137 	}
2138 	if (rrow != NULL) {
2139 		BIO_printf(bio_err,
2140 		    "The matching entry has the following details\n");
2141 		if (rrow[DB_type][0] == DB_TYPE_EXP)
2142 			p = "Expired";
2143 		else if (rrow[DB_type][0] == DB_TYPE_REV)
2144 			p = "Revoked";
2145 		else if (rrow[DB_type][0] == DB_TYPE_VAL)
2146 			p = "Valid";
2147 		else
2148 			p = "\ninvalid type, Data base error\n";
2149 		BIO_printf(bio_err, "Type	  :%s\n", p);
2150 		if (rrow[DB_type][0] == DB_TYPE_REV) {
2151 			p = rrow[DB_exp_date];
2152 			if (p == NULL)
2153 				p = "undef";
2154 			BIO_printf(bio_err, "Was revoked on:%s\n", p);
2155 		}
2156 		p = rrow[DB_exp_date];
2157 		if (p == NULL)
2158 			p = "undef";
2159 		BIO_printf(bio_err, "Expires on    :%s\n", p);
2160 		p = rrow[DB_serial];
2161 		if (p == NULL)
2162 			p = "undef";
2163 		BIO_printf(bio_err, "Serial Number :%s\n", p);
2164 		p = rrow[DB_file];
2165 		if (p == NULL)
2166 			p = "undef";
2167 		BIO_printf(bio_err, "File name     :%s\n", p);
2168 		p = rrow[DB_name];
2169 		if (p == NULL)
2170 			p = "undef";
2171 		BIO_printf(bio_err, "Subject Name  :%s\n", p);
2172 		ok = -1;	/* This is now a 'bad' error. */
2173 		goto err;
2174 	}
2175 
2176 	if (!default_op) {
2177 		BIO_printf(bio_err, "Certificate Details:\n");
2178 		/*
2179 		 * Never print signature details because signature not
2180 		 * present
2181 		 */
2182 		certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2183 		if (!X509_print_ex(bio_err, ret, nameopt, certopt))
2184 			goto err;
2185 	}
2186 	BIO_printf(bio_err, "Certificate is to be certified until ");
2187 	ASN1_TIME_print(bio_err, X509_get_notAfter(ret));
2188 	if (days)
2189 		BIO_printf(bio_err, " (%ld days)", days);
2190 	BIO_printf(bio_err, "\n");
2191 
2192 	if (!batch) {
2193 		char answer[25];
2194 
2195 		BIO_printf(bio_err, "Sign the certificate? [y/n]:");
2196 		(void) BIO_flush(bio_err);
2197 		if (!fgets(answer, sizeof(answer) - 1, stdin)) {
2198 			BIO_printf(bio_err,
2199 			    "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
2200 			ok = 0;
2201 			goto err;
2202 		}
2203 		if (!((answer[0] == 'y') || (answer[0] == 'Y'))) {
2204 			BIO_printf(bio_err,
2205 			    "CERTIFICATE WILL NOT BE CERTIFIED\n");
2206 			ok = 0;
2207 			goto err;
2208 		}
2209 	}
2210 
2211 	if ((pktmp = X509_get0_pubkey(ret)) == NULL)
2212 		goto err;
2213 
2214 	if (EVP_PKEY_missing_parameters(pktmp) &&
2215 	    !EVP_PKEY_missing_parameters(pkey)) {
2216 		if (!EVP_PKEY_copy_parameters(pktmp, pkey)) {
2217 			goto err;
2218 		}
2219 	}
2220 
2221 	if (!do_X509_sign(bio_err, ret, pkey, dgst, sigopts))
2222 		goto err;
2223 
2224 	/* We now just add it to the database */
2225 	row[DB_type] = malloc(2);
2226 
2227 	if ((tm = X509_get_notAfter(ret)) == NULL)
2228 		goto err;
2229 	row[DB_exp_date] = strndup(tm->data, tm->length);
2230 	if (row[DB_type] == NULL || row[DB_exp_date] == NULL) {
2231 		BIO_printf(bio_err, "Memory allocation failure\n");
2232 		goto err;
2233 	}
2234 
2235 	row[DB_rev_date] = NULL;
2236 
2237 	/* row[DB_serial] done already */
2238 	row[DB_file] = malloc(8);
2239 
2240 	if ((row[DB_type] == NULL) || (row[DB_file] == NULL) ||
2241 	    (row[DB_name] == NULL)) {
2242 		BIO_printf(bio_err, "Memory allocation failure\n");
2243 		goto err;
2244 	}
2245 	(void) strlcpy(row[DB_file], "unknown", 8);
2246 	row[DB_type][0] = DB_TYPE_VAL;
2247 	row[DB_type][1] = '\0';
2248 
2249 	if ((irow = reallocarray(NULL, DB_NUMBER + 1, sizeof(char *))) ==
2250 	    NULL) {
2251 		BIO_printf(bio_err, "Memory allocation failure\n");
2252 		goto err;
2253 	}
2254 	for (i = 0; i < DB_NUMBER; i++) {
2255 		irow[i] = row[i];
2256 		row[i] = NULL;
2257 	}
2258 	irow[DB_NUMBER] = NULL;
2259 
2260 	if (!TXT_DB_insert(db->db, irow)) {
2261 		BIO_printf(bio_err, "failed to update database\n");
2262 		BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
2263 		goto err;
2264 	}
2265 
2266 	*xret = ret;
2267 	ret = NULL;
2268 	ok = 1;
2269 
2270  err:
2271 	for (i = 0; i < DB_NUMBER; i++)
2272 		free(row[i]);
2273 
2274 	X509_NAME_free(CAname);
2275 	X509_NAME_free(subject);
2276 	X509_NAME_free(dn_subject);
2277 	X509_free(ret);
2278 
2279 	return (ok);
2280 }
2281 
2282 static int
write_new_certificate(BIO * bp,X509 * x,int output_der,int notext)2283 write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2284 {
2285 	if (output_der) {
2286 		if (!i2d_X509_bio(bp, x))
2287 			return (0);
2288 	}
2289 	if (!notext) {
2290 		if (!X509_print(bp, x))
2291 			return (0);
2292 	}
2293 
2294 	return PEM_write_bio_X509(bp, x);
2295 }
2296 
2297 static int
certify_spkac(X509 ** xret,char * infile,EVP_PKEY * pkey,X509 * x509,const EVP_MD * dgst,STACK_OF (OPENSSL_STRING)* sigopts,STACK_OF (CONF_VALUE)* policy,CA_DB * db,BIGNUM * serial,char * subj,unsigned long chtype,int multirdn,int email_dn,char * startdate,char * enddate,long days,char * ext_sect,CONF * lconf,int verbose,unsigned long certopt,unsigned long nameopt,int default_op,int ext_copy)2298 certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2299     const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
2300     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
2301     unsigned long chtype, int multirdn, int email_dn, char *startdate,
2302     char *enddate, long days, char *ext_sect, CONF *lconf, int verbose,
2303     unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy)
2304 {
2305 	STACK_OF(CONF_VALUE) *sk = NULL;
2306 	LHASH_OF(CONF_VALUE) *parms = NULL;
2307 	X509_REQ *req = NULL;
2308 	CONF_VALUE *cv = NULL;
2309 	NETSCAPE_SPKI *spki = NULL;
2310 	char *type, *buf;
2311 	EVP_PKEY *pktmp = NULL;
2312 	X509_NAME *n = NULL;
2313 	int ok = -1, i, j;
2314 	long errline;
2315 	int nid;
2316 
2317 	/*
2318 	 * Load input file into a hash table.  (This is just an easy
2319 	 * way to read and parse the file, then put it into a convenient
2320 	 * STACK format).
2321 	 */
2322 	parms = CONF_load(NULL, infile, &errline);
2323 	if (parms == NULL) {
2324 		BIO_printf(bio_err, "error on line %ld of %s\n",
2325 		    errline, infile);
2326 		ERR_print_errors(bio_err);
2327 		goto err;
2328 	}
2329 	sk = CONF_get_section(parms, "default");
2330 	if (sk_CONF_VALUE_num(sk) == 0) {
2331 		BIO_printf(bio_err, "no name/value pairs found in %s\n",
2332 		    infile);
2333 		CONF_free(parms);
2334 		goto err;
2335 	}
2336 	/*
2337 	 * Now create a dummy X509 request structure.  We don't actually
2338 	 * have an X509 request, but we have many of the components
2339 	 * (a public key, various DN components).  The idea is that we
2340 	 * put these components into the right X509 request structure
2341 	 * and we can use the same code as if you had a real X509 request.
2342 	 */
2343 	req = X509_REQ_new();
2344 	if (req == NULL) {
2345 		ERR_print_errors(bio_err);
2346 		goto err;
2347 	}
2348 	/*
2349 	 * Build up the subject name set.
2350 	 */
2351 	n = X509_REQ_get_subject_name(req);
2352 
2353 	for (i = 0;; i++) {
2354 		if (sk_CONF_VALUE_num(sk) <= i)
2355 			break;
2356 
2357 		cv = sk_CONF_VALUE_value(sk, i);
2358 		type = cv->name;
2359 		/*
2360 		 * Skip past any leading X. X: X, etc to allow for multiple
2361 		 * instances
2362 		 */
2363 		for (buf = cv->name; *buf; buf++) {
2364 			if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2365 				buf++;
2366 				if (*buf)
2367 					type = buf;
2368 				break;
2369 			}
2370 		}
2371 
2372 		buf = cv->value;
2373 		if ((nid = OBJ_txt2nid(type)) == NID_undef) {
2374 			if (strcmp(type, "SPKAC") == 0) {
2375 				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2376 				if (spki == NULL) {
2377 					BIO_printf(bio_err,
2378 					    "unable to load Netscape SPKAC structure\n");
2379 					ERR_print_errors(bio_err);
2380 					goto err;
2381 				}
2382 			}
2383 			continue;
2384 		}
2385 		if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
2386 		    (unsigned char *)buf, -1, -1, 0))
2387 			goto err;
2388 	}
2389 	if (spki == NULL) {
2390 		BIO_printf(bio_err,
2391 		    "Netscape SPKAC structure not found in %s\n", infile);
2392 		goto err;
2393 	}
2394 	/*
2395 	 * Now extract the key from the SPKI structure.
2396 	 */
2397 
2398 	BIO_printf(bio_err,
2399 	    "Check that the SPKAC request matches the signature\n");
2400 
2401 	if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) {
2402 		BIO_printf(bio_err, "error unpacking SPKAC public key\n");
2403 		goto err;
2404 	}
2405 	j = NETSCAPE_SPKI_verify(spki, pktmp);
2406 	if (j <= 0) {
2407 		BIO_printf(bio_err,
2408 		    "signature verification failed on SPKAC public key\n");
2409 		goto err;
2410 	}
2411 	BIO_printf(bio_err, "Signature ok\n");
2412 
2413 	if (!X509_REQ_set_pubkey(req, pktmp)) {
2414 		EVP_PKEY_free(pktmp);
2415 		goto err;
2416 	}
2417 	EVP_PKEY_free(pktmp);
2418 	ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial,
2419 	    subj, chtype, multirdn, email_dn, startdate, enddate, days, 1,
2420 	    verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
2421 	    ext_copy, 0);
2422 
2423  err:
2424 	X509_REQ_free(req);
2425 	CONF_free(parms);
2426 	NETSCAPE_SPKI_free(spki);
2427 
2428 	return (ok);
2429 }
2430 
2431 static int
check_time_format(const char * str)2432 check_time_format(const char *str)
2433 {
2434 	return ASN1_TIME_set_string(NULL, str);
2435 }
2436 
2437 static int
do_revoke(X509 * x509,CA_DB * db,int type,char * value)2438 do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2439 {
2440 	ASN1_UTCTIME *tm = NULL;
2441 	char *row[DB_NUMBER], **rrow, **irow;
2442 	char *rev_str = NULL;
2443 	BIGNUM *bn = NULL;
2444 	int ok = -1, i;
2445 
2446 	for (i = 0; i < DB_NUMBER; i++)
2447 		row[i] = NULL;
2448 	row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0);
2449 	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL);
2450 	if (bn == NULL)
2451 		goto err;
2452 	if (BN_is_zero(bn))
2453 		row[DB_serial] = strdup("00");
2454 	else
2455 		row[DB_serial] = BN_bn2hex(bn);
2456 	BN_free(bn);
2457 
2458 	if (row[DB_name] != NULL && row[DB_name][0] == '\0') {
2459 		/*
2460 		 * Entries with empty Subjects actually use the serial number
2461 		 * instead
2462 		 */
2463 		free(row[DB_name]);
2464 		row[DB_name] = strdup(row[DB_serial]);
2465 		if (row[DB_name] == NULL) {
2466 			BIO_printf(bio_err, "Memory allocation failure\n");
2467 			goto err;
2468 		}
2469 	}
2470 
2471 	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
2472 		BIO_printf(bio_err, "Memory allocation failure\n");
2473 		goto err;
2474 	}
2475 	/*
2476 	 * We have to lookup by serial number because name lookup skips
2477 	 * revoked certs
2478 	 */
2479 	rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2480 	if (rrow == NULL) {
2481 		BIO_printf(bio_err,
2482 		    "Adding Entry with serial number %s to DB for %s\n",
2483 		    row[DB_serial], row[DB_name]);
2484 
2485 		/* We now just add it to the database */
2486 		row[DB_type] = malloc(2);
2487 
2488 		if ((tm = X509_get_notAfter(x509)) == NULL)
2489 			goto err;
2490 		row[DB_exp_date] = strndup(tm->data, tm->length);
2491 		if (row[DB_type] == NULL || row[DB_exp_date] == NULL) {
2492 			BIO_printf(bio_err, "Memory allocation failure\n");
2493 			goto err;
2494 		}
2495 
2496 		row[DB_rev_date] = NULL;
2497 
2498 		/* row[DB_serial] done already */
2499 		row[DB_file] = malloc(8);
2500 
2501 		/* row[DB_name] done already */
2502 
2503 		if ((row[DB_type] == NULL) || (row[DB_file] == NULL)) {
2504 			BIO_printf(bio_err, "Memory allocation failure\n");
2505 			goto err;
2506 		}
2507 		(void) strlcpy(row[DB_file], "unknown", 8);
2508 		row[DB_type][0] = DB_TYPE_VAL;
2509 		row[DB_type][1] = '\0';
2510 
2511 		if ((irow = reallocarray(NULL, sizeof(char *),
2512 		    (DB_NUMBER + 1))) == NULL) {
2513 			BIO_printf(bio_err, "Memory allocation failure\n");
2514 			goto err;
2515 		}
2516 		for (i = 0; i < DB_NUMBER; i++) {
2517 			irow[i] = row[i];
2518 			row[i] = NULL;
2519 		}
2520 		irow[DB_NUMBER] = NULL;
2521 
2522 		if (!TXT_DB_insert(db->db, irow)) {
2523 			BIO_printf(bio_err, "failed to update database\n");
2524 			BIO_printf(bio_err, "TXT_DB error number %ld\n",
2525 			    db->db->error);
2526 			goto err;
2527 		}
2528 		/* Revoke Certificate */
2529 		ok = do_revoke(x509, db, type, value);
2530 
2531 		goto err;
2532 
2533 	} else if (index_name_cmp_noconst(row, rrow)) {
2534 		BIO_printf(bio_err, "ERROR:name does not match %s\n",
2535 		    row[DB_name]);
2536 		goto err;
2537 	} else if (rrow[DB_type][0] == DB_TYPE_REV) {
2538 		BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
2539 		    row[DB_serial]);
2540 		goto err;
2541 	} else {
2542 		BIO_printf(bio_err, "Revoking Certificate %s.\n",
2543 		    rrow[DB_serial]);
2544 		rev_str = make_revocation_str(type, value);
2545 		if (rev_str == NULL) {
2546 			BIO_printf(bio_err, "Error in revocation arguments\n");
2547 			goto err;
2548 		}
2549 		rrow[DB_type][0] = DB_TYPE_REV;
2550 		rrow[DB_type][1] = '\0';
2551 		rrow[DB_rev_date] = rev_str;
2552 	}
2553 	ok = 1;
2554 
2555  err:
2556 	for (i = 0; i < DB_NUMBER; i++)
2557 		free(row[i]);
2558 
2559 	return (ok);
2560 }
2561 
2562 static int
get_certificate_status(const char * serial,CA_DB * db)2563 get_certificate_status(const char *serial, CA_DB *db)
2564 {
2565 	char *row[DB_NUMBER], **rrow;
2566 	int ok = -1, i;
2567 
2568 	/* Free Resources */
2569 	for (i = 0; i < DB_NUMBER; i++)
2570 		row[i] = NULL;
2571 
2572 	/* Malloc needed char spaces */
2573 	row[DB_serial] = malloc(strlen(serial) + 2);
2574 	if (row[DB_serial] == NULL) {
2575 		BIO_printf(bio_err, "Malloc failure\n");
2576 		goto err;
2577 	}
2578 	if (strlen(serial) % 2) {
2579 		row[DB_serial][0] = '0';
2580 
2581 		/* Copy String from serial to row[DB_serial] */
2582 		memcpy(row[DB_serial] + 1, serial, strlen(serial));
2583 		row[DB_serial][strlen(serial) + 1] = '\0';
2584 	} else {
2585 		/* Copy String from serial to row[DB_serial] */
2586 		memcpy(row[DB_serial], serial, strlen(serial));
2587 		row[DB_serial][strlen(serial)] = '\0';
2588 	}
2589 
2590 	/* Make it Upper Case */
2591 	for (i = 0; row[DB_serial][i] != '\0'; i++)
2592 		row[DB_serial][i] = toupper((unsigned char) row[DB_serial][i]);
2593 
2594 
2595 	ok = 1;
2596 
2597 	/* Search for the certificate */
2598 	rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2599 	if (rrow == NULL) {
2600 		BIO_printf(bio_err, "Serial %s not present in db.\n",
2601 		    row[DB_serial]);
2602 		ok = -1;
2603 		goto err;
2604 	} else if (rrow[DB_type][0] == DB_TYPE_VAL) {
2605 		BIO_printf(bio_err, "%s=Valid (%c)\n",
2606 		    row[DB_serial], rrow[DB_type][0]);
2607 		goto err;
2608 	} else if (rrow[DB_type][0] == DB_TYPE_REV) {
2609 		BIO_printf(bio_err, "%s=Revoked (%c)\n",
2610 		    row[DB_serial], rrow[DB_type][0]);
2611 		goto err;
2612 	} else if (rrow[DB_type][0] == DB_TYPE_EXP) {
2613 		BIO_printf(bio_err, "%s=Expired (%c)\n",
2614 		    row[DB_serial], rrow[DB_type][0]);
2615 		goto err;
2616 	} else if (rrow[DB_type][0] == DB_TYPE_SUSP) {
2617 		BIO_printf(bio_err, "%s=Suspended (%c)\n",
2618 		    row[DB_serial], rrow[DB_type][0]);
2619 		goto err;
2620 	} else {
2621 		BIO_printf(bio_err, "%s=Unknown (%c).\n",
2622 		    row[DB_serial], rrow[DB_type][0]);
2623 		ok = -1;
2624 	}
2625 
2626  err:
2627 	for (i = 0; i < DB_NUMBER; i++)
2628 		free(row[i]);
2629 
2630 	return (ok);
2631 }
2632 
2633 static int
do_updatedb(CA_DB * db)2634 do_updatedb(CA_DB *db)
2635 {
2636 	ASN1_UTCTIME *a_tm = NULL;
2637 	int i, cnt = 0;
2638 	int db_y2k, a_y2k;	/* flags = 1 if y >= 2000 */
2639 	char **rrow, *a_tm_s = NULL;
2640 
2641 	a_tm = ASN1_UTCTIME_new();
2642 	if (a_tm == NULL) {
2643 		cnt = -1;
2644 		goto err;
2645 	}
2646 
2647 	/* get actual time and make a string */
2648 	a_tm = X509_gmtime_adj(a_tm, 0);
2649 	if (a_tm == NULL) {
2650 		cnt = -1;
2651 		goto err;
2652 	}
2653 	a_tm_s = strndup(a_tm->data, a_tm->length);
2654 	if (a_tm_s == NULL) {
2655 		cnt = -1;
2656 		goto err;
2657 	}
2658 
2659 	if (strncmp(a_tm_s, "49", 2) <= 0)
2660 		a_y2k = 1;
2661 	else
2662 		a_y2k = 0;
2663 
2664 	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
2665 		rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
2666 
2667 		if (rrow[DB_type][0] == DB_TYPE_VAL) {
2668 			/* ignore entries that are not valid */
2669 			if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2670 				db_y2k = 1;
2671 			else
2672 				db_y2k = 0;
2673 
2674 			if (db_y2k == a_y2k) {
2675 				/* all on the same y2k side */
2676 				if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) {
2677 					rrow[DB_type][0] = DB_TYPE_EXP;
2678 					rrow[DB_type][1] = '\0';
2679 					cnt++;
2680 
2681 					BIO_printf(bio_err, "%s=Expired\n",
2682 					    rrow[DB_serial]);
2683 				}
2684 			} else if (db_y2k < a_y2k) {
2685 				rrow[DB_type][0] = DB_TYPE_EXP;
2686 				rrow[DB_type][1] = '\0';
2687 				cnt++;
2688 
2689 				BIO_printf(bio_err, "%s=Expired\n",
2690 				    rrow[DB_serial]);
2691 			}
2692 		}
2693 	}
2694 
2695  err:
2696 	ASN1_UTCTIME_free(a_tm);
2697 	free(a_tm_s);
2698 
2699 	return (cnt);
2700 }
2701 
2702 static const char *crl_reasons[] = {
2703 	/* CRL reason strings */
2704 	"unspecified",
2705 	"keyCompromise",
2706 	"CACompromise",
2707 	"affiliationChanged",
2708 	"superseded",
2709 	"cessationOfOperation",
2710 	"certificateHold",
2711 	"removeFromCRL",
2712 	/* Additional pseudo reasons */
2713 	"holdInstruction",
2714 	"keyTime",
2715 	"CAkeyTime"
2716 };
2717 
2718 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2719 
2720 /* Given revocation information convert to a DB string.
2721  * The format of the string is:
2722  * revtime[,reason,extra]. Where 'revtime' is the
2723  * revocation time (the current time). 'reason' is the
2724  * optional CRL reason and 'extra' is any additional
2725  * argument
2726  */
2727 
2728 char *
make_revocation_str(int rev_type,char * rev_arg)2729 make_revocation_str(int rev_type, char *rev_arg)
2730 {
2731 	char *other = NULL, *str;
2732 	const char *reason = NULL;
2733 	ASN1_OBJECT *otmp;
2734 	ASN1_UTCTIME *revtm = NULL;
2735 	int i;
2736 	switch (rev_type) {
2737 	case REV_NONE:
2738 		break;
2739 
2740 	case REV_CRL_REASON:
2741 		for (i = 0; i < 8; i++) {
2742 			if (strcasecmp(rev_arg, crl_reasons[i]) == 0) {
2743 				reason = crl_reasons[i];
2744 				break;
2745 			}
2746 		}
2747 		if (reason == NULL) {
2748 			BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2749 			return NULL;
2750 		}
2751 		break;
2752 
2753 	case REV_HOLD:
2754 		/* Argument is an OID */
2755 		otmp = OBJ_txt2obj(rev_arg, 0);
2756 		ASN1_OBJECT_free(otmp);
2757 
2758 		if (otmp == NULL) {
2759 			BIO_printf(bio_err,
2760 			    "Invalid object identifier %s\n", rev_arg);
2761 			return NULL;
2762 		}
2763 		reason = "holdInstruction";
2764 		other = rev_arg;
2765 		break;
2766 
2767 	case REV_KEY_COMPROMISE:
2768 	case REV_CA_COMPROMISE:
2769 		/* Argument is the key compromise time  */
2770 		if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
2771 			BIO_printf(bio_err,
2772 			    "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n",
2773 			    rev_arg);
2774 			return NULL;
2775 		}
2776 		other = rev_arg;
2777 		if (rev_type == REV_KEY_COMPROMISE)
2778 			reason = "keyTime";
2779 		else
2780 			reason = "CAkeyTime";
2781 
2782 		break;
2783 	}
2784 
2785 	revtm = X509_gmtime_adj(NULL, 0);
2786 	if (revtm == NULL)
2787 		return NULL;
2788 
2789 	if (asprintf(&str, "%s%s%s%s%s", revtm->data,
2790 	    reason ? "," : "", reason ? reason : "",
2791 	    other ? "," : "", other ? other : "") == -1)
2792 		str = NULL;
2793 
2794 	ASN1_UTCTIME_free(revtm);
2795 
2796 	return str;
2797 }
2798 
2799 /* Convert revocation field to X509_REVOKED entry
2800  * return code:
2801  * 0 error
2802  * 1 OK
2803  * 2 OK and some extensions added (i.e. V2 CRL)
2804  */
2805 
2806 int
make_revoked(X509_REVOKED * rev,const char * str)2807 make_revoked(X509_REVOKED *rev, const char *str)
2808 {
2809 	char *tmp = NULL;
2810 	int reason_code = -1;
2811 	int i, ret = 0;
2812 	ASN1_OBJECT *hold = NULL;
2813 	ASN1_GENERALIZEDTIME *comp_time = NULL;
2814 	ASN1_ENUMERATED *rtmp = NULL;
2815 
2816 	ASN1_TIME *revDate = NULL;
2817 
2818 	i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2819 
2820 	if (i == 0)
2821 		goto err;
2822 
2823 	if (rev != NULL && !X509_REVOKED_set_revocationDate(rev, revDate))
2824 		goto err;
2825 
2826 	if (rev != NULL && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) {
2827 		rtmp = ASN1_ENUMERATED_new();
2828 		if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code))
2829 			goto err;
2830 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2831 			goto err;
2832 	}
2833 	if (rev != NULL && comp_time != NULL) {
2834 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date,
2835 		    comp_time, 0, 0))
2836 			goto err;
2837 	}
2838 	if (rev != NULL && hold != NULL) {
2839 		if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code,
2840 		    hold, 0, 0))
2841 			goto err;
2842 	}
2843 	if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2844 		ret = 2;
2845 	else
2846 		ret = 1;
2847 
2848  err:
2849 	free(tmp);
2850 
2851 	ASN1_OBJECT_free(hold);
2852 	ASN1_GENERALIZEDTIME_free(comp_time);
2853 	ASN1_ENUMERATED_free(rtmp);
2854 	ASN1_TIME_free(revDate);
2855 
2856 	return ret;
2857 }
2858 
2859 int
old_entry_print(BIO * bp,ASN1_OBJECT * obj,ASN1_STRING * str)2860 old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2861 {
2862 	char buf[25], *pbuf, *p;
2863 	int j;
2864 
2865 	j = i2a_ASN1_OBJECT(bp, obj);
2866 	pbuf = buf;
2867 	for (j = 22 - j; j > 0; j--)
2868 		*(pbuf++) = ' ';
2869 	*(pbuf++) = ':';
2870 	*(pbuf++) = '\0';
2871 	BIO_puts(bp, buf);
2872 
2873 	if (str->type == V_ASN1_PRINTABLESTRING)
2874 		BIO_printf(bp, "PRINTABLE:'");
2875 	else if (str->type == V_ASN1_T61STRING)
2876 		BIO_printf(bp, "T61STRING:'");
2877 	else if (str->type == V_ASN1_IA5STRING)
2878 		BIO_printf(bp, "IA5STRING:'");
2879 	else if (str->type == V_ASN1_UNIVERSALSTRING)
2880 		BIO_printf(bp, "UNIVERSALSTRING:'");
2881 	else
2882 		BIO_printf(bp, "ASN.1 %2d:'", str->type);
2883 
2884 	p = (char *) str->data;
2885 	for (j = str->length; j > 0; j--) {
2886 		if ((*p >= ' ') && (*p <= '~'))
2887 			BIO_printf(bp, "%c", *p);
2888 		else if (*p & 0x80)
2889 			BIO_printf(bp, "\\0x%02X", *p);
2890 		else if ((unsigned char) *p == 0xf7)
2891 			BIO_printf(bp, "^?");
2892 		else
2893 			BIO_printf(bp, "^%c", *p + '@');
2894 		p++;
2895 	}
2896 	BIO_printf(bp, "'\n");
2897 	return 1;
2898 }
2899 
2900 int
unpack_revinfo(ASN1_TIME ** prevtm,int * preason,ASN1_OBJECT ** phold,ASN1_GENERALIZEDTIME ** pinvtm,const char * str)2901 unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
2902     ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2903 {
2904 	char *tmp = NULL;
2905 	char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2906 	int reason_code = -1;
2907 	int ret = 0;
2908 	unsigned int i;
2909 	ASN1_OBJECT *hold = NULL;
2910 	ASN1_GENERALIZEDTIME *comp_time = NULL;
2911 
2912 	if ((tmp = strdup(str)) == NULL) {
2913 		BIO_printf(bio_err, "malloc failed\n");
2914 		goto err;
2915 	}
2916 	p = strchr(tmp, ',');
2917 	rtime_str = tmp;
2918 
2919 	if (p != NULL) {
2920 		*p = '\0';
2921 		p++;
2922 		reason_str = p;
2923 		p = strchr(p, ',');
2924 		if (p != NULL) {
2925 			*p = '\0';
2926 			arg_str = p + 1;
2927 		}
2928 	}
2929 	if (prevtm != NULL) {
2930 		*prevtm = ASN1_UTCTIME_new();
2931 		if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) {
2932 			BIO_printf(bio_err, "invalid revocation date %s\n",
2933 			    rtime_str);
2934 			goto err;
2935 		}
2936 	}
2937 	if (reason_str != NULL) {
2938 		for (i = 0; i < NUM_REASONS; i++) {
2939 			if (strcasecmp(reason_str, crl_reasons[i]) == 0) {
2940 				reason_code = i;
2941 				break;
2942 			}
2943 		}
2944 		if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) {
2945 			BIO_printf(bio_err, "invalid reason code %s\n",
2946 			    reason_str);
2947 			goto err;
2948 		}
2949 		if (reason_code == 7)
2950 			reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2951 		else if (reason_code == 8) {	/* Hold instruction */
2952 			if (arg_str == NULL) {
2953 				BIO_printf(bio_err,
2954 				    "missing hold instruction\n");
2955 				goto err;
2956 			}
2957 			reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2958 			hold = OBJ_txt2obj(arg_str, 0);
2959 
2960 			if (hold == NULL) {
2961 				BIO_printf(bio_err,
2962 				    "invalid object identifier %s\n", arg_str);
2963 				goto err;
2964 			}
2965 			if (phold != NULL)
2966 				*phold = hold;
2967 		} else if ((reason_code == 9) || (reason_code == 10)) {
2968 			if (arg_str == NULL) {
2969 				BIO_printf(bio_err,
2970 				    "missing compromised time\n");
2971 				goto err;
2972 			}
2973 			comp_time = ASN1_GENERALIZEDTIME_new();
2974 			if (!ASN1_GENERALIZEDTIME_set_string(comp_time,
2975 			    arg_str)) {
2976 				BIO_printf(bio_err,
2977 				    "invalid compromised time %s\n", arg_str);
2978 				goto err;
2979 			}
2980 			if (reason_code == 9)
2981 				reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2982 			else
2983 				reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2984 		}
2985 	}
2986 	if (preason != NULL)
2987 		*preason = reason_code;
2988 	if (pinvtm != NULL)
2989 		*pinvtm = comp_time;
2990 	else
2991 		ASN1_GENERALIZEDTIME_free(comp_time);
2992 
2993 	ret = 1;
2994 
2995  err:
2996 	free(tmp);
2997 
2998 	if (phold == NULL)
2999 		ASN1_OBJECT_free(hold);
3000 	if (pinvtm == NULL)
3001 		ASN1_GENERALIZEDTIME_free(comp_time);
3002 
3003 	return ret;
3004 }
3005 
3006 static char *
bin2hex(unsigned char * data,size_t len)3007 bin2hex(unsigned char *data, size_t len)
3008 {
3009 	char *ret = NULL;
3010 	char hex[] = "0123456789ABCDEF";
3011 	int i;
3012 
3013 	if ((ret = malloc(len * 2 + 1)) != NULL) {
3014 		for (i = 0; i < len; i++) {
3015 			ret[i * 2 + 0] = hex[data[i] >> 4];
3016 			ret[i * 2 + 1] = hex[data[i] & 0x0F];
3017 		}
3018 		ret[len * 2] = '\0';
3019 	}
3020 	return ret;
3021 }
3022