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