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