2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
59 /* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
65 #include <sys/types.h>
67 #include <openssl/conf.h>
68 #include <openssl/bio.h>
69 #include <openssl/err.h>
70 #include <openssl/bn.h>
71 #include <openssl/txt_db.h>
72 #include <openssl/evp.h>
73 #include <openssl/x509.h>
74 #include <openssl/x509v3.h>
75 #include <openssl/objects.h>
76 #include <openssl/ocsp.h>
77 #include <openssl/pem.h>
79 #ifdef OPENSSL_SYS_WINDOWS
80 #define strcasecmp _stricmp
86 # endif /* NO_STRINGS_H */
90 # ifdef OPENSSL_SYS_VMS
96 # elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
97 # include <sys/file.h>
113 #define BASE_SECTION "ca"
114 #define CONFIG_FILE "openssl.cnf"
116 #define ENV_DEFAULT_CA "default_ca"
118 #define ENV_DIR "dir"
119 #define ENV_CERTS "certs"
120 #define ENV_CRL_DIR "crl_dir"
121 #define ENV_CA_DB "CA_DB"
122 #define ENV_NEW_CERTS_DIR "new_certs_dir"
123 #define ENV_CERTIFICATE "certificate"
124 #define ENV_SERIAL "serial"
125 #define ENV_CRL "crl"
126 #define ENV_PRIVATE_KEY "private_key"
127 #define ENV_RANDFILE "RANDFILE"
128 #define ENV_DEFAULT_DAYS "default_days"
129 #define ENV_DEFAULT_STARTDATE "default_startdate"
130 #define ENV_DEFAULT_ENDDATE "default_enddate"
131 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
132 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
133 #define ENV_DEFAULT_MD "default_md"
134 #define ENV_DEFAULT_EMAIL_DN "email_in_dn"
135 #define ENV_PRESERVE "preserve"
136 #define ENV_POLICY "policy"
137 #define ENV_EXTENSIONS "x509_extensions"
138 #define ENV_CRLEXT "crl_extensions"
139 #define ENV_MSIE_HACK "msie_hack"
140 #define ENV_NAMEOPT "name_opt"
141 #define ENV_CERTOPT "cert_opt"
142 #define ENV_EXTCOPY "copy_extensions"
144 #define ENV_DATABASE "database"
147 #define DB_exp_date 1
148 #define DB_rev_date 2
149 #define DB_serial 3 /* index - unique */
151 #define DB_name 5 /* index - unique for active */
154 #define DB_TYPE_REV 'R'
155 #define DB_TYPE_EXP 'E'
156 #define DB_TYPE_VAL 'V'
158 /* Additional revocation information types */
160 #define REV_NONE 0 /* No addditional information */
161 #define REV_CRL_REASON 1 /* Value is CRL reason code */
162 #define REV_HOLD 2 /* Value is hold instruction */
163 #define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
164 #define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
166 static char *ca_usage[]={
169 " -verbose - Talk alot while doing things\n",
170 " -config file - A config file\n",
171 " -name arg - The particular CA definition to use\n",
172 " -gencrl - Generate a new CRL\n",
173 " -crldays days - Days is when the next CRL is due\n",
174 " -crlhours hours - Hours is when the next CRL is due\n",
175 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
176 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
177 " -days arg - number of days to certify the certificate for\n",
178 " -md arg - md to use, one of md2, md5, sha or sha1\n",
179 " -policy arg - The CA 'policy' to support\n",
180 " -keyfile arg - private key file\n",
181 " -keyform arg - private key file format (PEM or ENGINE)\n",
182 " -key arg - key to decode the private key if it is encrypted\n",
183 " -cert file - The CA certificate\n",
184 " -in file - The input PEM encoded certificate request(s)\n",
185 " -out file - Where to put the output file(s)\n",
186 " -outdir dir - Where to put output certificates\n",
187 " -infiles .... - The last argument, requests to process\n",
188 " -spkac file - File contains DN and signed public key and challenge\n",
189 " -ss_cert file - File contains a self signed cert to sign\n",
190 " -preserveDN - Don't re-order the DN\n",
191 " -noemailDN - Don't add the EMAIL field into certificate' subject\n",
192 " -batch - Don't ask questions\n",
193 " -msie_hack - msie modifications to handle all those universal strings\n",
194 " -revoke file - Revoke a certificate (given in file)\n",
195 " -subj arg - Use arg instead of request's subject\n",
196 " -extensions .. - Extension section (override value in config file)\n",
197 " -extfile file - Configuration file with X509v3 extentions to add\n",
198 " -crlexts .. - CRL extension section (override value in config file)\n",
199 #ifndef OPENSSL_NO_ENGINE
200 " -engine e - use engine e, possibly a hardware device.\n",
202 " -status serial - Shows certificate status given the serial number\n",
203 " -updatedb - Updates db for expired certificates\n",
208 extern int EF_PROTECT_FREE;
209 extern int EF_PROTECT_BELOW;
210 extern int EF_ALIGNMENT;
213 static void lookup_fail(char *name,char *tag);
214 static unsigned long index_serial_hash(const char **a);
215 static int index_serial_cmp(const char **a, const char **b);
216 static unsigned long index_name_hash(const char **a);
217 static int index_name_qual(char **a);
218 static int index_name_cmp(const char **a,const char **b);
219 static BIGNUM *load_serial(char *serialfile);
220 static int save_serial(char *serialfile, BIGNUM *serial);
221 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
222 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
223 BIGNUM *serial, char *subj, int email_dn, char *startdate,
224 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
225 int verbose, unsigned long certopt, unsigned long nameopt,
226 int default_op, int ext_copy);
227 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
228 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
229 TXT_DB *db, BIGNUM *serial, char *subj, int email_dn,
230 char *startdate, char *enddate, long days, int batch,
231 char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
232 unsigned long nameopt, int default_op, int ext_copy,
234 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
235 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
236 TXT_DB *db, BIGNUM *serial,char *subj, int email_dn,
237 char *startdate, char *enddate, long days, char *ext_sect,
238 CONF *conf, int verbose, unsigned long certopt,
239 unsigned long nameopt, int default_op, int ext_copy);
240 static int fix_data(int nid, int *type);
241 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
242 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
243 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
244 int email_dn, char *startdate, char *enddate, long days, int batch,
245 int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
246 unsigned long certopt, unsigned long nameopt, int default_op,
248 static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
249 static int get_certificate_status(const char *ser_status, TXT_DB *db);
250 static int do_updatedb(TXT_DB *db);
251 static int check_time_format(char *str);
252 char *make_revocation_str(int rev_type, char *rev_arg);
253 int make_revoked(X509_REVOKED *rev, char *str);
254 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
255 static CONF *conf=NULL;
256 static CONF *extconf=NULL;
257 static char *section=NULL;
259 static int preserve=0;
260 static int msie_hack=0;
262 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
263 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
264 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
265 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
268 int MAIN(int, char **);
270 int MAIN(int argc, char **argv)
273 char *key=NULL,*passargin=NULL;
288 char *configfile=NULL;
293 int keyform=FORMAT_PEM;
295 char *spkac_file=NULL;
296 char *ss_cert_file=NULL;
297 char *ser_status=NULL;
302 char *serialfile=NULL;
303 char *extensions=NULL;
306 char *tmp_email_dn=NULL;
308 int rev_type = REV_NONE;
309 char *rev_arg = NULL;
311 char *startdate=NULL;
316 unsigned long nameopt = 0, certopt = 0;
318 int ext_copy = EXT_COPY_NONE;
321 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
325 X509_REVOKED *r=NULL;
327 ASN1_INTEGER *tmpser;
331 const EVP_MD *dgst=NULL;
332 STACK_OF(CONF_VALUE) *attribs=NULL;
333 STACK_OF(X509) *cert_sk=NULL;
336 MS_STATIC char buf[3][BSIZE];
338 #ifndef OPENSSL_NO_ENGINE
358 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
359 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
365 if (strcmp(*argv,"-verbose") == 0)
367 else if (strcmp(*argv,"-config") == 0)
369 if (--argc < 1) goto bad;
370 configfile= *(++argv);
372 else if (strcmp(*argv,"-name") == 0)
374 if (--argc < 1) goto bad;
377 else if (strcmp(*argv,"-subj") == 0)
379 if (--argc < 1) goto bad;
383 else if (strcmp(*argv,"-startdate") == 0)
385 if (--argc < 1) goto bad;
386 startdate= *(++argv);
388 else if (strcmp(*argv,"-enddate") == 0)
390 if (--argc < 1) goto bad;
393 else if (strcmp(*argv,"-days") == 0)
395 if (--argc < 1) goto bad;
396 days=atoi(*(++argv));
398 else if (strcmp(*argv,"-md") == 0)
400 if (--argc < 1) goto bad;
403 else if (strcmp(*argv,"-policy") == 0)
405 if (--argc < 1) goto bad;
408 else if (strcmp(*argv,"-keyfile") == 0)
410 if (--argc < 1) goto bad;
413 else if (strcmp(*argv,"-keyform") == 0)
415 if (--argc < 1) goto bad;
416 keyform=str2fmt(*(++argv));
418 else if (strcmp(*argv,"-passin") == 0)
420 if (--argc < 1) goto bad;
421 passargin= *(++argv);
423 else if (strcmp(*argv,"-key") == 0)
425 if (--argc < 1) goto bad;
428 else if (strcmp(*argv,"-cert") == 0)
430 if (--argc < 1) goto bad;
433 else if (strcmp(*argv,"-in") == 0)
435 if (--argc < 1) goto bad;
439 else if (strcmp(*argv,"-out") == 0)
441 if (--argc < 1) goto bad;
444 else if (strcmp(*argv,"-outdir") == 0)
446 if (--argc < 1) goto bad;
449 else if (strcmp(*argv,"-notext") == 0)
451 else if (strcmp(*argv,"-batch") == 0)
453 else if (strcmp(*argv,"-preserveDN") == 0)
455 else if (strcmp(*argv,"-noemailDN") == 0)
457 else if (strcmp(*argv,"-gencrl") == 0)
459 else if (strcmp(*argv,"-msie_hack") == 0)
461 else if (strcmp(*argv,"-crldays") == 0)
463 if (--argc < 1) goto bad;
464 crldays= atol(*(++argv));
466 else if (strcmp(*argv,"-crlhours") == 0)
468 if (--argc < 1) goto bad;
469 crlhours= atol(*(++argv));
471 else if (strcmp(*argv,"-infiles") == 0)
478 else if (strcmp(*argv, "-ss_cert") == 0)
480 if (--argc < 1) goto bad;
481 ss_cert_file = *(++argv);
484 else if (strcmp(*argv, "-spkac") == 0)
486 if (--argc < 1) goto bad;
487 spkac_file = *(++argv);
490 else if (strcmp(*argv,"-revoke") == 0)
492 if (--argc < 1) goto bad;
496 else if (strcmp(*argv,"-extensions") == 0)
498 if (--argc < 1) goto bad;
499 extensions= *(++argv);
501 else if (strcmp(*argv,"-extfile") == 0)
503 if (--argc < 1) goto bad;
506 else if (strcmp(*argv,"-status") == 0)
508 if (--argc < 1) goto bad;
509 ser_status= *(++argv);
511 else if (strcmp(*argv,"-updatedb") == 0)
515 else if (strcmp(*argv,"-crlexts") == 0)
517 if (--argc < 1) goto bad;
520 else if (strcmp(*argv,"-crl_reason") == 0)
522 if (--argc < 1) goto bad;
524 rev_type = REV_CRL_REASON;
526 else if (strcmp(*argv,"-crl_hold") == 0)
528 if (--argc < 1) goto bad;
532 else if (strcmp(*argv,"-crl_compromise") == 0)
534 if (--argc < 1) goto bad;
536 rev_type = REV_KEY_COMPROMISE;
538 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
540 if (--argc < 1) goto bad;
542 rev_type = REV_CA_COMPROMISE;
544 #ifndef OPENSSL_NO_ENGINE
545 else if (strcmp(*argv,"-engine") == 0)
547 if (--argc < 1) goto bad;
554 BIO_printf(bio_err,"unknown option %s\n",*argv);
564 for (pp=ca_usage; (*pp != NULL); pp++)
565 BIO_printf(bio_err,"%s",*pp);
569 ERR_load_crypto_strings();
571 #ifndef OPENSSL_NO_ENGINE
572 e = setup_engine(bio_err, engine, 0);
575 /*****************************************************************/
577 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
578 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
579 if (configfile == NULL)
581 const char *s=X509_get_default_cert_area();
583 #ifdef OPENSSL_SYS_VMS
584 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE));
587 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1);
591 strcat(tofree,CONFIG_FILE);
595 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
596 conf = NCONF_new(NULL);
597 if (NCONF_load(conf,configfile,&errorline) <= 0)
600 BIO_printf(bio_err,"error loading the config file '%s'\n",
603 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
604 ,errorline,configfile);
609 OPENSSL_free(tofree);
613 if (!load_config(bio_err, conf))
616 /* Lets get the config section we are using */
619 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
622 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
629 p=NCONF_get_string(conf,NULL,"oid_file");
636 oid_bio=BIO_new_file(p,"r");
640 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
641 ERR_print_errors(bio_err);
647 OBJ_create_objects(oid_bio);
651 if (!add_oid_section(bio_err,conf))
653 ERR_print_errors(bio_err);
658 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
659 if (randfile == NULL)
661 app_RAND_load_file(randfile, bio_err, 0);
663 in=BIO_new(BIO_s_file());
664 out=BIO_new(BIO_s_file());
665 Sout=BIO_new(BIO_s_file());
666 Cout=BIO_new(BIO_s_file());
667 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
669 ERR_print_errors(bio_err);
673 /*****************************************************************/
674 /* report status of cert with serial number given on command line */
677 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
679 lookup_fail(section,ENV_DATABASE);
682 if (BIO_read_filename(in,dbfile) <= 0)
685 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
688 db=TXT_DB_read(in,DB_NUMBER);
689 if (db == NULL) goto err;
691 if (!make_serial_index(db))
694 if (get_certificate_status(ser_status,db) != 1)
695 BIO_printf(bio_err,"Error verifying serial %s!\n",
700 /*****************************************************************/
701 /* we definitely need a public key, so let's get it */
703 if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
704 section,ENV_PRIVATE_KEY)) == NULL))
706 lookup_fail(section,ENV_PRIVATE_KEY);
712 if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
714 BIO_printf(bio_err,"Error getting password\n");
718 pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
720 if (key) OPENSSL_cleanse(key,strlen(key));
723 /* load_key() has already printed an appropriate message */
727 /*****************************************************************/
728 /* we need a certificate */
729 if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
730 section,ENV_CERTIFICATE)) == NULL))
732 lookup_fail(section,ENV_CERTIFICATE);
735 x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
740 if (!X509_check_private_key(x509,pkey))
742 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
746 f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
749 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
751 f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
754 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
757 f=NCONF_get_string(conf,section,ENV_NAMEOPT);
761 if (!set_name_ex(&nameopt, f))
763 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
771 f=NCONF_get_string(conf,section,ENV_CERTOPT);
775 if (!set_cert_ex(&certopt, f))
777 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
785 f=NCONF_get_string(conf,section,ENV_EXTCOPY);
789 if (!set_ext_copy(&ext_copy, f))
791 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
798 /*****************************************************************/
799 /* lookup where to write new certificates */
800 if ((outdir == NULL) && (req))
804 if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
807 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
810 #ifndef OPENSSL_SYS_VMS
811 /* outdir is a directory spec, but access() for VMS demands a
812 filename. In any case, stat(), below, will catch the problem
813 if outdir is not a directory spec, and the fopen() or open()
814 will catch an error if there is no write access.
816 Presumably, this problem could also be solved by using the DEC
817 C routines to convert the directory syntax to Unixly, and give
818 that to access(). However, time's too short to do that just
821 if (access(outdir,R_OK|W_OK|X_OK) != 0)
823 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
828 if (stat(outdir,&sb) != 0)
830 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
835 if (!(sb.st_mode & S_IFDIR))
837 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
845 /*****************************************************************/
846 /* we need to load the database file */
847 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
849 lookup_fail(section,ENV_DATABASE);
852 if (BIO_read_filename(in,dbfile) <= 0)
855 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
858 db=TXT_DB_read(in,DB_NUMBER);
859 if (db == NULL) goto err;
861 /* Lets check some fields */
862 for (i=0; i<sk_num(db->data); i++)
864 pp=(char **)sk_value(db->data,i);
865 if ((pp[DB_type][0] != DB_TYPE_REV) &&
866 (pp[DB_rev_date][0] != '\0'))
868 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
871 if ((pp[DB_type][0] == DB_TYPE_REV) &&
872 !make_revoked(NULL, pp[DB_rev_date]))
874 BIO_printf(bio_err," in entry %d\n", i+1);
877 if (!check_time_format(pp[DB_exp_date]))
879 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
889 if ((j&1) || (j < 2))
891 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
896 if (!( ((*p >= '0') && (*p <= '9')) ||
897 ((*p >= 'A') && (*p <= 'F')) ||
898 ((*p >= 'a') && (*p <= 'f'))) )
900 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);
908 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
909 #ifdef OPENSSL_SYS_VMS
911 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
912 out = BIO_push(tmpbio, out);
915 TXT_DB_write(out,db);
916 BIO_printf(bio_err,"%d entries loaded from the database\n",
918 BIO_printf(bio_err,"generating index\n");
921 if (!make_serial_index(db))
924 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
925 LHASH_HASH_FN(index_name_hash),
926 LHASH_COMP_FN(index_name_cmp)))
928 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
929 db->error,db->arg1,db->arg2);
933 /*****************************************************************/
934 /* Update the db file for expired certificates */
938 BIO_printf(bio_err, "Updating %s ...\n",
944 BIO_printf(bio_err,"Malloc failure\n");
949 if (verbose) BIO_printf(bio_err,
950 "No entries found to mark expired\n");
954 out = BIO_new(BIO_s_file());
957 ERR_print_errors(bio_err);
961 #ifndef OPENSSL_SYS_VMS
962 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
964 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-new", dbfile);
966 if (j < 0 || j >= sizeof buf[0])
968 BIO_printf(bio_err, "file name too long\n");
971 if (BIO_write_filename(out,buf[0]) <= 0)
974 BIO_printf(bio_err,"unable to open '%s'\n",
978 j=TXT_DB_write(out,db);
979 if (j <= 0) goto err;
983 #ifndef OPENSSL_SYS_VMS
984 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
986 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-old", dbfile);
988 if (j < 0 || j >= sizeof buf[1])
990 BIO_printf(bio_err, "file name too long\n");
993 if (rename(dbfile,buf[1]) < 0)
996 "unable to rename %s to %s\n",
1001 if (rename(buf[0],dbfile) < 0)
1004 "unable to rename %s to %s\n",
1007 rename(buf[1],dbfile);
1011 if (verbose) BIO_printf(bio_err,
1012 "Done. %d entries marked as expired\n",i);
1017 /*****************************************************************/
1018 /* Read extentions config file */
1021 extconf = NCONF_new(NULL);
1022 if (NCONF_load(extconf,extfile,&errorline) <= 0)
1025 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
1028 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
1035 BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
1037 /* We can have sections in the ext file */
1038 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
1039 extensions = "default";
1042 /*****************************************************************/
1045 if (outfile != NULL)
1047 if (BIO_write_filename(Sout,outfile) <= 0)
1055 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1056 #ifdef OPENSSL_SYS_VMS
1058 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1059 Sout = BIO_push(tmpbio, Sout);
1067 if ((md == NULL) && ((md=NCONF_get_string(conf,
1068 section,ENV_DEFAULT_MD)) == NULL))
1070 lookup_fail(section,ENV_DEFAULT_MD);
1073 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1074 section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1076 if(strcmp(tmp_email_dn,"no") == 0)
1079 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1081 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1085 BIO_printf(bio_err,"message digest is %s\n",
1086 OBJ_nid2ln(dgst->type));
1087 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1088 section,ENV_POLICY)) == NULL))
1090 lookup_fail(section,ENV_POLICY);
1094 BIO_printf(bio_err,"policy is %s\n",policy);
1096 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1099 lookup_fail(section,ENV_SERIAL);
1105 /* no '-extfile' option, so we look for extensions
1106 * in the main configuration file */
1109 extensions=NCONF_get_string(conf,section,
1116 /* Check syntax of file */
1118 X509V3_set_ctx_test(&ctx);
1119 X509V3_set_nconf(&ctx, conf);
1120 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1124 "Error Loading extension section %s\n",
1132 if (startdate == NULL)
1134 startdate=NCONF_get_string(conf,section,
1135 ENV_DEFAULT_STARTDATE);
1136 if (startdate == NULL)
1139 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1141 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1144 if (startdate == NULL) startdate="today";
1146 if (enddate == NULL)
1148 enddate=NCONF_get_string(conf,section,
1149 ENV_DEFAULT_ENDDATE);
1150 if (enddate == NULL)
1153 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1155 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1161 if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1164 if (!enddate && (days == 0))
1166 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1170 if ((serial=load_serial(serialfile)) == NULL)
1172 BIO_printf(bio_err,"error while loading serial number\n");
1177 if (BN_is_zero(serial))
1178 BIO_printf(bio_err,"next serial number is 00\n");
1181 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1182 BIO_printf(bio_err,"next serial number is %s\n",f);
1187 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1189 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1193 if ((cert_sk=sk_X509_new_null()) == NULL)
1195 BIO_printf(bio_err,"Memory allocation failure\n");
1198 if (spkac_file != NULL)
1201 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1202 serial,subj,email_dn,startdate,enddate,days,extensions,
1203 conf,verbose,certopt,nameopt,default_op,ext_copy);
1204 if (j < 0) goto err;
1208 BIO_printf(bio_err,"\n");
1209 if (!BN_add_word(serial,1)) goto err;
1210 if (!sk_X509_push(cert_sk,x))
1212 BIO_printf(bio_err,"Memory allocation failure\n");
1222 if (ss_cert_file != NULL)
1225 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1226 db,serial,subj,email_dn,startdate,enddate,days,batch,
1227 extensions,conf,verbose, certopt, nameopt,
1228 default_op, ext_copy, e);
1229 if (j < 0) goto err;
1233 BIO_printf(bio_err,"\n");
1234 if (!BN_add_word(serial,1)) goto err;
1235 if (!sk_X509_push(cert_sk,x))
1237 BIO_printf(bio_err,"Memory allocation failure\n");
1245 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1246 serial,subj,email_dn,startdate,enddate,days,batch,
1247 extensions,conf,verbose, certopt, nameopt,
1248 default_op, ext_copy);
1249 if (j < 0) goto err;
1253 BIO_printf(bio_err,"\n");
1254 if (!BN_add_word(serial,1)) goto err;
1255 if (!sk_X509_push(cert_sk,x))
1257 BIO_printf(bio_err,"Memory allocation failure\n");
1262 for (i=0; i<argc; i++)
1265 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1266 serial,subj,email_dn,startdate,enddate,days,batch,
1267 extensions,conf,verbose, certopt, nameopt,
1268 default_op, ext_copy);
1269 if (j < 0) goto err;
1273 BIO_printf(bio_err,"\n");
1274 if (!BN_add_word(serial,1)) goto err;
1275 if (!sk_X509_push(cert_sk,x))
1277 BIO_printf(bio_err,"Memory allocation failure\n");
1282 /* we have a stack of newly certified certificates
1283 * and a data base and serial number that need
1286 if (sk_X509_num(cert_sk) > 0)
1290 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1291 (void)BIO_flush(bio_err);
1293 fgets(buf[0],10,stdin);
1294 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1296 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1302 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1304 if(strlen(serialfile) > BSIZE-5 || strlen(dbfile) > BSIZE-5)
1306 BIO_printf(bio_err,"file name too long\n");
1310 strcpy(buf[0],serialfile);
1312 #ifdef OPENSSL_SYS_VMS
1313 strcat(buf[0],"-new");
1315 strcat(buf[0],".new");
1318 if (!save_serial(buf[0],serial)) goto err;
1320 strcpy(buf[1],dbfile);
1322 #ifdef OPENSSL_SYS_VMS
1323 strcat(buf[1],"-new");
1325 strcat(buf[1],".new");
1328 if (BIO_write_filename(out,buf[1]) <= 0)
1331 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1334 l=TXT_DB_write(out,db);
1335 if (l <= 0) goto err;
1339 BIO_printf(bio_err,"writing new certificates\n");
1340 for (i=0; i<sk_X509_num(cert_sk); i++)
1345 x=sk_X509_value(cert_sk,i);
1347 j=x->cert_info->serialNumber->length;
1348 p=(char *)x->cert_info->serialNumber->data;
1350 if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1352 BIO_printf(bio_err,"certificate file name too long\n");
1356 strcpy(buf[2],outdir);
1358 #ifndef OPENSSL_SYS_VMS
1362 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1367 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1376 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1379 BIO_printf(bio_err,"writing %s\n",buf[2]);
1381 if (BIO_write_filename(Cout,buf[2]) <= 0)
1386 write_new_certificate(Cout,x, 0, notext);
1387 write_new_certificate(Sout,x, output_der, notext);
1390 if (sk_X509_num(cert_sk))
1392 /* Rename the database and the serial file */
1393 strncpy(buf[2],serialfile,BSIZE-4);
1394 buf[2][BSIZE-4]='\0';
1396 #ifdef OPENSSL_SYS_VMS
1397 strcat(buf[2],"-old");
1399 strcat(buf[2],".old");
1406 if (rename(serialfile,buf[2]) < 0)
1408 BIO_printf(bio_err,"unable to rename %s to %s\n",
1413 if (rename(buf[0],serialfile) < 0)
1415 BIO_printf(bio_err,"unable to rename %s to %s\n",
1418 rename(buf[2],serialfile);
1422 strncpy(buf[2],dbfile,BSIZE-4);
1423 buf[2][BSIZE-4]='\0';
1425 #ifdef OPENSSL_SYS_VMS
1426 strcat(buf[2],"-old");
1428 strcat(buf[2],".old");
1431 if (rename(dbfile,buf[2]) < 0)
1433 BIO_printf(bio_err,"unable to rename %s to %s\n",
1438 if (rename(buf[1],dbfile) < 0)
1440 BIO_printf(bio_err,"unable to rename %s to %s\n",
1443 rename(buf[2],dbfile);
1446 BIO_printf(bio_err,"Data Base Updated\n");
1450 /*****************************************************************/
1456 crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1462 /* Check syntax of file */
1464 X509V3_set_ctx_test(&ctx);
1465 X509V3_set_nconf(&ctx, conf);
1466 if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1469 "Error Loading CRL extension section %s\n",
1476 if (!crldays && !crlhours)
1478 if (!NCONF_get_number(conf,section,
1479 ENV_DEFAULT_CRL_DAYS, &crldays))
1481 if (!NCONF_get_number(conf,section,
1482 ENV_DEFAULT_CRL_HOURS, &crlhours))
1485 if ((crldays == 0) && (crlhours == 0))
1487 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1491 if (verbose) BIO_printf(bio_err,"making CRL\n");
1492 if ((crl=X509_CRL_new()) == NULL) goto err;
1493 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1495 tmptm = ASN1_TIME_new();
1496 if (!tmptm) goto err;
1497 X509_gmtime_adj(tmptm,0);
1498 X509_CRL_set_lastUpdate(crl, tmptm);
1499 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1500 X509_CRL_set_nextUpdate(crl, tmptm);
1502 ASN1_TIME_free(tmptm);
1504 for (i=0; i<sk_num(db->data); i++)
1506 pp=(char **)sk_value(db->data,i);
1507 if (pp[DB_type][0] == DB_TYPE_REV)
1509 if ((r=X509_REVOKED_new()) == NULL) goto err;
1510 j = make_revoked(r, pp[DB_rev_date]);
1512 if (j == 2) crl_v2 = 1;
1513 if (!BN_hex2bn(&serial, pp[DB_serial]))
1515 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1520 X509_REVOKED_set_serialNumber(r, tmpser);
1521 ASN1_INTEGER_free(tmpser);
1522 X509_CRL_add0_revoked(crl,r);
1526 /* sort the data so it will be written in serial
1530 /* we now have a CRL */
1531 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1534 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1536 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1542 #ifndef OPENSSL_NO_DSA
1543 if (pkey->type == EVP_PKEY_DSA)
1550 /* Add any extensions asked for */
1555 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1556 X509V3_set_nconf(&crlctx, conf);
1558 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1559 crl_ext, crl)) goto err;
1561 if (crl_ext || crl_v2)
1563 if (!X509_CRL_set_version(crl, 1))
1564 goto err; /* version 2 CRL */
1567 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1569 PEM_write_bio_X509_CRL(Sout,crl);
1571 /*****************************************************************/
1576 BIO_printf(bio_err,"no input files\n");
1582 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1584 if (revcert == NULL)
1586 j=do_revoke(revcert,db, rev_type, rev_arg);
1587 if (j <= 0) goto err;
1590 if(strlen(dbfile) > BSIZE-5)
1592 BIO_printf(bio_err,"filename too long\n");
1596 strcpy(buf[0],dbfile);
1597 #ifndef OPENSSL_SYS_VMS
1598 strcat(buf[0],".new");
1600 strcat(buf[0],"-new");
1602 if (BIO_write_filename(out,buf[0]) <= 0)
1605 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1608 j=TXT_DB_write(out,db);
1609 if (j <= 0) goto err;
1614 strncpy(buf[1],dbfile,BSIZE-4);
1615 buf[1][BSIZE-4]='\0';
1616 #ifndef OPENSSL_SYS_VMS
1617 strcat(buf[1],".old");
1619 strcat(buf[1],"-old");
1621 if (rename(dbfile,buf[1]) < 0)
1623 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1627 if (rename(buf[0],dbfile) < 0)
1629 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1631 rename(buf[1],dbfile);
1634 BIO_printf(bio_err,"Data Base Updated\n");
1637 /*****************************************************************/
1641 OPENSSL_free(tofree);
1648 sk_X509_pop_free(cert_sk,X509_free);
1650 if (ret) ERR_print_errors(bio_err);
1651 app_RAND_write_file(randfile, bio_err);
1652 if (free_key && key)
1656 EVP_PKEY_free(pkey);
1665 static void lookup_fail(char *name, char *tag)
1667 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1670 static unsigned long index_serial_hash(const char **a)
1675 while (*n == '0') n++;
1676 return(lh_strhash(n));
1679 static int index_serial_cmp(const char **a, const char **b)
1683 for (aa=a[DB_serial]; *aa == '0'; aa++);
1684 for (bb=b[DB_serial]; *bb == '0'; bb++);
1685 return(strcmp(aa,bb));
1688 static unsigned long index_name_hash(const char **a)
1689 { return(lh_strhash(a[DB_name])); }
1691 static int index_name_qual(char **a)
1692 { return(a[0][0] == 'V'); }
1694 static int index_name_cmp(const char **a, const char **b)
1695 { return(strcmp(a[DB_name],
1698 static BIGNUM *load_serial(char *serialfile)
1702 MS_STATIC char buf[1024];
1703 ASN1_INTEGER *ai=NULL;
1705 if ((in=BIO_new(BIO_s_file())) == NULL)
1707 ERR_print_errors(bio_err);
1711 if (BIO_read_filename(in,serialfile) <= 0)
1716 ai=ASN1_INTEGER_new();
1717 if (ai == NULL) goto err;
1718 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1720 BIO_printf(bio_err,"unable to load number from %s\n",
1724 ret=ASN1_INTEGER_to_BN(ai,NULL);
1727 BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
1731 if (in != NULL) BIO_free(in);
1732 if (ai != NULL) ASN1_INTEGER_free(ai);
1736 static int save_serial(char *serialfile, BIGNUM *serial)
1740 ASN1_INTEGER *ai=NULL;
1742 out=BIO_new(BIO_s_file());
1745 ERR_print_errors(bio_err);
1748 if (BIO_write_filename(out,serialfile) <= 0)
1754 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1756 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1759 i2a_ASN1_INTEGER(out,ai);
1763 if (out != NULL) BIO_free_all(out);
1764 if (ai != NULL) ASN1_INTEGER_free(ai);
1768 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1769 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1770 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1771 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1772 unsigned long certopt, unsigned long nameopt, int default_op,
1777 EVP_PKEY *pktmp=NULL;
1780 in=BIO_new(BIO_s_file());
1782 if (BIO_read_filename(in,infile) <= 0)
1787 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1789 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1794 X509_REQ_print(bio_err,req);
1796 BIO_printf(bio_err,"Check that the request matches the signature\n");
1798 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1800 BIO_printf(bio_err,"error unpacking public key\n");
1803 i=X509_REQ_verify(req,pktmp);
1804 EVP_PKEY_free(pktmp);
1808 BIO_printf(bio_err,"Signature verification problems....\n");
1814 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1818 BIO_printf(bio_err,"Signature ok\n");
1820 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1821 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1822 certopt, nameopt, default_op, ext_copy);
1825 if (req != NULL) X509_REQ_free(req);
1826 if (in != NULL) BIO_free(in);
1830 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1831 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1832 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1833 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1834 unsigned long certopt, unsigned long nameopt, int default_op,
1835 int ext_copy, ENGINE *e)
1838 X509_REQ *rreq=NULL;
1839 EVP_PKEY *pktmp=NULL;
1842 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1845 X509_print(bio_err,req);
1847 BIO_printf(bio_err,"Check that the request matches the signature\n");
1849 if ((pktmp=X509_get_pubkey(req)) == NULL)
1851 BIO_printf(bio_err,"error unpacking public key\n");
1854 i=X509_verify(req,pktmp);
1855 EVP_PKEY_free(pktmp);
1859 BIO_printf(bio_err,"Signature verification problems....\n");
1865 BIO_printf(bio_err,"Signature did not match the certificate\n");
1869 BIO_printf(bio_err,"Signature ok\n");
1871 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1874 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1875 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1879 if (rreq != NULL) X509_REQ_free(rreq);
1880 if (req != NULL) X509_free(req);
1884 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1885 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1886 int email_dn, char *startdate, char *enddate, long days, int batch,
1887 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1888 unsigned long certopt, unsigned long nameopt, int default_op,
1891 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1892 ASN1_UTCTIME *tm,*tmptm;
1893 ASN1_STRING *str,*str2;
1897 X509_NAME_ENTRY *ne;
1898 X509_NAME_ENTRY *tne,*push;
1900 int ok= -1,i,j,last,nid;
1903 char *row[DB_NUMBER],**rrow,**irow=NULL;
1906 tmptm=ASN1_UTCTIME_new();
1909 BIO_printf(bio_err,"malloc error\n");
1913 for (i=0; i<DB_NUMBER; i++)
1918 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1922 ERR_print_errors(bio_err);
1925 X509_REQ_set_subject_name(req,n);
1926 req->req_info->enc.modified = 1;
1931 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1933 name=X509_REQ_get_subject_name(req);
1934 for (i=0; i<X509_NAME_entry_count(name); i++)
1936 ne= X509_NAME_get_entry(name,i);
1937 str=X509_NAME_ENTRY_get_data(ne);
1938 obj=X509_NAME_ENTRY_get_object(ne);
1942 /* assume all type should be strings */
1943 nid=OBJ_obj2nid(ne->object);
1945 if (str->type == V_ASN1_UNIVERSALSTRING)
1946 ASN1_UNIVERSALSTRING_to_string(str);
1948 if ((str->type == V_ASN1_IA5STRING) &&
1949 (nid != NID_pkcs9_emailAddress))
1950 str->type=V_ASN1_T61STRING;
1952 if ((nid == NID_pkcs9_emailAddress) &&
1953 (str->type == V_ASN1_PRINTABLESTRING))
1954 str->type=V_ASN1_IA5STRING;
1957 /* If no EMAIL is wanted in the subject */
1958 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1961 /* check some things */
1962 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1963 (str->type != V_ASN1_IA5STRING))
1965 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1968 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1970 j=ASN1_PRINTABLE_type(str->data,str->length);
1971 if ( ((j == V_ASN1_T61STRING) &&
1972 (str->type != V_ASN1_T61STRING)) ||
1973 ((j == V_ASN1_IA5STRING) &&
1974 (str->type == V_ASN1_PRINTABLESTRING)))
1976 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1982 old_entry_print(bio_err, obj, str);
1985 /* Ok, now we check the 'policy' stuff. */
1986 if ((subject=X509_NAME_new()) == NULL)
1988 BIO_printf(bio_err,"Memory allocation failure\n");
1992 /* take a copy of the issuer name before we mess with it. */
1993 CAname=X509_NAME_dup(x509->cert_info->subject);
1994 if (CAname == NULL) goto err;
1997 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1999 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
2000 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
2002 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
2010 /* lookup the object in the supplied name list */
2011 j=X509_NAME_get_index_by_OBJ(name,obj,last);
2014 if (last != -1) break;
2019 tne=X509_NAME_get_entry(name,j);
2023 /* depending on the 'policy', decide what to do. */
2025 if (strcmp(cv->value,"optional") == 0)
2030 else if (strcmp(cv->value,"supplied") == 0)
2034 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2040 else if (strcmp(cv->value,"match") == 0)
2046 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2053 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2054 if ((j < 0) && (last2 == -1))
2056 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2061 push=X509_NAME_get_entry(CAname,j);
2062 str=X509_NAME_ENTRY_get_data(tne);
2063 str2=X509_NAME_ENTRY_get_data(push);
2065 if (ASN1_STRING_cmp(str,str2) != 0)
2070 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));
2076 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2082 if (!X509_NAME_add_entry(subject,push, -1, 0))
2085 X509_NAME_ENTRY_free(push);
2086 BIO_printf(bio_err,"Memory allocation failure\n");
2096 X509_NAME_free(subject);
2097 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
2098 subject=X509_NAME_dup(name);
2099 if (subject == NULL) goto err;
2103 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2105 /* Build the correct Subject if no e-mail is wanted in the subject */
2106 /* and add it later on because of the method extensions are added (altName) */
2109 dn_subject = subject;
2112 X509_NAME_ENTRY *tmpne;
2113 /* Its best to dup the subject DN and then delete any email
2114 * addresses because this retains its structure.
2116 if (!(dn_subject = X509_NAME_dup(subject)))
2118 BIO_printf(bio_err,"Memory allocation failure\n");
2121 while((i = X509_NAME_get_index_by_NID(dn_subject,
2122 NID_pkcs9_emailAddress, -1)) >= 0)
2124 tmpne = X509_NAME_get_entry(dn_subject, i);
2125 X509_NAME_delete_entry(dn_subject, i);
2126 X509_NAME_ENTRY_free(tmpne);
2130 if (BN_is_zero(serial))
2131 row[DB_serial]=BUF_strdup("00");
2133 row[DB_serial]=BN_bn2hex(serial);
2134 if (row[DB_serial] == NULL)
2136 BIO_printf(bio_err,"Memory allocation failure\n");
2140 rrow=TXT_DB_get_by_index(db,DB_name,row);
2143 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2148 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2151 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2153 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2160 "The matching entry has the following details\n");
2161 if (rrow[DB_type][0] == 'E')
2163 else if (rrow[DB_type][0] == 'R')
2165 else if (rrow[DB_type][0] == 'V')
2168 p="\ninvalid type, Data base error\n";
2169 BIO_printf(bio_err,"Type :%s\n",p);;
2170 if (rrow[DB_type][0] == 'R')
2172 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2173 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2175 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2176 BIO_printf(bio_err,"Expires on :%s\n",p);
2177 p=rrow[DB_serial]; if (p == NULL) p="undef";
2178 BIO_printf(bio_err,"Serial Number :%s\n",p);
2179 p=rrow[DB_file]; if (p == NULL) p="undef";
2180 BIO_printf(bio_err,"File name :%s\n",p);
2181 p=rrow[DB_name]; if (p == NULL) p="undef";
2182 BIO_printf(bio_err,"Subject Name :%s\n",p);
2183 ok= -1; /* This is now a 'bad' error. */
2187 /* We are now totally happy, lets make and sign the certificate */
2189 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2191 if ((ret=X509_new()) == NULL) goto err;
2195 /* Make it an X509 v3 certificate. */
2196 if (!X509_set_version(x509,2)) goto err;
2199 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2201 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2204 if (strcmp(startdate,"today") == 0)
2205 X509_gmtime_adj(X509_get_notBefore(ret),0);
2206 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2208 if (enddate == NULL)
2209 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2210 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2212 if (!X509_set_subject_name(ret,subject)) goto err;
2214 pktmp=X509_REQ_get_pubkey(req);
2215 i = X509_set_pubkey(ret,pktmp);
2216 EVP_PKEY_free(pktmp);
2219 /* Lets add the extensions, if there are any */
2223 if (ci->version == NULL)
2224 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2226 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2228 /* Free the current entries if any, there should not
2229 * be any I believe */
2230 if (ci->extensions != NULL)
2231 sk_X509_EXTENSION_pop_free(ci->extensions,
2232 X509_EXTENSION_free);
2234 ci->extensions = NULL;
2236 /* Initialize the context structure */
2237 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2242 BIO_printf(bio_err, "Extra configuration file found\n");
2244 /* Use the extconf configuration db LHASH */
2245 X509V3_set_nconf(&ctx, extconf);
2247 /* Test the structure (needed?) */
2248 /* X509V3_set_ctx_test(&ctx); */
2250 /* Adds exts contained in the configuration file */
2251 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2254 "ERROR: adding extensions in section %s\n",
2256 ERR_print_errors(bio_err);
2260 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2264 /* We found extensions to be set from config file */
2265 X509V3_set_nconf(&ctx, lconf);
2267 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2269 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2270 ERR_print_errors(bio_err);
2275 BIO_printf(bio_err, "Successfully added extensions from config\n");
2279 /* Copy extensions from request (if any) */
2281 if (!copy_extensions(ret, req, ext_copy))
2283 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2284 ERR_print_errors(bio_err);
2288 /* Set the right value for the noemailDN option */
2291 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2296 BIO_printf(bio_err, "Certificate Details:\n");
2297 /* Never print signature details because signature not present */
2298 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2299 X509_print_ex(bio_err, ret, nameopt, certopt);
2302 BIO_printf(bio_err,"Certificate is to be certified until ");
2303 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2304 if (days) BIO_printf(bio_err," (%d days)",days);
2305 BIO_printf(bio_err, "\n");
2310 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2311 (void)BIO_flush(bio_err);
2313 fgets(buf,sizeof(buf)-1,stdin);
2314 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2316 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2323 #ifndef OPENSSL_NO_DSA
2324 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2325 pktmp=X509_get_pubkey(ret);
2326 if (EVP_PKEY_missing_parameters(pktmp) &&
2327 !EVP_PKEY_missing_parameters(pkey))
2328 EVP_PKEY_copy_parameters(pktmp,pkey);
2329 EVP_PKEY_free(pktmp);
2332 if (!X509_sign(ret,pkey,dgst))
2335 /* We now just add it to the database */
2336 row[DB_type]=(char *)OPENSSL_malloc(2);
2338 tm=X509_get_notAfter(ret);
2339 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2340 memcpy(row[DB_exp_date],tm->data,tm->length);
2341 row[DB_exp_date][tm->length]='\0';
2343 row[DB_rev_date]=NULL;
2345 /* row[DB_serial] done already */
2346 row[DB_file]=(char *)OPENSSL_malloc(8);
2347 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2349 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2350 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2352 BIO_printf(bio_err,"Memory allocation failure\n");
2355 strcpy(row[DB_file],"unknown");
2356 row[DB_type][0]='V';
2357 row[DB_type][1]='\0';
2359 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2361 BIO_printf(bio_err,"Memory allocation failure\n");
2365 for (i=0; i<DB_NUMBER; i++)
2370 irow[DB_NUMBER]=NULL;
2372 if (!TXT_DB_insert(db,irow))
2374 BIO_printf(bio_err,"failed to update database\n");
2375 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2380 for (i=0; i<DB_NUMBER; i++)
2381 if (row[i] != NULL) OPENSSL_free(row[i]);
2384 X509_NAME_free(CAname);
2385 if (subject != NULL)
2386 X509_NAME_free(subject);
2387 if ((dn_subject != NULL) && !email_dn)
2388 X509_NAME_free(dn_subject);
2390 ASN1_UTCTIME_free(tmptm);
2393 if (ret != NULL) X509_free(ret);
2401 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2406 (void)i2d_X509_bio(bp,x);
2410 /* ??? Not needed since X509_print prints all this stuff anyway */
2411 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2412 BIO_printf(bp,"issuer :%s\n",f);
2414 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2415 BIO_printf(bp,"subject:%s\n",f);
2417 BIO_puts(bp,"serial :");
2418 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2419 BIO_puts(bp,"\n\n");
2421 if (!notext)X509_print(bp,x);
2422 PEM_write_bio_X509(bp,x);
2425 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2426 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2427 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2428 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2429 unsigned long nameopt, int default_op, int ext_copy)
2431 STACK_OF(CONF_VALUE) *sk=NULL;
2434 CONF_VALUE *cv=NULL;
2435 NETSCAPE_SPKI *spki = NULL;
2438 EVP_PKEY *pktmp=NULL;
2440 X509_NAME_ENTRY *ne=NULL;
2446 * Load input file into a hash table. (This is just an easy
2447 * way to read and parse the file, then put it into a convenient
2450 parms=CONF_load(NULL,infile,&errline);
2453 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2454 ERR_print_errors(bio_err);
2458 sk=CONF_get_section(parms, "default");
2459 if (sk_CONF_VALUE_num(sk) == 0)
2461 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2467 * Now create a dummy X509 request structure. We don't actually
2468 * have an X509 request, but we have many of the components
2469 * (a public key, various DN components). The idea is that we
2470 * put these components into the right X509 request structure
2471 * and we can use the same code as if you had a real X509 request.
2476 ERR_print_errors(bio_err);
2481 * Build up the subject name set.
2488 if (sk_CONF_VALUE_num(sk) <= i) break;
2490 cv=sk_CONF_VALUE_value(sk,i);
2492 /* Skip past any leading X. X: X, etc to allow for
2493 * multiple instances
2495 for (buf = cv->name; *buf ; buf++)
2496 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2499 if (*buf) type = buf;
2504 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2506 if (strcmp(type, "SPKAC") == 0)
2508 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2511 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2512 ERR_print_errors(bio_err);
2520 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2524 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2525 if (fix_data(nid, &j) == 0)
2528 "invalid characters in string %s\n",buf);
2532 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2533 (unsigned char *)buf,
2534 strlen(buf))) == NULL)
2537 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2541 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2547 * Now extract the key from the SPKI structure.
2550 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2552 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2554 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2558 j = NETSCAPE_SPKI_verify(spki, pktmp);
2561 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2564 BIO_printf(bio_err,"Signature ok\n");
2566 X509_REQ_set_pubkey(req,pktmp);
2567 EVP_PKEY_free(pktmp);
2568 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2569 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2572 if (req != NULL) X509_REQ_free(req);
2573 if (parms != NULL) CONF_free(parms);
2574 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2575 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2580 static int fix_data(int nid, int *type)
2582 if (nid == NID_pkcs9_emailAddress)
2583 *type=V_ASN1_IA5STRING;
2584 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2585 *type=V_ASN1_T61STRING;
2586 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2587 *type=V_ASN1_T61STRING;
2588 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2590 if (nid == NID_pkcs9_unstructuredName)
2591 *type=V_ASN1_IA5STRING;
2595 static int check_time_format(char *str)
2599 tm.data=(unsigned char *)str;
2600 tm.length=strlen(str);
2601 tm.type=V_ASN1_UTCTIME;
2602 return(ASN1_UTCTIME_check(&tm));
2605 static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2607 ASN1_UTCTIME *tm=NULL;
2608 char *row[DB_NUMBER],**rrow,**irow;
2609 char *rev_str = NULL;
2613 for (i=0; i<DB_NUMBER; i++)
2615 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2616 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2618 row[DB_serial]=BUF_strdup("00");
2620 row[DB_serial]=BN_bn2hex(bn);
2622 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2624 BIO_printf(bio_err,"Memory allocation failure\n");
2627 /* We have to lookup by serial number because name lookup
2628 * skips revoked certs
2630 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2633 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2635 /* We now just add it to the database */
2636 row[DB_type]=(char *)OPENSSL_malloc(2);
2638 tm=X509_get_notAfter(x509);
2639 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2640 memcpy(row[DB_exp_date],tm->data,tm->length);
2641 row[DB_exp_date][tm->length]='\0';
2643 row[DB_rev_date]=NULL;
2645 /* row[DB_serial] done already */
2646 row[DB_file]=(char *)OPENSSL_malloc(8);
2648 /* row[DB_name] done already */
2650 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2651 (row[DB_file] == NULL))
2653 BIO_printf(bio_err,"Memory allocation failure\n");
2656 strcpy(row[DB_file],"unknown");
2657 row[DB_type][0]='V';
2658 row[DB_type][1]='\0';
2660 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2662 BIO_printf(bio_err,"Memory allocation failure\n");
2666 for (i=0; i<DB_NUMBER; i++)
2671 irow[DB_NUMBER]=NULL;
2673 if (!TXT_DB_insert(db,irow))
2675 BIO_printf(bio_err,"failed to update database\n");
2676 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2680 /* Revoke Certificate */
2681 ok = do_revoke(x509,db, type, value);
2686 else if (index_name_cmp((const char **)row,(const char **)rrow))
2688 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2692 else if (rrow[DB_type][0]=='R')
2694 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2700 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2701 rev_str = make_revocation_str(type, value);
2704 BIO_printf(bio_err, "Error in revocation arguments\n");
2707 rrow[DB_type][0]='R';
2708 rrow[DB_type][1]='\0';
2709 rrow[DB_rev_date] = rev_str;
2713 for (i=0; i<DB_NUMBER; i++)
2716 OPENSSL_free(row[i]);
2721 static int get_certificate_status(const char *serial, TXT_DB *db)
2723 char *row[DB_NUMBER],**rrow;
2726 /* Free Resources */
2727 for (i=0; i<DB_NUMBER; i++)
2730 /* Malloc needed char spaces */
2731 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2732 if (row[DB_serial] == NULL)
2734 BIO_printf(bio_err,"Malloc failure\n");
2738 if (strlen(serial) % 2)
2740 /* Set the first char to 0 */;
2741 row[DB_serial][0]='0';
2743 /* Copy String from serial to row[DB_serial] */
2744 memcpy(row[DB_serial]+1, serial, strlen(serial));
2745 row[DB_serial][strlen(serial)+1]='\0';
2749 /* Copy String from serial to row[DB_serial] */
2750 memcpy(row[DB_serial], serial, strlen(serial));
2751 row[DB_serial][strlen(serial)]='\0';
2754 /* Make it Upper Case */
2755 for (i=0; row[DB_serial][i] != '\0'; i++)
2756 row[DB_serial][i] = toupper(row[DB_serial][i]);
2761 /* Search for the certificate */
2762 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2765 BIO_printf(bio_err,"Serial %s not present in db.\n",
2770 else if (rrow[DB_type][0]=='V')
2772 BIO_printf(bio_err,"%s=Valid (%c)\n",
2773 row[DB_serial], rrow[DB_type][0]);
2776 else if (rrow[DB_type][0]=='R')
2778 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2779 row[DB_serial], rrow[DB_type][0]);
2782 else if (rrow[DB_type][0]=='E')
2784 BIO_printf(bio_err,"%s=Expired (%c)\n",
2785 row[DB_serial], rrow[DB_type][0]);
2788 else if (rrow[DB_type][0]=='S')
2790 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2791 row[DB_serial], rrow[DB_type][0]);
2796 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2797 row[DB_serial], rrow[DB_type][0]);
2801 for (i=0; i<DB_NUMBER; i++)
2804 OPENSSL_free(row[i]);
2809 static int do_updatedb (TXT_DB *db)
2811 ASN1_UTCTIME *a_tm = NULL;
2813 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2814 char **rrow, *a_tm_s;
2816 a_tm = ASN1_UTCTIME_new();
2818 /* get actual time and make a string */
2819 a_tm = X509_gmtime_adj(a_tm, 0);
2820 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2827 memcpy(a_tm_s, a_tm->data, a_tm->length);
2828 a_tm_s[a_tm->length] = '\0';
2830 if (strncmp(a_tm_s, "49", 2) <= 0)
2835 for (i = 0; i < sk_num(db->data); i++)
2837 rrow = (char **) sk_value(db->data, i);
2839 if (rrow[DB_type][0] == 'V')
2841 /* ignore entries that are not valid */
2842 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2847 if (db_y2k == a_y2k)
2849 /* all on the same y2k side */
2850 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2852 rrow[DB_type][0] = 'E';
2853 rrow[DB_type][1] = '\0';
2856 BIO_printf(bio_err, "%s=Expired\n",
2860 else if (db_y2k < a_y2k)
2862 rrow[DB_type][0] = 'E';
2863 rrow[DB_type][1] = '\0';
2866 BIO_printf(bio_err, "%s=Expired\n",
2875 ASN1_UTCTIME_free(a_tm);
2876 OPENSSL_free(a_tm_s);
2881 static char *crl_reasons[] = {
2882 /* CRL reason strings */
2886 "affiliationChanged",
2888 "cessationOfOperation",
2891 /* Additional pseudo reasons */
2897 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2899 /* Given revocation information convert to a DB string.
2900 * The format of the string is:
2901 * revtime[,reason,extra]. Where 'revtime' is the
2902 * revocation time (the current time). 'reason' is the
2903 * optional CRL reason and 'extra' is any additional
2907 char *make_revocation_str(int rev_type, char *rev_arg)
2909 char *reason = NULL, *other = NULL, *str;
2911 ASN1_UTCTIME *revtm = NULL;
2918 case REV_CRL_REASON:
2919 for (i = 0; i < 8; i++)
2921 if (!strcasecmp(rev_arg, crl_reasons[i]))
2923 reason = crl_reasons[i];
2929 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2935 /* Argument is an OID */
2937 otmp = OBJ_txt2obj(rev_arg, 0);
2938 ASN1_OBJECT_free(otmp);
2942 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2946 reason = "holdInstruction";
2950 case REV_KEY_COMPROMISE:
2951 case REV_CA_COMPROMISE:
2953 /* Argument is the key compromise time */
2954 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2956 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2960 if (rev_type == REV_KEY_COMPROMISE)
2963 reason = "CAkeyTime";
2969 revtm = X509_gmtime_adj(NULL, 0);
2971 i = revtm->length + 1;
2973 if (reason) i += strlen(reason) + 1;
2974 if (other) i += strlen(other) + 1;
2976 str = OPENSSL_malloc(i);
2978 if (!str) return NULL;
2980 strcpy(str, (char *)revtm->data);
2984 strcat(str, reason);
2991 ASN1_UTCTIME_free(revtm);
2995 /* Convert revocation field to X509_REVOKED entry
2999 * 2 OK and some extensions added (i.e. V2 CRL)
3003 int make_revoked(X509_REVOKED *rev, char *str)
3006 int reason_code = -1;
3008 ASN1_OBJECT *hold = NULL;
3009 ASN1_GENERALIZEDTIME *comp_time = NULL;
3010 ASN1_ENUMERATED *rtmp = NULL;
3012 ASN1_TIME *revDate = NULL;
3014 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
3019 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
3022 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3024 rtmp = ASN1_ENUMERATED_new();
3025 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3027 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3031 if (rev && comp_time)
3033 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3038 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3042 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3048 if (tmp) OPENSSL_free(tmp);
3049 ASN1_OBJECT_free(hold);
3050 ASN1_GENERALIZEDTIME_free(comp_time);
3051 ASN1_ENUMERATED_free(rtmp);
3052 ASN1_TIME_free(revDate);
3058 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
3059 * where characters may be escaped by \
3061 X509_NAME *do_subject(char *subject, long chtype)
3063 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
3064 char *buf = OPENSSL_malloc(buflen);
3065 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
3066 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
3067 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
3069 char *sp = subject, *bp = buf;
3072 X509_NAME *n = NULL;
3075 if (!buf || !ne_types || !ne_values)
3077 BIO_printf(bio_err, "malloc error\n");
3081 if (*subject != '/')
3083 BIO_printf(bio_err, "Subject does not start with '/'.\n");
3086 sp++; /* skip leading / */
3091 ne_types[ne_num] = bp;
3094 if (*sp == '\\') /* is there anything to escape in the type...? */
3100 BIO_printf(bio_err, "escape character at end of string\n");
3104 else if (*sp == '=')
3115 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
3118 ne_values[ne_num] = bp;
3127 BIO_printf(bio_err, "escape character at end of string\n");
3131 else if (*sp == '/')
3143 if (!(n = X509_NAME_new()))
3146 for (i = 0; i < ne_num; i++)
3148 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
3150 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
3156 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
3160 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
3164 OPENSSL_free(ne_values);
3165 OPENSSL_free(ne_types);
3172 OPENSSL_free(ne_values);
3174 OPENSSL_free(ne_types);
3180 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3182 char buf[25],*pbuf, *p;
3184 j=i2a_ASN1_OBJECT(bp,obj);
3186 for (j=22-j; j>0; j--)
3192 if (str->type == V_ASN1_PRINTABLESTRING)
3193 BIO_printf(bp,"PRINTABLE:'");
3194 else if (str->type == V_ASN1_T61STRING)
3195 BIO_printf(bp,"T61STRING:'");
3196 else if (str->type == V_ASN1_IA5STRING)
3197 BIO_printf(bp,"IA5STRING:'");
3198 else if (str->type == V_ASN1_UNIVERSALSTRING)
3199 BIO_printf(bp,"UNIVERSALSTRING:'");
3201 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3203 p=(char *)str->data;
3204 for (j=str->length; j>0; j--)
3206 if ((*p >= ' ') && (*p <= '~'))
3207 BIO_printf(bp,"%c",*p);
3209 BIO_printf(bp,"\\0x%02X",*p);
3210 else if ((unsigned char)*p == 0xf7)
3211 BIO_printf(bp,"^?");
3212 else BIO_printf(bp,"^%c",*p+'@');
3215 BIO_printf(bp,"'\n");
3219 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3222 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3223 int reason_code = -1;
3225 ASN1_OBJECT *hold = NULL;
3226 ASN1_GENERALIZEDTIME *comp_time = NULL;
3227 tmp = BUF_strdup(str);
3229 p = strchr(tmp, ',');
3248 *prevtm = ASN1_UTCTIME_new();
3249 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3251 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3257 for (i = 0; i < NUM_REASONS; i++)
3259 if(!strcasecmp(reason_str, crl_reasons[i]))
3265 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3267 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3271 if (reason_code == 7)
3272 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3273 else if (reason_code == 8) /* Hold instruction */
3277 BIO_printf(bio_err, "missing hold instruction\n");
3280 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3281 hold = OBJ_txt2obj(arg_str, 0);
3285 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3288 if (phold) *phold = hold;
3290 else if ((reason_code == 9) || (reason_code == 10))
3294 BIO_printf(bio_err, "missing compromised time\n");
3297 comp_time = ASN1_GENERALIZEDTIME_new();
3298 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3300 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3303 if (reason_code == 9)
3304 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3306 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3310 if (preason) *preason = reason_code;
3311 if (pinvtm) *pinvtm = comp_time;
3312 else ASN1_GENERALIZEDTIME_free(comp_time);
3318 if (tmp) OPENSSL_free(tmp);
3319 if (!phold) ASN1_OBJECT_free(hold);
3320 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3325 int make_serial_index(TXT_DB *db)
3327 if (!TXT_DB_create_index(db, DB_serial, NULL,
3328 LHASH_HASH_FN(index_serial_hash),
3329 LHASH_COMP_FN(index_serial_cmp)))
3332 "error creating serial number index:(%ld,%ld,%ld)\n",
3333 db->error,db->arg1,db->arg2);