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