2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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.
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).
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.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
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)"
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
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.]
59 /* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
65 #include <sys/types.h>
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>
76 #include <openssl/ocsp.h>
77 #include <openssl/pem.h>
79 #ifdef OPENSSL_SYS_WINDOWS
80 #define strcasecmp _stricmp
86 # endif /* NO_STRINGS_H */
90 # ifdef OPENSSL_SYS_VMS
96 # elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
97 # include <sys/file.h>
113 #define BASE_SECTION "ca"
114 #define CONFIG_FILE "openssl.cnf"
116 #define ENV_DEFAULT_CA "default_ca"
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"
129 #define ENV_DEFAULT_STARTDATE "default_startdate"
130 #define ENV_DEFAULT_ENDDATE "default_enddate"
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"
134 #define ENV_DEFAULT_EMAIL_DN "email_in_dn"
135 #define ENV_PRESERVE "preserve"
136 #define ENV_POLICY "policy"
137 #define ENV_EXTENSIONS "x509_extensions"
138 #define ENV_CRLEXT "crl_extensions"
139 #define ENV_MSIE_HACK "msie_hack"
140 #define ENV_NAMEOPT "name_opt"
141 #define ENV_CERTOPT "cert_opt"
142 #define ENV_EXTCOPY "copy_extensions"
144 #define ENV_DATABASE "database"
147 #define DB_exp_date 1
148 #define DB_rev_date 2
149 #define DB_serial 3 /* index - unique */
151 #define DB_name 5 /* index - unique for active */
154 #define DB_TYPE_REV 'R'
155 #define DB_TYPE_EXP 'E'
156 #define DB_TYPE_VAL 'V'
158 /* Additional revocation information types */
160 #define REV_NONE 0 /* No addditional information */
161 #define REV_CRL_REASON 1 /* Value is CRL reason code */
162 #define REV_HOLD 2 /* Value is hold instruction */
163 #define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
164 #define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
166 static char *ca_usage[]={
169 " -verbose - Talk alot while doing things\n",
170 " -config file - A config file\n",
171 " -name arg - The particular CA definition to use\n",
172 " -gencrl - Generate a new CRL\n",
173 " -crldays days - Days is when the next CRL is due\n",
174 " -crlhours hours - Hours is when the next CRL is due\n",
175 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
176 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
177 " -days arg - number of days to certify the certificate for\n",
178 " -md arg - md to use, one of md2, md5, sha or sha1\n",
179 " -policy arg - The CA 'policy' to support\n",
180 " -keyfile arg - private key file\n",
181 " -keyform arg - private key file format (PEM or ENGINE)\n",
182 " -key arg - key to decode the private key if it is encrypted\n",
183 " -cert file - The CA certificate\n",
184 " -in file - The input PEM encoded certificate request(s)\n",
185 " -out file - Where to put the output file(s)\n",
186 " -outdir dir - Where to put output certificates\n",
187 " -infiles .... - The last argument, requests to process\n",
188 " -spkac file - File contains DN and signed public key and challenge\n",
189 " -ss_cert file - File contains a self signed cert to sign\n",
190 " -preserveDN - Don't re-order the DN\n",
191 " -noemailDN - Don't add the EMAIL field into certificate' subject\n",
192 " -batch - Don't ask questions\n",
193 " -msie_hack - msie modifications to handle all those universal strings\n",
194 " -revoke file - Revoke a certificate (given in file)\n",
195 " -subj arg - Use arg instead of request's subject\n",
196 " -extensions .. - Extension section (override value in config file)\n",
197 " -extfile file - Configuration file with X509v3 extentions to add\n",
198 " -crlexts .. - CRL extension section (override value in config file)\n",
199 " -engine e - use engine e, possibly a hardware device.\n",
200 " -status serial - Shows certificate status given the serial number\n",
201 " -updatedb - Updates db for expired certificates\n",
206 extern int EF_PROTECT_FREE;
207 extern int EF_PROTECT_BELOW;
208 extern int EF_ALIGNMENT;
211 static void lookup_fail(char *name,char *tag);
212 static unsigned long index_serial_hash(const char **a);
213 static int index_serial_cmp(const char **a, const char **b);
214 static unsigned long index_name_hash(const char **a);
215 static int index_name_qual(char **a);
216 static int index_name_cmp(const char **a,const char **b);
217 static BIGNUM *load_serial(char *serialfile);
218 static int save_serial(char *serialfile, BIGNUM *serial);
219 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
220 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
221 BIGNUM *serial, char *subj, int email_dn, char *startdate,
222 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
223 int verbose, unsigned long certopt, unsigned long nameopt,
224 int default_op, int ext_copy);
225 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
226 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
227 TXT_DB *db, BIGNUM *serial, char *subj, int email_dn,
228 char *startdate, char *enddate, long days, int batch,
229 char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
230 unsigned long nameopt, int default_op, int ext_copy,
232 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
233 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
234 TXT_DB *db, BIGNUM *serial,char *subj, int email_dn,
235 char *startdate, char *enddate, long days, char *ext_sect,
236 CONF *conf, int verbose, unsigned long certopt,
237 unsigned long nameopt, int default_op, int ext_copy);
238 static int fix_data(int nid, int *type);
239 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
240 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
241 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
242 int email_dn, char *startdate, char *enddate, long days, int batch,
243 int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
244 unsigned long certopt, unsigned long nameopt, int default_op,
246 static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
247 static int get_certificate_status(const char *ser_status, TXT_DB *db);
248 static int do_updatedb(TXT_DB *db);
249 static int check_time_format(char *str);
250 char *make_revocation_str(int rev_type, char *rev_arg);
251 int make_revoked(X509_REVOKED *rev, char *str);
252 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
253 static CONF *conf=NULL;
254 static CONF *extconf=NULL;
255 static char *section=NULL;
257 static int preserve=0;
258 static int msie_hack=0;
260 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
261 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
262 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
263 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
266 int MAIN(int, char **);
268 int MAIN(int argc, char **argv)
271 char *key=NULL,*passargin=NULL;
286 char *configfile=NULL;
291 int keyform=FORMAT_PEM;
293 char *spkac_file=NULL;
294 char *ss_cert_file=NULL;
295 char *ser_status=NULL;
300 char *serialfile=NULL;
301 char *extensions=NULL;
304 char *tmp_email_dn=NULL;
306 int rev_type = REV_NONE;
307 char *rev_arg = NULL;
309 char *startdate=NULL;
314 unsigned long nameopt = 0, certopt = 0;
316 int ext_copy = EXT_COPY_NONE;
319 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
323 X509_REVOKED *r=NULL;
325 ASN1_INTEGER *tmpser;
329 const EVP_MD *dgst=NULL;
330 STACK_OF(CONF_VALUE) *attribs=NULL;
331 STACK_OF(X509) *cert_sk=NULL;
334 MS_STATIC char buf[3][BSIZE];
353 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
354 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
360 if (strcmp(*argv,"-verbose") == 0)
362 else if (strcmp(*argv,"-config") == 0)
364 if (--argc < 1) goto bad;
365 configfile= *(++argv);
367 else if (strcmp(*argv,"-name") == 0)
369 if (--argc < 1) goto bad;
372 else if (strcmp(*argv,"-subj") == 0)
374 if (--argc < 1) goto bad;
378 else if (strcmp(*argv,"-startdate") == 0)
380 if (--argc < 1) goto bad;
381 startdate= *(++argv);
383 else if (strcmp(*argv,"-enddate") == 0)
385 if (--argc < 1) goto bad;
388 else if (strcmp(*argv,"-days") == 0)
390 if (--argc < 1) goto bad;
391 days=atoi(*(++argv));
393 else if (strcmp(*argv,"-md") == 0)
395 if (--argc < 1) goto bad;
398 else if (strcmp(*argv,"-policy") == 0)
400 if (--argc < 1) goto bad;
403 else if (strcmp(*argv,"-keyfile") == 0)
405 if (--argc < 1) goto bad;
408 else if (strcmp(*argv,"-keyform") == 0)
410 if (--argc < 1) goto bad;
411 keyform=str2fmt(*(++argv));
413 else if (strcmp(*argv,"-passin") == 0)
415 if (--argc < 1) goto bad;
416 passargin= *(++argv);
418 else if (strcmp(*argv,"-key") == 0)
420 if (--argc < 1) goto bad;
423 else if (strcmp(*argv,"-cert") == 0)
425 if (--argc < 1) goto bad;
428 else if (strcmp(*argv,"-in") == 0)
430 if (--argc < 1) goto bad;
434 else if (strcmp(*argv,"-out") == 0)
436 if (--argc < 1) goto bad;
439 else if (strcmp(*argv,"-outdir") == 0)
441 if (--argc < 1) goto bad;
444 else if (strcmp(*argv,"-notext") == 0)
446 else if (strcmp(*argv,"-batch") == 0)
448 else if (strcmp(*argv,"-preserveDN") == 0)
450 else if (strcmp(*argv,"-noemailDN") == 0)
452 else if (strcmp(*argv,"-gencrl") == 0)
454 else if (strcmp(*argv,"-msie_hack") == 0)
456 else if (strcmp(*argv,"-crldays") == 0)
458 if (--argc < 1) goto bad;
459 crldays= atol(*(++argv));
461 else if (strcmp(*argv,"-crlhours") == 0)
463 if (--argc < 1) goto bad;
464 crlhours= atol(*(++argv));
466 else if (strcmp(*argv,"-infiles") == 0)
473 else if (strcmp(*argv, "-ss_cert") == 0)
475 if (--argc < 1) goto bad;
476 ss_cert_file = *(++argv);
479 else if (strcmp(*argv, "-spkac") == 0)
481 if (--argc < 1) goto bad;
482 spkac_file = *(++argv);
485 else if (strcmp(*argv,"-revoke") == 0)
487 if (--argc < 1) goto bad;
491 else if (strcmp(*argv,"-extensions") == 0)
493 if (--argc < 1) goto bad;
494 extensions= *(++argv);
496 else if (strcmp(*argv,"-extfile") == 0)
498 if (--argc < 1) goto bad;
501 else if (strcmp(*argv,"-status") == 0)
503 if (--argc < 1) goto bad;
504 ser_status= *(++argv);
506 else if (strcmp(*argv,"-updatedb") == 0)
510 else if (strcmp(*argv,"-crlexts") == 0)
512 if (--argc < 1) goto bad;
515 else if (strcmp(*argv,"-crl_reason") == 0)
517 if (--argc < 1) goto bad;
519 rev_type = REV_CRL_REASON;
521 else if (strcmp(*argv,"-crl_hold") == 0)
523 if (--argc < 1) goto bad;
527 else if (strcmp(*argv,"-crl_compromise") == 0)
529 if (--argc < 1) goto bad;
531 rev_type = REV_KEY_COMPROMISE;
533 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
535 if (--argc < 1) goto bad;
537 rev_type = REV_CA_COMPROMISE;
539 else if (strcmp(*argv,"-engine") == 0)
541 if (--argc < 1) goto bad;
547 BIO_printf(bio_err,"unknown option %s\n",*argv);
557 for (pp=ca_usage; (*pp != NULL); pp++)
558 BIO_printf(bio_err,"%s",*pp);
562 ERR_load_crypto_strings();
564 e = setup_engine(bio_err, engine, 0);
566 /*****************************************************************/
567 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
568 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
569 if (configfile == NULL)
571 /* We will just use 'buf[0]' as a temporary buffer. */
572 #ifdef OPENSSL_SYS_VMS
573 strncpy(buf[0],X509_get_default_cert_area(),
574 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
576 strncpy(buf[0],X509_get_default_cert_area(),
577 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
578 buf[0][sizeof(buf[0])-2-sizeof(CONFIG_FILE)]='\0';
581 strcat(buf[0],CONFIG_FILE);
585 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
586 conf = NCONF_new(NULL);
587 if (NCONF_load(conf,configfile,&errorline) <= 0)
590 BIO_printf(bio_err,"error loading the config file '%s'\n",
593 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
594 ,errorline,configfile);
598 if (!load_config(bio_err, conf))
601 /* Lets get the config section we are using */
604 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
607 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
614 p=NCONF_get_string(conf,NULL,"oid_file");
621 oid_bio=BIO_new_file(p,"r");
625 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
626 ERR_print_errors(bio_err);
632 OBJ_create_objects(oid_bio);
636 if (!add_oid_section(bio_err,conf))
638 ERR_print_errors(bio_err);
643 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
644 if (randfile == NULL)
646 app_RAND_load_file(randfile, bio_err, 0);
648 in=BIO_new(BIO_s_file());
649 out=BIO_new(BIO_s_file());
650 Sout=BIO_new(BIO_s_file());
651 Cout=BIO_new(BIO_s_file());
652 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
654 ERR_print_errors(bio_err);
658 /*****************************************************************/
659 /* report status of cert with serial number given on command line */
662 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
664 lookup_fail(section,ENV_DATABASE);
667 if (BIO_read_filename(in,dbfile) <= 0)
670 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
673 db=TXT_DB_read(in,DB_NUMBER);
674 if (db == NULL) goto err;
676 if (!make_serial_index(db))
679 if (get_certificate_status(ser_status,db) != 1)
680 BIO_printf(bio_err,"Error verifying serial %s!\n",
685 /*****************************************************************/
686 /* we definitely need a public key, so let's get it */
688 if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
689 section,ENV_PRIVATE_KEY)) == NULL))
691 lookup_fail(section,ENV_PRIVATE_KEY);
697 if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
699 BIO_printf(bio_err,"Error getting password\n");
703 pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
705 if (key) memset(key,0,strlen(key));
708 /* load_key() has already printed an appropriate message */
712 /*****************************************************************/
713 /* we need a certificate */
714 if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
715 section,ENV_CERTIFICATE)) == NULL))
717 lookup_fail(section,ENV_CERTIFICATE);
720 x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
725 if (!X509_check_private_key(x509,pkey))
727 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
731 f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
734 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
736 f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
739 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
742 f=NCONF_get_string(conf,section,ENV_NAMEOPT);
746 if (!set_name_ex(&nameopt, f))
748 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
756 f=NCONF_get_string(conf,section,ENV_CERTOPT);
760 if (!set_cert_ex(&certopt, f))
762 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
770 f=NCONF_get_string(conf,section,ENV_EXTCOPY);
774 if (!set_ext_copy(&ext_copy, f))
776 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
783 /*****************************************************************/
784 /* lookup where to write new certificates */
785 if ((outdir == NULL) && (req))
789 if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
792 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
795 #ifndef OPENSSL_SYS_VMS
796 /* outdir is a directory spec, but access() for VMS demands a
797 filename. In any case, stat(), below, will catch the problem
798 if outdir is not a directory spec, and the fopen() or open()
799 will catch an error if there is no write access.
801 Presumably, this problem could also be solved by using the DEC
802 C routines to convert the directory syntax to Unixly, and give
803 that to access(). However, time's too short to do that just
806 if (access(outdir,R_OK|W_OK|X_OK) != 0)
808 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
813 if (stat(outdir,&sb) != 0)
815 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
820 if (!(sb.st_mode & S_IFDIR))
822 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
830 /*****************************************************************/
831 /* we need to load the database file */
832 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
834 lookup_fail(section,ENV_DATABASE);
837 if (BIO_read_filename(in,dbfile) <= 0)
840 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
843 db=TXT_DB_read(in,DB_NUMBER);
844 if (db == NULL) goto err;
846 /* Lets check some fields */
847 for (i=0; i<sk_num(db->data); i++)
849 pp=(char **)sk_value(db->data,i);
850 if ((pp[DB_type][0] != DB_TYPE_REV) &&
851 (pp[DB_rev_date][0] != '\0'))
853 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
856 if ((pp[DB_type][0] == DB_TYPE_REV) &&
857 !make_revoked(NULL, pp[DB_rev_date]))
859 BIO_printf(bio_err," in entry %d\n", i+1);
862 if (!check_time_format(pp[DB_exp_date]))
864 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
874 if ((j&1) || (j < 2))
876 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
881 if (!( ((*p >= '0') && (*p <= '9')) ||
882 ((*p >= 'A') && (*p <= 'F')) ||
883 ((*p >= 'a') && (*p <= 'f'))) )
885 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);
893 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
894 #ifdef OPENSSL_SYS_VMS
896 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
897 out = BIO_push(tmpbio, out);
900 TXT_DB_write(out,db);
901 BIO_printf(bio_err,"%d entries loaded from the database\n",
903 BIO_printf(bio_err,"generating index\n");
906 if (!make_serial_index(db))
909 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
910 LHASH_HASH_FN(index_name_hash),
911 LHASH_COMP_FN(index_name_cmp)))
913 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
914 db->error,db->arg1,db->arg2);
918 /*****************************************************************/
919 /* Update the db file for expired certificates */
923 BIO_printf(bio_err, "Updating %s ...\n",
929 BIO_printf(bio_err,"Malloc failure\n");
934 if (verbose) BIO_printf(bio_err,
935 "No entries found to mark expired\n");
939 out = BIO_new(BIO_s_file());
942 ERR_print_errors(bio_err);
946 #ifndef OPENSSL_SYS_VMS
947 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
949 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-new", dbfile);
951 if (j < 0 || j >= sizeof buf[0])
953 BIO_printf(bio_err, "file name too long\n");
956 if (BIO_write_filename(out,buf[0]) <= 0)
959 BIO_printf(bio_err,"unable to open '%s'\n",
963 j=TXT_DB_write(out,db);
964 if (j <= 0) goto err;
968 #ifndef OPENSSL_SYS_VMS
969 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
971 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-old", dbfile);
973 if (j < 0 || j >= sizeof buf[1])
975 BIO_printf(bio_err, "file name too long\n");
978 if (rename(dbfile,buf[1]) < 0)
981 "unable to rename %s to %s\n",
986 if (rename(buf[0],dbfile) < 0)
989 "unable to rename %s to %s\n",
992 rename(buf[1],dbfile);
996 if (verbose) BIO_printf(bio_err,
997 "Done. %d entries marked as expired\n",i);
1002 /*****************************************************************/
1003 /* Read extentions config file */
1006 extconf = NCONF_new(NULL);
1007 if (NCONF_load(extconf,extfile,&errorline) <= 0)
1010 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
1013 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
1020 BIO_printf(bio_err, "Succesfully loaded extensions file %s\n", extfile);
1022 /* We can have sections in the ext file */
1023 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
1024 extensions = "default";
1027 /*****************************************************************/
1030 if (outfile != NULL)
1032 if (BIO_write_filename(Sout,outfile) <= 0)
1040 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1041 #ifdef OPENSSL_SYS_VMS
1043 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1044 Sout = BIO_push(tmpbio, Sout);
1052 if ((md == NULL) && ((md=NCONF_get_string(conf,
1053 section,ENV_DEFAULT_MD)) == NULL))
1055 lookup_fail(section,ENV_DEFAULT_MD);
1058 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1059 section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1061 if(strcmp(tmp_email_dn,"no") == 0)
1064 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1066 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1070 BIO_printf(bio_err,"message digest is %s\n",
1071 OBJ_nid2ln(dgst->type));
1072 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1073 section,ENV_POLICY)) == NULL))
1075 lookup_fail(section,ENV_POLICY);
1079 BIO_printf(bio_err,"policy is %s\n",policy);
1081 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1084 lookup_fail(section,ENV_SERIAL);
1090 /* no '-extfile' option, so we look for extensions
1091 * in the main configuration file */
1094 extensions=NCONF_get_string(conf,section,
1101 /* Check syntax of file */
1103 X509V3_set_ctx_test(&ctx);
1104 X509V3_set_nconf(&ctx, conf);
1105 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1109 "Error Loading extension section %s\n",
1117 if (startdate == NULL)
1119 startdate=NCONF_get_string(conf,section,
1120 ENV_DEFAULT_STARTDATE);
1121 if (startdate == NULL)
1124 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1126 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1129 if (startdate == NULL) startdate="today";
1131 if (enddate == NULL)
1133 enddate=NCONF_get_string(conf,section,
1134 ENV_DEFAULT_ENDDATE);
1135 if (enddate == NULL)
1138 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1140 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1146 if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1149 if (!enddate && (days == 0))
1151 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1155 if ((serial=load_serial(serialfile)) == NULL)
1157 BIO_printf(bio_err,"error while loading serial number\n");
1162 if (BN_is_zero(serial))
1163 BIO_printf(bio_err,"next serial number is 00\n");
1166 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1167 BIO_printf(bio_err,"next serial number is %s\n",f);
1172 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1174 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1178 if ((cert_sk=sk_X509_new_null()) == NULL)
1180 BIO_printf(bio_err,"Memory allocation failure\n");
1183 if (spkac_file != NULL)
1186 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1187 serial,subj,email_dn,startdate,enddate,days,extensions,
1188 conf,verbose,certopt,nameopt,default_op,ext_copy);
1189 if (j < 0) goto err;
1193 BIO_printf(bio_err,"\n");
1194 if (!BN_add_word(serial,1)) goto err;
1195 if (!sk_X509_push(cert_sk,x))
1197 BIO_printf(bio_err,"Memory allocation failure\n");
1207 if (ss_cert_file != NULL)
1210 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1211 db,serial,subj,email_dn,startdate,enddate,days,batch,
1212 extensions,conf,verbose, certopt, nameopt,
1213 default_op, ext_copy, e);
1214 if (j < 0) goto err;
1218 BIO_printf(bio_err,"\n");
1219 if (!BN_add_word(serial,1)) goto err;
1220 if (!sk_X509_push(cert_sk,x))
1222 BIO_printf(bio_err,"Memory allocation failure\n");
1230 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1231 serial,subj,email_dn,startdate,enddate,days,batch,
1232 extensions,conf,verbose, certopt, nameopt,
1233 default_op, ext_copy);
1234 if (j < 0) goto err;
1238 BIO_printf(bio_err,"\n");
1239 if (!BN_add_word(serial,1)) goto err;
1240 if (!sk_X509_push(cert_sk,x))
1242 BIO_printf(bio_err,"Memory allocation failure\n");
1247 for (i=0; i<argc; i++)
1250 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1251 serial,subj,email_dn,startdate,enddate,days,batch,
1252 extensions,conf,verbose, certopt, nameopt,
1253 default_op, ext_copy);
1254 if (j < 0) goto err;
1258 BIO_printf(bio_err,"\n");
1259 if (!BN_add_word(serial,1)) goto err;
1260 if (!sk_X509_push(cert_sk,x))
1262 BIO_printf(bio_err,"Memory allocation failure\n");
1267 /* we have a stack of newly certified certificates
1268 * and a data base and serial number that need
1271 if (sk_X509_num(cert_sk) > 0)
1275 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1276 (void)BIO_flush(bio_err);
1278 fgets(buf[0],10,stdin);
1279 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1281 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1287 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1289 strncpy(buf[0],serialfile,BSIZE-4);
1290 buf[0][BSIZE-4]='\0';
1292 #ifdef OPENSSL_SYS_VMS
1293 strcat(buf[0],"-new");
1295 strcat(buf[0],".new");
1298 if (!save_serial(buf[0],serial)) goto err;
1300 strncpy(buf[1],dbfile,BSIZE-4);
1301 buf[1][BSIZE-4]='\0';
1303 #ifdef OPENSSL_SYS_VMS
1304 strcat(buf[1],"-new");
1306 strcat(buf[1],".new");
1309 if (BIO_write_filename(out,buf[1]) <= 0)
1312 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1315 l=TXT_DB_write(out,db);
1316 if (l <= 0) goto err;
1320 BIO_printf(bio_err,"writing new certificates\n");
1321 for (i=0; i<sk_X509_num(cert_sk); i++)
1326 x=sk_X509_value(cert_sk,i);
1328 j=x->cert_info->serialNumber->length;
1329 p=(char *)x->cert_info->serialNumber->data;
1331 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1332 buf[2][BSIZE-(j*2)-6]='\0';
1334 #ifndef OPENSSL_SYS_VMS
1338 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1343 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1352 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1355 BIO_printf(bio_err,"writing %s\n",buf[2]);
1357 if (BIO_write_filename(Cout,buf[2]) <= 0)
1362 write_new_certificate(Cout,x, 0, notext);
1363 write_new_certificate(Sout,x, output_der, notext);
1366 if (sk_X509_num(cert_sk))
1368 /* Rename the database and the serial file */
1369 strncpy(buf[2],serialfile,BSIZE-4);
1370 buf[2][BSIZE-4]='\0';
1372 #ifdef OPENSSL_SYS_VMS
1373 strcat(buf[2],"-old");
1375 strcat(buf[2],".old");
1382 if (rename(serialfile,buf[2]) < 0)
1384 BIO_printf(bio_err,"unable to rename %s to %s\n",
1389 if (rename(buf[0],serialfile) < 0)
1391 BIO_printf(bio_err,"unable to rename %s to %s\n",
1394 rename(buf[2],serialfile);
1398 strncpy(buf[2],dbfile,BSIZE-4);
1399 buf[2][BSIZE-4]='\0';
1401 #ifdef OPENSSL_SYS_VMS
1402 strcat(buf[2],"-old");
1404 strcat(buf[2],".old");
1407 if (rename(dbfile,buf[2]) < 0)
1409 BIO_printf(bio_err,"unable to rename %s to %s\n",
1414 if (rename(buf[1],dbfile) < 0)
1416 BIO_printf(bio_err,"unable to rename %s to %s\n",
1419 rename(buf[2],dbfile);
1422 BIO_printf(bio_err,"Data Base Updated\n");
1426 /*****************************************************************/
1432 crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1438 /* Check syntax of file */
1440 X509V3_set_ctx_test(&ctx);
1441 X509V3_set_nconf(&ctx, conf);
1442 if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1445 "Error Loading CRL extension section %s\n",
1452 if (!crldays && !crlhours)
1454 if (!NCONF_get_number(conf,section,
1455 ENV_DEFAULT_CRL_DAYS, &crldays))
1457 if (!NCONF_get_number(conf,section,
1458 ENV_DEFAULT_CRL_HOURS, &crlhours))
1461 if ((crldays == 0) && (crlhours == 0))
1463 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1467 if (verbose) BIO_printf(bio_err,"making CRL\n");
1468 if ((crl=X509_CRL_new()) == NULL) goto err;
1469 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1471 tmptm = ASN1_TIME_new();
1472 if (!tmptm) goto err;
1473 X509_gmtime_adj(tmptm,0);
1474 X509_CRL_set_lastUpdate(crl, tmptm);
1475 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1476 X509_CRL_set_nextUpdate(crl, tmptm);
1478 ASN1_TIME_free(tmptm);
1480 for (i=0; i<sk_num(db->data); i++)
1482 pp=(char **)sk_value(db->data,i);
1483 if (pp[DB_type][0] == DB_TYPE_REV)
1485 if ((r=X509_REVOKED_new()) == NULL) goto err;
1486 j = make_revoked(r, pp[DB_rev_date]);
1488 if (j == 2) crl_v2 = 1;
1489 if (!BN_hex2bn(&serial, pp[DB_serial]))
1491 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1496 X509_REVOKED_set_serialNumber(r, tmpser);
1497 ASN1_INTEGER_free(tmpser);
1498 X509_CRL_add0_revoked(crl,r);
1502 /* sort the data so it will be written in serial
1506 /* we now have a CRL */
1507 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1510 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1512 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1518 #ifndef OPENSSL_NO_DSA
1519 if (pkey->type == EVP_PKEY_DSA)
1523 #ifndef OPENSSL_NO_ECDSA
1524 if (pkey->type == EVP_PKEY_EC)
1531 /* Add any extensions asked for */
1536 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1537 X509V3_set_nconf(&crlctx, conf);
1539 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1540 crl_ext, crl)) goto err;
1542 if (crl_ext || crl_v2)
1544 if (!X509_CRL_set_version(crl, 1))
1545 goto err; /* version 2 CRL */
1548 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1550 PEM_write_bio_X509_CRL(Sout,crl);
1552 /*****************************************************************/
1557 BIO_printf(bio_err,"no input files\n");
1563 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1565 if (revcert == NULL)
1567 j=do_revoke(revcert,db, rev_type, rev_arg);
1568 if (j <= 0) goto err;
1571 strncpy(buf[0],dbfile,BSIZE-4);
1572 buf[0][BSIZE-4]='\0';
1573 #ifndef OPENSSL_SYS_VMS
1574 strcat(buf[0],".new");
1576 strcat(buf[0],"-new");
1578 if (BIO_write_filename(out,buf[0]) <= 0)
1581 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1584 j=TXT_DB_write(out,db);
1585 if (j <= 0) goto err;
1586 strncpy(buf[1],dbfile,BSIZE-4);
1587 buf[1][BSIZE-4]='\0';
1588 #ifndef OPENSSL_SYS_VMS
1589 strcat(buf[1],".old");
1591 strcat(buf[1],"-old");
1597 if (rename(dbfile,buf[1]) < 0)
1599 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1603 if (rename(buf[0],dbfile) < 0)
1605 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1607 rename(buf[1],dbfile);
1610 BIO_printf(bio_err,"Data Base Updated\n");
1613 /*****************************************************************/
1621 sk_X509_pop_free(cert_sk,X509_free);
1623 if (ret) ERR_print_errors(bio_err);
1624 app_RAND_write_file(randfile, bio_err);
1629 EVP_PKEY_free(pkey);
1638 static void lookup_fail(char *name, char *tag)
1640 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1643 static unsigned long index_serial_hash(const char **a)
1648 while (*n == '0') n++;
1649 return(lh_strhash(n));
1652 static int index_serial_cmp(const char **a, const char **b)
1656 for (aa=a[DB_serial]; *aa == '0'; aa++);
1657 for (bb=b[DB_serial]; *bb == '0'; bb++);
1658 return(strcmp(aa,bb));
1661 static unsigned long index_name_hash(const char **a)
1662 { return(lh_strhash(a[DB_name])); }
1664 static int index_name_qual(char **a)
1665 { return(a[0][0] == 'V'); }
1667 static int index_name_cmp(const char **a, const char **b)
1668 { return(strcmp(a[DB_name],
1671 static BIGNUM *load_serial(char *serialfile)
1675 MS_STATIC char buf[1024];
1676 ASN1_INTEGER *ai=NULL;
1678 if ((in=BIO_new(BIO_s_file())) == NULL)
1680 ERR_print_errors(bio_err);
1684 if (BIO_read_filename(in,serialfile) <= 0)
1689 ai=ASN1_INTEGER_new();
1690 if (ai == NULL) goto err;
1691 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1693 BIO_printf(bio_err,"unable to load number from %s\n",
1697 ret=ASN1_INTEGER_to_BN(ai,NULL);
1700 BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
1704 if (in != NULL) BIO_free(in);
1705 if (ai != NULL) ASN1_INTEGER_free(ai);
1709 static int save_serial(char *serialfile, BIGNUM *serial)
1713 ASN1_INTEGER *ai=NULL;
1715 out=BIO_new(BIO_s_file());
1718 ERR_print_errors(bio_err);
1721 if (BIO_write_filename(out,serialfile) <= 0)
1727 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1729 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1732 i2a_ASN1_INTEGER(out,ai);
1736 if (out != NULL) BIO_free_all(out);
1737 if (ai != NULL) ASN1_INTEGER_free(ai);
1741 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1742 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1743 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1744 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1745 unsigned long certopt, unsigned long nameopt, int default_op,
1750 EVP_PKEY *pktmp=NULL;
1753 in=BIO_new(BIO_s_file());
1755 if (BIO_read_filename(in,infile) <= 0)
1760 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1762 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1767 X509_REQ_print(bio_err,req);
1769 BIO_printf(bio_err,"Check that the request matches the signature\n");
1771 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1773 BIO_printf(bio_err,"error unpacking public key\n");
1776 i=X509_REQ_verify(req,pktmp);
1777 EVP_PKEY_free(pktmp);
1781 BIO_printf(bio_err,"Signature verification problems....\n");
1787 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1791 BIO_printf(bio_err,"Signature ok\n");
1793 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1794 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1795 certopt, nameopt, default_op, ext_copy);
1798 if (req != NULL) X509_REQ_free(req);
1799 if (in != NULL) BIO_free(in);
1803 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1804 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1805 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1806 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1807 unsigned long certopt, unsigned long nameopt, int default_op,
1808 int ext_copy, ENGINE *e)
1811 X509_REQ *rreq=NULL;
1812 EVP_PKEY *pktmp=NULL;
1815 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1818 X509_print(bio_err,req);
1820 BIO_printf(bio_err,"Check that the request matches the signature\n");
1822 if ((pktmp=X509_get_pubkey(req)) == NULL)
1824 BIO_printf(bio_err,"error unpacking public key\n");
1827 i=X509_verify(req,pktmp);
1828 EVP_PKEY_free(pktmp);
1832 BIO_printf(bio_err,"Signature verification problems....\n");
1838 BIO_printf(bio_err,"Signature did not match the certificate\n");
1842 BIO_printf(bio_err,"Signature ok\n");
1844 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1847 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1848 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1852 if (rreq != NULL) X509_REQ_free(rreq);
1853 if (req != NULL) X509_free(req);
1857 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1858 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1859 int email_dn, char *startdate, char *enddate, long days, int batch,
1860 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1861 unsigned long certopt, unsigned long nameopt, int default_op,
1864 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1865 ASN1_UTCTIME *tm,*tmptm;
1866 ASN1_STRING *str,*str2;
1870 X509_NAME_ENTRY *ne;
1871 X509_NAME_ENTRY *tne,*push;
1873 int ok= -1,i,j,last,nid;
1876 char *row[DB_NUMBER],**rrow,**irow=NULL;
1879 tmptm=ASN1_UTCTIME_new();
1882 BIO_printf(bio_err,"malloc error\n");
1886 for (i=0; i<DB_NUMBER; i++)
1891 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1895 ERR_print_errors(bio_err);
1898 X509_REQ_set_subject_name(req,n);
1899 req->req_info->enc.modified = 1;
1904 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1906 name=X509_REQ_get_subject_name(req);
1907 for (i=0; i<X509_NAME_entry_count(name); i++)
1909 ne= X509_NAME_get_entry(name,i);
1910 str=X509_NAME_ENTRY_get_data(ne);
1911 obj=X509_NAME_ENTRY_get_object(ne);
1915 /* assume all type should be strings */
1916 nid=OBJ_obj2nid(ne->object);
1918 if (str->type == V_ASN1_UNIVERSALSTRING)
1919 ASN1_UNIVERSALSTRING_to_string(str);
1921 if ((str->type == V_ASN1_IA5STRING) &&
1922 (nid != NID_pkcs9_emailAddress))
1923 str->type=V_ASN1_T61STRING;
1925 if ((nid == NID_pkcs9_emailAddress) &&
1926 (str->type == V_ASN1_PRINTABLESTRING))
1927 str->type=V_ASN1_IA5STRING;
1930 /* If no EMAIL is wanted in the subject */
1931 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1934 /* check some things */
1935 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1936 (str->type != V_ASN1_IA5STRING))
1938 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1941 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1943 j=ASN1_PRINTABLE_type(str->data,str->length);
1944 if ( ((j == V_ASN1_T61STRING) &&
1945 (str->type != V_ASN1_T61STRING)) ||
1946 ((j == V_ASN1_IA5STRING) &&
1947 (str->type == V_ASN1_PRINTABLESTRING)))
1949 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1955 old_entry_print(bio_err, obj, str);
1958 /* Ok, now we check the 'policy' stuff. */
1959 if ((subject=X509_NAME_new()) == NULL)
1961 BIO_printf(bio_err,"Memory allocation failure\n");
1965 /* take a copy of the issuer name before we mess with it. */
1966 CAname=X509_NAME_dup(x509->cert_info->subject);
1967 if (CAname == NULL) goto err;
1970 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1972 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1973 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1975 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1983 /* lookup the object in the supplied name list */
1984 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1987 if (last != -1) break;
1992 tne=X509_NAME_get_entry(name,j);
1996 /* depending on the 'policy', decide what to do. */
1998 if (strcmp(cv->value,"optional") == 0)
2003 else if (strcmp(cv->value,"supplied") == 0)
2007 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2013 else if (strcmp(cv->value,"match") == 0)
2019 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2026 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2027 if ((j < 0) && (last2 == -1))
2029 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2034 push=X509_NAME_get_entry(CAname,j);
2035 str=X509_NAME_ENTRY_get_data(tne);
2036 str2=X509_NAME_ENTRY_get_data(push);
2038 if (ASN1_STRING_cmp(str,str2) != 0)
2043 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));
2049 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2055 if (!X509_NAME_add_entry(subject,push, -1, 0))
2058 X509_NAME_ENTRY_free(push);
2059 BIO_printf(bio_err,"Memory allocation failure\n");
2069 X509_NAME_free(subject);
2070 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
2071 subject=X509_NAME_dup(name);
2072 if (subject == NULL) goto err;
2076 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2078 /* Build the correct Subject if no e-mail is wanted in the subject */
2079 /* and add it later on because of the method extensions are added (altName) */
2082 dn_subject = subject;
2085 X509_NAME_ENTRY *tmpne;
2086 /* Its best to dup the subject DN and then delete any email
2087 * addresses because this retains its structure.
2089 if (!(dn_subject = X509_NAME_dup(subject)))
2091 BIO_printf(bio_err,"Memory allocation failure\n");
2094 while((i = X509_NAME_get_index_by_NID(dn_subject,
2095 NID_pkcs9_emailAddress, -1)) >= 0)
2097 tmpne = X509_NAME_get_entry(dn_subject, i);
2098 X509_NAME_delete_entry(dn_subject, i);
2099 X509_NAME_ENTRY_free(tmpne);
2103 if (BN_is_zero(serial))
2104 row[DB_serial]=BUF_strdup("00");
2106 row[DB_serial]=BN_bn2hex(serial);
2107 if (row[DB_serial] == NULL)
2109 BIO_printf(bio_err,"Memory allocation failure\n");
2113 rrow=TXT_DB_get_by_index(db,DB_name,row);
2116 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2121 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2124 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2126 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2133 "The matching entry has the following details\n");
2134 if (rrow[DB_type][0] == 'E')
2136 else if (rrow[DB_type][0] == 'R')
2138 else if (rrow[DB_type][0] == 'V')
2141 p="\ninvalid type, Data base error\n";
2142 BIO_printf(bio_err,"Type :%s\n",p);;
2143 if (rrow[DB_type][0] == 'R')
2145 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2146 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2148 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2149 BIO_printf(bio_err,"Expires on :%s\n",p);
2150 p=rrow[DB_serial]; if (p == NULL) p="undef";
2151 BIO_printf(bio_err,"Serial Number :%s\n",p);
2152 p=rrow[DB_file]; if (p == NULL) p="undef";
2153 BIO_printf(bio_err,"File name :%s\n",p);
2154 p=rrow[DB_name]; if (p == NULL) p="undef";
2155 BIO_printf(bio_err,"Subject Name :%s\n",p);
2156 ok= -1; /* This is now a 'bad' error. */
2160 /* We are now totally happy, lets make and sign the certificate */
2162 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2164 if ((ret=X509_new()) == NULL) goto err;
2168 /* Make it an X509 v3 certificate. */
2169 if (!X509_set_version(x509,2)) goto err;
2172 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2174 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2177 if (strcmp(startdate,"today") == 0)
2178 X509_gmtime_adj(X509_get_notBefore(ret),0);
2179 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2181 if (enddate == NULL)
2182 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2183 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2185 if (!X509_set_subject_name(ret,subject)) goto err;
2187 pktmp=X509_REQ_get_pubkey(req);
2188 i = X509_set_pubkey(ret,pktmp);
2189 EVP_PKEY_free(pktmp);
2192 /* Lets add the extensions, if there are any */
2196 if (ci->version == NULL)
2197 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2199 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2201 /* Free the current entries if any, there should not
2202 * be any I believe */
2203 if (ci->extensions != NULL)
2204 sk_X509_EXTENSION_pop_free(ci->extensions,
2205 X509_EXTENSION_free);
2207 ci->extensions = NULL;
2209 /* Initialize the context structure */
2210 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2215 BIO_printf(bio_err, "Extra configuration file found\n");
2217 /* Use the extconf configuration db LHASH */
2218 X509V3_set_nconf(&ctx, extconf);
2220 /* Test the structure (needed?) */
2221 /* X509V3_set_ctx_test(&ctx); */
2223 /* Adds exts contained in the configuration file */
2224 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2227 "ERROR: adding extensions in section %s\n",
2229 ERR_print_errors(bio_err);
2233 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2237 /* We found extensions to be set from config file */
2238 X509V3_set_nconf(&ctx, lconf);
2240 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2242 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2243 ERR_print_errors(bio_err);
2248 BIO_printf(bio_err, "Successfully added extensions from config\n");
2252 /* Copy extensions from request (if any) */
2254 if (!copy_extensions(ret, req, ext_copy))
2256 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2257 ERR_print_errors(bio_err);
2261 /* Set the right value for the noemailDN option */
2264 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2269 BIO_printf(bio_err, "Certificate Details:\n");
2270 /* Never print signature details because signature not present */
2271 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2272 X509_print_ex(bio_err, ret, nameopt, certopt);
2275 BIO_printf(bio_err,"Certificate is to be certified until ");
2276 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2277 if (days) BIO_printf(bio_err," (%d days)",days);
2278 BIO_printf(bio_err, "\n");
2283 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2284 (void)BIO_flush(bio_err);
2286 fgets(buf,sizeof(buf)-1,stdin);
2287 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2289 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2296 #ifndef OPENSSL_NO_DSA
2297 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2298 pktmp=X509_get_pubkey(ret);
2299 if (EVP_PKEY_missing_parameters(pktmp) &&
2300 !EVP_PKEY_missing_parameters(pkey))
2301 EVP_PKEY_copy_parameters(pktmp,pkey);
2302 EVP_PKEY_free(pktmp);
2304 #ifndef OPENSSL_NO_ECDSA
2305 if (pkey->type == EVP_PKEY_EC)
2307 pktmp = X509_get_pubkey(ret);
2308 if (EVP_PKEY_missing_parameters(pktmp) &&
2309 !EVP_PKEY_missing_parameters(pkey))
2310 EVP_PKEY_copy_parameters(pktmp, pkey);
2311 EVP_PKEY_free(pktmp);
2315 if (!X509_sign(ret,pkey,dgst))
2318 /* We now just add it to the database */
2319 row[DB_type]=(char *)OPENSSL_malloc(2);
2321 tm=X509_get_notAfter(ret);
2322 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2323 memcpy(row[DB_exp_date],tm->data,tm->length);
2324 row[DB_exp_date][tm->length]='\0';
2326 row[DB_rev_date]=NULL;
2328 /* row[DB_serial] done already */
2329 row[DB_file]=(char *)OPENSSL_malloc(8);
2330 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2332 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2333 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2335 BIO_printf(bio_err,"Memory allocation failure\n");
2338 strcpy(row[DB_file],"unknown");
2339 row[DB_type][0]='V';
2340 row[DB_type][1]='\0';
2342 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2344 BIO_printf(bio_err,"Memory allocation failure\n");
2348 for (i=0; i<DB_NUMBER; i++)
2353 irow[DB_NUMBER]=NULL;
2355 if (!TXT_DB_insert(db,irow))
2357 BIO_printf(bio_err,"failed to update database\n");
2358 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2363 for (i=0; i<DB_NUMBER; i++)
2364 if (row[i] != NULL) OPENSSL_free(row[i]);
2367 X509_NAME_free(CAname);
2368 if (subject != NULL)
2369 X509_NAME_free(subject);
2370 if ((dn_subject != NULL) && !email_dn)
2371 X509_NAME_free(dn_subject);
2373 ASN1_UTCTIME_free(tmptm);
2376 if (ret != NULL) X509_free(ret);
2384 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2389 (void)i2d_X509_bio(bp,x);
2393 /* ??? Not needed since X509_print prints all this stuff anyway */
2394 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2395 BIO_printf(bp,"issuer :%s\n",f);
2397 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2398 BIO_printf(bp,"subject:%s\n",f);
2400 BIO_puts(bp,"serial :");
2401 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2402 BIO_puts(bp,"\n\n");
2404 if (!notext)X509_print(bp,x);
2405 PEM_write_bio_X509(bp,x);
2408 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2409 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2410 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2411 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2412 unsigned long nameopt, int default_op, int ext_copy)
2414 STACK_OF(CONF_VALUE) *sk=NULL;
2417 CONF_VALUE *cv=NULL;
2418 NETSCAPE_SPKI *spki = NULL;
2421 EVP_PKEY *pktmp=NULL;
2423 X509_NAME_ENTRY *ne=NULL;
2429 * Load input file into a hash table. (This is just an easy
2430 * way to read and parse the file, then put it into a convenient
2433 parms=CONF_load(NULL,infile,&errline);
2436 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2437 ERR_print_errors(bio_err);
2441 sk=CONF_get_section(parms, "default");
2442 if (sk_CONF_VALUE_num(sk) == 0)
2444 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2450 * Now create a dummy X509 request structure. We don't actually
2451 * have an X509 request, but we have many of the components
2452 * (a public key, various DN components). The idea is that we
2453 * put these components into the right X509 request structure
2454 * and we can use the same code as if you had a real X509 request.
2459 ERR_print_errors(bio_err);
2464 * Build up the subject name set.
2471 if (sk_CONF_VALUE_num(sk) <= i) break;
2473 cv=sk_CONF_VALUE_value(sk,i);
2475 /* Skip past any leading X. X: X, etc to allow for
2476 * multiple instances
2478 for (buf = cv->name; *buf ; buf++)
2479 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2482 if (*buf) type = buf;
2487 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2489 if (strcmp(type, "SPKAC") == 0)
2491 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2494 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2495 ERR_print_errors(bio_err);
2503 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2507 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2508 if (fix_data(nid, &j) == 0)
2511 "invalid characters in string %s\n",buf);
2515 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2516 (unsigned char *)buf,
2517 strlen(buf))) == NULL)
2520 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2524 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2530 * Now extract the key from the SPKI structure.
2533 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2535 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2537 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2541 j = NETSCAPE_SPKI_verify(spki, pktmp);
2544 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2547 BIO_printf(bio_err,"Signature ok\n");
2549 X509_REQ_set_pubkey(req,pktmp);
2550 EVP_PKEY_free(pktmp);
2551 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2552 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2555 if (req != NULL) X509_REQ_free(req);
2556 if (parms != NULL) CONF_free(parms);
2557 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2558 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2563 static int fix_data(int nid, int *type)
2565 if (nid == NID_pkcs9_emailAddress)
2566 *type=V_ASN1_IA5STRING;
2567 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2568 *type=V_ASN1_T61STRING;
2569 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2570 *type=V_ASN1_T61STRING;
2571 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2573 if (nid == NID_pkcs9_unstructuredName)
2574 *type=V_ASN1_IA5STRING;
2578 static int check_time_format(char *str)
2582 tm.data=(unsigned char *)str;
2583 tm.length=strlen(str);
2584 tm.type=V_ASN1_UTCTIME;
2585 return(ASN1_UTCTIME_check(&tm));
2588 static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2590 ASN1_UTCTIME *tm=NULL;
2591 char *row[DB_NUMBER],**rrow,**irow;
2592 char *rev_str = NULL;
2596 for (i=0; i<DB_NUMBER; i++)
2598 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2599 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2601 row[DB_serial]=BUF_strdup("00");
2603 row[DB_serial]=BN_bn2hex(bn);
2605 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2607 BIO_printf(bio_err,"Memory allocation failure\n");
2610 /* We have to lookup by serial number because name lookup
2611 * skips revoked certs
2613 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2616 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2618 /* We now just add it to the database */
2619 row[DB_type]=(char *)OPENSSL_malloc(2);
2621 tm=X509_get_notAfter(x509);
2622 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2623 memcpy(row[DB_exp_date],tm->data,tm->length);
2624 row[DB_exp_date][tm->length]='\0';
2626 row[DB_rev_date]=NULL;
2628 /* row[DB_serial] done already */
2629 row[DB_file]=(char *)OPENSSL_malloc(8);
2631 /* row[DB_name] done already */
2633 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2634 (row[DB_file] == NULL))
2636 BIO_printf(bio_err,"Memory allocation failure\n");
2639 strcpy(row[DB_file],"unknown");
2640 row[DB_type][0]='V';
2641 row[DB_type][1]='\0';
2643 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2645 BIO_printf(bio_err,"Memory allocation failure\n");
2649 for (i=0; i<DB_NUMBER; i++)
2654 irow[DB_NUMBER]=NULL;
2656 if (!TXT_DB_insert(db,irow))
2658 BIO_printf(bio_err,"failed to update database\n");
2659 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2663 /* Revoke Certificate */
2664 ok = do_revoke(x509,db, type, value);
2669 else if (index_name_cmp((const char **)row,(const char **)rrow))
2671 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2675 else if (rrow[DB_type][0]=='R')
2677 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2683 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2684 rev_str = make_revocation_str(type, value);
2687 BIO_printf(bio_err, "Error in revocation arguments\n");
2690 rrow[DB_type][0]='R';
2691 rrow[DB_type][1]='\0';
2692 rrow[DB_rev_date] = rev_str;
2696 for (i=0; i<DB_NUMBER; i++)
2699 OPENSSL_free(row[i]);
2704 static int get_certificate_status(const char *serial, TXT_DB *db)
2706 char *row[DB_NUMBER],**rrow;
2709 /* Free Resources */
2710 for (i=0; i<DB_NUMBER; i++)
2713 /* Malloc needed char spaces */
2714 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2715 if (row[DB_serial] == NULL)
2717 BIO_printf(bio_err,"Malloc failure\n");
2721 if (strlen(serial) % 2)
2723 /* Set the first char to 0 */;
2724 row[DB_serial][0]='0';
2726 /* Copy String from serial to row[DB_serial] */
2727 memcpy(row[DB_serial]+1, serial, strlen(serial));
2728 row[DB_serial][strlen(serial)+1]='\0';
2732 /* Copy String from serial to row[DB_serial] */
2733 memcpy(row[DB_serial], serial, strlen(serial));
2734 row[DB_serial][strlen(serial)]='\0';
2737 /* Make it Upper Case */
2738 for (i=0; row[DB_serial][i] != '\0'; i++)
2739 row[DB_serial][i] = toupper(row[DB_serial][i]);
2744 /* Search for the certificate */
2745 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2748 BIO_printf(bio_err,"Serial %s not present in db.\n",
2753 else if (rrow[DB_type][0]=='V')
2755 BIO_printf(bio_err,"%s=Valid (%c)\n",
2756 row[DB_serial], rrow[DB_type][0]);
2759 else if (rrow[DB_type][0]=='R')
2761 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2762 row[DB_serial], rrow[DB_type][0]);
2765 else if (rrow[DB_type][0]=='E')
2767 BIO_printf(bio_err,"%s=Expired (%c)\n",
2768 row[DB_serial], rrow[DB_type][0]);
2771 else if (rrow[DB_type][0]=='S')
2773 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2774 row[DB_serial], rrow[DB_type][0]);
2779 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2780 row[DB_serial], rrow[DB_type][0]);
2784 for (i=0; i<DB_NUMBER; i++)
2787 OPENSSL_free(row[i]);
2792 static int do_updatedb (TXT_DB *db)
2794 ASN1_UTCTIME *a_tm = NULL;
2796 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2797 char **rrow, *a_tm_s;
2799 a_tm = ASN1_UTCTIME_new();
2801 /* get actual time and make a string */
2802 a_tm = X509_gmtime_adj(a_tm, 0);
2803 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2810 memcpy(a_tm_s, a_tm->data, a_tm->length);
2811 a_tm_s[a_tm->length] = '\0';
2813 if (strncmp(a_tm_s, "49", 2) <= 0)
2818 for (i = 0; i < sk_num(db->data); i++)
2820 rrow = (char **) sk_value(db->data, i);
2822 if (rrow[DB_type][0] == 'V')
2824 /* ignore entries that are not valid */
2825 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2830 if (db_y2k == a_y2k)
2832 /* all on the same y2k side */
2833 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2835 rrow[DB_type][0] = 'E';
2836 rrow[DB_type][1] = '\0';
2839 BIO_printf(bio_err, "%s=Expired\n",
2843 else if (db_y2k < a_y2k)
2845 rrow[DB_type][0] = 'E';
2846 rrow[DB_type][1] = '\0';
2849 BIO_printf(bio_err, "%s=Expired\n",
2858 ASN1_UTCTIME_free(a_tm);
2859 OPENSSL_free(a_tm_s);
2864 static char *crl_reasons[] = {
2865 /* CRL reason strings */
2869 "affiliationChanged",
2871 "cessationOfOperation",
2874 /* Additional pseudo reasons */
2880 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2882 /* Given revocation information convert to a DB string.
2883 * The format of the string is:
2884 * revtime[,reason,extra]. Where 'revtime' is the
2885 * revocation time (the current time). 'reason' is the
2886 * optional CRL reason and 'extra' is any additional
2890 char *make_revocation_str(int rev_type, char *rev_arg)
2892 char *reason = NULL, *other = NULL, *str;
2894 ASN1_UTCTIME *revtm = NULL;
2901 case REV_CRL_REASON:
2902 for (i = 0; i < 8; i++)
2904 if (!strcasecmp(rev_arg, crl_reasons[i]))
2906 reason = crl_reasons[i];
2912 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2918 /* Argument is an OID */
2920 otmp = OBJ_txt2obj(rev_arg, 0);
2921 ASN1_OBJECT_free(otmp);
2925 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2929 reason = "holdInstruction";
2933 case REV_KEY_COMPROMISE:
2934 case REV_CA_COMPROMISE:
2936 /* Argument is the key compromise time */
2937 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2939 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2943 if (rev_type == REV_KEY_COMPROMISE)
2946 reason = "CAkeyTime";
2952 revtm = X509_gmtime_adj(NULL, 0);
2954 i = revtm->length + 1;
2956 if (reason) i += strlen(reason) + 1;
2957 if (other) i += strlen(other) + 1;
2959 str = OPENSSL_malloc(i);
2961 if (!str) return NULL;
2963 strcpy(str, (char *)revtm->data);
2967 strcat(str, reason);
2974 ASN1_UTCTIME_free(revtm);
2978 /* Convert revocation field to X509_REVOKED entry
2982 * 2 OK and some extensions added (i.e. V2 CRL)
2986 int make_revoked(X509_REVOKED *rev, char *str)
2989 int reason_code = -1;
2991 ASN1_OBJECT *hold = NULL;
2992 ASN1_GENERALIZEDTIME *comp_time = NULL;
2993 ASN1_ENUMERATED *rtmp = NULL;
2995 ASN1_TIME *revDate = NULL;
2997 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
3002 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
3005 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3007 rtmp = ASN1_ENUMERATED_new();
3008 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3010 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3014 if (rev && comp_time)
3016 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3021 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3025 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3031 if (tmp) OPENSSL_free(tmp);
3032 ASN1_OBJECT_free(hold);
3033 ASN1_GENERALIZEDTIME_free(comp_time);
3034 ASN1_ENUMERATED_free(rtmp);
3035 ASN1_TIME_free(revDate);
3041 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
3042 * where characters may be escaped by \
3044 X509_NAME *do_subject(char *subject, long chtype)
3046 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
3047 char *buf = OPENSSL_malloc(buflen);
3048 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
3049 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
3050 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
3052 char *sp = subject, *bp = buf;
3055 X509_NAME *n = NULL;
3058 if (!buf || !ne_types || !ne_values)
3060 BIO_printf(bio_err, "malloc error\n");
3064 if (*subject != '/')
3066 BIO_printf(bio_err, "Subject does not start with '/'.\n");
3069 sp++; /* skip leading / */
3074 ne_types[ne_num] = bp;
3077 if (*sp == '\\') /* is there anything to escape in the type...? */
3083 BIO_printf(bio_err, "escape character at end of string\n");
3087 else if (*sp == '=')
3098 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
3101 ne_values[ne_num] = bp;
3110 BIO_printf(bio_err, "escape character at end of string\n");
3114 else if (*sp == '/')
3126 if (!(n = X509_NAME_new()))
3129 for (i = 0; i < ne_num; i++)
3131 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
3133 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
3139 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
3143 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
3147 OPENSSL_free(ne_values);
3148 OPENSSL_free(ne_types);
3155 OPENSSL_free(ne_values);
3157 OPENSSL_free(ne_types);
3163 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3165 char buf[25],*pbuf, *p;
3167 j=i2a_ASN1_OBJECT(bp,obj);
3169 for (j=22-j; j>0; j--)
3175 if (str->type == V_ASN1_PRINTABLESTRING)
3176 BIO_printf(bp,"PRINTABLE:'");
3177 else if (str->type == V_ASN1_T61STRING)
3178 BIO_printf(bp,"T61STRING:'");
3179 else if (str->type == V_ASN1_IA5STRING)
3180 BIO_printf(bp,"IA5STRING:'");
3181 else if (str->type == V_ASN1_UNIVERSALSTRING)
3182 BIO_printf(bp,"UNIVERSALSTRING:'");
3184 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3186 p=(char *)str->data;
3187 for (j=str->length; j>0; j--)
3189 if ((*p >= ' ') && (*p <= '~'))
3190 BIO_printf(bp,"%c",*p);
3192 BIO_printf(bp,"\\0x%02X",*p);
3193 else if ((unsigned char)*p == 0xf7)
3194 BIO_printf(bp,"^?");
3195 else BIO_printf(bp,"^%c",*p+'@');
3198 BIO_printf(bp,"'\n");
3202 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3205 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3206 int reason_code = -1;
3208 ASN1_OBJECT *hold = NULL;
3209 ASN1_GENERALIZEDTIME *comp_time = NULL;
3210 tmp = BUF_strdup(str);
3212 p = strchr(tmp, ',');
3231 *prevtm = ASN1_UTCTIME_new();
3232 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3234 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3240 for (i = 0; i < NUM_REASONS; i++)
3242 if(!strcasecmp(reason_str, crl_reasons[i]))
3248 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3250 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3254 if (reason_code == 7)
3255 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3256 else if (reason_code == 8) /* Hold instruction */
3260 BIO_printf(bio_err, "missing hold instruction\n");
3263 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3264 hold = OBJ_txt2obj(arg_str, 0);
3268 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3271 if (phold) *phold = hold;
3273 else if ((reason_code == 9) || (reason_code == 10))
3277 BIO_printf(bio_err, "missing compromised time\n");
3280 comp_time = ASN1_GENERALIZEDTIME_new();
3281 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3283 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3286 if (reason_code == 9)
3287 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3289 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3293 if (preason) *preason = reason_code;
3294 if (pinvtm) *pinvtm = comp_time;
3295 else ASN1_GENERALIZEDTIME_free(comp_time);
3301 if (tmp) OPENSSL_free(tmp);
3302 if (!phold) ASN1_OBJECT_free(hold);
3303 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3308 int make_serial_index(TXT_DB *db)
3310 if (!TXT_DB_create_index(db, DB_serial, NULL,
3311 LHASH_HASH_FN(index_serial_hash),
3312 LHASH_COMP_FN(index_serial_cmp)))
3315 "error creating serial number index:(%ld,%ld,%ld)\n",
3316 db->error,db->arg1,db->arg2);