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"
146 /* Additional revocation information types */
148 #define REV_NONE 0 /* No addditional information */
149 #define REV_CRL_REASON 1 /* Value is CRL reason code */
150 #define REV_HOLD 2 /* Value is hold instruction */
151 #define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
152 #define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
154 static char *ca_usage[]={
157 " -verbose - Talk alot while doing things\n",
158 " -config file - A config file\n",
159 " -name arg - The particular CA definition to use\n",
160 " -gencrl - Generate a new CRL\n",
161 " -crldays days - Days is when the next CRL is due\n",
162 " -crlhours hours - Hours is when the next CRL is due\n",
163 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
164 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
165 " -days arg - number of days to certify the certificate for\n",
166 " -md arg - md to use, one of md2, md5, sha or sha1\n",
167 " -policy arg - The CA 'policy' to support\n",
168 " -keyfile arg - private key file\n",
169 " -keyform arg - private key file format (PEM or ENGINE)\n",
170 " -key arg - key to decode the private key if it is encrypted\n",
171 " -cert file - The CA certificate\n",
172 " -in file - The input PEM encoded certificate request(s)\n",
173 " -out file - Where to put the output file(s)\n",
174 " -outdir dir - Where to put output certificates\n",
175 " -infiles .... - The last argument, requests to process\n",
176 " -spkac file - File contains DN and signed public key and challenge\n",
177 " -ss_cert file - File contains a self signed cert to sign\n",
178 " -preserveDN - Don't re-order the DN\n",
179 " -noemailDN - Don't add the EMAIL field into certificate' subject\n",
180 " -batch - Don't ask questions\n",
181 " -msie_hack - msie modifications to handle all those universal strings\n",
182 " -revoke file - Revoke a certificate (given in file)\n",
183 " -subj arg - Use arg instead of request's subject\n",
184 " -extensions .. - Extension section (override value in config file)\n",
185 " -extfile file - Configuration file with X509v3 extentions to add\n",
186 " -crlexts .. - CRL extension section (override value in config file)\n",
187 #ifndef OPENSSL_NO_ENGINE
188 " -engine e - use engine e, possibly a hardware device.\n",
190 " -status serial - Shows certificate status given the serial number\n",
191 " -updatedb - Updates db for expired certificates\n",
196 extern int EF_PROTECT_FREE;
197 extern int EF_PROTECT_BELOW;
198 extern int EF_ALIGNMENT;
201 static void lookup_fail(char *name,char *tag);
202 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
203 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
204 BIGNUM *serial, char *subj, int email_dn, char *startdate,
205 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
206 int verbose, unsigned long certopt, unsigned long nameopt,
207 int default_op, int ext_copy);
208 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
209 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
210 CA_DB *db, BIGNUM *serial, char *subj, int email_dn,
211 char *startdate, char *enddate, long days, int batch,
212 char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
213 unsigned long nameopt, int default_op, int ext_copy,
215 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
216 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
217 CA_DB *db, BIGNUM *serial,char *subj, int email_dn,
218 char *startdate, char *enddate, long days, char *ext_sect,
219 CONF *conf, int verbose, unsigned long certopt,
220 unsigned long nameopt, int default_op, int ext_copy);
221 static int fix_data(int nid, int *type);
222 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
223 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
224 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,
225 int email_dn, char *startdate, char *enddate, long days, int batch,
226 int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
227 unsigned long certopt, unsigned long nameopt, int default_op,
229 static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
230 static int get_certificate_status(const char *ser_status, CA_DB *db);
231 static int do_updatedb(CA_DB *db);
232 static int check_time_format(char *str);
233 char *make_revocation_str(int rev_type, char *rev_arg);
234 int make_revoked(X509_REVOKED *rev, char *str);
235 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
236 static CONF *conf=NULL;
237 static CONF *extconf=NULL;
238 static char *section=NULL;
240 static int preserve=0;
241 static int msie_hack=0;
244 int MAIN(int, char **);
246 int MAIN(int argc, char **argv)
249 char *key=NULL,*passargin=NULL;
264 char *configfile=NULL;
269 int keyform=FORMAT_PEM;
271 char *spkac_file=NULL;
272 char *ss_cert_file=NULL;
273 char *ser_status=NULL;
278 char *serialfile=NULL;
279 char *extensions=NULL;
282 char *tmp_email_dn=NULL;
284 int rev_type = REV_NONE;
285 char *rev_arg = NULL;
287 char *startdate=NULL;
292 unsigned long nameopt = 0, certopt = 0;
294 int ext_copy = EXT_COPY_NONE;
297 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
301 X509_REVOKED *r=NULL;
303 ASN1_INTEGER *tmpser;
306 const EVP_MD *dgst=NULL;
307 STACK_OF(CONF_VALUE) *attribs=NULL;
308 STACK_OF(X509) *cert_sk=NULL;
311 MS_STATIC char buf[3][BSIZE];
313 #ifndef OPENSSL_NO_ENGINE
334 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
335 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
341 if (strcmp(*argv,"-verbose") == 0)
343 else if (strcmp(*argv,"-config") == 0)
345 if (--argc < 1) goto bad;
346 configfile= *(++argv);
348 else if (strcmp(*argv,"-name") == 0)
350 if (--argc < 1) goto bad;
353 else if (strcmp(*argv,"-subj") == 0)
355 if (--argc < 1) goto bad;
359 else if (strcmp(*argv,"-startdate") == 0)
361 if (--argc < 1) goto bad;
362 startdate= *(++argv);
364 else if (strcmp(*argv,"-enddate") == 0)
366 if (--argc < 1) goto bad;
369 else if (strcmp(*argv,"-days") == 0)
371 if (--argc < 1) goto bad;
372 days=atoi(*(++argv));
374 else if (strcmp(*argv,"-md") == 0)
376 if (--argc < 1) goto bad;
379 else if (strcmp(*argv,"-policy") == 0)
381 if (--argc < 1) goto bad;
384 else if (strcmp(*argv,"-keyfile") == 0)
386 if (--argc < 1) goto bad;
389 else if (strcmp(*argv,"-keyform") == 0)
391 if (--argc < 1) goto bad;
392 keyform=str2fmt(*(++argv));
394 else if (strcmp(*argv,"-passin") == 0)
396 if (--argc < 1) goto bad;
397 passargin= *(++argv);
399 else if (strcmp(*argv,"-key") == 0)
401 if (--argc < 1) goto bad;
404 else if (strcmp(*argv,"-cert") == 0)
406 if (--argc < 1) goto bad;
409 else if (strcmp(*argv,"-in") == 0)
411 if (--argc < 1) goto bad;
415 else if (strcmp(*argv,"-out") == 0)
417 if (--argc < 1) goto bad;
420 else if (strcmp(*argv,"-outdir") == 0)
422 if (--argc < 1) goto bad;
425 else if (strcmp(*argv,"-notext") == 0)
427 else if (strcmp(*argv,"-batch") == 0)
429 else if (strcmp(*argv,"-preserveDN") == 0)
431 else if (strcmp(*argv,"-noemailDN") == 0)
433 else if (strcmp(*argv,"-gencrl") == 0)
435 else if (strcmp(*argv,"-msie_hack") == 0)
437 else if (strcmp(*argv,"-crldays") == 0)
439 if (--argc < 1) goto bad;
440 crldays= atol(*(++argv));
442 else if (strcmp(*argv,"-crlhours") == 0)
444 if (--argc < 1) goto bad;
445 crlhours= atol(*(++argv));
447 else if (strcmp(*argv,"-infiles") == 0)
454 else if (strcmp(*argv, "-ss_cert") == 0)
456 if (--argc < 1) goto bad;
457 ss_cert_file = *(++argv);
460 else if (strcmp(*argv, "-spkac") == 0)
462 if (--argc < 1) goto bad;
463 spkac_file = *(++argv);
466 else if (strcmp(*argv,"-revoke") == 0)
468 if (--argc < 1) goto bad;
472 else if (strcmp(*argv,"-extensions") == 0)
474 if (--argc < 1) goto bad;
475 extensions= *(++argv);
477 else if (strcmp(*argv,"-extfile") == 0)
479 if (--argc < 1) goto bad;
482 else if (strcmp(*argv,"-status") == 0)
484 if (--argc < 1) goto bad;
485 ser_status= *(++argv);
487 else if (strcmp(*argv,"-updatedb") == 0)
491 else if (strcmp(*argv,"-crlexts") == 0)
493 if (--argc < 1) goto bad;
496 else if (strcmp(*argv,"-crl_reason") == 0)
498 if (--argc < 1) goto bad;
500 rev_type = REV_CRL_REASON;
502 else if (strcmp(*argv,"-crl_hold") == 0)
504 if (--argc < 1) goto bad;
508 else if (strcmp(*argv,"-crl_compromise") == 0)
510 if (--argc < 1) goto bad;
512 rev_type = REV_KEY_COMPROMISE;
514 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
516 if (--argc < 1) goto bad;
518 rev_type = REV_CA_COMPROMISE;
520 #ifndef OPENSSL_NO_ENGINE
521 else if (strcmp(*argv,"-engine") == 0)
523 if (--argc < 1) goto bad;
530 BIO_printf(bio_err,"unknown option %s\n",*argv);
540 for (pp=ca_usage; (*pp != NULL); pp++)
541 BIO_printf(bio_err,"%s",*pp);
545 ERR_load_crypto_strings();
547 #ifndef OPENSSL_NO_ENGINE
548 e = setup_engine(bio_err, engine, 0);
551 /*****************************************************************/
553 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
554 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
555 if (configfile == NULL)
557 const char *s=X509_get_default_cert_area();
559 #ifdef OPENSSL_SYS_VMS
560 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE));
563 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1);
567 strcat(tofree,CONFIG_FILE);
571 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
572 conf = NCONF_new(NULL);
573 if (NCONF_load(conf,configfile,&errorline) <= 0)
576 BIO_printf(bio_err,"error loading the config file '%s'\n",
579 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
580 ,errorline,configfile);
585 OPENSSL_free(tofree);
589 if (!load_config(bio_err, conf))
592 /* Lets get the config section we are using */
595 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
598 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
605 p=NCONF_get_string(conf,NULL,"oid_file");
612 oid_bio=BIO_new_file(p,"r");
616 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
617 ERR_print_errors(bio_err);
623 OBJ_create_objects(oid_bio);
627 if (!add_oid_section(bio_err,conf))
629 ERR_print_errors(bio_err);
634 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
635 if (randfile == NULL)
637 app_RAND_load_file(randfile, bio_err, 0);
639 db_attr.unique_subject = 1;
640 p = NCONF_get_string(conf, section, "unique_subject");
644 BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
648 case 'f': /* false */
649 case 'F': /* FALSE */
652 db_attr.unique_subject = 0;
659 db_attr.unique_subject = 1;
665 BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
668 BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
669 db_attr.unique_subject);
672 in=BIO_new(BIO_s_file());
673 out=BIO_new(BIO_s_file());
674 Sout=BIO_new(BIO_s_file());
675 Cout=BIO_new(BIO_s_file());
676 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
678 ERR_print_errors(bio_err);
682 /*****************************************************************/
683 /* report status of cert with serial number given on command line */
686 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
688 lookup_fail(section,ENV_DATABASE);
691 db = load_index(dbfile,&db_attr);
692 if (db == NULL) goto err;
694 if (!index_index(db)) goto err;
696 if (get_certificate_status(ser_status,db) != 1)
697 BIO_printf(bio_err,"Error verifying serial %s!\n",
702 /*****************************************************************/
703 /* we definitely need a public key, so let's get it */
705 if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
706 section,ENV_PRIVATE_KEY)) == NULL))
708 lookup_fail(section,ENV_PRIVATE_KEY);
714 if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
716 BIO_printf(bio_err,"Error getting password\n");
720 pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
722 if (key) OPENSSL_cleanse(key,strlen(key));
725 /* load_key() has already printed an appropriate message */
729 /*****************************************************************/
730 /* we need a certificate */
731 if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
732 section,ENV_CERTIFICATE)) == NULL))
734 lookup_fail(section,ENV_CERTIFICATE);
737 x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
742 if (!X509_check_private_key(x509,pkey))
744 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
748 f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
751 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
753 f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
756 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
759 f=NCONF_get_string(conf,section,ENV_NAMEOPT);
763 if (!set_name_ex(&nameopt, f))
765 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
773 f=NCONF_get_string(conf,section,ENV_CERTOPT);
777 if (!set_cert_ex(&certopt, f))
779 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
787 f=NCONF_get_string(conf,section,ENV_EXTCOPY);
791 if (!set_ext_copy(&ext_copy, f))
793 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
800 /*****************************************************************/
801 /* lookup where to write new certificates */
802 if ((outdir == NULL) && (req))
806 if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
809 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
812 #ifndef OPENSSL_SYS_VMS
813 /* outdir is a directory spec, but access() for VMS demands a
814 filename. In any case, stat(), below, will catch the problem
815 if outdir is not a directory spec, and the fopen() or open()
816 will catch an error if there is no write access.
818 Presumably, this problem could also be solved by using the DEC
819 C routines to convert the directory syntax to Unixly, and give
820 that to access(). However, time's too short to do that just
823 if (access(outdir,R_OK|W_OK|X_OK) != 0)
825 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
830 if (stat(outdir,&sb) != 0)
832 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
837 if (!(sb.st_mode & S_IFDIR))
839 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
847 /*****************************************************************/
848 /* we need to load the database file */
849 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
851 lookup_fail(section,ENV_DATABASE);
854 db = load_index(dbfile, &db_attr);
855 if (db == NULL) goto err;
857 /* Lets check some fields */
858 for (i=0; i<sk_num(db->db->data); i++)
860 pp=(char **)sk_value(db->db->data,i);
861 if ((pp[DB_type][0] != DB_TYPE_REV) &&
862 (pp[DB_rev_date][0] != '\0'))
864 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
867 if ((pp[DB_type][0] == DB_TYPE_REV) &&
868 !make_revoked(NULL, pp[DB_rev_date]))
870 BIO_printf(bio_err," in entry %d\n", i+1);
873 if (!check_time_format(pp[DB_exp_date]))
875 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
885 if ((j&1) || (j < 2))
887 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
892 if (!( ((*p >= '0') && (*p <= '9')) ||
893 ((*p >= 'A') && (*p <= 'F')) ||
894 ((*p >= 'a') && (*p <= 'f'))) )
896 BIO_printf(bio_err,"entry %d: bad serial number characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
904 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
905 #ifdef OPENSSL_SYS_VMS
907 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
908 out = BIO_push(tmpbio, out);
911 TXT_DB_write(out,db->db);
912 BIO_printf(bio_err,"%d entries loaded from the database\n",
914 BIO_printf(bio_err,"generating index\n");
917 if (!index_index(db)) goto err;
919 /*****************************************************************/
920 /* Update the db file for expired certificates */
924 BIO_printf(bio_err, "Updating %s ...\n",
930 BIO_printf(bio_err,"Malloc failure\n");
935 if (verbose) BIO_printf(bio_err,
936 "No entries found to mark expired\n");
940 if (!save_index(dbfile,"new",db)) goto err;
942 if (!rotate_index(dbfile,"new","old")) goto err;
944 if (verbose) BIO_printf(bio_err,
945 "Done. %d entries marked as expired\n",i);
950 /*****************************************************************/
951 /* Read extentions config file */
954 extconf = NCONF_new(NULL);
955 if (NCONF_load(extconf,extfile,&errorline) <= 0)
958 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
961 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
968 BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
970 /* We can have sections in the ext file */
971 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
972 extensions = "default";
975 /*****************************************************************/
980 if (BIO_write_filename(Sout,outfile) <= 0)
988 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
989 #ifdef OPENSSL_SYS_VMS
991 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
992 Sout = BIO_push(tmpbio, Sout);
1000 if ((md == NULL) && ((md=NCONF_get_string(conf,
1001 section,ENV_DEFAULT_MD)) == NULL))
1003 lookup_fail(section,ENV_DEFAULT_MD);
1006 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1007 section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1009 if(strcmp(tmp_email_dn,"no") == 0)
1012 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1014 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1018 BIO_printf(bio_err,"message digest is %s\n",
1019 OBJ_nid2ln(dgst->type));
1020 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1021 section,ENV_POLICY)) == NULL))
1023 lookup_fail(section,ENV_POLICY);
1027 BIO_printf(bio_err,"policy is %s\n",policy);
1029 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1032 lookup_fail(section,ENV_SERIAL);
1038 /* no '-extfile' option, so we look for extensions
1039 * in the main configuration file */
1042 extensions=NCONF_get_string(conf,section,
1049 /* Check syntax of file */
1051 X509V3_set_ctx_test(&ctx);
1052 X509V3_set_nconf(&ctx, conf);
1053 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1057 "Error Loading extension section %s\n",
1065 if (startdate == NULL)
1067 startdate=NCONF_get_string(conf,section,
1068 ENV_DEFAULT_STARTDATE);
1069 if (startdate == NULL)
1072 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1074 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1077 if (startdate == NULL) startdate="today";
1079 if (enddate == NULL)
1081 enddate=NCONF_get_string(conf,section,
1082 ENV_DEFAULT_ENDDATE);
1083 if (enddate == NULL)
1086 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1088 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1094 if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1097 if (!enddate && (days == 0))
1099 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1103 if ((serial=load_serial(serialfile, 0, NULL)) == NULL)
1105 BIO_printf(bio_err,"error while loading serial number\n");
1110 if (BN_is_zero(serial))
1111 BIO_printf(bio_err,"next serial number is 00\n");
1114 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1115 BIO_printf(bio_err,"next serial number is %s\n",f);
1120 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1122 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1126 if ((cert_sk=sk_X509_new_null()) == NULL)
1128 BIO_printf(bio_err,"Memory allocation failure\n");
1131 if (spkac_file != NULL)
1134 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1135 serial,subj,email_dn,startdate,enddate,days,extensions,
1136 conf,verbose,certopt,nameopt,default_op,ext_copy);
1137 if (j < 0) goto err;
1141 BIO_printf(bio_err,"\n");
1142 if (!BN_add_word(serial,1)) goto err;
1143 if (!sk_X509_push(cert_sk,x))
1145 BIO_printf(bio_err,"Memory allocation failure\n");
1155 if (ss_cert_file != NULL)
1158 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1159 db,serial,subj,email_dn,startdate,enddate,days,batch,
1160 extensions,conf,verbose, certopt, nameopt,
1161 default_op, ext_copy, e);
1162 if (j < 0) goto err;
1166 BIO_printf(bio_err,"\n");
1167 if (!BN_add_word(serial,1)) goto err;
1168 if (!sk_X509_push(cert_sk,x))
1170 BIO_printf(bio_err,"Memory allocation failure\n");
1178 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1179 serial,subj,email_dn,startdate,enddate,days,batch,
1180 extensions,conf,verbose, certopt, nameopt,
1181 default_op, ext_copy);
1182 if (j < 0) goto err;
1186 BIO_printf(bio_err,"\n");
1187 if (!BN_add_word(serial,1)) goto err;
1188 if (!sk_X509_push(cert_sk,x))
1190 BIO_printf(bio_err,"Memory allocation failure\n");
1195 for (i=0; i<argc; i++)
1198 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1199 serial,subj,email_dn,startdate,enddate,days,batch,
1200 extensions,conf,verbose, certopt, nameopt,
1201 default_op, ext_copy);
1202 if (j < 0) goto err;
1206 BIO_printf(bio_err,"\n");
1207 if (!BN_add_word(serial,1)) goto err;
1208 if (!sk_X509_push(cert_sk,x))
1210 BIO_printf(bio_err,"Memory allocation failure\n");
1215 /* we have a stack of newly certified certificates
1216 * and a data base and serial number that need
1219 if (sk_X509_num(cert_sk) > 0)
1223 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1224 (void)BIO_flush(bio_err);
1226 fgets(buf[0],10,stdin);
1227 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1229 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1235 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1237 if(strlen(serialfile) > BSIZE-5 || strlen(dbfile) > BSIZE-5)
1239 BIO_printf(bio_err,"file name too long\n");
1243 strcpy(buf[0],serialfile);
1245 #ifdef OPENSSL_SYS_VMS
1246 strcat(buf[0],"-new");
1248 strcat(buf[0],".new");
1251 if (!save_serial(buf[0],serial,NULL)) goto err;
1253 if (!save_index(dbfile, "new", db)) goto err;
1257 BIO_printf(bio_err,"writing new certificates\n");
1258 for (i=0; i<sk_X509_num(cert_sk); i++)
1263 x=sk_X509_value(cert_sk,i);
1265 j=x->cert_info->serialNumber->length;
1266 p=(char *)x->cert_info->serialNumber->data;
1268 if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1270 BIO_printf(bio_err,"certificate file name too long\n");
1274 strcpy(buf[2],outdir);
1276 #ifndef OPENSSL_SYS_VMS
1280 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1285 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1294 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1297 BIO_printf(bio_err,"writing %s\n",buf[2]);
1299 if (BIO_write_filename(Cout,buf[2]) <= 0)
1304 write_new_certificate(Cout,x, 0, notext);
1305 write_new_certificate(Sout,x, output_der, notext);
1308 if (sk_X509_num(cert_sk))
1310 /* Rename the database and the serial file */
1311 strncpy(buf[2],serialfile,BSIZE-4);
1312 buf[2][BSIZE-4]='\0';
1314 #ifdef OPENSSL_SYS_VMS
1315 strcat(buf[2],"-old");
1317 strcat(buf[2],".old");
1324 if (rename(serialfile,buf[2]) < 0)
1326 BIO_printf(bio_err,"unable to rename %s to %s\n",
1331 if (rename(buf[0],serialfile) < 0)
1333 BIO_printf(bio_err,"unable to rename %s to %s\n",
1336 rename(buf[2],serialfile);
1340 if (!rotate_index(dbfile,"new","old")) goto err;
1342 BIO_printf(bio_err,"Data Base Updated\n");
1346 /*****************************************************************/
1352 crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1358 /* Check syntax of file */
1360 X509V3_set_ctx_test(&ctx);
1361 X509V3_set_nconf(&ctx, conf);
1362 if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1365 "Error Loading CRL extension section %s\n",
1372 if (!crldays && !crlhours)
1374 if (!NCONF_get_number(conf,section,
1375 ENV_DEFAULT_CRL_DAYS, &crldays))
1377 if (!NCONF_get_number(conf,section,
1378 ENV_DEFAULT_CRL_HOURS, &crlhours))
1381 if ((crldays == 0) && (crlhours == 0))
1383 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1387 if (verbose) BIO_printf(bio_err,"making CRL\n");
1388 if ((crl=X509_CRL_new()) == NULL) goto err;
1389 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1391 tmptm = ASN1_TIME_new();
1392 if (!tmptm) goto err;
1393 X509_gmtime_adj(tmptm,0);
1394 X509_CRL_set_lastUpdate(crl, tmptm);
1395 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1396 X509_CRL_set_nextUpdate(crl, tmptm);
1398 ASN1_TIME_free(tmptm);
1400 for (i=0; i<sk_num(db->db->data); i++)
1402 pp=(char **)sk_value(db->db->data,i);
1403 if (pp[DB_type][0] == DB_TYPE_REV)
1405 if ((r=X509_REVOKED_new()) == NULL) goto err;
1406 j = make_revoked(r, pp[DB_rev_date]);
1408 if (j == 2) crl_v2 = 1;
1409 if (!BN_hex2bn(&serial, pp[DB_serial]))
1411 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1416 X509_REVOKED_set_serialNumber(r, tmpser);
1417 ASN1_INTEGER_free(tmpser);
1418 X509_CRL_add0_revoked(crl,r);
1422 /* sort the data so it will be written in serial
1426 /* we now have a CRL */
1427 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1430 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1432 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1438 #ifndef OPENSSL_NO_DSA
1439 if (pkey->type == EVP_PKEY_DSA)
1443 #ifndef OPENSSL_NO_ECDSA
1444 if (pkey->type == EVP_PKEY_EC)
1451 /* Add any extensions asked for */
1456 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1457 X509V3_set_nconf(&crlctx, conf);
1459 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1460 crl_ext, crl)) goto err;
1462 if (crl_ext || crl_v2)
1464 if (!X509_CRL_set_version(crl, 1))
1465 goto err; /* version 2 CRL */
1468 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1470 PEM_write_bio_X509_CRL(Sout,crl);
1472 /*****************************************************************/
1477 BIO_printf(bio_err,"no input files\n");
1483 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1485 if (revcert == NULL)
1487 j=do_revoke(revcert,db, rev_type, rev_arg);
1488 if (j <= 0) goto err;
1491 if (!save_index(dbfile, "new", db)) goto err;
1493 if (!rotate_index(dbfile, "new", "old")) goto err;
1495 BIO_printf(bio_err,"Data Base Updated\n");
1498 /*****************************************************************/
1502 OPENSSL_free(tofree);
1509 sk_X509_pop_free(cert_sk,X509_free);
1511 if (ret) ERR_print_errors(bio_err);
1512 app_RAND_write_file(randfile, bio_err);
1513 if (free_key && key)
1517 EVP_PKEY_free(pkey);
1526 static void lookup_fail(char *name, char *tag)
1528 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1531 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1532 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1533 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1534 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1535 unsigned long certopt, unsigned long nameopt, int default_op,
1540 EVP_PKEY *pktmp=NULL;
1543 in=BIO_new(BIO_s_file());
1545 if (BIO_read_filename(in,infile) <= 0)
1550 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1552 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1557 X509_REQ_print(bio_err,req);
1559 BIO_printf(bio_err,"Check that the request matches the signature\n");
1561 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1563 BIO_printf(bio_err,"error unpacking public key\n");
1566 i=X509_REQ_verify(req,pktmp);
1567 EVP_PKEY_free(pktmp);
1571 BIO_printf(bio_err,"Signature verification problems....\n");
1577 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1581 BIO_printf(bio_err,"Signature ok\n");
1583 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1584 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1585 certopt, nameopt, default_op, ext_copy);
1588 if (req != NULL) X509_REQ_free(req);
1589 if (in != NULL) BIO_free(in);
1593 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1594 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1595 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1596 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1597 unsigned long certopt, unsigned long nameopt, int default_op,
1598 int ext_copy, ENGINE *e)
1601 X509_REQ *rreq=NULL;
1602 EVP_PKEY *pktmp=NULL;
1605 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1608 X509_print(bio_err,req);
1610 BIO_printf(bio_err,"Check that the request matches the signature\n");
1612 if ((pktmp=X509_get_pubkey(req)) == NULL)
1614 BIO_printf(bio_err,"error unpacking public key\n");
1617 i=X509_verify(req,pktmp);
1618 EVP_PKEY_free(pktmp);
1622 BIO_printf(bio_err,"Signature verification problems....\n");
1628 BIO_printf(bio_err,"Signature did not match the certificate\n");
1632 BIO_printf(bio_err,"Signature ok\n");
1634 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1637 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1638 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1642 if (rreq != NULL) X509_REQ_free(rreq);
1643 if (req != NULL) X509_free(req);
1647 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1648 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1649 int email_dn, char *startdate, char *enddate, long days, int batch,
1650 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1651 unsigned long certopt, unsigned long nameopt, int default_op,
1654 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1655 ASN1_UTCTIME *tm,*tmptm;
1656 ASN1_STRING *str,*str2;
1660 X509_NAME_ENTRY *ne;
1661 X509_NAME_ENTRY *tne,*push;
1663 int ok= -1,i,j,last,nid;
1666 char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
1669 tmptm=ASN1_UTCTIME_new();
1672 BIO_printf(bio_err,"malloc error\n");
1676 for (i=0; i<DB_NUMBER; i++)
1681 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1685 ERR_print_errors(bio_err);
1688 X509_REQ_set_subject_name(req,n);
1689 req->req_info->enc.modified = 1;
1694 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1696 name=X509_REQ_get_subject_name(req);
1697 for (i=0; i<X509_NAME_entry_count(name); i++)
1699 ne= X509_NAME_get_entry(name,i);
1700 str=X509_NAME_ENTRY_get_data(ne);
1701 obj=X509_NAME_ENTRY_get_object(ne);
1705 /* assume all type should be strings */
1706 nid=OBJ_obj2nid(ne->object);
1708 if (str->type == V_ASN1_UNIVERSALSTRING)
1709 ASN1_UNIVERSALSTRING_to_string(str);
1711 if ((str->type == V_ASN1_IA5STRING) &&
1712 (nid != NID_pkcs9_emailAddress))
1713 str->type=V_ASN1_T61STRING;
1715 if ((nid == NID_pkcs9_emailAddress) &&
1716 (str->type == V_ASN1_PRINTABLESTRING))
1717 str->type=V_ASN1_IA5STRING;
1720 /* If no EMAIL is wanted in the subject */
1721 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1724 /* check some things */
1725 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1726 (str->type != V_ASN1_IA5STRING))
1728 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1731 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1733 j=ASN1_PRINTABLE_type(str->data,str->length);
1734 if ( ((j == V_ASN1_T61STRING) &&
1735 (str->type != V_ASN1_T61STRING)) ||
1736 ((j == V_ASN1_IA5STRING) &&
1737 (str->type == V_ASN1_PRINTABLESTRING)))
1739 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1745 old_entry_print(bio_err, obj, str);
1748 /* Ok, now we check the 'policy' stuff. */
1749 if ((subject=X509_NAME_new()) == NULL)
1751 BIO_printf(bio_err,"Memory allocation failure\n");
1755 /* take a copy of the issuer name before we mess with it. */
1756 CAname=X509_NAME_dup(x509->cert_info->subject);
1757 if (CAname == NULL) goto err;
1760 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1762 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1763 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1765 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1773 /* lookup the object in the supplied name list */
1774 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1777 if (last != -1) break;
1782 tne=X509_NAME_get_entry(name,j);
1786 /* depending on the 'policy', decide what to do. */
1788 if (strcmp(cv->value,"optional") == 0)
1793 else if (strcmp(cv->value,"supplied") == 0)
1797 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1803 else if (strcmp(cv->value,"match") == 0)
1809 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1816 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1817 if ((j < 0) && (last2 == -1))
1819 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1824 push=X509_NAME_get_entry(CAname,j);
1825 str=X509_NAME_ENTRY_get_data(tne);
1826 str2=X509_NAME_ENTRY_get_data(push);
1828 if (ASN1_STRING_cmp(str,str2) != 0)
1833 BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str2 == NULL)?"NULL":(char *)str2->data),((str == NULL)?"NULL":(char *)str->data));
1839 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1845 if (!X509_NAME_add_entry(subject,push, -1, 0))
1848 X509_NAME_ENTRY_free(push);
1849 BIO_printf(bio_err,"Memory allocation failure\n");
1859 X509_NAME_free(subject);
1860 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1861 subject=X509_NAME_dup(name);
1862 if (subject == NULL) goto err;
1866 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1868 /* Build the correct Subject if no e-mail is wanted in the subject */
1869 /* and add it later on because of the method extensions are added (altName) */
1872 dn_subject = subject;
1875 X509_NAME_ENTRY *tmpne;
1876 /* Its best to dup the subject DN and then delete any email
1877 * addresses because this retains its structure.
1879 if (!(dn_subject = X509_NAME_dup(subject)))
1881 BIO_printf(bio_err,"Memory allocation failure\n");
1884 while((i = X509_NAME_get_index_by_NID(dn_subject,
1885 NID_pkcs9_emailAddress, -1)) >= 0)
1887 tmpne = X509_NAME_get_entry(dn_subject, i);
1888 X509_NAME_delete_entry(dn_subject, i);
1889 X509_NAME_ENTRY_free(tmpne);
1893 if (BN_is_zero(serial))
1894 row[DB_serial]=BUF_strdup("00");
1896 row[DB_serial]=BN_bn2hex(serial);
1897 if (row[DB_serial] == NULL)
1899 BIO_printf(bio_err,"Memory allocation failure\n");
1903 if (db->attributes.unique_subject)
1905 rrow=TXT_DB_get_by_index(db->db,DB_name,row);
1909 "ERROR:There is already a certificate for %s\n",
1915 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1918 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1920 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1927 "The matching entry has the following details\n");
1928 if (rrow[DB_type][0] == 'E')
1930 else if (rrow[DB_type][0] == 'R')
1932 else if (rrow[DB_type][0] == 'V')
1935 p="\ninvalid type, Data base error\n";
1936 BIO_printf(bio_err,"Type :%s\n",p);;
1937 if (rrow[DB_type][0] == 'R')
1939 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1940 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1942 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1943 BIO_printf(bio_err,"Expires on :%s\n",p);
1944 p=rrow[DB_serial]; if (p == NULL) p="undef";
1945 BIO_printf(bio_err,"Serial Number :%s\n",p);
1946 p=rrow[DB_file]; if (p == NULL) p="undef";
1947 BIO_printf(bio_err,"File name :%s\n",p);
1948 p=rrow[DB_name]; if (p == NULL) p="undef";
1949 BIO_printf(bio_err,"Subject Name :%s\n",p);
1950 ok= -1; /* This is now a 'bad' error. */
1954 /* We are now totally happy, lets make and sign the certificate */
1956 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1958 if ((ret=X509_new()) == NULL) goto err;
1962 /* Make it an X509 v3 certificate. */
1963 if (!X509_set_version(ret,2)) goto err;
1966 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1968 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1971 if (strcmp(startdate,"today") == 0)
1972 X509_gmtime_adj(X509_get_notBefore(ret),0);
1973 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1975 if (enddate == NULL)
1976 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1977 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1979 if (!X509_set_subject_name(ret,subject)) goto err;
1981 pktmp=X509_REQ_get_pubkey(req);
1982 i = X509_set_pubkey(ret,pktmp);
1983 EVP_PKEY_free(pktmp);
1986 /* Lets add the extensions, if there are any */
1990 if (ci->version == NULL)
1991 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1993 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1995 /* Free the current entries if any, there should not
1996 * be any I believe */
1997 if (ci->extensions != NULL)
1998 sk_X509_EXTENSION_pop_free(ci->extensions,
1999 X509_EXTENSION_free);
2001 ci->extensions = NULL;
2003 /* Initialize the context structure */
2004 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2009 BIO_printf(bio_err, "Extra configuration file found\n");
2011 /* Use the extconf configuration db LHASH */
2012 X509V3_set_nconf(&ctx, extconf);
2014 /* Test the structure (needed?) */
2015 /* X509V3_set_ctx_test(&ctx); */
2017 /* Adds exts contained in the configuration file */
2018 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2021 "ERROR: adding extensions in section %s\n",
2023 ERR_print_errors(bio_err);
2027 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2031 /* We found extensions to be set from config file */
2032 X509V3_set_nconf(&ctx, lconf);
2034 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2036 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2037 ERR_print_errors(bio_err);
2042 BIO_printf(bio_err, "Successfully added extensions from config\n");
2046 /* Copy extensions from request (if any) */
2048 if (!copy_extensions(ret, req, ext_copy))
2050 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2051 ERR_print_errors(bio_err);
2055 /* Set the right value for the noemailDN option */
2058 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2063 BIO_printf(bio_err, "Certificate Details:\n");
2064 /* Never print signature details because signature not present */
2065 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2066 X509_print_ex(bio_err, ret, nameopt, certopt);
2069 BIO_printf(bio_err,"Certificate is to be certified until ");
2070 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2071 if (days) BIO_printf(bio_err," (%d days)",days);
2072 BIO_printf(bio_err, "\n");
2077 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2078 (void)BIO_flush(bio_err);
2080 fgets(buf,sizeof(buf)-1,stdin);
2081 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2083 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2090 #ifndef OPENSSL_NO_DSA
2091 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2092 pktmp=X509_get_pubkey(ret);
2093 if (EVP_PKEY_missing_parameters(pktmp) &&
2094 !EVP_PKEY_missing_parameters(pkey))
2095 EVP_PKEY_copy_parameters(pktmp,pkey);
2096 EVP_PKEY_free(pktmp);
2098 #ifndef OPENSSL_NO_ECDSA
2099 if (pkey->type == EVP_PKEY_EC)
2101 pktmp = X509_get_pubkey(ret);
2102 if (EVP_PKEY_missing_parameters(pktmp) &&
2103 !EVP_PKEY_missing_parameters(pkey))
2104 EVP_PKEY_copy_parameters(pktmp, pkey);
2105 EVP_PKEY_free(pktmp);
2109 if (!X509_sign(ret,pkey,dgst))
2112 /* We now just add it to the database */
2113 row[DB_type]=(char *)OPENSSL_malloc(2);
2115 tm=X509_get_notAfter(ret);
2116 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2117 memcpy(row[DB_exp_date],tm->data,tm->length);
2118 row[DB_exp_date][tm->length]='\0';
2120 row[DB_rev_date]=NULL;
2122 /* row[DB_serial] done already */
2123 row[DB_file]=(char *)OPENSSL_malloc(8);
2124 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2126 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2127 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2129 BIO_printf(bio_err,"Memory allocation failure\n");
2132 strcpy(row[DB_file],"unknown");
2133 row[DB_type][0]='V';
2134 row[DB_type][1]='\0';
2136 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2138 BIO_printf(bio_err,"Memory allocation failure\n");
2142 for (i=0; i<DB_NUMBER; i++)
2147 irow[DB_NUMBER]=NULL;
2149 if (!TXT_DB_insert(db->db,irow))
2151 BIO_printf(bio_err,"failed to update database\n");
2152 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2157 for (i=0; i<DB_NUMBER; i++)
2158 if (row[i] != NULL) OPENSSL_free(row[i]);
2161 X509_NAME_free(CAname);
2162 if (subject != NULL)
2163 X509_NAME_free(subject);
2164 if ((dn_subject != NULL) && !email_dn)
2165 X509_NAME_free(dn_subject);
2167 ASN1_UTCTIME_free(tmptm);
2170 if (ret != NULL) X509_free(ret);
2178 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2183 (void)i2d_X509_bio(bp,x);
2187 /* ??? Not needed since X509_print prints all this stuff anyway */
2188 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2189 BIO_printf(bp,"issuer :%s\n",f);
2191 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2192 BIO_printf(bp,"subject:%s\n",f);
2194 BIO_puts(bp,"serial :");
2195 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2196 BIO_puts(bp,"\n\n");
2198 if (!notext)X509_print(bp,x);
2199 PEM_write_bio_X509(bp,x);
2202 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2203 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2204 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2205 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2206 unsigned long nameopt, int default_op, int ext_copy)
2208 STACK_OF(CONF_VALUE) *sk=NULL;
2211 CONF_VALUE *cv=NULL;
2212 NETSCAPE_SPKI *spki = NULL;
2215 EVP_PKEY *pktmp=NULL;
2217 X509_NAME_ENTRY *ne=NULL;
2223 * Load input file into a hash table. (This is just an easy
2224 * way to read and parse the file, then put it into a convenient
2227 parms=CONF_load(NULL,infile,&errline);
2230 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2231 ERR_print_errors(bio_err);
2235 sk=CONF_get_section(parms, "default");
2236 if (sk_CONF_VALUE_num(sk) == 0)
2238 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2244 * Now create a dummy X509 request structure. We don't actually
2245 * have an X509 request, but we have many of the components
2246 * (a public key, various DN components). The idea is that we
2247 * put these components into the right X509 request structure
2248 * and we can use the same code as if you had a real X509 request.
2253 ERR_print_errors(bio_err);
2258 * Build up the subject name set.
2265 if (sk_CONF_VALUE_num(sk) <= i) break;
2267 cv=sk_CONF_VALUE_value(sk,i);
2269 /* Skip past any leading X. X: X, etc to allow for
2270 * multiple instances
2272 for (buf = cv->name; *buf ; buf++)
2273 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2276 if (*buf) type = buf;
2281 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2283 if (strcmp(type, "SPKAC") == 0)
2285 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2288 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2289 ERR_print_errors(bio_err);
2297 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2301 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2302 if (fix_data(nid, &j) == 0)
2305 "invalid characters in string %s\n",buf);
2309 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2310 (unsigned char *)buf,
2311 strlen(buf))) == NULL)
2314 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2318 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2324 * Now extract the key from the SPKI structure.
2327 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2329 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2331 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2335 j = NETSCAPE_SPKI_verify(spki, pktmp);
2338 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2341 BIO_printf(bio_err,"Signature ok\n");
2343 X509_REQ_set_pubkey(req,pktmp);
2344 EVP_PKEY_free(pktmp);
2345 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2346 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2349 if (req != NULL) X509_REQ_free(req);
2350 if (parms != NULL) CONF_free(parms);
2351 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2352 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2357 static int fix_data(int nid, int *type)
2359 if (nid == NID_pkcs9_emailAddress)
2360 *type=V_ASN1_IA5STRING;
2361 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2362 *type=V_ASN1_T61STRING;
2363 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2364 *type=V_ASN1_T61STRING;
2365 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2367 if (nid == NID_pkcs9_unstructuredName)
2368 *type=V_ASN1_IA5STRING;
2372 static int check_time_format(char *str)
2376 tm.data=(unsigned char *)str;
2377 tm.length=strlen(str);
2378 tm.type=V_ASN1_UTCTIME;
2379 return(ASN1_UTCTIME_check(&tm));
2382 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2384 ASN1_UTCTIME *tm=NULL;
2385 char *row[DB_NUMBER],**rrow,**irow;
2386 char *rev_str = NULL;
2390 for (i=0; i<DB_NUMBER; i++)
2392 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2393 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2395 row[DB_serial]=BUF_strdup("00");
2397 row[DB_serial]=BN_bn2hex(bn);
2399 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2401 BIO_printf(bio_err,"Memory allocation failure\n");
2404 /* We have to lookup by serial number because name lookup
2405 * skips revoked certs
2407 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2410 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2412 /* We now just add it to the database */
2413 row[DB_type]=(char *)OPENSSL_malloc(2);
2415 tm=X509_get_notAfter(x509);
2416 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2417 memcpy(row[DB_exp_date],tm->data,tm->length);
2418 row[DB_exp_date][tm->length]='\0';
2420 row[DB_rev_date]=NULL;
2422 /* row[DB_serial] done already */
2423 row[DB_file]=(char *)OPENSSL_malloc(8);
2425 /* row[DB_name] done already */
2427 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2428 (row[DB_file] == NULL))
2430 BIO_printf(bio_err,"Memory allocation failure\n");
2433 strcpy(row[DB_file],"unknown");
2434 row[DB_type][0]='V';
2435 row[DB_type][1]='\0';
2437 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2439 BIO_printf(bio_err,"Memory allocation failure\n");
2443 for (i=0; i<DB_NUMBER; i++)
2448 irow[DB_NUMBER]=NULL;
2450 if (!TXT_DB_insert(db->db,irow))
2452 BIO_printf(bio_err,"failed to update database\n");
2453 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2457 /* Revoke Certificate */
2458 ok = do_revoke(x509,db, type, value);
2463 else if (index_name_cmp((const char **)row,(const char **)rrow))
2465 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2469 else if (rrow[DB_type][0]=='R')
2471 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2477 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2478 rev_str = make_revocation_str(type, value);
2481 BIO_printf(bio_err, "Error in revocation arguments\n");
2484 rrow[DB_type][0]='R';
2485 rrow[DB_type][1]='\0';
2486 rrow[DB_rev_date] = rev_str;
2490 for (i=0; i<DB_NUMBER; i++)
2493 OPENSSL_free(row[i]);
2498 static int get_certificate_status(const char *serial, CA_DB *db)
2500 char *row[DB_NUMBER],**rrow;
2503 /* Free Resources */
2504 for (i=0; i<DB_NUMBER; i++)
2507 /* Malloc needed char spaces */
2508 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2509 if (row[DB_serial] == NULL)
2511 BIO_printf(bio_err,"Malloc failure\n");
2515 if (strlen(serial) % 2)
2517 /* Set the first char to 0 */;
2518 row[DB_serial][0]='0';
2520 /* Copy String from serial to row[DB_serial] */
2521 memcpy(row[DB_serial]+1, serial, strlen(serial));
2522 row[DB_serial][strlen(serial)+1]='\0';
2526 /* Copy String from serial to row[DB_serial] */
2527 memcpy(row[DB_serial], serial, strlen(serial));
2528 row[DB_serial][strlen(serial)]='\0';
2531 /* Make it Upper Case */
2532 for (i=0; row[DB_serial][i] != '\0'; i++)
2533 row[DB_serial][i] = toupper(row[DB_serial][i]);
2538 /* Search for the certificate */
2539 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2542 BIO_printf(bio_err,"Serial %s not present in db.\n",
2547 else if (rrow[DB_type][0]=='V')
2549 BIO_printf(bio_err,"%s=Valid (%c)\n",
2550 row[DB_serial], rrow[DB_type][0]);
2553 else if (rrow[DB_type][0]=='R')
2555 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2556 row[DB_serial], rrow[DB_type][0]);
2559 else if (rrow[DB_type][0]=='E')
2561 BIO_printf(bio_err,"%s=Expired (%c)\n",
2562 row[DB_serial], rrow[DB_type][0]);
2565 else if (rrow[DB_type][0]=='S')
2567 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2568 row[DB_serial], rrow[DB_type][0]);
2573 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2574 row[DB_serial], rrow[DB_type][0]);
2578 for (i=0; i<DB_NUMBER; i++)
2581 OPENSSL_free(row[i]);
2586 static int do_updatedb (CA_DB *db)
2588 ASN1_UTCTIME *a_tm = NULL;
2590 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2591 char **rrow, *a_tm_s;
2593 a_tm = ASN1_UTCTIME_new();
2595 /* get actual time and make a string */
2596 a_tm = X509_gmtime_adj(a_tm, 0);
2597 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2604 memcpy(a_tm_s, a_tm->data, a_tm->length);
2605 a_tm_s[a_tm->length] = '\0';
2607 if (strncmp(a_tm_s, "49", 2) <= 0)
2612 for (i = 0; i < sk_num(db->db->data); i++)
2614 rrow = (char **) sk_value(db->db->data, i);
2616 if (rrow[DB_type][0] == 'V')
2618 /* ignore entries that are not valid */
2619 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2624 if (db_y2k == a_y2k)
2626 /* all on the same y2k side */
2627 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2629 rrow[DB_type][0] = 'E';
2630 rrow[DB_type][1] = '\0';
2633 BIO_printf(bio_err, "%s=Expired\n",
2637 else if (db_y2k < a_y2k)
2639 rrow[DB_type][0] = 'E';
2640 rrow[DB_type][1] = '\0';
2643 BIO_printf(bio_err, "%s=Expired\n",
2652 ASN1_UTCTIME_free(a_tm);
2653 OPENSSL_free(a_tm_s);
2658 static char *crl_reasons[] = {
2659 /* CRL reason strings */
2663 "affiliationChanged",
2665 "cessationOfOperation",
2668 /* Additional pseudo reasons */
2674 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2676 /* Given revocation information convert to a DB string.
2677 * The format of the string is:
2678 * revtime[,reason,extra]. Where 'revtime' is the
2679 * revocation time (the current time). 'reason' is the
2680 * optional CRL reason and 'extra' is any additional
2684 char *make_revocation_str(int rev_type, char *rev_arg)
2686 char *reason = NULL, *other = NULL, *str;
2688 ASN1_UTCTIME *revtm = NULL;
2695 case REV_CRL_REASON:
2696 for (i = 0; i < 8; i++)
2698 if (!strcasecmp(rev_arg, crl_reasons[i]))
2700 reason = crl_reasons[i];
2706 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2712 /* Argument is an OID */
2714 otmp = OBJ_txt2obj(rev_arg, 0);
2715 ASN1_OBJECT_free(otmp);
2719 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2723 reason = "holdInstruction";
2727 case REV_KEY_COMPROMISE:
2728 case REV_CA_COMPROMISE:
2730 /* Argument is the key compromise time */
2731 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2733 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2737 if (rev_type == REV_KEY_COMPROMISE)
2740 reason = "CAkeyTime";
2746 revtm = X509_gmtime_adj(NULL, 0);
2748 i = revtm->length + 1;
2750 if (reason) i += strlen(reason) + 1;
2751 if (other) i += strlen(other) + 1;
2753 str = OPENSSL_malloc(i);
2755 if (!str) return NULL;
2757 strcpy(str, (char *)revtm->data);
2761 strcat(str, reason);
2768 ASN1_UTCTIME_free(revtm);
2772 /* Convert revocation field to X509_REVOKED entry
2776 * 2 OK and some extensions added (i.e. V2 CRL)
2780 int make_revoked(X509_REVOKED *rev, char *str)
2783 int reason_code = -1;
2785 ASN1_OBJECT *hold = NULL;
2786 ASN1_GENERALIZEDTIME *comp_time = NULL;
2787 ASN1_ENUMERATED *rtmp = NULL;
2789 ASN1_TIME *revDate = NULL;
2791 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2796 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2799 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2801 rtmp = ASN1_ENUMERATED_new();
2802 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2804 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2808 if (rev && comp_time)
2810 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2815 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2819 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2825 if (tmp) OPENSSL_free(tmp);
2826 ASN1_OBJECT_free(hold);
2827 ASN1_GENERALIZEDTIME_free(comp_time);
2828 ASN1_ENUMERATED_free(rtmp);
2829 ASN1_TIME_free(revDate);
2835 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2836 * where characters may be escaped by \
2838 X509_NAME *do_subject(char *subject, long chtype)
2840 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2841 char *buf = OPENSSL_malloc(buflen);
2842 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2843 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2844 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2846 char *sp = subject, *bp = buf;
2849 X509_NAME *n = NULL;
2852 if (!buf || !ne_types || !ne_values)
2854 BIO_printf(bio_err, "malloc error\n");
2858 if (*subject != '/')
2860 BIO_printf(bio_err, "Subject does not start with '/'.\n");
2863 sp++; /* skip leading / */
2868 ne_types[ne_num] = bp;
2871 if (*sp == '\\') /* is there anything to escape in the type...? */
2877 BIO_printf(bio_err, "escape character at end of string\n");
2881 else if (*sp == '=')
2892 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2895 ne_values[ne_num] = bp;
2904 BIO_printf(bio_err, "escape character at end of string\n");
2908 else if (*sp == '/')
2920 if (!(n = X509_NAME_new()))
2923 for (i = 0; i < ne_num; i++)
2925 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2927 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2933 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2937 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
2941 OPENSSL_free(ne_values);
2942 OPENSSL_free(ne_types);
2949 OPENSSL_free(ne_values);
2951 OPENSSL_free(ne_types);
2957 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2959 char buf[25],*pbuf, *p;
2961 j=i2a_ASN1_OBJECT(bp,obj);
2963 for (j=22-j; j>0; j--)
2969 if (str->type == V_ASN1_PRINTABLESTRING)
2970 BIO_printf(bp,"PRINTABLE:'");
2971 else if (str->type == V_ASN1_T61STRING)
2972 BIO_printf(bp,"T61STRING:'");
2973 else if (str->type == V_ASN1_IA5STRING)
2974 BIO_printf(bp,"IA5STRING:'");
2975 else if (str->type == V_ASN1_UNIVERSALSTRING)
2976 BIO_printf(bp,"UNIVERSALSTRING:'");
2978 BIO_printf(bp,"ASN.1 %2d:'",str->type);
2980 p=(char *)str->data;
2981 for (j=str->length; j>0; j--)
2983 if ((*p >= ' ') && (*p <= '~'))
2984 BIO_printf(bp,"%c",*p);
2986 BIO_printf(bp,"\\0x%02X",*p);
2987 else if ((unsigned char)*p == 0xf7)
2988 BIO_printf(bp,"^?");
2989 else BIO_printf(bp,"^%c",*p+'@');
2992 BIO_printf(bp,"'\n");
2996 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
2999 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3000 int reason_code = -1;
3002 ASN1_OBJECT *hold = NULL;
3003 ASN1_GENERALIZEDTIME *comp_time = NULL;
3004 tmp = BUF_strdup(str);
3006 p = strchr(tmp, ',');
3025 *prevtm = ASN1_UTCTIME_new();
3026 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3028 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3034 for (i = 0; i < NUM_REASONS; i++)
3036 if(!strcasecmp(reason_str, crl_reasons[i]))
3042 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3044 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3048 if (reason_code == 7)
3049 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3050 else if (reason_code == 8) /* Hold instruction */
3054 BIO_printf(bio_err, "missing hold instruction\n");
3057 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3058 hold = OBJ_txt2obj(arg_str, 0);
3062 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3065 if (phold) *phold = hold;
3067 else if ((reason_code == 9) || (reason_code == 10))
3071 BIO_printf(bio_err, "missing compromised time\n");
3074 comp_time = ASN1_GENERALIZEDTIME_new();
3075 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3077 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3080 if (reason_code == 9)
3081 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3083 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3087 if (preason) *preason = reason_code;
3088 if (pinvtm) *pinvtm = comp_time;
3089 else ASN1_GENERALIZEDTIME_free(comp_time);
3095 if (tmp) OPENSSL_free(tmp);
3096 if (!phold) ASN1_OBJECT_free(hold);
3097 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);