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, int selfsign);
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,
228 int ext_copy, int selfsign);
229 static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
230 static int get_certificate_status(const char *ser_status, CA_DB *db);
231 static int do_updatedb(CA_DB *db);
232 static int check_time_format(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;
296 X509 *x509=NULL, *x509p = NULL;
298 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
302 X509_REVOKED *r=NULL;
304 ASN1_INTEGER *tmpser;
307 const EVP_MD *dgst=NULL;
308 STACK_OF(CONF_VALUE) *attribs=NULL;
309 STACK_OF(X509) *cert_sk=NULL;
312 MS_STATIC char buf[3][BSIZE];
314 #ifndef OPENSSL_NO_ENGINE
335 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
336 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
342 if (strcmp(*argv,"-verbose") == 0)
344 else if (strcmp(*argv,"-config") == 0)
346 if (--argc < 1) goto bad;
347 configfile= *(++argv);
349 else if (strcmp(*argv,"-name") == 0)
351 if (--argc < 1) goto bad;
354 else if (strcmp(*argv,"-subj") == 0)
356 if (--argc < 1) goto bad;
360 else if (strcmp(*argv,"-startdate") == 0)
362 if (--argc < 1) goto bad;
363 startdate= *(++argv);
365 else if (strcmp(*argv,"-enddate") == 0)
367 if (--argc < 1) goto bad;
370 else if (strcmp(*argv,"-days") == 0)
372 if (--argc < 1) goto bad;
373 days=atoi(*(++argv));
375 else if (strcmp(*argv,"-md") == 0)
377 if (--argc < 1) goto bad;
380 else if (strcmp(*argv,"-policy") == 0)
382 if (--argc < 1) goto bad;
385 else if (strcmp(*argv,"-keyfile") == 0)
387 if (--argc < 1) goto bad;
390 else if (strcmp(*argv,"-keyform") == 0)
392 if (--argc < 1) goto bad;
393 keyform=str2fmt(*(++argv));
395 else if (strcmp(*argv,"-passin") == 0)
397 if (--argc < 1) goto bad;
398 passargin= *(++argv);
400 else if (strcmp(*argv,"-key") == 0)
402 if (--argc < 1) goto bad;
405 else if (strcmp(*argv,"-cert") == 0)
407 if (--argc < 1) goto bad;
410 else if (strcmp(*argv,"-selfsign") == 0)
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();
562 #ifdef OPENSSL_SYS_VMS
563 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE));
566 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1);
570 strcat(tofree,CONFIG_FILE);
574 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
575 conf = NCONF_new(NULL);
576 if (NCONF_load(conf,configfile,&errorline) <= 0)
579 BIO_printf(bio_err,"error loading the config file '%s'\n",
582 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
583 ,errorline,configfile);
588 OPENSSL_free(tofree);
592 if (!load_config(bio_err, conf))
595 /* Lets get the config section we are using */
598 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
601 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
608 p=NCONF_get_string(conf,NULL,"oid_file");
615 oid_bio=BIO_new_file(p,"r");
619 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
620 ERR_print_errors(bio_err);
626 OBJ_create_objects(oid_bio);
630 if (!add_oid_section(bio_err,conf))
632 ERR_print_errors(bio_err);
637 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
638 if (randfile == NULL)
640 app_RAND_load_file(randfile, bio_err, 0);
642 db_attr.unique_subject = 1;
643 p = NCONF_get_string(conf, section, "unique_subject");
647 BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
651 case 'f': /* false */
652 case 'F': /* FALSE */
655 db_attr.unique_subject = 0;
662 db_attr.unique_subject = 1;
668 BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
671 BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n",
672 db_attr.unique_subject);
675 in=BIO_new(BIO_s_file());
676 out=BIO_new(BIO_s_file());
677 Sout=BIO_new(BIO_s_file());
678 Cout=BIO_new(BIO_s_file());
679 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
681 ERR_print_errors(bio_err);
685 /*****************************************************************/
686 /* report status of cert with serial number given on command line */
689 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
691 lookup_fail(section,ENV_DATABASE);
694 db = load_index(dbfile,&db_attr);
695 if (db == NULL) goto err;
697 if (!index_index(db)) goto err;
699 if (get_certificate_status(ser_status,db) != 1)
700 BIO_printf(bio_err,"Error verifying serial %s!\n",
705 /*****************************************************************/
706 /* we definitely need a private key, so let's get it */
708 if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
709 section,ENV_PRIVATE_KEY)) == NULL))
711 lookup_fail(section,ENV_PRIVATE_KEY);
717 if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
719 BIO_printf(bio_err,"Error getting password\n");
723 pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
725 if (key) OPENSSL_cleanse(key,strlen(key));
728 /* load_key() has already printed an appropriate message */
732 /*****************************************************************/
733 /* we need a certificate */
734 if (!selfsign || spkac_file || ss_cert_file || gencrl)
736 if ((certfile == NULL)
737 && ((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 if (!selfsign) x509p = x509;
756 f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
759 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
761 f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
764 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
767 f=NCONF_get_string(conf,section,ENV_NAMEOPT);
771 if (!set_name_ex(&nameopt, f))
773 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
781 f=NCONF_get_string(conf,section,ENV_CERTOPT);
785 if (!set_cert_ex(&certopt, f))
787 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
795 f=NCONF_get_string(conf,section,ENV_EXTCOPY);
799 if (!set_ext_copy(&ext_copy, f))
801 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
808 /*****************************************************************/
809 /* lookup where to write new certificates */
810 if ((outdir == NULL) && (req))
814 if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
817 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
820 #ifndef OPENSSL_SYS_VMS
821 /* outdir is a directory spec, but access() for VMS demands a
822 filename. In any case, stat(), below, will catch the problem
823 if outdir is not a directory spec, and the fopen() or open()
824 will catch an error if there is no write access.
826 Presumably, this problem could also be solved by using the DEC
827 C routines to convert the directory syntax to Unixly, and give
828 that to access(). However, time's too short to do that just
831 if (access(outdir,R_OK|W_OK|X_OK) != 0)
833 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
838 if (stat(outdir,&sb) != 0)
840 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
845 if (!(sb.st_mode & S_IFDIR))
847 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
855 /*****************************************************************/
856 /* we need to load the database file */
857 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
859 lookup_fail(section,ENV_DATABASE);
862 db = load_index(dbfile, &db_attr);
863 if (db == NULL) goto err;
865 /* Lets check some fields */
866 for (i=0; i<sk_num(db->db->data); i++)
868 pp=(char **)sk_value(db->db->data,i);
869 if ((pp[DB_type][0] != DB_TYPE_REV) &&
870 (pp[DB_rev_date][0] != '\0'))
872 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
875 if ((pp[DB_type][0] == DB_TYPE_REV) &&
876 !make_revoked(NULL, pp[DB_rev_date]))
878 BIO_printf(bio_err," in entry %d\n", i+1);
881 if (!check_time_format(pp[DB_exp_date]))
883 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
893 if ((j&1) || (j < 2))
895 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
900 if (!( ((*p >= '0') && (*p <= '9')) ||
901 ((*p >= 'A') && (*p <= 'F')) ||
902 ((*p >= 'a') && (*p <= 'f'))) )
904 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);
912 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
913 #ifdef OPENSSL_SYS_VMS
915 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
916 out = BIO_push(tmpbio, out);
919 TXT_DB_write(out,db->db);
920 BIO_printf(bio_err,"%d entries loaded from the database\n",
922 BIO_printf(bio_err,"generating index\n");
925 if (!index_index(db)) goto err;
927 /*****************************************************************/
928 /* Update the db file for expired certificates */
932 BIO_printf(bio_err, "Updating %s ...\n",
938 BIO_printf(bio_err,"Malloc failure\n");
943 if (verbose) BIO_printf(bio_err,
944 "No entries found to mark expired\n");
948 if (!save_index(dbfile,"new",db)) goto err;
950 if (!rotate_index(dbfile,"new","old")) goto err;
952 if (verbose) BIO_printf(bio_err,
953 "Done. %d entries marked as expired\n",i);
958 /*****************************************************************/
959 /* Read extentions config file */
962 extconf = NCONF_new(NULL);
963 if (NCONF_load(extconf,extfile,&errorline) <= 0)
966 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
969 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
976 BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
978 /* We can have sections in the ext file */
979 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
980 extensions = "default";
983 /*****************************************************************/
988 if (BIO_write_filename(Sout,outfile) <= 0)
996 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
997 #ifdef OPENSSL_SYS_VMS
999 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1000 Sout = BIO_push(tmpbio, Sout);
1008 if ((md == NULL) && ((md=NCONF_get_string(conf,
1009 section,ENV_DEFAULT_MD)) == NULL))
1011 lookup_fail(section,ENV_DEFAULT_MD);
1014 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1015 section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1017 if(strcmp(tmp_email_dn,"no") == 0)
1020 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1022 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1026 BIO_printf(bio_err,"message digest is %s\n",
1027 OBJ_nid2ln(dgst->type));
1028 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1029 section,ENV_POLICY)) == NULL))
1031 lookup_fail(section,ENV_POLICY);
1035 BIO_printf(bio_err,"policy is %s\n",policy);
1037 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1040 lookup_fail(section,ENV_SERIAL);
1046 /* no '-extfile' option, so we look for extensions
1047 * in the main configuration file */
1050 extensions=NCONF_get_string(conf,section,
1057 /* Check syntax of file */
1059 X509V3_set_ctx_test(&ctx);
1060 X509V3_set_nconf(&ctx, conf);
1061 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1065 "Error Loading extension section %s\n",
1073 if (startdate == NULL)
1075 startdate=NCONF_get_string(conf,section,
1076 ENV_DEFAULT_STARTDATE);
1077 if (startdate == NULL)
1080 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1082 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1085 if (startdate == NULL) startdate="today";
1087 if (enddate == NULL)
1089 enddate=NCONF_get_string(conf,section,
1090 ENV_DEFAULT_ENDDATE);
1091 if (enddate == NULL)
1094 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1096 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1102 if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1105 if (!enddate && (days == 0))
1107 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1111 if ((serial=load_serial(serialfile, 0, NULL)) == NULL)
1113 BIO_printf(bio_err,"error while loading serial number\n");
1118 if (BN_is_zero(serial))
1119 BIO_printf(bio_err,"next serial number is 00\n");
1122 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1123 BIO_printf(bio_err,"next serial number is %s\n",f);
1128 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1130 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1134 if ((cert_sk=sk_X509_new_null()) == NULL)
1136 BIO_printf(bio_err,"Memory allocation failure\n");
1139 if (spkac_file != NULL)
1142 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1143 serial,subj,email_dn,startdate,enddate,days,extensions,
1144 conf,verbose,certopt,nameopt,default_op,ext_copy);
1145 if (j < 0) goto err;
1149 BIO_printf(bio_err,"\n");
1150 if (!BN_add_word(serial,1)) goto err;
1151 if (!sk_X509_push(cert_sk,x))
1153 BIO_printf(bio_err,"Memory allocation failure\n");
1163 if (ss_cert_file != NULL)
1166 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1167 db,serial,subj,email_dn,startdate,enddate,days,batch,
1168 extensions,conf,verbose, certopt, nameopt,
1169 default_op, ext_copy, e);
1170 if (j < 0) goto err;
1174 BIO_printf(bio_err,"\n");
1175 if (!BN_add_word(serial,1)) goto err;
1176 if (!sk_X509_push(cert_sk,x))
1178 BIO_printf(bio_err,"Memory allocation failure\n");
1186 j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
1187 serial,subj,email_dn,startdate,enddate,days,batch,
1188 extensions,conf,verbose, certopt, nameopt,
1189 default_op, ext_copy, selfsign);
1190 if (j < 0) goto err;
1194 BIO_printf(bio_err,"\n");
1195 if (!BN_add_word(serial,1)) goto err;
1196 if (!sk_X509_push(cert_sk,x))
1198 BIO_printf(bio_err,"Memory allocation failure\n");
1203 for (i=0; i<argc; i++)
1206 j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
1207 serial,subj,email_dn,startdate,enddate,days,batch,
1208 extensions,conf,verbose, certopt, nameopt,
1209 default_op, ext_copy, selfsign);
1210 if (j < 0) goto err;
1214 BIO_printf(bio_err,"\n");
1215 if (!BN_add_word(serial,1)) goto err;
1216 if (!sk_X509_push(cert_sk,x))
1218 BIO_printf(bio_err,"Memory allocation failure\n");
1223 /* we have a stack of newly certified certificates
1224 * and a data base and serial number that need
1227 if (sk_X509_num(cert_sk) > 0)
1231 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1232 (void)BIO_flush(bio_err);
1234 fgets(buf[0],10,stdin);
1235 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1237 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1243 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1245 if(strlen(serialfile) > BSIZE-5 || strlen(dbfile) > BSIZE-5)
1247 BIO_printf(bio_err,"file name too long\n");
1251 strcpy(buf[0],serialfile);
1253 #ifdef OPENSSL_SYS_VMS
1254 strcat(buf[0],"-new");
1256 strcat(buf[0],".new");
1259 if (!save_serial(buf[0],serial,NULL)) goto err;
1261 if (!save_index(dbfile, "new", db)) goto err;
1265 BIO_printf(bio_err,"writing new certificates\n");
1266 for (i=0; i<sk_X509_num(cert_sk); i++)
1271 x=sk_X509_value(cert_sk,i);
1273 j=x->cert_info->serialNumber->length;
1274 p=(char *)x->cert_info->serialNumber->data;
1276 if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1278 BIO_printf(bio_err,"certificate file name too long\n");
1282 strcpy(buf[2],outdir);
1284 #ifndef OPENSSL_SYS_VMS
1288 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1293 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1302 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1305 BIO_printf(bio_err,"writing %s\n",buf[2]);
1307 if (BIO_write_filename(Cout,buf[2]) <= 0)
1312 write_new_certificate(Cout,x, 0, notext);
1313 write_new_certificate(Sout,x, output_der, notext);
1316 if (sk_X509_num(cert_sk))
1318 /* Rename the database and the serial file */
1319 strncpy(buf[2],serialfile,BSIZE-4);
1320 buf[2][BSIZE-4]='\0';
1322 #ifdef OPENSSL_SYS_VMS
1323 strcat(buf[2],"-old");
1325 strcat(buf[2],".old");
1332 if (rename(serialfile,buf[2]) < 0)
1334 BIO_printf(bio_err,"unable to rename %s to %s\n",
1339 if (rename(buf[0],serialfile) < 0)
1341 BIO_printf(bio_err,"unable to rename %s to %s\n",
1344 rename(buf[2],serialfile);
1348 if (!rotate_index(dbfile,"new","old")) goto err;
1350 BIO_printf(bio_err,"Data Base Updated\n");
1354 /*****************************************************************/
1360 crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1366 /* Check syntax of file */
1368 X509V3_set_ctx_test(&ctx);
1369 X509V3_set_nconf(&ctx, conf);
1370 if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1373 "Error Loading CRL extension section %s\n",
1380 if (!crldays && !crlhours)
1382 if (!NCONF_get_number(conf,section,
1383 ENV_DEFAULT_CRL_DAYS, &crldays))
1385 if (!NCONF_get_number(conf,section,
1386 ENV_DEFAULT_CRL_HOURS, &crlhours))
1389 if ((crldays == 0) && (crlhours == 0))
1391 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1395 if (verbose) BIO_printf(bio_err,"making CRL\n");
1396 if ((crl=X509_CRL_new()) == NULL) goto err;
1397 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1399 tmptm = ASN1_TIME_new();
1400 if (!tmptm) goto err;
1401 X509_gmtime_adj(tmptm,0);
1402 X509_CRL_set_lastUpdate(crl, tmptm);
1403 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1404 X509_CRL_set_nextUpdate(crl, tmptm);
1406 ASN1_TIME_free(tmptm);
1408 for (i=0; i<sk_num(db->db->data); i++)
1410 pp=(char **)sk_value(db->db->data,i);
1411 if (pp[DB_type][0] == DB_TYPE_REV)
1413 if ((r=X509_REVOKED_new()) == NULL) goto err;
1414 j = make_revoked(r, pp[DB_rev_date]);
1416 if (j == 2) crl_v2 = 1;
1417 if (!BN_hex2bn(&serial, pp[DB_serial]))
1419 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1424 X509_REVOKED_set_serialNumber(r, tmpser);
1425 ASN1_INTEGER_free(tmpser);
1426 X509_CRL_add0_revoked(crl,r);
1430 /* sort the data so it will be written in serial
1434 /* we now have a CRL */
1435 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1438 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1440 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1446 #ifndef OPENSSL_NO_DSA
1447 if (pkey->type == EVP_PKEY_DSA)
1451 #ifndef OPENSSL_NO_ECDSA
1452 if (pkey->type == EVP_PKEY_EC)
1459 /* Add any extensions asked for */
1464 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1465 X509V3_set_nconf(&crlctx, conf);
1467 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1468 crl_ext, crl)) goto err;
1470 if (crl_ext || crl_v2)
1472 if (!X509_CRL_set_version(crl, 1))
1473 goto err; /* version 2 CRL */
1476 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1478 PEM_write_bio_X509_CRL(Sout,crl);
1480 /*****************************************************************/
1485 BIO_printf(bio_err,"no input files\n");
1491 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1493 if (revcert == NULL)
1495 j=do_revoke(revcert,db, rev_type, rev_arg);
1496 if (j <= 0) goto err;
1499 if (!save_index(dbfile, "new", db)) goto err;
1501 if (!rotate_index(dbfile, "new", "old")) goto err;
1503 BIO_printf(bio_err,"Data Base Updated\n");
1506 /*****************************************************************/
1510 OPENSSL_free(tofree);
1517 sk_X509_pop_free(cert_sk,X509_free);
1519 if (ret) ERR_print_errors(bio_err);
1520 app_RAND_write_file(randfile, bio_err);
1521 if (free_key && key)
1525 EVP_PKEY_free(pkey);
1526 if (x509) X509_free(x509);
1534 static void lookup_fail(char *name, char *tag)
1536 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1539 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1540 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1541 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1542 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1543 unsigned long certopt, unsigned long nameopt, int default_op,
1544 int ext_copy, int selfsign)
1548 EVP_PKEY *pktmp=NULL;
1551 in=BIO_new(BIO_s_file());
1553 if (BIO_read_filename(in,infile) <= 0)
1558 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1560 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1565 X509_REQ_print(bio_err,req);
1567 BIO_printf(bio_err,"Check that the request matches the signature\n");
1569 if (selfsign && !X509_REQ_check_private_key(req,pkey))
1571 BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
1575 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1577 BIO_printf(bio_err,"error unpacking public key\n");
1580 i=X509_REQ_verify(req,pktmp);
1581 EVP_PKEY_free(pktmp);
1585 BIO_printf(bio_err,"Signature verification problems....\n");
1591 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1595 BIO_printf(bio_err,"Signature ok\n");
1597 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1598 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1599 certopt, nameopt, default_op, ext_copy, selfsign);
1602 if (req != NULL) X509_REQ_free(req);
1603 if (in != NULL) BIO_free(in);
1607 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1608 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1609 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1610 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1611 unsigned long certopt, unsigned long nameopt, int default_op,
1612 int ext_copy, ENGINE *e)
1615 X509_REQ *rreq=NULL;
1616 EVP_PKEY *pktmp=NULL;
1619 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1622 X509_print(bio_err,req);
1624 BIO_printf(bio_err,"Check that the request matches the signature\n");
1626 if ((pktmp=X509_get_pubkey(req)) == NULL)
1628 BIO_printf(bio_err,"error unpacking public key\n");
1631 i=X509_verify(req,pktmp);
1632 EVP_PKEY_free(pktmp);
1636 BIO_printf(bio_err,"Signature verification problems....\n");
1642 BIO_printf(bio_err,"Signature did not match the certificate\n");
1646 BIO_printf(bio_err,"Signature ok\n");
1648 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1651 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1652 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1656 if (rreq != NULL) X509_REQ_free(rreq);
1657 if (req != NULL) X509_free(req);
1661 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1662 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1663 int email_dn, char *startdate, char *enddate, long days, int batch,
1664 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1665 unsigned long certopt, unsigned long nameopt, int default_op,
1666 int ext_copy, int selfsign)
1668 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1669 ASN1_UTCTIME *tm,*tmptm;
1670 ASN1_STRING *str,*str2;
1674 X509_NAME_ENTRY *ne;
1675 X509_NAME_ENTRY *tne,*push;
1677 int ok= -1,i,j,last,nid;
1680 char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
1683 tmptm=ASN1_UTCTIME_new();
1686 BIO_printf(bio_err,"malloc error\n");
1690 for (i=0; i<DB_NUMBER; i++)
1695 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1699 ERR_print_errors(bio_err);
1702 X509_REQ_set_subject_name(req,n);
1703 req->req_info->enc.modified = 1;
1708 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1710 name=X509_REQ_get_subject_name(req);
1711 for (i=0; i<X509_NAME_entry_count(name); i++)
1713 ne= X509_NAME_get_entry(name,i);
1714 str=X509_NAME_ENTRY_get_data(ne);
1715 obj=X509_NAME_ENTRY_get_object(ne);
1719 /* assume all type should be strings */
1720 nid=OBJ_obj2nid(ne->object);
1722 if (str->type == V_ASN1_UNIVERSALSTRING)
1723 ASN1_UNIVERSALSTRING_to_string(str);
1725 if ((str->type == V_ASN1_IA5STRING) &&
1726 (nid != NID_pkcs9_emailAddress))
1727 str->type=V_ASN1_T61STRING;
1729 if ((nid == NID_pkcs9_emailAddress) &&
1730 (str->type == V_ASN1_PRINTABLESTRING))
1731 str->type=V_ASN1_IA5STRING;
1734 /* If no EMAIL is wanted in the subject */
1735 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1738 /* check some things */
1739 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1740 (str->type != V_ASN1_IA5STRING))
1742 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1745 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1747 j=ASN1_PRINTABLE_type(str->data,str->length);
1748 if ( ((j == V_ASN1_T61STRING) &&
1749 (str->type != V_ASN1_T61STRING)) ||
1750 ((j == V_ASN1_IA5STRING) &&
1751 (str->type == V_ASN1_PRINTABLESTRING)))
1753 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1759 old_entry_print(bio_err, obj, str);
1762 /* Ok, now we check the 'policy' stuff. */
1763 if ((subject=X509_NAME_new()) == NULL)
1765 BIO_printf(bio_err,"Memory allocation failure\n");
1769 /* take a copy of the issuer name before we mess with it. */
1771 CAname=X509_NAME_dup(name);
1773 CAname=X509_NAME_dup(x509->cert_info->subject);
1774 if (CAname == NULL) goto err;
1777 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1779 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1780 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1782 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1790 /* lookup the object in the supplied name list */
1791 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1794 if (last != -1) break;
1799 tne=X509_NAME_get_entry(name,j);
1803 /* depending on the 'policy', decide what to do. */
1805 if (strcmp(cv->value,"optional") == 0)
1810 else if (strcmp(cv->value,"supplied") == 0)
1814 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1820 else if (strcmp(cv->value,"match") == 0)
1826 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1833 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1834 if ((j < 0) && (last2 == -1))
1836 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1841 push=X509_NAME_get_entry(CAname,j);
1842 str=X509_NAME_ENTRY_get_data(tne);
1843 str2=X509_NAME_ENTRY_get_data(push);
1845 if (ASN1_STRING_cmp(str,str2) != 0)
1850 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));
1856 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1862 if (!X509_NAME_add_entry(subject,push, -1, 0))
1865 X509_NAME_ENTRY_free(push);
1866 BIO_printf(bio_err,"Memory allocation failure\n");
1876 X509_NAME_free(subject);
1877 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1878 subject=X509_NAME_dup(name);
1879 if (subject == NULL) goto err;
1883 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1885 /* Build the correct Subject if no e-mail is wanted in the subject */
1886 /* and add it later on because of the method extensions are added (altName) */
1889 dn_subject = subject;
1892 X509_NAME_ENTRY *tmpne;
1893 /* Its best to dup the subject DN and then delete any email
1894 * addresses because this retains its structure.
1896 if (!(dn_subject = X509_NAME_dup(subject)))
1898 BIO_printf(bio_err,"Memory allocation failure\n");
1901 while((i = X509_NAME_get_index_by_NID(dn_subject,
1902 NID_pkcs9_emailAddress, -1)) >= 0)
1904 tmpne = X509_NAME_get_entry(dn_subject, i);
1905 X509_NAME_delete_entry(dn_subject, i);
1906 X509_NAME_ENTRY_free(tmpne);
1910 if (BN_is_zero(serial))
1911 row[DB_serial]=BUF_strdup("00");
1913 row[DB_serial]=BN_bn2hex(serial);
1914 if (row[DB_serial] == NULL)
1916 BIO_printf(bio_err,"Memory allocation failure\n");
1920 if (db->attributes.unique_subject)
1922 rrow=TXT_DB_get_by_index(db->db,DB_name,row);
1926 "ERROR:There is already a certificate for %s\n",
1932 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
1935 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1937 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1944 "The matching entry has the following details\n");
1945 if (rrow[DB_type][0] == 'E')
1947 else if (rrow[DB_type][0] == 'R')
1949 else if (rrow[DB_type][0] == 'V')
1952 p="\ninvalid type, Data base error\n";
1953 BIO_printf(bio_err,"Type :%s\n",p);;
1954 if (rrow[DB_type][0] == 'R')
1956 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1957 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1959 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1960 BIO_printf(bio_err,"Expires on :%s\n",p);
1961 p=rrow[DB_serial]; if (p == NULL) p="undef";
1962 BIO_printf(bio_err,"Serial Number :%s\n",p);
1963 p=rrow[DB_file]; if (p == NULL) p="undef";
1964 BIO_printf(bio_err,"File name :%s\n",p);
1965 p=rrow[DB_name]; if (p == NULL) p="undef";
1966 BIO_printf(bio_err,"Subject Name :%s\n",p);
1967 ok= -1; /* This is now a 'bad' error. */
1971 /* We are now totally happy, lets make and sign the certificate */
1973 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1975 if ((ret=X509_new()) == NULL) goto err;
1979 /* Make it an X509 v3 certificate. */
1980 if (!X509_set_version(ret,2)) goto err;
1983 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1987 if (!X509_set_issuer_name(ret,subject))
1992 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1996 if (strcmp(startdate,"today") == 0)
1997 X509_gmtime_adj(X509_get_notBefore(ret),0);
1998 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2000 if (enddate == NULL)
2001 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2002 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2004 if (!X509_set_subject_name(ret,subject)) goto err;
2006 pktmp=X509_REQ_get_pubkey(req);
2007 i = X509_set_pubkey(ret,pktmp);
2008 EVP_PKEY_free(pktmp);
2011 /* Lets add the extensions, if there are any */
2015 if (ci->version == NULL)
2016 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2018 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2020 /* Free the current entries if any, there should not
2021 * be any I believe */
2022 if (ci->extensions != NULL)
2023 sk_X509_EXTENSION_pop_free(ci->extensions,
2024 X509_EXTENSION_free);
2026 ci->extensions = NULL;
2028 /* Initialize the context structure */
2030 X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
2032 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2037 BIO_printf(bio_err, "Extra configuration file found\n");
2039 /* Use the extconf configuration db LHASH */
2040 X509V3_set_nconf(&ctx, extconf);
2042 /* Test the structure (needed?) */
2043 /* X509V3_set_ctx_test(&ctx); */
2045 /* Adds exts contained in the configuration file */
2046 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2049 "ERROR: adding extensions in section %s\n",
2051 ERR_print_errors(bio_err);
2055 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2059 /* We found extensions to be set from config file */
2060 X509V3_set_nconf(&ctx, lconf);
2062 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2064 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2065 ERR_print_errors(bio_err);
2070 BIO_printf(bio_err, "Successfully added extensions from config\n");
2074 /* Copy extensions from request (if any) */
2076 if (!copy_extensions(ret, req, ext_copy))
2078 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2079 ERR_print_errors(bio_err);
2083 /* Set the right value for the noemailDN option */
2086 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2091 BIO_printf(bio_err, "Certificate Details:\n");
2092 /* Never print signature details because signature not present */
2093 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2094 X509_print_ex(bio_err, ret, nameopt, certopt);
2097 BIO_printf(bio_err,"Certificate is to be certified until ");
2098 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2099 if (days) BIO_printf(bio_err," (%d days)",days);
2100 BIO_printf(bio_err, "\n");
2105 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2106 (void)BIO_flush(bio_err);
2108 fgets(buf,sizeof(buf)-1,stdin);
2109 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2111 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2118 #ifndef OPENSSL_NO_DSA
2119 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2120 pktmp=X509_get_pubkey(ret);
2121 if (EVP_PKEY_missing_parameters(pktmp) &&
2122 !EVP_PKEY_missing_parameters(pkey))
2123 EVP_PKEY_copy_parameters(pktmp,pkey);
2124 EVP_PKEY_free(pktmp);
2126 #ifndef OPENSSL_NO_ECDSA
2127 if (pkey->type == EVP_PKEY_EC)
2129 pktmp = X509_get_pubkey(ret);
2130 if (EVP_PKEY_missing_parameters(pktmp) &&
2131 !EVP_PKEY_missing_parameters(pkey))
2132 EVP_PKEY_copy_parameters(pktmp, pkey);
2133 EVP_PKEY_free(pktmp);
2137 if (!X509_sign(ret,pkey,dgst))
2140 /* We now just add it to the database */
2141 row[DB_type]=(char *)OPENSSL_malloc(2);
2143 tm=X509_get_notAfter(ret);
2144 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2145 memcpy(row[DB_exp_date],tm->data,tm->length);
2146 row[DB_exp_date][tm->length]='\0';
2148 row[DB_rev_date]=NULL;
2150 /* row[DB_serial] done already */
2151 row[DB_file]=(char *)OPENSSL_malloc(8);
2152 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2154 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2155 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2157 BIO_printf(bio_err,"Memory allocation failure\n");
2160 strcpy(row[DB_file],"unknown");
2161 row[DB_type][0]='V';
2162 row[DB_type][1]='\0';
2164 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2166 BIO_printf(bio_err,"Memory allocation failure\n");
2170 for (i=0; i<DB_NUMBER; i++)
2175 irow[DB_NUMBER]=NULL;
2177 if (!TXT_DB_insert(db->db,irow))
2179 BIO_printf(bio_err,"failed to update database\n");
2180 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2185 for (i=0; i<DB_NUMBER; i++)
2186 if (row[i] != NULL) OPENSSL_free(row[i]);
2189 X509_NAME_free(CAname);
2190 if (subject != NULL)
2191 X509_NAME_free(subject);
2192 if ((dn_subject != NULL) && !email_dn)
2193 X509_NAME_free(dn_subject);
2195 ASN1_UTCTIME_free(tmptm);
2198 if (ret != NULL) X509_free(ret);
2206 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2211 (void)i2d_X509_bio(bp,x);
2215 /* ??? Not needed since X509_print prints all this stuff anyway */
2216 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2217 BIO_printf(bp,"issuer :%s\n",f);
2219 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2220 BIO_printf(bp,"subject:%s\n",f);
2222 BIO_puts(bp,"serial :");
2223 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2224 BIO_puts(bp,"\n\n");
2226 if (!notext)X509_print(bp,x);
2227 PEM_write_bio_X509(bp,x);
2230 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2231 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2232 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2233 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2234 unsigned long nameopt, int default_op, int ext_copy)
2236 STACK_OF(CONF_VALUE) *sk=NULL;
2239 CONF_VALUE *cv=NULL;
2240 NETSCAPE_SPKI *spki = NULL;
2243 EVP_PKEY *pktmp=NULL;
2245 X509_NAME_ENTRY *ne=NULL;
2251 * Load input file into a hash table. (This is just an easy
2252 * way to read and parse the file, then put it into a convenient
2255 parms=CONF_load(NULL,infile,&errline);
2258 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2259 ERR_print_errors(bio_err);
2263 sk=CONF_get_section(parms, "default");
2264 if (sk_CONF_VALUE_num(sk) == 0)
2266 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2272 * Now create a dummy X509 request structure. We don't actually
2273 * have an X509 request, but we have many of the components
2274 * (a public key, various DN components). The idea is that we
2275 * put these components into the right X509 request structure
2276 * and we can use the same code as if you had a real X509 request.
2281 ERR_print_errors(bio_err);
2286 * Build up the subject name set.
2293 if (sk_CONF_VALUE_num(sk) <= i) break;
2295 cv=sk_CONF_VALUE_value(sk,i);
2297 /* Skip past any leading X. X: X, etc to allow for
2298 * multiple instances
2300 for (buf = cv->name; *buf ; buf++)
2301 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2304 if (*buf) type = buf;
2309 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2311 if (strcmp(type, "SPKAC") == 0)
2313 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2316 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2317 ERR_print_errors(bio_err);
2325 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2329 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2330 if (fix_data(nid, &j) == 0)
2333 "invalid characters in string %s\n",buf);
2337 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2338 (unsigned char *)buf,
2339 strlen(buf))) == NULL)
2342 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2346 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2352 * Now extract the key from the SPKI structure.
2355 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2357 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2359 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2363 j = NETSCAPE_SPKI_verify(spki, pktmp);
2366 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2369 BIO_printf(bio_err,"Signature ok\n");
2371 X509_REQ_set_pubkey(req,pktmp);
2372 EVP_PKEY_free(pktmp);
2373 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2374 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2377 if (req != NULL) X509_REQ_free(req);
2378 if (parms != NULL) CONF_free(parms);
2379 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2380 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2385 static int fix_data(int nid, int *type)
2387 if (nid == NID_pkcs9_emailAddress)
2388 *type=V_ASN1_IA5STRING;
2389 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2390 *type=V_ASN1_T61STRING;
2391 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2392 *type=V_ASN1_T61STRING;
2393 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2395 if (nid == NID_pkcs9_unstructuredName)
2396 *type=V_ASN1_IA5STRING;
2400 static int check_time_format(char *str)
2404 tm.data=(unsigned char *)str;
2405 tm.length=strlen(str);
2406 tm.type=V_ASN1_UTCTIME;
2407 return(ASN1_UTCTIME_check(&tm));
2410 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2412 ASN1_UTCTIME *tm=NULL;
2413 char *row[DB_NUMBER],**rrow,**irow;
2414 char *rev_str = NULL;
2418 for (i=0; i<DB_NUMBER; i++)
2420 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2421 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2423 row[DB_serial]=BUF_strdup("00");
2425 row[DB_serial]=BN_bn2hex(bn);
2427 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2429 BIO_printf(bio_err,"Memory allocation failure\n");
2432 /* We have to lookup by serial number because name lookup
2433 * skips revoked certs
2435 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2438 BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]);
2440 /* We now just add it to the database */
2441 row[DB_type]=(char *)OPENSSL_malloc(2);
2443 tm=X509_get_notAfter(x509);
2444 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2445 memcpy(row[DB_exp_date],tm->data,tm->length);
2446 row[DB_exp_date][tm->length]='\0';
2448 row[DB_rev_date]=NULL;
2450 /* row[DB_serial] done already */
2451 row[DB_file]=(char *)OPENSSL_malloc(8);
2453 /* row[DB_name] done already */
2455 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2456 (row[DB_file] == NULL))
2458 BIO_printf(bio_err,"Memory allocation failure\n");
2461 strcpy(row[DB_file],"unknown");
2462 row[DB_type][0]='V';
2463 row[DB_type][1]='\0';
2465 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2467 BIO_printf(bio_err,"Memory allocation failure\n");
2471 for (i=0; i<DB_NUMBER; i++)
2476 irow[DB_NUMBER]=NULL;
2478 if (!TXT_DB_insert(db->db,irow))
2480 BIO_printf(bio_err,"failed to update database\n");
2481 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error);
2485 /* Revoke Certificate */
2486 ok = do_revoke(x509,db, type, value);
2491 else if (index_name_cmp((const char **)row,(const char **)rrow))
2493 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2497 else if (rrow[DB_type][0]=='R')
2499 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2505 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2506 rev_str = make_revocation_str(type, value);
2509 BIO_printf(bio_err, "Error in revocation arguments\n");
2512 rrow[DB_type][0]='R';
2513 rrow[DB_type][1]='\0';
2514 rrow[DB_rev_date] = rev_str;
2518 for (i=0; i<DB_NUMBER; i++)
2521 OPENSSL_free(row[i]);
2526 static int get_certificate_status(const char *serial, CA_DB *db)
2528 char *row[DB_NUMBER],**rrow;
2531 /* Free Resources */
2532 for (i=0; i<DB_NUMBER; i++)
2535 /* Malloc needed char spaces */
2536 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2537 if (row[DB_serial] == NULL)
2539 BIO_printf(bio_err,"Malloc failure\n");
2543 if (strlen(serial) % 2)
2545 /* Set the first char to 0 */;
2546 row[DB_serial][0]='0';
2548 /* Copy String from serial to row[DB_serial] */
2549 memcpy(row[DB_serial]+1, serial, strlen(serial));
2550 row[DB_serial][strlen(serial)+1]='\0';
2554 /* Copy String from serial to row[DB_serial] */
2555 memcpy(row[DB_serial], serial, strlen(serial));
2556 row[DB_serial][strlen(serial)]='\0';
2559 /* Make it Upper Case */
2560 for (i=0; row[DB_serial][i] != '\0'; i++)
2561 row[DB_serial][i] = toupper(row[DB_serial][i]);
2566 /* Search for the certificate */
2567 rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
2570 BIO_printf(bio_err,"Serial %s not present in db.\n",
2575 else if (rrow[DB_type][0]=='V')
2577 BIO_printf(bio_err,"%s=Valid (%c)\n",
2578 row[DB_serial], rrow[DB_type][0]);
2581 else if (rrow[DB_type][0]=='R')
2583 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2584 row[DB_serial], rrow[DB_type][0]);
2587 else if (rrow[DB_type][0]=='E')
2589 BIO_printf(bio_err,"%s=Expired (%c)\n",
2590 row[DB_serial], rrow[DB_type][0]);
2593 else if (rrow[DB_type][0]=='S')
2595 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2596 row[DB_serial], rrow[DB_type][0]);
2601 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2602 row[DB_serial], rrow[DB_type][0]);
2606 for (i=0; i<DB_NUMBER; i++)
2609 OPENSSL_free(row[i]);
2614 static int do_updatedb (CA_DB *db)
2616 ASN1_UTCTIME *a_tm = NULL;
2618 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2619 char **rrow, *a_tm_s;
2621 a_tm = ASN1_UTCTIME_new();
2623 /* get actual time and make a string */
2624 a_tm = X509_gmtime_adj(a_tm, 0);
2625 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2632 memcpy(a_tm_s, a_tm->data, a_tm->length);
2633 a_tm_s[a_tm->length] = '\0';
2635 if (strncmp(a_tm_s, "49", 2) <= 0)
2640 for (i = 0; i < sk_num(db->db->data); i++)
2642 rrow = (char **) sk_value(db->db->data, i);
2644 if (rrow[DB_type][0] == 'V')
2646 /* ignore entries that are not valid */
2647 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2652 if (db_y2k == a_y2k)
2654 /* all on the same y2k side */
2655 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2657 rrow[DB_type][0] = 'E';
2658 rrow[DB_type][1] = '\0';
2661 BIO_printf(bio_err, "%s=Expired\n",
2665 else if (db_y2k < a_y2k)
2667 rrow[DB_type][0] = 'E';
2668 rrow[DB_type][1] = '\0';
2671 BIO_printf(bio_err, "%s=Expired\n",
2680 ASN1_UTCTIME_free(a_tm);
2681 OPENSSL_free(a_tm_s);
2686 static char *crl_reasons[] = {
2687 /* CRL reason strings */
2691 "affiliationChanged",
2693 "cessationOfOperation",
2696 /* Additional pseudo reasons */
2702 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2704 /* Given revocation information convert to a DB string.
2705 * The format of the string is:
2706 * revtime[,reason,extra]. Where 'revtime' is the
2707 * revocation time (the current time). 'reason' is the
2708 * optional CRL reason and 'extra' is any additional
2712 char *make_revocation_str(int rev_type, char *rev_arg)
2714 char *reason = NULL, *other = NULL, *str;
2716 ASN1_UTCTIME *revtm = NULL;
2723 case REV_CRL_REASON:
2724 for (i = 0; i < 8; i++)
2726 if (!strcasecmp(rev_arg, crl_reasons[i]))
2728 reason = crl_reasons[i];
2734 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2740 /* Argument is an OID */
2742 otmp = OBJ_txt2obj(rev_arg, 0);
2743 ASN1_OBJECT_free(otmp);
2747 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2751 reason = "holdInstruction";
2755 case REV_KEY_COMPROMISE:
2756 case REV_CA_COMPROMISE:
2758 /* Argument is the key compromise time */
2759 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2761 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2765 if (rev_type == REV_KEY_COMPROMISE)
2768 reason = "CAkeyTime";
2774 revtm = X509_gmtime_adj(NULL, 0);
2776 i = revtm->length + 1;
2778 if (reason) i += strlen(reason) + 1;
2779 if (other) i += strlen(other) + 1;
2781 str = OPENSSL_malloc(i);
2783 if (!str) return NULL;
2785 strcpy(str, (char *)revtm->data);
2789 strcat(str, reason);
2796 ASN1_UTCTIME_free(revtm);
2800 /* Convert revocation field to X509_REVOKED entry
2804 * 2 OK and some extensions added (i.e. V2 CRL)
2808 int make_revoked(X509_REVOKED *rev, char *str)
2811 int reason_code = -1;
2813 ASN1_OBJECT *hold = NULL;
2814 ASN1_GENERALIZEDTIME *comp_time = NULL;
2815 ASN1_ENUMERATED *rtmp = NULL;
2817 ASN1_TIME *revDate = NULL;
2819 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2824 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2827 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2829 rtmp = ASN1_ENUMERATED_new();
2830 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2832 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2836 if (rev && comp_time)
2838 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2843 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2847 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2853 if (tmp) OPENSSL_free(tmp);
2854 ASN1_OBJECT_free(hold);
2855 ASN1_GENERALIZEDTIME_free(comp_time);
2856 ASN1_ENUMERATED_free(rtmp);
2857 ASN1_TIME_free(revDate);
2863 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2864 * where characters may be escaped by \
2866 X509_NAME *do_subject(char *subject, long chtype)
2868 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2869 char *buf = OPENSSL_malloc(buflen);
2870 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2871 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2872 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2874 char *sp = subject, *bp = buf;
2877 X509_NAME *n = NULL;
2880 if (!buf || !ne_types || !ne_values)
2882 BIO_printf(bio_err, "malloc error\n");
2886 if (*subject != '/')
2888 BIO_printf(bio_err, "Subject does not start with '/'.\n");
2891 sp++; /* skip leading / */
2896 ne_types[ne_num] = bp;
2899 if (*sp == '\\') /* is there anything to escape in the type...? */
2905 BIO_printf(bio_err, "escape character at end of string\n");
2909 else if (*sp == '=')
2920 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2923 ne_values[ne_num] = bp;
2932 BIO_printf(bio_err, "escape character at end of string\n");
2936 else if (*sp == '/')
2948 if (!(n = X509_NAME_new()))
2951 for (i = 0; i < ne_num; i++)
2953 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2955 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2961 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2965 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
2969 OPENSSL_free(ne_values);
2970 OPENSSL_free(ne_types);
2977 OPENSSL_free(ne_values);
2979 OPENSSL_free(ne_types);
2985 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2987 char buf[25],*pbuf, *p;
2989 j=i2a_ASN1_OBJECT(bp,obj);
2991 for (j=22-j; j>0; j--)
2997 if (str->type == V_ASN1_PRINTABLESTRING)
2998 BIO_printf(bp,"PRINTABLE:'");
2999 else if (str->type == V_ASN1_T61STRING)
3000 BIO_printf(bp,"T61STRING:'");
3001 else if (str->type == V_ASN1_IA5STRING)
3002 BIO_printf(bp,"IA5STRING:'");
3003 else if (str->type == V_ASN1_UNIVERSALSTRING)
3004 BIO_printf(bp,"UNIVERSALSTRING:'");
3006 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3008 p=(char *)str->data;
3009 for (j=str->length; j>0; j--)
3011 if ((*p >= ' ') && (*p <= '~'))
3012 BIO_printf(bp,"%c",*p);
3014 BIO_printf(bp,"\\0x%02X",*p);
3015 else if ((unsigned char)*p == 0xf7)
3016 BIO_printf(bp,"^?");
3017 else BIO_printf(bp,"^%c",*p+'@');
3020 BIO_printf(bp,"'\n");
3024 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3027 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3028 int reason_code = -1;
3030 ASN1_OBJECT *hold = NULL;
3031 ASN1_GENERALIZEDTIME *comp_time = NULL;
3032 tmp = BUF_strdup(str);
3034 p = strchr(tmp, ',');
3053 *prevtm = ASN1_UTCTIME_new();
3054 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3056 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3062 for (i = 0; i < NUM_REASONS; i++)
3064 if(!strcasecmp(reason_str, crl_reasons[i]))
3070 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3072 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3076 if (reason_code == 7)
3077 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3078 else if (reason_code == 8) /* Hold instruction */
3082 BIO_printf(bio_err, "missing hold instruction\n");
3085 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3086 hold = OBJ_txt2obj(arg_str, 0);
3090 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3093 if (phold) *phold = hold;
3095 else if ((reason_code == 9) || (reason_code == 10))
3099 BIO_printf(bio_err, "missing compromised time\n");
3102 comp_time = ASN1_GENERALIZEDTIME_new();
3103 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3105 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3108 if (reason_code == 9)
3109 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3111 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3115 if (preason) *preason = reason_code;
3116 if (pinvtm) *pinvtm = comp_time;
3117 else ASN1_GENERALIZEDTIME_free(comp_time);
3123 if (tmp) OPENSSL_free(tmp);
3124 if (!phold) ASN1_OBJECT_free(hold);
3125 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);