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