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