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)
1547 #ifndef OPENSSL_NO_ECDSA
1548 if (pkey->type == EVP_PKEY_EC)
1555 /* Add any extensions asked for */
1560 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1561 X509V3_set_nconf(&crlctx, conf);
1563 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1564 crl_ext, crl)) goto err;
1566 if (crl_ext || crl_v2)
1568 if (!X509_CRL_set_version(crl, 1))
1569 goto err; /* version 2 CRL */
1572 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1574 PEM_write_bio_X509_CRL(Sout,crl);
1576 /*****************************************************************/
1581 BIO_printf(bio_err,"no input files\n");
1587 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1589 if (revcert == NULL)
1591 j=do_revoke(revcert,db, rev_type, rev_arg);
1592 if (j <= 0) goto err;
1595 if(strlen(dbfile) > BSIZE-5)
1597 BIO_printf(bio_err,"filename too long\n");
1601 strcpy(buf[0],dbfile);
1602 #ifndef OPENSSL_SYS_VMS
1603 strcat(buf[0],".new");
1605 strcat(buf[0],"-new");
1607 if (BIO_write_filename(out,buf[0]) <= 0)
1610 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1613 j=TXT_DB_write(out,db);
1614 if (j <= 0) goto err;
1615 strncpy(buf[1],dbfile,BSIZE-4);
1616 buf[1][BSIZE-4]='\0';
1617 #ifndef OPENSSL_SYS_VMS
1618 strcat(buf[1],".old");
1620 strcat(buf[1],"-old");
1626 if (rename(dbfile,buf[1]) < 0)
1628 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1632 if (rename(buf[0],dbfile) < 0)
1634 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1636 rename(buf[1],dbfile);
1639 BIO_printf(bio_err,"Data Base Updated\n");
1642 /*****************************************************************/
1646 OPENSSL_free(tofree);
1653 sk_X509_pop_free(cert_sk,X509_free);
1655 if (ret) ERR_print_errors(bio_err);
1656 app_RAND_write_file(randfile, bio_err);
1657 if (free_key && key)
1661 EVP_PKEY_free(pkey);
1670 static void lookup_fail(char *name, char *tag)
1672 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1675 static unsigned long index_serial_hash(const char **a)
1680 while (*n == '0') n++;
1681 return(lh_strhash(n));
1684 static int index_serial_cmp(const char **a, const char **b)
1688 for (aa=a[DB_serial]; *aa == '0'; aa++);
1689 for (bb=b[DB_serial]; *bb == '0'; bb++);
1690 return(strcmp(aa,bb));
1693 static unsigned long index_name_hash(const char **a)
1694 { return(lh_strhash(a[DB_name])); }
1696 static int index_name_qual(char **a)
1697 { return(a[0][0] == 'V'); }
1699 static int index_name_cmp(const char **a, const char **b)
1700 { return(strcmp(a[DB_name],
1703 static BIGNUM *load_serial(char *serialfile)
1707 MS_STATIC char buf[1024];
1708 ASN1_INTEGER *ai=NULL;
1710 if ((in=BIO_new(BIO_s_file())) == NULL)
1712 ERR_print_errors(bio_err);
1716 if (BIO_read_filename(in,serialfile) <= 0)
1721 ai=ASN1_INTEGER_new();
1722 if (ai == NULL) goto err;
1723 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1725 BIO_printf(bio_err,"unable to load number from %s\n",
1729 ret=ASN1_INTEGER_to_BN(ai,NULL);
1732 BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
1736 if (in != NULL) BIO_free(in);
1737 if (ai != NULL) ASN1_INTEGER_free(ai);
1741 static int save_serial(char *serialfile, BIGNUM *serial)
1745 ASN1_INTEGER *ai=NULL;
1747 out=BIO_new(BIO_s_file());
1750 ERR_print_errors(bio_err);
1753 if (BIO_write_filename(out,serialfile) <= 0)
1759 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1761 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1764 i2a_ASN1_INTEGER(out,ai);
1768 if (out != NULL) BIO_free_all(out);
1769 if (ai != NULL) ASN1_INTEGER_free(ai);
1773 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1774 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1775 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1776 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1777 unsigned long certopt, unsigned long nameopt, int default_op,
1782 EVP_PKEY *pktmp=NULL;
1785 in=BIO_new(BIO_s_file());
1787 if (BIO_read_filename(in,infile) <= 0)
1792 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1794 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1799 X509_REQ_print(bio_err,req);
1801 BIO_printf(bio_err,"Check that the request matches the signature\n");
1803 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1805 BIO_printf(bio_err,"error unpacking public key\n");
1808 i=X509_REQ_verify(req,pktmp);
1809 EVP_PKEY_free(pktmp);
1813 BIO_printf(bio_err,"Signature verification problems....\n");
1819 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1823 BIO_printf(bio_err,"Signature ok\n");
1825 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1826 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1827 certopt, nameopt, default_op, ext_copy);
1830 if (req != NULL) X509_REQ_free(req);
1831 if (in != NULL) BIO_free(in);
1835 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1836 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1837 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1838 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1839 unsigned long certopt, unsigned long nameopt, int default_op,
1840 int ext_copy, ENGINE *e)
1843 X509_REQ *rreq=NULL;
1844 EVP_PKEY *pktmp=NULL;
1847 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1850 X509_print(bio_err,req);
1852 BIO_printf(bio_err,"Check that the request matches the signature\n");
1854 if ((pktmp=X509_get_pubkey(req)) == NULL)
1856 BIO_printf(bio_err,"error unpacking public key\n");
1859 i=X509_verify(req,pktmp);
1860 EVP_PKEY_free(pktmp);
1864 BIO_printf(bio_err,"Signature verification problems....\n");
1870 BIO_printf(bio_err,"Signature did not match the certificate\n");
1874 BIO_printf(bio_err,"Signature ok\n");
1876 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1879 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1880 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1884 if (rreq != NULL) X509_REQ_free(rreq);
1885 if (req != NULL) X509_free(req);
1889 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1890 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1891 int email_dn, char *startdate, char *enddate, long days, int batch,
1892 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1893 unsigned long certopt, unsigned long nameopt, int default_op,
1896 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1897 ASN1_UTCTIME *tm,*tmptm;
1898 ASN1_STRING *str,*str2;
1902 X509_NAME_ENTRY *ne;
1903 X509_NAME_ENTRY *tne,*push;
1905 int ok= -1,i,j,last,nid;
1908 char *row[DB_NUMBER],**rrow,**irow=NULL;
1911 tmptm=ASN1_UTCTIME_new();
1914 BIO_printf(bio_err,"malloc error\n");
1918 for (i=0; i<DB_NUMBER; i++)
1923 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1927 ERR_print_errors(bio_err);
1930 X509_REQ_set_subject_name(req,n);
1931 req->req_info->enc.modified = 1;
1936 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1938 name=X509_REQ_get_subject_name(req);
1939 for (i=0; i<X509_NAME_entry_count(name); i++)
1941 ne= X509_NAME_get_entry(name,i);
1942 str=X509_NAME_ENTRY_get_data(ne);
1943 obj=X509_NAME_ENTRY_get_object(ne);
1947 /* assume all type should be strings */
1948 nid=OBJ_obj2nid(ne->object);
1950 if (str->type == V_ASN1_UNIVERSALSTRING)
1951 ASN1_UNIVERSALSTRING_to_string(str);
1953 if ((str->type == V_ASN1_IA5STRING) &&
1954 (nid != NID_pkcs9_emailAddress))
1955 str->type=V_ASN1_T61STRING;
1957 if ((nid == NID_pkcs9_emailAddress) &&
1958 (str->type == V_ASN1_PRINTABLESTRING))
1959 str->type=V_ASN1_IA5STRING;
1962 /* If no EMAIL is wanted in the subject */
1963 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1966 /* check some things */
1967 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1968 (str->type != V_ASN1_IA5STRING))
1970 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1973 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1975 j=ASN1_PRINTABLE_type(str->data,str->length);
1976 if ( ((j == V_ASN1_T61STRING) &&
1977 (str->type != V_ASN1_T61STRING)) ||
1978 ((j == V_ASN1_IA5STRING) &&
1979 (str->type == V_ASN1_PRINTABLESTRING)))
1981 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1987 old_entry_print(bio_err, obj, str);
1990 /* Ok, now we check the 'policy' stuff. */
1991 if ((subject=X509_NAME_new()) == NULL)
1993 BIO_printf(bio_err,"Memory allocation failure\n");
1997 /* take a copy of the issuer name before we mess with it. */
1998 CAname=X509_NAME_dup(x509->cert_info->subject);
1999 if (CAname == NULL) goto err;
2002 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
2004 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
2005 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
2007 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
2015 /* lookup the object in the supplied name list */
2016 j=X509_NAME_get_index_by_OBJ(name,obj,last);
2019 if (last != -1) break;
2024 tne=X509_NAME_get_entry(name,j);
2028 /* depending on the 'policy', decide what to do. */
2030 if (strcmp(cv->value,"optional") == 0)
2035 else if (strcmp(cv->value,"supplied") == 0)
2039 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2045 else if (strcmp(cv->value,"match") == 0)
2051 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2058 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2059 if ((j < 0) && (last2 == -1))
2061 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2066 push=X509_NAME_get_entry(CAname,j);
2067 str=X509_NAME_ENTRY_get_data(tne);
2068 str2=X509_NAME_ENTRY_get_data(push);
2070 if (ASN1_STRING_cmp(str,str2) != 0)
2075 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));
2081 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2087 if (!X509_NAME_add_entry(subject,push, -1, 0))
2090 X509_NAME_ENTRY_free(push);
2091 BIO_printf(bio_err,"Memory allocation failure\n");
2101 X509_NAME_free(subject);
2102 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
2103 subject=X509_NAME_dup(name);
2104 if (subject == NULL) goto err;
2108 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2110 /* Build the correct Subject if no e-mail is wanted in the subject */
2111 /* and add it later on because of the method extensions are added (altName) */
2114 dn_subject = subject;
2117 X509_NAME_ENTRY *tmpne;
2118 /* Its best to dup the subject DN and then delete any email
2119 * addresses because this retains its structure.
2121 if (!(dn_subject = X509_NAME_dup(subject)))
2123 BIO_printf(bio_err,"Memory allocation failure\n");
2126 while((i = X509_NAME_get_index_by_NID(dn_subject,
2127 NID_pkcs9_emailAddress, -1)) >= 0)
2129 tmpne = X509_NAME_get_entry(dn_subject, i);
2130 X509_NAME_delete_entry(dn_subject, i);
2131 X509_NAME_ENTRY_free(tmpne);
2135 if (BN_is_zero(serial))
2136 row[DB_serial]=BUF_strdup("00");
2138 row[DB_serial]=BN_bn2hex(serial);
2139 if (row[DB_serial] == NULL)
2141 BIO_printf(bio_err,"Memory allocation failure\n");
2145 rrow=TXT_DB_get_by_index(db,DB_name,row);
2148 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2153 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2156 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2158 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2165 "The matching entry has the following details\n");
2166 if (rrow[DB_type][0] == 'E')
2168 else if (rrow[DB_type][0] == 'R')
2170 else if (rrow[DB_type][0] == 'V')
2173 p="\ninvalid type, Data base error\n";
2174 BIO_printf(bio_err,"Type :%s\n",p);;
2175 if (rrow[DB_type][0] == 'R')
2177 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2178 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2180 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2181 BIO_printf(bio_err,"Expires on :%s\n",p);
2182 p=rrow[DB_serial]; if (p == NULL) p="undef";
2183 BIO_printf(bio_err,"Serial Number :%s\n",p);
2184 p=rrow[DB_file]; if (p == NULL) p="undef";
2185 BIO_printf(bio_err,"File name :%s\n",p);
2186 p=rrow[DB_name]; if (p == NULL) p="undef";
2187 BIO_printf(bio_err,"Subject Name :%s\n",p);
2188 ok= -1; /* This is now a 'bad' error. */
2192 /* We are now totally happy, lets make and sign the certificate */
2194 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2196 if ((ret=X509_new()) == NULL) goto err;
2200 /* Make it an X509 v3 certificate. */
2201 if (!X509_set_version(x509,2)) goto err;
2204 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2206 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2209 if (strcmp(startdate,"today") == 0)
2210 X509_gmtime_adj(X509_get_notBefore(ret),0);
2211 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2213 if (enddate == NULL)
2214 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2215 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2217 if (!X509_set_subject_name(ret,subject)) goto err;
2219 pktmp=X509_REQ_get_pubkey(req);
2220 i = X509_set_pubkey(ret,pktmp);
2221 EVP_PKEY_free(pktmp);
2224 /* Lets add the extensions, if there are any */
2228 if (ci->version == NULL)
2229 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2231 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2233 /* Free the current entries if any, there should not
2234 * be any I believe */
2235 if (ci->extensions != NULL)
2236 sk_X509_EXTENSION_pop_free(ci->extensions,
2237 X509_EXTENSION_free);
2239 ci->extensions = NULL;
2241 /* Initialize the context structure */
2242 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2247 BIO_printf(bio_err, "Extra configuration file found\n");
2249 /* Use the extconf configuration db LHASH */
2250 X509V3_set_nconf(&ctx, extconf);
2252 /* Test the structure (needed?) */
2253 /* X509V3_set_ctx_test(&ctx); */
2255 /* Adds exts contained in the configuration file */
2256 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2259 "ERROR: adding extensions in section %s\n",
2261 ERR_print_errors(bio_err);
2265 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2269 /* We found extensions to be set from config file */
2270 X509V3_set_nconf(&ctx, lconf);
2272 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2274 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2275 ERR_print_errors(bio_err);
2280 BIO_printf(bio_err, "Successfully added extensions from config\n");
2284 /* Copy extensions from request (if any) */
2286 if (!copy_extensions(ret, req, ext_copy))
2288 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2289 ERR_print_errors(bio_err);
2293 /* Set the right value for the noemailDN option */
2296 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2301 BIO_printf(bio_err, "Certificate Details:\n");
2302 /* Never print signature details because signature not present */
2303 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2304 X509_print_ex(bio_err, ret, nameopt, certopt);
2307 BIO_printf(bio_err,"Certificate is to be certified until ");
2308 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2309 if (days) BIO_printf(bio_err," (%d days)",days);
2310 BIO_printf(bio_err, "\n");
2315 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2316 (void)BIO_flush(bio_err);
2318 fgets(buf,sizeof(buf)-1,stdin);
2319 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2321 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2328 #ifndef OPENSSL_NO_DSA
2329 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2330 pktmp=X509_get_pubkey(ret);
2331 if (EVP_PKEY_missing_parameters(pktmp) &&
2332 !EVP_PKEY_missing_parameters(pkey))
2333 EVP_PKEY_copy_parameters(pktmp,pkey);
2334 EVP_PKEY_free(pktmp);
2336 #ifndef OPENSSL_NO_ECDSA
2337 if (pkey->type == EVP_PKEY_EC)
2339 pktmp = X509_get_pubkey(ret);
2340 if (EVP_PKEY_missing_parameters(pktmp) &&
2341 !EVP_PKEY_missing_parameters(pkey))
2342 EVP_PKEY_copy_parameters(pktmp, pkey);
2343 EVP_PKEY_free(pktmp);
2347 if (!X509_sign(ret,pkey,dgst))
2350 /* We now just add it to the database */
2351 row[DB_type]=(char *)OPENSSL_malloc(2);
2353 tm=X509_get_notAfter(ret);
2354 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2355 memcpy(row[DB_exp_date],tm->data,tm->length);
2356 row[DB_exp_date][tm->length]='\0';
2358 row[DB_rev_date]=NULL;
2360 /* row[DB_serial] done already */
2361 row[DB_file]=(char *)OPENSSL_malloc(8);
2362 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2364 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2365 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2367 BIO_printf(bio_err,"Memory allocation failure\n");
2370 strcpy(row[DB_file],"unknown");
2371 row[DB_type][0]='V';
2372 row[DB_type][1]='\0';
2374 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2376 BIO_printf(bio_err,"Memory allocation failure\n");
2380 for (i=0; i<DB_NUMBER; i++)
2385 irow[DB_NUMBER]=NULL;
2387 if (!TXT_DB_insert(db,irow))
2389 BIO_printf(bio_err,"failed to update database\n");
2390 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2395 for (i=0; i<DB_NUMBER; i++)
2396 if (row[i] != NULL) OPENSSL_free(row[i]);
2399 X509_NAME_free(CAname);
2400 if (subject != NULL)
2401 X509_NAME_free(subject);
2402 if ((dn_subject != NULL) && !email_dn)
2403 X509_NAME_free(dn_subject);
2405 ASN1_UTCTIME_free(tmptm);
2408 if (ret != NULL) X509_free(ret);
2416 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2421 (void)i2d_X509_bio(bp,x);
2425 /* ??? Not needed since X509_print prints all this stuff anyway */
2426 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2427 BIO_printf(bp,"issuer :%s\n",f);
2429 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2430 BIO_printf(bp,"subject:%s\n",f);
2432 BIO_puts(bp,"serial :");
2433 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2434 BIO_puts(bp,"\n\n");
2436 if (!notext)X509_print(bp,x);
2437 PEM_write_bio_X509(bp,x);
2440 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2441 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2442 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2443 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2444 unsigned long nameopt, int default_op, int ext_copy)
2446 STACK_OF(CONF_VALUE) *sk=NULL;
2449 CONF_VALUE *cv=NULL;
2450 NETSCAPE_SPKI *spki = NULL;
2453 EVP_PKEY *pktmp=NULL;
2455 X509_NAME_ENTRY *ne=NULL;
2461 * Load input file into a hash table. (This is just an easy
2462 * way to read and parse the file, then put it into a convenient
2465 parms=CONF_load(NULL,infile,&errline);
2468 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2469 ERR_print_errors(bio_err);
2473 sk=CONF_get_section(parms, "default");
2474 if (sk_CONF_VALUE_num(sk) == 0)
2476 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2482 * Now create a dummy X509 request structure. We don't actually
2483 * have an X509 request, but we have many of the components
2484 * (a public key, various DN components). The idea is that we
2485 * put these components into the right X509 request structure
2486 * and we can use the same code as if you had a real X509 request.
2491 ERR_print_errors(bio_err);
2496 * Build up the subject name set.
2503 if (sk_CONF_VALUE_num(sk) <= i) break;
2505 cv=sk_CONF_VALUE_value(sk,i);
2507 /* Skip past any leading X. X: X, etc to allow for
2508 * multiple instances
2510 for (buf = cv->name; *buf ; buf++)
2511 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2514 if (*buf) type = buf;
2519 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2521 if (strcmp(type, "SPKAC") == 0)
2523 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2526 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2527 ERR_print_errors(bio_err);
2535 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2539 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2540 if (fix_data(nid, &j) == 0)
2543 "invalid characters in string %s\n",buf);
2547 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2548 (unsigned char *)buf,
2549 strlen(buf))) == NULL)
2552 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2556 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2562 * Now extract the key from the SPKI structure.
2565 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2567 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2569 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2573 j = NETSCAPE_SPKI_verify(spki, pktmp);
2576 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2579 BIO_printf(bio_err,"Signature ok\n");
2581 X509_REQ_set_pubkey(req,pktmp);
2582 EVP_PKEY_free(pktmp);
2583 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2584 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2587 if (req != NULL) X509_REQ_free(req);
2588 if (parms != NULL) CONF_free(parms);
2589 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2590 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2595 static int fix_data(int nid, int *type)
2597 if (nid == NID_pkcs9_emailAddress)
2598 *type=V_ASN1_IA5STRING;
2599 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2600 *type=V_ASN1_T61STRING;
2601 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2602 *type=V_ASN1_T61STRING;
2603 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2605 if (nid == NID_pkcs9_unstructuredName)
2606 *type=V_ASN1_IA5STRING;
2610 static int check_time_format(char *str)
2614 tm.data=(unsigned char *)str;
2615 tm.length=strlen(str);
2616 tm.type=V_ASN1_UTCTIME;
2617 return(ASN1_UTCTIME_check(&tm));
2620 static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2622 ASN1_UTCTIME *tm=NULL;
2623 char *row[DB_NUMBER],**rrow,**irow;
2624 char *rev_str = NULL;
2628 for (i=0; i<DB_NUMBER; i++)
2630 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2631 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2633 row[DB_serial]=BUF_strdup("00");
2635 row[DB_serial]=BN_bn2hex(bn);
2637 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2639 BIO_printf(bio_err,"Memory allocation failure\n");
2642 /* We have to lookup by serial number because name lookup
2643 * skips revoked certs
2645 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2648 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2650 /* We now just add it to the database */
2651 row[DB_type]=(char *)OPENSSL_malloc(2);
2653 tm=X509_get_notAfter(x509);
2654 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2655 memcpy(row[DB_exp_date],tm->data,tm->length);
2656 row[DB_exp_date][tm->length]='\0';
2658 row[DB_rev_date]=NULL;
2660 /* row[DB_serial] done already */
2661 row[DB_file]=(char *)OPENSSL_malloc(8);
2663 /* row[DB_name] done already */
2665 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2666 (row[DB_file] == NULL))
2668 BIO_printf(bio_err,"Memory allocation failure\n");
2671 strcpy(row[DB_file],"unknown");
2672 row[DB_type][0]='V';
2673 row[DB_type][1]='\0';
2675 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2677 BIO_printf(bio_err,"Memory allocation failure\n");
2681 for (i=0; i<DB_NUMBER; i++)
2686 irow[DB_NUMBER]=NULL;
2688 if (!TXT_DB_insert(db,irow))
2690 BIO_printf(bio_err,"failed to update database\n");
2691 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2695 /* Revoke Certificate */
2696 ok = do_revoke(x509,db, type, value);
2701 else if (index_name_cmp((const char **)row,(const char **)rrow))
2703 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2707 else if (rrow[DB_type][0]=='R')
2709 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2715 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2716 rev_str = make_revocation_str(type, value);
2719 BIO_printf(bio_err, "Error in revocation arguments\n");
2722 rrow[DB_type][0]='R';
2723 rrow[DB_type][1]='\0';
2724 rrow[DB_rev_date] = rev_str;
2728 for (i=0; i<DB_NUMBER; i++)
2731 OPENSSL_free(row[i]);
2736 static int get_certificate_status(const char *serial, TXT_DB *db)
2738 char *row[DB_NUMBER],**rrow;
2741 /* Free Resources */
2742 for (i=0; i<DB_NUMBER; i++)
2745 /* Malloc needed char spaces */
2746 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2747 if (row[DB_serial] == NULL)
2749 BIO_printf(bio_err,"Malloc failure\n");
2753 if (strlen(serial) % 2)
2755 /* Set the first char to 0 */;
2756 row[DB_serial][0]='0';
2758 /* Copy String from serial to row[DB_serial] */
2759 memcpy(row[DB_serial]+1, serial, strlen(serial));
2760 row[DB_serial][strlen(serial)+1]='\0';
2764 /* Copy String from serial to row[DB_serial] */
2765 memcpy(row[DB_serial], serial, strlen(serial));
2766 row[DB_serial][strlen(serial)]='\0';
2769 /* Make it Upper Case */
2770 for (i=0; row[DB_serial][i] != '\0'; i++)
2771 row[DB_serial][i] = toupper(row[DB_serial][i]);
2776 /* Search for the certificate */
2777 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2780 BIO_printf(bio_err,"Serial %s not present in db.\n",
2785 else if (rrow[DB_type][0]=='V')
2787 BIO_printf(bio_err,"%s=Valid (%c)\n",
2788 row[DB_serial], rrow[DB_type][0]);
2791 else if (rrow[DB_type][0]=='R')
2793 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2794 row[DB_serial], rrow[DB_type][0]);
2797 else if (rrow[DB_type][0]=='E')
2799 BIO_printf(bio_err,"%s=Expired (%c)\n",
2800 row[DB_serial], rrow[DB_type][0]);
2803 else if (rrow[DB_type][0]=='S')
2805 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2806 row[DB_serial], rrow[DB_type][0]);
2811 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2812 row[DB_serial], rrow[DB_type][0]);
2816 for (i=0; i<DB_NUMBER; i++)
2819 OPENSSL_free(row[i]);
2824 static int do_updatedb (TXT_DB *db)
2826 ASN1_UTCTIME *a_tm = NULL;
2828 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2829 char **rrow, *a_tm_s;
2831 a_tm = ASN1_UTCTIME_new();
2833 /* get actual time and make a string */
2834 a_tm = X509_gmtime_adj(a_tm, 0);
2835 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2842 memcpy(a_tm_s, a_tm->data, a_tm->length);
2843 a_tm_s[a_tm->length] = '\0';
2845 if (strncmp(a_tm_s, "49", 2) <= 0)
2850 for (i = 0; i < sk_num(db->data); i++)
2852 rrow = (char **) sk_value(db->data, i);
2854 if (rrow[DB_type][0] == 'V')
2856 /* ignore entries that are not valid */
2857 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2862 if (db_y2k == a_y2k)
2864 /* all on the same y2k side */
2865 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2867 rrow[DB_type][0] = 'E';
2868 rrow[DB_type][1] = '\0';
2871 BIO_printf(bio_err, "%s=Expired\n",
2875 else if (db_y2k < a_y2k)
2877 rrow[DB_type][0] = 'E';
2878 rrow[DB_type][1] = '\0';
2881 BIO_printf(bio_err, "%s=Expired\n",
2890 ASN1_UTCTIME_free(a_tm);
2891 OPENSSL_free(a_tm_s);
2896 static char *crl_reasons[] = {
2897 /* CRL reason strings */
2901 "affiliationChanged",
2903 "cessationOfOperation",
2906 /* Additional pseudo reasons */
2912 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2914 /* Given revocation information convert to a DB string.
2915 * The format of the string is:
2916 * revtime[,reason,extra]. Where 'revtime' is the
2917 * revocation time (the current time). 'reason' is the
2918 * optional CRL reason and 'extra' is any additional
2922 char *make_revocation_str(int rev_type, char *rev_arg)
2924 char *reason = NULL, *other = NULL, *str;
2926 ASN1_UTCTIME *revtm = NULL;
2933 case REV_CRL_REASON:
2934 for (i = 0; i < 8; i++)
2936 if (!strcasecmp(rev_arg, crl_reasons[i]))
2938 reason = crl_reasons[i];
2944 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2950 /* Argument is an OID */
2952 otmp = OBJ_txt2obj(rev_arg, 0);
2953 ASN1_OBJECT_free(otmp);
2957 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2961 reason = "holdInstruction";
2965 case REV_KEY_COMPROMISE:
2966 case REV_CA_COMPROMISE:
2968 /* Argument is the key compromise time */
2969 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2971 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2975 if (rev_type == REV_KEY_COMPROMISE)
2978 reason = "CAkeyTime";
2984 revtm = X509_gmtime_adj(NULL, 0);
2986 i = revtm->length + 1;
2988 if (reason) i += strlen(reason) + 1;
2989 if (other) i += strlen(other) + 1;
2991 str = OPENSSL_malloc(i);
2993 if (!str) return NULL;
2995 strcpy(str, (char *)revtm->data);
2999 strcat(str, reason);
3006 ASN1_UTCTIME_free(revtm);
3010 /* Convert revocation field to X509_REVOKED entry
3014 * 2 OK and some extensions added (i.e. V2 CRL)
3018 int make_revoked(X509_REVOKED *rev, char *str)
3021 int reason_code = -1;
3023 ASN1_OBJECT *hold = NULL;
3024 ASN1_GENERALIZEDTIME *comp_time = NULL;
3025 ASN1_ENUMERATED *rtmp = NULL;
3027 ASN1_TIME *revDate = NULL;
3029 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
3034 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
3037 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3039 rtmp = ASN1_ENUMERATED_new();
3040 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3042 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3046 if (rev && comp_time)
3048 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3053 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3057 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3063 if (tmp) OPENSSL_free(tmp);
3064 ASN1_OBJECT_free(hold);
3065 ASN1_GENERALIZEDTIME_free(comp_time);
3066 ASN1_ENUMERATED_free(rtmp);
3067 ASN1_TIME_free(revDate);
3073 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
3074 * where characters may be escaped by \
3076 X509_NAME *do_subject(char *subject, long chtype)
3078 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
3079 char *buf = OPENSSL_malloc(buflen);
3080 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
3081 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
3082 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
3084 char *sp = subject, *bp = buf;
3087 X509_NAME *n = NULL;
3090 if (!buf || !ne_types || !ne_values)
3092 BIO_printf(bio_err, "malloc error\n");
3096 if (*subject != '/')
3098 BIO_printf(bio_err, "Subject does not start with '/'.\n");
3101 sp++; /* skip leading / */
3106 ne_types[ne_num] = bp;
3109 if (*sp == '\\') /* is there anything to escape in the type...? */
3115 BIO_printf(bio_err, "escape character at end of string\n");
3119 else if (*sp == '=')
3130 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
3133 ne_values[ne_num] = bp;
3142 BIO_printf(bio_err, "escape character at end of string\n");
3146 else if (*sp == '/')
3158 if (!(n = X509_NAME_new()))
3161 for (i = 0; i < ne_num; i++)
3163 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
3165 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
3171 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
3175 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
3179 OPENSSL_free(ne_values);
3180 OPENSSL_free(ne_types);
3187 OPENSSL_free(ne_values);
3189 OPENSSL_free(ne_types);
3195 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3197 char buf[25],*pbuf, *p;
3199 j=i2a_ASN1_OBJECT(bp,obj);
3201 for (j=22-j; j>0; j--)
3207 if (str->type == V_ASN1_PRINTABLESTRING)
3208 BIO_printf(bp,"PRINTABLE:'");
3209 else if (str->type == V_ASN1_T61STRING)
3210 BIO_printf(bp,"T61STRING:'");
3211 else if (str->type == V_ASN1_IA5STRING)
3212 BIO_printf(bp,"IA5STRING:'");
3213 else if (str->type == V_ASN1_UNIVERSALSTRING)
3214 BIO_printf(bp,"UNIVERSALSTRING:'");
3216 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3218 p=(char *)str->data;
3219 for (j=str->length; j>0; j--)
3221 if ((*p >= ' ') && (*p <= '~'))
3222 BIO_printf(bp,"%c",*p);
3224 BIO_printf(bp,"\\0x%02X",*p);
3225 else if ((unsigned char)*p == 0xf7)
3226 BIO_printf(bp,"^?");
3227 else BIO_printf(bp,"^%c",*p+'@');
3230 BIO_printf(bp,"'\n");
3234 int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3237 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3238 int reason_code = -1;
3240 ASN1_OBJECT *hold = NULL;
3241 ASN1_GENERALIZEDTIME *comp_time = NULL;
3242 tmp = BUF_strdup(str);
3244 p = strchr(tmp, ',');
3263 *prevtm = ASN1_UTCTIME_new();
3264 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3266 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3272 for (i = 0; i < NUM_REASONS; i++)
3274 if(!strcasecmp(reason_str, crl_reasons[i]))
3280 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3282 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3286 if (reason_code == 7)
3287 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3288 else if (reason_code == 8) /* Hold instruction */
3292 BIO_printf(bio_err, "missing hold instruction\n");
3295 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3296 hold = OBJ_txt2obj(arg_str, 0);
3300 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3303 if (phold) *phold = hold;
3305 else if ((reason_code == 9) || (reason_code == 10))
3309 BIO_printf(bio_err, "missing compromised time\n");
3312 comp_time = ASN1_GENERALIZEDTIME_new();
3313 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3315 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3318 if (reason_code == 9)
3319 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3321 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3325 if (preason) *preason = reason_code;
3326 if (pinvtm) *pinvtm = comp_time;
3327 else ASN1_GENERALIZEDTIME_free(comp_time);
3333 if (tmp) OPENSSL_free(tmp);
3334 if (!phold) ASN1_OBJECT_free(hold);
3335 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3340 int make_serial_index(TXT_DB *db)
3342 if (!TXT_DB_create_index(db, DB_serial, NULL,
3343 LHASH_HASH_FN(index_serial_hash),
3344 LHASH_COMP_FN(index_serial_cmp)))
3347 "error creating serial number index:(%ld,%ld,%ld)\n",
3348 db->error,db->arg1,db->arg2);