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