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