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_CRLNUMBER "crlnumber"
126 #define ENV_CRL "crl"
127 #define ENV_PRIVATE_KEY "private_key"
128 #define ENV_RANDFILE "RANDFILE"
129 #define ENV_DEFAULT_DAYS "default_days"
130 #define ENV_DEFAULT_STARTDATE "default_startdate"
131 #define ENV_DEFAULT_ENDDATE "default_enddate"
132 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
133 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
134 #define ENV_DEFAULT_MD "default_md"
135 #define ENV_DEFAULT_EMAIL_DN "email_in_dn"
136 #define ENV_PRESERVE "preserve"
137 #define ENV_POLICY "policy"
138 #define ENV_EXTENSIONS "x509_extensions"
139 #define ENV_CRLEXT "crl_extensions"
140 #define ENV_MSIE_HACK "msie_hack"
141 #define ENV_NAMEOPT "name_opt"
142 #define ENV_CERTOPT "cert_opt"
143 #define ENV_EXTCOPY "copy_extensions"
145 #define ENV_DATABASE "database"
147 /* Additional revocation information types */
149 #define REV_NONE 0 /* No addditional information */
150 #define REV_CRL_REASON 1 /* Value is CRL reason code */
151 #define REV_HOLD 2 /* Value is hold instruction */
152 #define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
153 #define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
155 static char *ca_usage[]={
158 " -verbose - Talk alot while doing things\n",
159 " -config file - A config file\n",
160 " -name arg - The particular CA definition to use\n",
161 " -gencrl - Generate a new CRL\n",
162 " -crldays days - Days is when the next CRL is due\n",
163 " -crlhours hours - Hours is when the next CRL is due\n",
164 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
165 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
166 " -days arg - number of days to certify the certificate for\n",
167 " -md arg - md to use, one of md2, md5, sha or sha1\n",
168 " -policy arg - The CA 'policy' to support\n",
169 " -keyfile arg - private key file\n",
170 " -keyform arg - private key file format (PEM or ENGINE)\n",
171 " -key arg - key to decode the private key if it is encrypted\n",
172 " -cert file - The CA certificate\n",
173 " -in file - The input PEM encoded certificate request(s)\n",
174 " -out file - Where to put the output file(s)\n",
175 " -outdir dir - Where to put output certificates\n",
176 " -infiles .... - The last argument, requests to process\n",
177 " -spkac file - File contains DN and signed public key and challenge\n",
178 " -ss_cert file - File contains a self signed cert to sign\n",
179 " -preserveDN - Don't re-order the DN\n",
180 " -noemailDN - Don't add the EMAIL field into certificate' subject\n",
181 " -batch - Don't ask questions\n",
182 " -msie_hack - msie modifications to handle all those universal strings\n",
183 " -revoke file - Revoke a certificate (given in file)\n",
184 " -subj arg - Use arg instead of request's subject\n",
185 " -extensions .. - Extension section (override value in config file)\n",
186 " -extfile file - Configuration file with X509v3 extentions to add\n",
187 " -crlexts .. - CRL extension section (override value in config file)\n",
188 #ifndef OPENSSL_NO_ENGINE
189 " -engine e - use engine e, possibly a hardware device.\n",
191 " -status serial - Shows certificate status given the serial number\n",
192 " -updatedb - Updates db for expired certificates\n",
197 extern int EF_PROTECT_FREE;
198 extern int EF_PROTECT_BELOW;
199 extern int EF_ALIGNMENT;
202 static void lookup_fail(char *name,char *tag);
203 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
204 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
205 BIGNUM *serial, char *subj, int email_dn, char *startdate,
206 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
207 int verbose, unsigned long certopt, unsigned long nameopt,
208 int default_op, int ext_copy);
209 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
210 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
211 CA_DB *db, BIGNUM *serial, char *subj, int email_dn,
212 char *startdate, char *enddate, long days, int batch,
213 char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
214 unsigned long nameopt, int default_op, int ext_copy,
216 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
217 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
218 CA_DB *db, BIGNUM *serial,char *subj, int email_dn,
219 char *startdate, char *enddate, long days, char *ext_sect,
220 CONF *conf, int verbose, unsigned long certopt,
221 unsigned long nameopt, int default_op, int ext_copy);
222 static int fix_data(int nid, int *type);
223 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
224 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
225 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,
226 int email_dn, char *startdate, char *enddate, long days, int batch,
227 int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
228 unsigned long certopt, unsigned long nameopt, int default_op,
230 static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
231 static int get_certificate_status(const char *ser_status, CA_DB *db);
232 static int do_updatedb(CA_DB *db);
233 static int check_time_format(char *str);
234 char *make_revocation_str(int rev_type, char *rev_arg);
235 int make_revoked(X509_REVOKED *rev, char *str);
236 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
237 static CONF *conf=NULL;
238 static CONF *extconf=NULL;
239 static char *section=NULL;
241 static int preserve=0;
242 static int msie_hack=0;
245 int MAIN(int, char **);
247 int MAIN(int argc, char **argv)
250 char *key=NULL,*passargin=NULL;
265 char *configfile=NULL;
270 int keyform=FORMAT_PEM;
272 char *spkac_file=NULL;
273 char *ss_cert_file=NULL;
274 char *ser_status=NULL;
279 char *serialfile=NULL;
280 char *crlnumberfile=NULL;
281 char *extensions=NULL;
284 char *tmp_email_dn=NULL;
286 int rev_type = REV_NONE;
287 char *rev_arg = NULL;
289 BIGNUM *crlnumber=NULL;
290 char *startdate=NULL;
295 unsigned long nameopt = 0, certopt = 0;
297 int ext_copy = EXT_COPY_NONE;
300 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
304 X509_REVOKED *r=NULL;
306 ASN1_INTEGER *tmpser;
309 const EVP_MD *dgst=NULL;
310 STACK_OF(CONF_VALUE) *attribs=NULL;
311 STACK_OF(X509) *cert_sk=NULL;
314 MS_STATIC char buf[3][BSIZE];
316 #ifndef OPENSSL_NO_ENGINE
337 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
338 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
344 if (strcmp(*argv,"-verbose") == 0)
346 else if (strcmp(*argv,"-config") == 0)
348 if (--argc < 1) goto bad;
349 configfile= *(++argv);
351 else if (strcmp(*argv,"-name") == 0)
353 if (--argc < 1) goto bad;
356 else if (strcmp(*argv,"-subj") == 0)
358 if (--argc < 1) goto bad;
362 else if (strcmp(*argv,"-startdate") == 0)
364 if (--argc < 1) goto bad;
365 startdate= *(++argv);
367 else if (strcmp(*argv,"-enddate") == 0)
369 if (--argc < 1) goto bad;
372 else if (strcmp(*argv,"-days") == 0)
374 if (--argc < 1) goto bad;
375 days=atoi(*(++argv));
377 else if (strcmp(*argv,"-md") == 0)
379 if (--argc < 1) goto bad;
382 else if (strcmp(*argv,"-policy") == 0)
384 if (--argc < 1) goto bad;
387 else if (strcmp(*argv,"-keyfile") == 0)
389 if (--argc < 1) goto bad;
392 else if (strcmp(*argv,"-keyform") == 0)
394 if (--argc < 1) goto bad;
395 keyform=str2fmt(*(++argv));
397 else if (strcmp(*argv,"-passin") == 0)
399 if (--argc < 1) goto bad;
400 passargin= *(++argv);
402 else if (strcmp(*argv,"-key") == 0)
404 if (--argc < 1) goto bad;
407 else if (strcmp(*argv,"-cert") == 0)
409 if (--argc < 1) goto bad;
412 else if (strcmp(*argv,"-in") == 0)
414 if (--argc < 1) goto bad;
418 else if (strcmp(*argv,"-out") == 0)
420 if (--argc < 1) goto bad;
423 else if (strcmp(*argv,"-outdir") == 0)
425 if (--argc < 1) goto bad;
428 else if (strcmp(*argv,"-notext") == 0)
430 else if (strcmp(*argv,"-batch") == 0)
432 else if (strcmp(*argv,"-preserveDN") == 0)
434 else if (strcmp(*argv,"-noemailDN") == 0)
436 else if (strcmp(*argv,"-gencrl") == 0)
438 else if (strcmp(*argv,"-msie_hack") == 0)
440 else if (strcmp(*argv,"-crldays") == 0)
442 if (--argc < 1) goto bad;
443 crldays= atol(*(++argv));
445 else if (strcmp(*argv,"-crlhours") == 0)
447 if (--argc < 1) goto bad;
448 crlhours= atol(*(++argv));
450 else if (strcmp(*argv,"-infiles") == 0)
457 else if (strcmp(*argv, "-ss_cert") == 0)
459 if (--argc < 1) goto bad;
460 ss_cert_file = *(++argv);
463 else if (strcmp(*argv, "-spkac") == 0)
465 if (--argc < 1) goto bad;
466 spkac_file = *(++argv);
469 else if (strcmp(*argv,"-revoke") == 0)
471 if (--argc < 1) goto bad;
475 else if (strcmp(*argv,"-extensions") == 0)
477 if (--argc < 1) goto bad;
478 extensions= *(++argv);
480 else if (strcmp(*argv,"-extfile") == 0)
482 if (--argc < 1) goto bad;
485 else if (strcmp(*argv,"-status") == 0)
487 if (--argc < 1) goto bad;
488 ser_status= *(++argv);
490 else if (strcmp(*argv,"-updatedb") == 0)
494 else if (strcmp(*argv,"-crlexts") == 0)
496 if (--argc < 1) goto bad;
499 else if (strcmp(*argv,"-crl_reason") == 0)
501 if (--argc < 1) goto bad;
503 rev_type = REV_CRL_REASON;
505 else if (strcmp(*argv,"-crl_hold") == 0)
507 if (--argc < 1) goto bad;
511 else if (strcmp(*argv,"-crl_compromise") == 0)
513 if (--argc < 1) goto bad;
515 rev_type = REV_KEY_COMPROMISE;
517 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
519 if (--argc < 1) goto bad;
521 rev_type = REV_CA_COMPROMISE;
523 #ifndef OPENSSL_NO_ENGINE
524 else if (strcmp(*argv,"-engine") == 0)
526 if (--argc < 1) goto bad;
533 BIO_printf(bio_err,"unknown option %s\n",*argv);
543 for (pp=ca_usage; (*pp != NULL); pp++)
544 BIO_printf(bio_err,"%s",*pp);
548 ERR_load_crypto_strings();
550 #ifndef OPENSSL_NO_ENGINE
551 e = setup_engine(bio_err, engine, 0);
554 /*****************************************************************/
556 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
557 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
558 if (configfile == NULL)
560 const char *s=X509_get_default_cert_area();
563 #ifdef OPENSSL_SYS_VMS
564 len = strlen(s)+sizeof(CONFIG_FILE);
565 tofree=OPENSSL_malloc(len);
568 len = strlen(s)+sizeof(CONFIG_FILE)+1;
569 tofree=OPENSSL_malloc(len);
570 BUF_strlcpy(tofree,s,len);
571 BUF_strlcat(tofree,"/",len);
573 BUF_strlcat(tofree,CONFIG_FILE,len);
577 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
578 conf = NCONF_new(NULL);
579 if (NCONF_load(conf,configfile,&errorline) <= 0)
582 BIO_printf(bio_err,"error loading the config file '%s'\n",
585 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
586 ,errorline,configfile);
591 OPENSSL_free(tofree);
595 if (!load_config(bio_err, conf))
598 /* Lets get the config section we are using */
601 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
604 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
611 p=NCONF_get_string(conf,NULL,"oid_file");
618 oid_bio=BIO_new_file(p,"r");
622 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
623 ERR_print_errors(bio_err);
629 OBJ_create_objects(oid_bio);
633 if (!add_oid_section(bio_err,conf))
635 ERR_print_errors(bio_err);
640 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
641 if (randfile == NULL)
643 app_RAND_load_file(randfile, bio_err, 0);
645 db_attr.unique_subject = 1;
646 p = NCONF_get_string(conf, section, "unique_subject");
650 BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
654 case 'f': /* false */
655 case 'F': /* FALSE */
658 db_attr.unique_subject = 0;
665 db_attr.unique_subject = 1;
671 BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
674 BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
675 db_attr.unique_subject);
678 in=BIO_new(BIO_s_file());
679 out=BIO_new(BIO_s_file());
680 Sout=BIO_new(BIO_s_file());
681 Cout=BIO_new(BIO_s_file());
682 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
684 ERR_print_errors(bio_err);
688 /*****************************************************************/
689 /* report status of cert with serial number given on command line */
692 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
694 lookup_fail(section,ENV_DATABASE);
697 db = load_index(dbfile,&db_attr);
698 if (db == NULL) goto err;
700 if (!index_index(db)) goto err;
702 if (get_certificate_status(ser_status,db) != 1)
703 BIO_printf(bio_err,"Error verifying serial %s!\n",
708 /*****************************************************************/
709 /* we definitely need a public key, so let's get it */
711 if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
712 section,ENV_PRIVATE_KEY)) == NULL))
714 lookup_fail(section,ENV_PRIVATE_KEY);
720 if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
722 BIO_printf(bio_err,"Error getting password\n");
726 pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
728 if (key) OPENSSL_cleanse(key,strlen(key));
731 /* load_key() has already printed an appropriate message */
735 /*****************************************************************/
736 /* we need a certificate */
737 if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
738 section,ENV_CERTIFICATE)) == NULL))
740 lookup_fail(section,ENV_CERTIFICATE);
743 x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
748 if (!X509_check_private_key(x509,pkey))
750 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
754 f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
757 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
759 f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
762 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
765 f=NCONF_get_string(conf,section,ENV_NAMEOPT);
769 if (!set_name_ex(&nameopt, f))
771 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
779 f=NCONF_get_string(conf,section,ENV_CERTOPT);
783 if (!set_cert_ex(&certopt, f))
785 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
793 f=NCONF_get_string(conf,section,ENV_EXTCOPY);
797 if (!set_ext_copy(&ext_copy, f))
799 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
806 /*****************************************************************/
807 /* lookup where to write new certificates */
808 if ((outdir == NULL) && (req))
812 if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
815 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
818 #ifndef OPENSSL_SYS_VMS
819 /* outdir is a directory spec, but access() for VMS demands a
820 filename. In any case, stat(), below, will catch the problem
821 if outdir is not a directory spec, and the fopen() or open()
822 will catch an error if there is no write access.
824 Presumably, this problem could also be solved by using the DEC
825 C routines to convert the directory syntax to Unixly, and give
826 that to access(). However, time's too short to do that just
829 if (access(outdir,R_OK|W_OK|X_OK) != 0)
831 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
836 if (stat(outdir,&sb) != 0)
838 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
843 if (!(sb.st_mode & S_IFDIR))
845 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
853 /*****************************************************************/
854 /* we need to load the database file */
855 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
857 lookup_fail(section,ENV_DATABASE);
860 db = load_index(dbfile, &db_attr);
861 if (db == NULL) goto err;
863 /* Lets check some fields */
864 for (i=0; i<sk_num(db->db->data); i++)
866 pp=(char **)sk_value(db->db->data,i);
867 if ((pp[DB_type][0] != DB_TYPE_REV) &&
868 (pp[DB_rev_date][0] != '\0'))
870 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
873 if ((pp[DB_type][0] == DB_TYPE_REV) &&
874 !make_revoked(NULL, pp[DB_rev_date]))
876 BIO_printf(bio_err," in entry %d\n", i+1);
879 if (!check_time_format(pp[DB_exp_date]))
881 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
891 if ((j&1) || (j < 2))
893 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
898 if (!( ((*p >= '0') && (*p <= '9')) ||
899 ((*p >= 'A') && (*p <= 'F')) ||
900 ((*p >= 'a') && (*p <= 'f'))) )
902 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);
910 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
911 #ifdef OPENSSL_SYS_VMS
913 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
914 out = BIO_push(tmpbio, out);
917 TXT_DB_write(out,db->db);
918 BIO_printf(bio_err,"%d entries loaded from the database\n",
920 BIO_printf(bio_err,"generating index\n");
923 if (!index_index(db)) goto err;
925 /*****************************************************************/
926 /* Update the db file for expired certificates */
930 BIO_printf(bio_err, "Updating %s ...\n",
936 BIO_printf(bio_err,"Malloc failure\n");
941 if (verbose) BIO_printf(bio_err,
942 "No entries found to mark expired\n");
946 if (!save_index(dbfile,"new",db)) goto err;
948 if (!rotate_index(dbfile,"new","old")) goto err;
950 if (verbose) BIO_printf(bio_err,
951 "Done. %d entries marked as expired\n",i);
956 /*****************************************************************/
957 /* Read extentions config file */
960 extconf = NCONF_new(NULL);
961 if (NCONF_load(extconf,extfile,&errorline) <= 0)
964 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
967 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
974 BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
976 /* We can have sections in the ext file */
977 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
978 extensions = "default";
981 /*****************************************************************/
986 if (BIO_write_filename(Sout,outfile) <= 0)
994 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
995 #ifdef OPENSSL_SYS_VMS
997 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
998 Sout = BIO_push(tmpbio, Sout);
1006 if ((md == NULL) && ((md=NCONF_get_string(conf,
1007 section,ENV_DEFAULT_MD)) == NULL))
1009 lookup_fail(section,ENV_DEFAULT_MD);
1012 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1013 section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1015 if(strcmp(tmp_email_dn,"no") == 0)
1018 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1020 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1024 BIO_printf(bio_err,"message digest is %s\n",
1025 OBJ_nid2ln(dgst->type));
1026 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1027 section,ENV_POLICY)) == NULL))
1029 lookup_fail(section,ENV_POLICY);
1033 BIO_printf(bio_err,"policy is %s\n",policy);
1035 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1038 lookup_fail(section,ENV_SERIAL);
1044 /* no '-extfile' option, so we look for extensions
1045 * in the main configuration file */
1048 extensions=NCONF_get_string(conf,section,
1055 /* Check syntax of file */
1057 X509V3_set_ctx_test(&ctx);
1058 X509V3_set_nconf(&ctx, conf);
1059 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1063 "Error Loading extension section %s\n",
1071 if (startdate == NULL)
1073 startdate=NCONF_get_string(conf,section,
1074 ENV_DEFAULT_STARTDATE);
1075 if (startdate == NULL)
1078 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1080 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1083 if (startdate == NULL) startdate="today";
1085 if (enddate == NULL)
1087 enddate=NCONF_get_string(conf,section,
1088 ENV_DEFAULT_ENDDATE);
1089 if (enddate == NULL)
1092 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1094 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1100 if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1103 if (!enddate && (days == 0))
1105 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1109 if ((serial=load_serial(serialfile, 0, NULL)) == NULL)
1111 BIO_printf(bio_err,"error while loading serial number\n");
1116 if (BN_is_zero(serial))
1117 BIO_printf(bio_err,"next serial number is 00\n");
1120 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1121 BIO_printf(bio_err,"next serial number is %s\n",f);
1126 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1128 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1132 if ((cert_sk=sk_X509_new_null()) == NULL)
1134 BIO_printf(bio_err,"Memory allocation failure\n");
1137 if (spkac_file != NULL)
1140 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1141 serial,subj,email_dn,startdate,enddate,days,extensions,
1142 conf,verbose,certopt,nameopt,default_op,ext_copy);
1143 if (j < 0) goto err;
1147 BIO_printf(bio_err,"\n");
1148 if (!BN_add_word(serial,1)) goto err;
1149 if (!sk_X509_push(cert_sk,x))
1151 BIO_printf(bio_err,"Memory allocation failure\n");
1161 if (ss_cert_file != NULL)
1164 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1165 db,serial,subj,email_dn,startdate,enddate,days,batch,
1166 extensions,conf,verbose, certopt, nameopt,
1167 default_op, ext_copy, e);
1168 if (j < 0) goto err;
1172 BIO_printf(bio_err,"\n");
1173 if (!BN_add_word(serial,1)) goto err;
1174 if (!sk_X509_push(cert_sk,x))
1176 BIO_printf(bio_err,"Memory allocation failure\n");
1184 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1185 serial,subj,email_dn,startdate,enddate,days,batch,
1186 extensions,conf,verbose, certopt, nameopt,
1187 default_op, ext_copy);
1188 if (j < 0) goto err;
1192 BIO_printf(bio_err,"\n");
1193 if (!BN_add_word(serial,1)) goto err;
1194 if (!sk_X509_push(cert_sk,x))
1196 BIO_printf(bio_err,"Memory allocation failure\n");
1201 for (i=0; i<argc; i++)
1204 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1205 serial,subj,email_dn,startdate,enddate,days,batch,
1206 extensions,conf,verbose, certopt, nameopt,
1207 default_op, ext_copy);
1208 if (j < 0) goto err;
1212 BIO_printf(bio_err,"\n");
1213 if (!BN_add_word(serial,1)) goto err;
1214 if (!sk_X509_push(cert_sk,x))
1216 BIO_printf(bio_err,"Memory allocation failure\n");
1221 /* we have a stack of newly certified certificates
1222 * and a data base and serial number that need
1225 if (sk_X509_num(cert_sk) > 0)
1229 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1230 (void)BIO_flush(bio_err);
1232 fgets(buf[0],10,stdin);
1233 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1235 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1241 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1243 if (!save_serial(serialfile,"new",serial,NULL)) goto err;
1245 if (!save_index(dbfile, "new", db)) goto err;
1249 BIO_printf(bio_err,"writing new certificates\n");
1250 for (i=0; i<sk_X509_num(cert_sk); i++)
1255 x=sk_X509_value(cert_sk,i);
1257 j=x->cert_info->serialNumber->length;
1258 p=(char *)x->cert_info->serialNumber->data;
1260 if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1262 BIO_printf(bio_err,"certificate file name too long\n");
1266 strcpy(buf[2],outdir);
1268 #ifndef OPENSSL_SYS_VMS
1269 BUF_strlcat(buf[2],"/",sizeof(buf[2]));
1272 n=(char *)&(buf[2][strlen(buf[2])]);
1277 if (n >= &(buf[2][sizeof(buf[2])]))
1280 &buf[2][0] + sizeof(buf[2]) - n,
1281 "%02X",(unsigned char)*(p++));
1290 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1293 BIO_printf(bio_err,"writing %s\n",buf[2]);
1295 if (BIO_write_filename(Cout,buf[2]) <= 0)
1300 write_new_certificate(Cout,x, 0, notext);
1301 write_new_certificate(Sout,x, output_der, notext);
1304 if (sk_X509_num(cert_sk))
1306 /* Rename the database and the serial file */
1307 if (!rotate_serial(serialfile,"new","old")) goto err;
1309 if (!rotate_index(dbfile,"new","old")) goto err;
1311 BIO_printf(bio_err,"Data Base Updated\n");
1315 /*****************************************************************/
1321 crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1327 /* Check syntax of file */
1329 X509V3_set_ctx_test(&ctx);
1330 X509V3_set_nconf(&ctx, conf);
1331 if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1334 "Error Loading CRL extension section %s\n",
1341 if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER))
1343 if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL)
1345 BIO_printf(bio_err,"error while loading CRL number\n");
1349 if (!crldays && !crlhours)
1351 if (!NCONF_get_number(conf,section,
1352 ENV_DEFAULT_CRL_DAYS, &crldays))
1354 if (!NCONF_get_number(conf,section,
1355 ENV_DEFAULT_CRL_HOURS, &crlhours))
1358 if ((crldays == 0) && (crlhours == 0))
1360 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1364 if (verbose) BIO_printf(bio_err,"making CRL\n");
1365 if ((crl=X509_CRL_new()) == NULL) goto err;
1366 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1368 tmptm = ASN1_TIME_new();
1369 if (!tmptm) goto err;
1370 X509_gmtime_adj(tmptm,0);
1371 X509_CRL_set_lastUpdate(crl, tmptm);
1372 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1373 X509_CRL_set_nextUpdate(crl, tmptm);
1375 ASN1_TIME_free(tmptm);
1377 for (i=0; i<sk_num(db->db->data); i++)
1379 pp=(char **)sk_value(db->db->data,i);
1380 if (pp[DB_type][0] == DB_TYPE_REV)
1382 if ((r=X509_REVOKED_new()) == NULL) goto err;
1383 j = make_revoked(r, pp[DB_rev_date]);
1385 if (j == 2) crl_v2 = 1;
1386 if (!BN_hex2bn(&serial, pp[DB_serial]))
1388 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1393 X509_REVOKED_set_serialNumber(r, tmpser);
1394 ASN1_INTEGER_free(tmpser);
1395 X509_CRL_add0_revoked(crl,r);
1399 /* sort the data so it will be written in serial
1403 /* we now have a CRL */
1404 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1407 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1409 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1415 #ifndef OPENSSL_NO_DSA
1416 if (pkey->type == EVP_PKEY_DSA)
1423 /* Add any extensions asked for */
1425 if (crl_ext || crlnumberfile != NULL)
1428 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1429 X509V3_set_nconf(&crlctx, conf);
1432 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1433 crl_ext, crl)) goto err;
1434 if (crlnumberfile != NULL)
1436 tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
1437 if (!tmpser) goto err;
1438 X509_CRL_add1_ext_i2d(crl,NID_crl_number,tmpser,0,0);
1439 ASN1_INTEGER_free(tmpser);
1441 if (!BN_add_word(crlnumber,1)) goto err;
1444 if (crl_ext || crl_v2)
1446 if (!X509_CRL_set_version(crl, 1))
1447 goto err; /* version 2 CRL */
1451 if (crlnumberfile != NULL) /* we have a CRL number that need updating */
1452 if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
1454 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1456 PEM_write_bio_X509_CRL(Sout,crl);
1458 if (crlnumberfile != NULL) /* Rename the crlnumber file */
1459 if (!rotate_serial(crlnumberfile,"new","old")) goto err;
1462 /*****************************************************************/
1467 BIO_printf(bio_err,"no input files\n");
1473 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1475 if (revcert == NULL)
1477 j=do_revoke(revcert,db, rev_type, rev_arg);
1478 if (j <= 0) goto err;
1481 if (!save_index(dbfile, "new", db)) goto err;
1483 if (!rotate_index(dbfile, "new", "old")) goto err;
1485 BIO_printf(bio_err,"Data Base Updated\n");
1488 /*****************************************************************/
1492 OPENSSL_free(tofree);
1499 sk_X509_pop_free(cert_sk,X509_free);
1501 if (ret) ERR_print_errors(bio_err);
1502 app_RAND_write_file(randfile, bio_err);
1503 if (free_key && key)
1507 EVP_PKEY_free(pkey);
1516 static void lookup_fail(char *name, char *tag)
1518 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1521 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1522 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1523 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1524 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1525 unsigned long certopt, unsigned long nameopt, int default_op,
1530 EVP_PKEY *pktmp=NULL;
1533 in=BIO_new(BIO_s_file());
1535 if (BIO_read_filename(in,infile) <= 0)
1540 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1542 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1547 X509_REQ_print(bio_err,req);
1549 BIO_printf(bio_err,"Check that the request matches the signature\n");
1551 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1553 BIO_printf(bio_err,"error unpacking public key\n");
1556 i=X509_REQ_verify(req,pktmp);
1557 EVP_PKEY_free(pktmp);
1561 BIO_printf(bio_err,"Signature verification problems....\n");
1567 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1571 BIO_printf(bio_err,"Signature ok\n");
1573 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1574 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1575 certopt, nameopt, default_op, ext_copy);
1578 if (req != NULL) X509_REQ_free(req);
1579 if (in != NULL) BIO_free(in);
1583 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1584 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1585 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1586 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1587 unsigned long certopt, unsigned long nameopt, int default_op,
1588 int ext_copy, ENGINE *e)
1591 X509_REQ *rreq=NULL;
1592 EVP_PKEY *pktmp=NULL;
1595 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1598 X509_print(bio_err,req);
1600 BIO_printf(bio_err,"Check that the request matches the signature\n");
1602 if ((pktmp=X509_get_pubkey(req)) == NULL)
1604 BIO_printf(bio_err,"error unpacking public key\n");
1607 i=X509_verify(req,pktmp);
1608 EVP_PKEY_free(pktmp);
1612 BIO_printf(bio_err,"Signature verification problems....\n");
1618 BIO_printf(bio_err,"Signature did not match the certificate\n");
1622 BIO_printf(bio_err,"Signature ok\n");
1624 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1627 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1628 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1632 if (rreq != NULL) X509_REQ_free(rreq);
1633 if (req != NULL) X509_free(req);
1637 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1638 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1639 int email_dn, char *startdate, char *enddate, long days, int batch,
1640 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1641 unsigned long certopt, unsigned long nameopt, int default_op,
1644 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1645 ASN1_UTCTIME *tm,*tmptm;
1646 ASN1_STRING *str,*str2;
1650 X509_NAME_ENTRY *ne;
1651 X509_NAME_ENTRY *tne,*push;
1653 int ok= -1,i,j,last,nid;
1656 char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
1659 tmptm=ASN1_UTCTIME_new();
1662 BIO_printf(bio_err,"malloc error\n");
1666 for (i=0; i<DB_NUMBER; i++)
1671 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1675 ERR_print_errors(bio_err);
1678 X509_REQ_set_subject_name(req,n);
1679 req->req_info->enc.modified = 1;
1684 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1686 name=X509_REQ_get_subject_name(req);
1687 for (i=0; i<X509_NAME_entry_count(name); i++)
1689 ne= X509_NAME_get_entry(name,i);
1690 str=X509_NAME_ENTRY_get_data(ne);
1691 obj=X509_NAME_ENTRY_get_object(ne);
1695 /* assume all type should be strings */
1696 nid=OBJ_obj2nid(ne->object);
1698 if (str->type == V_ASN1_UNIVERSALSTRING)
1699 ASN1_UNIVERSALSTRING_to_string(str);
1701 if ((str->type == V_ASN1_IA5STRING) &&
1702 (nid != NID_pkcs9_emailAddress))
1703 str->type=V_ASN1_T61STRING;
1705 if ((nid == NID_pkcs9_emailAddress) &&
1706 (str->type == V_ASN1_PRINTABLESTRING))
1707 str->type=V_ASN1_IA5STRING;
1710 /* If no EMAIL is wanted in the subject */
1711 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1714 /* check some things */
1715 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1716 (str->type != V_ASN1_IA5STRING))
1718 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1721 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1723 j=ASN1_PRINTABLE_type(str->data,str->length);
1724 if ( ((j == V_ASN1_T61STRING) &&
1725 (str->type != V_ASN1_T61STRING)) ||
1726 ((j == V_ASN1_IA5STRING) &&
1727 (str->type == V_ASN1_PRINTABLESTRING)))
1729 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1735 old_entry_print(bio_err, obj, str);
1738 /* Ok, now we check the 'policy' stuff. */
1739 if ((subject=X509_NAME_new()) == NULL)
1741 BIO_printf(bio_err,"Memory allocation failure\n");
1745 /* take a copy of the issuer name before we mess with it. */
1746 CAname=X509_NAME_dup(x509->cert_info->subject);
1747 if (CAname == NULL) goto err;
1750 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1752 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1753 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1755 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1763 /* lookup the object in the supplied name list */
1764 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1767 if (last != -1) break;
1772 tne=X509_NAME_get_entry(name,j);
1776 /* depending on the 'policy', decide what to do. */
1778 if (strcmp(cv->value,"optional") == 0)
1783 else if (strcmp(cv->value,"supplied") == 0)
1787 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1793 else if (strcmp(cv->value,"match") == 0)
1799 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1806 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1807 if ((j < 0) && (last2 == -1))
1809 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1814 push=X509_NAME_get_entry(CAname,j);
1815 str=X509_NAME_ENTRY_get_data(tne);
1816 str2=X509_NAME_ENTRY_get_data(push);
1818 if (ASN1_STRING_cmp(str,str2) != 0)
1823 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));
1829 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1835 if (!X509_NAME_add_entry(subject,push, -1, 0))
1838 X509_NAME_ENTRY_free(push);
1839 BIO_printf(bio_err,"Memory allocation failure\n");
1849 X509_NAME_free(subject);
1850 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1851 subject=X509_NAME_dup(name);
1852 if (subject == NULL) goto err;
1856 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1858 /* Build the correct Subject if no e-mail is wanted in the subject */
1859 /* and add it later on because of the method extensions are added (altName) */
1862 dn_subject = subject;
1865 X509_NAME_ENTRY *tmpne;
1866 /* Its best to dup the subject DN and then delete any email
1867 * addresses because this retains its structure.
1869 if (!(dn_subject = X509_NAME_dup(subject)))
1871 BIO_printf(bio_err,"Memory allocation failure\n");
1874 while((i = X509_NAME_get_index_by_NID(dn_subject,
1875 NID_pkcs9_emailAddress, -1)) >= 0)
1877 tmpne = X509_NAME_get_entry(dn_subject, i);
1878 X509_NAME_delete_entry(dn_subject, i);
1879 X509_NAME_ENTRY_free(tmpne);
1883 if (BN_is_zero(serial))
1884 row[DB_serial]=BUF_strdup("00");
1886 row[DB_serial]=BN_bn2hex(serial);
1887 if (row[DB_serial] == NULL)
1889 BIO_printf(bio_err,"Memory allocation failure\n");
1893 if (db->attributes.unique_subject)
1895 rrow=TXT_DB_get_by_index(db->db,DB_name,row);
1899 "ERROR:There is already a certificate for %s\n",
1905 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1908 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1910 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1917 "The matching entry has the following details\n");
1918 if (rrow[DB_type][0] == 'E')
1920 else if (rrow[DB_type][0] == 'R')
1922 else if (rrow[DB_type][0] == 'V')
1925 p="\ninvalid type, Data base error\n";
1926 BIO_printf(bio_err,"Type :%s\n",p);;
1927 if (rrow[DB_type][0] == 'R')
1929 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1930 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1932 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1933 BIO_printf(bio_err,"Expires on :%s\n",p);
1934 p=rrow[DB_serial]; if (p == NULL) p="undef";
1935 BIO_printf(bio_err,"Serial Number :%s\n",p);
1936 p=rrow[DB_file]; if (p == NULL) p="undef";
1937 BIO_printf(bio_err,"File name :%s\n",p);
1938 p=rrow[DB_name]; if (p == NULL) p="undef";
1939 BIO_printf(bio_err,"Subject Name :%s\n",p);
1940 ok= -1; /* This is now a 'bad' error. */
1944 /* We are now totally happy, lets make and sign the certificate */
1946 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1948 if ((ret=X509_new()) == NULL) goto err;
1952 /* Make it an X509 v3 certificate. */
1953 if (!X509_set_version(ret,2)) goto err;
1956 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1958 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1961 if (strcmp(startdate,"today") == 0)
1962 X509_gmtime_adj(X509_get_notBefore(ret),0);
1963 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1965 if (enddate == NULL)
1966 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1967 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1969 if (!X509_set_subject_name(ret,subject)) goto err;
1971 pktmp=X509_REQ_get_pubkey(req);
1972 i = X509_set_pubkey(ret,pktmp);
1973 EVP_PKEY_free(pktmp);
1976 /* Lets add the extensions, if there are any */
1980 if (ci->version == NULL)
1981 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1983 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1985 /* Free the current entries if any, there should not
1986 * be any I believe */
1987 if (ci->extensions != NULL)
1988 sk_X509_EXTENSION_pop_free(ci->extensions,
1989 X509_EXTENSION_free);
1991 ci->extensions = NULL;
1993 /* Initialize the context structure */
1994 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1999 BIO_printf(bio_err, "Extra configuration file found\n");
2001 /* Use the extconf configuration db LHASH */
2002 X509V3_set_nconf(&ctx, extconf);
2004 /* Test the structure (needed?) */
2005 /* X509V3_set_ctx_test(&ctx); */
2007 /* Adds exts contained in the configuration file */
2008 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2011 "ERROR: adding extensions in section %s\n",
2013 ERR_print_errors(bio_err);
2017 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2021 /* We found extensions to be set from config file */
2022 X509V3_set_nconf(&ctx, lconf);
2024 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2026 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2027 ERR_print_errors(bio_err);
2032 BIO_printf(bio_err, "Successfully added extensions from config\n");
2036 /* Copy extensions from request (if any) */
2038 if (!copy_extensions(ret, req, ext_copy))
2040 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2041 ERR_print_errors(bio_err);
2045 /* Set the right value for the noemailDN option */
2048 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2053 BIO_printf(bio_err, "Certificate Details:\n");
2054 /* Never print signature details because signature not present */
2055 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2056 X509_print_ex(bio_err, ret, nameopt, certopt);
2059 BIO_printf(bio_err,"Certificate is to be certified until ");
2060 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2061 if (days) BIO_printf(bio_err," (%d days)",days);
2062 BIO_printf(bio_err, "\n");
2067 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2068 (void)BIO_flush(bio_err);
2070 fgets(buf,sizeof(buf)-1,stdin);
2071 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2073 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2080 #ifndef OPENSSL_NO_DSA
2081 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2082 pktmp=X509_get_pubkey(ret);
2083 if (EVP_PKEY_missing_parameters(pktmp) &&
2084 !EVP_PKEY_missing_parameters(pkey))
2085 EVP_PKEY_copy_parameters(pktmp,pkey);
2086 EVP_PKEY_free(pktmp);
2089 if (!X509_sign(ret,pkey,dgst))
2092 /* We now just add it to the database */
2093 row[DB_type]=(char *)OPENSSL_malloc(2);
2095 tm=X509_get_notAfter(ret);
2096 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2097 memcpy(row[DB_exp_date],tm->data,tm->length);
2098 row[DB_exp_date][tm->length]='\0';
2100 row[DB_rev_date]=NULL;
2102 /* row[DB_serial] done already */
2103 row[DB_file]=(char *)OPENSSL_malloc(8);
2104 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2106 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2107 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2109 BIO_printf(bio_err,"Memory allocation failure\n");
2112 BUF_strlcpy(row[DB_file],"unknown",8);
2113 row[DB_type][0]='V';
2114 row[DB_type][1]='\0';
2116 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2118 BIO_printf(bio_err,"Memory allocation failure\n");
2122 for (i=0; i<DB_NUMBER; i++)
2127 irow[DB_NUMBER]=NULL;
2129 if (!TXT_DB_insert(db->db,irow))
2131 BIO_printf(bio_err,"failed to update database\n");
2132 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2137 for (i=0; i<DB_NUMBER; i++)
2138 if (row[i] != NULL) OPENSSL_free(row[i]);
2141 X509_NAME_free(CAname);
2142 if (subject != NULL)
2143 X509_NAME_free(subject);
2144 if ((dn_subject != NULL) && !email_dn)
2145 X509_NAME_free(dn_subject);
2147 ASN1_UTCTIME_free(tmptm);
2150 if (ret != NULL) X509_free(ret);
2158 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2163 (void)i2d_X509_bio(bp,x);
2167 /* ??? Not needed since X509_print prints all this stuff anyway */
2168 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2169 BIO_printf(bp,"issuer :%s\n",f);
2171 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2172 BIO_printf(bp,"subject:%s\n",f);
2174 BIO_puts(bp,"serial :");
2175 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2176 BIO_puts(bp,"\n\n");
2178 if (!notext)X509_print(bp,x);
2179 PEM_write_bio_X509(bp,x);
2182 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2183 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2184 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2185 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2186 unsigned long nameopt, int default_op, int ext_copy)
2188 STACK_OF(CONF_VALUE) *sk=NULL;
2191 CONF_VALUE *cv=NULL;
2192 NETSCAPE_SPKI *spki = NULL;
2195 EVP_PKEY *pktmp=NULL;
2197 X509_NAME_ENTRY *ne=NULL;
2203 * Load input file into a hash table. (This is just an easy
2204 * way to read and parse the file, then put it into a convenient
2207 parms=CONF_load(NULL,infile,&errline);
2210 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2211 ERR_print_errors(bio_err);
2215 sk=CONF_get_section(parms, "default");
2216 if (sk_CONF_VALUE_num(sk) == 0)
2218 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2224 * Now create a dummy X509 request structure. We don't actually
2225 * have an X509 request, but we have many of the components
2226 * (a public key, various DN components). The idea is that we
2227 * put these components into the right X509 request structure
2228 * and we can use the same code as if you had a real X509 request.
2233 ERR_print_errors(bio_err);
2238 * Build up the subject name set.
2245 if (sk_CONF_VALUE_num(sk) <= i) break;
2247 cv=sk_CONF_VALUE_value(sk,i);
2249 /* Skip past any leading X. X: X, etc to allow for
2250 * multiple instances
2252 for (buf = cv->name; *buf ; buf++)
2253 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2256 if (*buf) type = buf;
2261 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2263 if (strcmp(type, "SPKAC") == 0)
2265 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2268 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2269 ERR_print_errors(bio_err);
2277 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2281 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2282 if (fix_data(nid, &j) == 0)
2285 "invalid characters in string %s\n",buf);
2289 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2290 (unsigned char *)buf,
2291 strlen(buf))) == NULL)
2294 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2298 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2304 * Now extract the key from the SPKI structure.
2307 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2309 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2311 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2315 j = NETSCAPE_SPKI_verify(spki, pktmp);
2318 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2321 BIO_printf(bio_err,"Signature ok\n");
2323 X509_REQ_set_pubkey(req,pktmp);
2324 EVP_PKEY_free(pktmp);
2325 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2326 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2329 if (req != NULL) X509_REQ_free(req);
2330 if (parms != NULL) CONF_free(parms);
2331 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2332 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2337 static int fix_data(int nid, int *type)
2339 if (nid == NID_pkcs9_emailAddress)
2340 *type=V_ASN1_IA5STRING;
2341 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2342 *type=V_ASN1_T61STRING;
2343 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2344 *type=V_ASN1_T61STRING;
2345 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2347 if (nid == NID_pkcs9_unstructuredName)
2348 *type=V_ASN1_IA5STRING;
2352 static int check_time_format(char *str)
2356 tm.data=(unsigned char *)str;
2357 tm.length=strlen(str);
2358 tm.type=V_ASN1_UTCTIME;
2359 return(ASN1_UTCTIME_check(&tm));
2362 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2364 ASN1_UTCTIME *tm=NULL;
2365 char *row[DB_NUMBER],**rrow,**irow;
2366 char *rev_str = NULL;
2370 for (i=0; i<DB_NUMBER; i++)
2372 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2373 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2375 row[DB_serial]=BUF_strdup("00");
2377 row[DB_serial]=BN_bn2hex(bn);
2379 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2381 BIO_printf(bio_err,"Memory allocation failure\n");
2384 /* We have to lookup by serial number because name lookup
2385 * skips revoked certs
2387 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2390 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2392 /* We now just add it to the database */
2393 row[DB_type]=(char *)OPENSSL_malloc(2);
2395 tm=X509_get_notAfter(x509);
2396 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2397 memcpy(row[DB_exp_date],tm->data,tm->length);
2398 row[DB_exp_date][tm->length]='\0';
2400 row[DB_rev_date]=NULL;
2402 /* row[DB_serial] done already */
2403 row[DB_file]=(char *)OPENSSL_malloc(8);
2405 /* row[DB_name] done already */
2407 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2408 (row[DB_file] == NULL))
2410 BIO_printf(bio_err,"Memory allocation failure\n");
2413 BUF_strlcpy(row[DB_file],"unknown",8);
2414 row[DB_type][0]='V';
2415 row[DB_type][1]='\0';
2417 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2419 BIO_printf(bio_err,"Memory allocation failure\n");
2423 for (i=0; i<DB_NUMBER; i++)
2428 irow[DB_NUMBER]=NULL;
2430 if (!TXT_DB_insert(db->db,irow))
2432 BIO_printf(bio_err,"failed to update database\n");
2433 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2437 /* Revoke Certificate */
2438 ok = do_revoke(x509,db, type, value);
2443 else if (index_name_cmp((const char **)row,(const char **)rrow))
2445 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2449 else if (rrow[DB_type][0]=='R')
2451 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2457 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2458 rev_str = make_revocation_str(type, value);
2461 BIO_printf(bio_err, "Error in revocation arguments\n");
2464 rrow[DB_type][0]='R';
2465 rrow[DB_type][1]='\0';
2466 rrow[DB_rev_date] = rev_str;
2470 for (i=0; i<DB_NUMBER; i++)
2473 OPENSSL_free(row[i]);
2478 static int get_certificate_status(const char *serial, CA_DB *db)
2480 char *row[DB_NUMBER],**rrow;
2483 /* Free Resources */
2484 for (i=0; i<DB_NUMBER; i++)
2487 /* Malloc needed char spaces */
2488 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2489 if (row[DB_serial] == NULL)
2491 BIO_printf(bio_err,"Malloc failure\n");
2495 if (strlen(serial) % 2)
2497 /* Set the first char to 0 */;
2498 row[DB_serial][0]='0';
2500 /* Copy String from serial to row[DB_serial] */
2501 memcpy(row[DB_serial]+1, serial, strlen(serial));
2502 row[DB_serial][strlen(serial)+1]='\0';
2506 /* Copy String from serial to row[DB_serial] */
2507 memcpy(row[DB_serial], serial, strlen(serial));
2508 row[DB_serial][strlen(serial)]='\0';
2511 /* Make it Upper Case */
2512 for (i=0; row[DB_serial][i] != '\0'; i++)
2513 row[DB_serial][i] = toupper(row[DB_serial][i]);
2518 /* Search for the certificate */
2519 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2522 BIO_printf(bio_err,"Serial %s not present in db.\n",
2527 else if (rrow[DB_type][0]=='V')
2529 BIO_printf(bio_err,"%s=Valid (%c)\n",
2530 row[DB_serial], rrow[DB_type][0]);
2533 else if (rrow[DB_type][0]=='R')
2535 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2536 row[DB_serial], rrow[DB_type][0]);
2539 else if (rrow[DB_type][0]=='E')
2541 BIO_printf(bio_err,"%s=Expired (%c)\n",
2542 row[DB_serial], rrow[DB_type][0]);
2545 else if (rrow[DB_type][0]=='S')
2547 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2548 row[DB_serial], rrow[DB_type][0]);
2553 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2554 row[DB_serial], rrow[DB_type][0]);
2558 for (i=0; i<DB_NUMBER; i++)
2561 OPENSSL_free(row[i]);
2566 static int do_updatedb (CA_DB *db)
2568 ASN1_UTCTIME *a_tm = NULL;
2570 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2571 char **rrow, *a_tm_s;
2573 a_tm = ASN1_UTCTIME_new();
2575 /* get actual time and make a string */
2576 a_tm = X509_gmtime_adj(a_tm, 0);
2577 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2584 memcpy(a_tm_s, a_tm->data, a_tm->length);
2585 a_tm_s[a_tm->length] = '\0';
2587 if (strncmp(a_tm_s, "49", 2) <= 0)
2592 for (i = 0; i < sk_num(db->db->data); i++)
2594 rrow = (char **) sk_value(db->db->data, i);
2596 if (rrow[DB_type][0] == 'V')
2598 /* ignore entries that are not valid */
2599 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2604 if (db_y2k == a_y2k)
2606 /* all on the same y2k side */
2607 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2609 rrow[DB_type][0] = 'E';
2610 rrow[DB_type][1] = '\0';
2613 BIO_printf(bio_err, "%s=Expired\n",
2617 else if (db_y2k < a_y2k)
2619 rrow[DB_type][0] = 'E';
2620 rrow[DB_type][1] = '\0';
2623 BIO_printf(bio_err, "%s=Expired\n",
2632 ASN1_UTCTIME_free(a_tm);
2633 OPENSSL_free(a_tm_s);
2638 static char *crl_reasons[] = {
2639 /* CRL reason strings */
2643 "affiliationChanged",
2645 "cessationOfOperation",
2648 /* Additional pseudo reasons */
2654 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2656 /* Given revocation information convert to a DB string.
2657 * The format of the string is:
2658 * revtime[,reason,extra]. Where 'revtime' is the
2659 * revocation time (the current time). 'reason' is the
2660 * optional CRL reason and 'extra' is any additional
2664 char *make_revocation_str(int rev_type, char *rev_arg)
2666 char *reason = NULL, *other = NULL, *str;
2668 ASN1_UTCTIME *revtm = NULL;
2675 case REV_CRL_REASON:
2676 for (i = 0; i < 8; i++)
2678 if (!strcasecmp(rev_arg, crl_reasons[i]))
2680 reason = crl_reasons[i];
2686 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2692 /* Argument is an OID */
2694 otmp = OBJ_txt2obj(rev_arg, 0);
2695 ASN1_OBJECT_free(otmp);
2699 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2703 reason = "holdInstruction";
2707 case REV_KEY_COMPROMISE:
2708 case REV_CA_COMPROMISE:
2710 /* Argument is the key compromise time */
2711 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2713 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2717 if (rev_type == REV_KEY_COMPROMISE)
2720 reason = "CAkeyTime";
2726 revtm = X509_gmtime_adj(NULL, 0);
2728 i = revtm->length + 1;
2730 if (reason) i += strlen(reason) + 1;
2731 if (other) i += strlen(other) + 1;
2733 str = OPENSSL_malloc(i);
2735 if (!str) return NULL;
2737 BUF_strlcpy(str, (char *)revtm->data, i);
2740 BUF_strlcat(str, ",", i);
2741 BUF_strlcat(str, reason, i);
2745 BUF_strlcat(str, ",", i);
2746 BUF_strlcat(str, other, i);
2748 ASN1_UTCTIME_free(revtm);
2752 /* Convert revocation field to X509_REVOKED entry
2756 * 2 OK and some extensions added (i.e. V2 CRL)
2760 int make_revoked(X509_REVOKED *rev, char *str)
2763 int reason_code = -1;
2765 ASN1_OBJECT *hold = NULL;
2766 ASN1_GENERALIZEDTIME *comp_time = NULL;
2767 ASN1_ENUMERATED *rtmp = NULL;
2769 ASN1_TIME *revDate = NULL;
2771 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2776 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2779 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2781 rtmp = ASN1_ENUMERATED_new();
2782 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2784 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2788 if (rev && comp_time)
2790 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2795 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2799 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2805 if (tmp) OPENSSL_free(tmp);
2806 ASN1_OBJECT_free(hold);
2807 ASN1_GENERALIZEDTIME_free(comp_time);
2808 ASN1_ENUMERATED_free(rtmp);
2809 ASN1_TIME_free(revDate);
2815 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2816 * where characters may be escaped by \
2818 X509_NAME *do_subject(char *subject, long chtype)
2820 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2821 char *buf = OPENSSL_malloc(buflen);
2822 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2823 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2824 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2826 char *sp = subject, *bp = buf;
2829 X509_NAME *n = NULL;
2832 if (!buf || !ne_types || !ne_values)
2834 BIO_printf(bio_err, "malloc error\n");
2838 if (*subject != '/')
2840 BIO_printf(bio_err, "Subject does not start with '/'.\n");
2843 sp++; /* skip leading / */
2848 ne_types[ne_num] = bp;
2851 if (*sp == '\\') /* is there anything to escape in the type...? */
2857 BIO_printf(bio_err, "escape character at end of string\n");
2861 else if (*sp == '=')
2872 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2875 ne_values[ne_num] = bp;
2884 BIO_printf(bio_err, "escape character at end of string\n");
2888 else if (*sp == '/')
2900 if (!(n = X509_NAME_new()))
2903 for (i = 0; i < ne_num; i++)
2905 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2907 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2913 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2917 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
2921 OPENSSL_free(ne_values);
2922 OPENSSL_free(ne_types);
2929 OPENSSL_free(ne_values);
2931 OPENSSL_free(ne_types);
2937 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2939 char buf[25],*pbuf, *p;
2941 j=i2a_ASN1_OBJECT(bp,obj);
2943 for (j=22-j; j>0; j--)
2949 if (str->type == V_ASN1_PRINTABLESTRING)
2950 BIO_printf(bp,"PRINTABLE:'");
2951 else if (str->type == V_ASN1_T61STRING)
2952 BIO_printf(bp,"T61STRING:'");
2953 else if (str->type == V_ASN1_IA5STRING)
2954 BIO_printf(bp,"IA5STRING:'");
2955 else if (str->type == V_ASN1_UNIVERSALSTRING)
2956 BIO_printf(bp,"UNIVERSALSTRING:'");
2958 BIO_printf(bp,"ASN.1 %2d:'",str->type);
2960 p=(char *)str->data;
2961 for (j=str->length; j>0; j--)
2963 if ((*p >= ' ') && (*p <= '~'))
2964 BIO_printf(bp,"%c",*p);
2966 BIO_printf(bp,"\\0x%02X",*p);
2967 else if ((unsigned char)*p == 0xf7)
2968 BIO_printf(bp,"^?");
2969 else BIO_printf(bp,"^%c",*p+'@');
2972 BIO_printf(bp,"'\n");
2976 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
2979 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2980 int reason_code = -1;
2982 ASN1_OBJECT *hold = NULL;
2983 ASN1_GENERALIZEDTIME *comp_time = NULL;
2984 tmp = BUF_strdup(str);
2986 p = strchr(tmp, ',');
3005 *prevtm = ASN1_UTCTIME_new();
3006 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3008 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3014 for (i = 0; i < NUM_REASONS; i++)
3016 if(!strcasecmp(reason_str, crl_reasons[i]))
3022 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3024 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3028 if (reason_code == 7)
3029 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3030 else if (reason_code == 8) /* Hold instruction */
3034 BIO_printf(bio_err, "missing hold instruction\n");
3037 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3038 hold = OBJ_txt2obj(arg_str, 0);
3042 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3045 if (phold) *phold = hold;
3047 else if ((reason_code == 9) || (reason_code == 10))
3051 BIO_printf(bio_err, "missing compromised time\n");
3054 comp_time = ASN1_GENERALIZEDTIME_new();
3055 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3057 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3060 if (reason_code == 9)
3061 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3063 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3067 if (preason) *preason = reason_code;
3068 if (pinvtm) *pinvtm = comp_time;
3069 else ASN1_GENERALIZEDTIME_free(comp_time);
3075 if (tmp) OPENSSL_free(tmp);
3076 if (!phold) ASN1_OBJECT_free(hold);
3077 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);