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>
68 #include <openssl/conf.h>
69 #include <openssl/bio.h>
70 #include <openssl/err.h>
71 #include <openssl/bn.h>
72 #include <openssl/txt_db.h>
73 #include <openssl/evp.h>
74 #include <openssl/x509.h>
75 #include <openssl/x509v3.h>
76 #include <openssl/objects.h>
77 #include <openssl/pem.h>
78 #include <openssl/engine.h>
88 # include <sys/file.h>
102 #define BASE_SECTION "ca"
103 #define CONFIG_FILE "openssl.cnf"
105 #define ENV_DEFAULT_CA "default_ca"
107 #define ENV_DIR "dir"
108 #define ENV_CERTS "certs"
109 #define ENV_CRL_DIR "crl_dir"
110 #define ENV_CA_DB "CA_DB"
111 #define ENV_NEW_CERTS_DIR "new_certs_dir"
112 #define ENV_CERTIFICATE "certificate"
113 #define ENV_SERIAL "serial"
114 #define ENV_CRL "crl"
115 #define ENV_PRIVATE_KEY "private_key"
116 #define ENV_RANDFILE "RANDFILE"
117 #define ENV_DEFAULT_DAYS "default_days"
118 #define ENV_DEFAULT_STARTDATE "default_startdate"
119 #define ENV_DEFAULT_ENDDATE "default_enddate"
120 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
121 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
122 #define ENV_DEFAULT_MD "default_md"
123 #define ENV_PRESERVE "preserve"
124 #define ENV_POLICY "policy"
125 #define ENV_EXTENSIONS "x509_extensions"
126 #define ENV_CRLEXT "crl_extensions"
127 #define ENV_MSIE_HACK "msie_hack"
129 #define ENV_DATABASE "database"
132 #define DB_exp_date 1
133 #define DB_rev_date 2
134 #define DB_serial 3 /* index - unique */
136 #define DB_name 5 /* index - unique for active */
139 #define DB_TYPE_REV 'R'
140 #define DB_TYPE_EXP 'E'
141 #define DB_TYPE_VAL 'V'
143 static char *ca_usage[]={
146 " -verbose - Talk alot while doing things\n",
147 " -config file - A config file\n",
148 " -name arg - The particular CA definition to use\n",
149 " -gencrl - Generate a new CRL\n",
150 " -crldays days - Days is when the next CRL is due\n",
151 " -crlhours hours - Hours is when the next CRL is due\n",
152 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
153 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
154 " -days arg - number of days to certify the certificate for\n",
155 " -md arg - md to use, one of md2, md5, sha or sha1\n",
156 " -policy arg - The CA 'policy' to support\n",
157 " -keyfile arg - private key file\n",
158 " -keyform arg - private key file format (PEM or ENGINE)\n",
159 " -key arg - key to decode the private key if it is encrypted\n",
160 " -cert file - The CA certificate\n",
161 " -in file - The input PEM encoded certificate request(s)\n",
162 " -out file - Where to put the output file(s)\n",
163 " -outdir dir - Where to put output certificates\n",
164 " -infiles .... - The last argument, requests to process\n",
165 " -spkac file - File contains DN and signed public key and challenge\n",
166 " -ss_cert file - File contains a self signed cert to sign\n",
167 " -preserveDN - Don't re-order the DN\n",
168 " -batch - Don't ask questions\n",
169 " -msie_hack - msie modifications to handle all those universal strings\n",
170 " -revoke file - Revoke a certificate (given in file)\n",
171 " -extensions .. - Extension section (override value in config file)\n",
172 " -crlexts .. - CRL extension section (override value in config file)\n",
173 " -engine e - use engine e, possibly a hardware device.\n",
174 " -status serial - Shows certificate status given the serial number\n",
175 " -updatedb - Updates db for expired certificates\n",
180 extern int EF_PROTECT_FREE;
181 extern int EF_PROTECT_BELOW;
182 extern int EF_ALIGNMENT;
185 static void lookup_fail(char *name,char *tag);
186 static unsigned long index_serial_hash(const char **a);
187 static int index_serial_cmp(const char **a, const char **b);
188 static unsigned long index_name_hash(const char **a);
189 static int index_name_qual(char **a);
190 static int index_name_cmp(const char **a,const char **b);
191 static BIGNUM *load_serial(char *serialfile);
192 static int save_serial(char *serialfile, BIGNUM *serial);
193 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
194 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
195 BIGNUM *serial, char *startdate,char *enddate, int days,
196 int batch, char *ext_sect, LHASH *conf,int verbose);
197 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
198 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
199 TXT_DB *db, BIGNUM *serial,char *startdate,
200 char *enddate, int days, int batch, char *ext_sect,
201 LHASH *conf,int verbose);
202 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
203 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
204 TXT_DB *db, BIGNUM *serial,char *startdate,
205 char *enddate, int days, char *ext_sect,LHASH *conf,
207 static int fix_data(int nid, int *type);
208 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
209 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
210 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
211 char *startdate, char *enddate, int days, int batch, int verbose,
212 X509_REQ *req, char *ext_sect, LHASH *conf);
213 static int do_revoke(X509 *x509, TXT_DB *db);
214 static int get_certificate_status(const char *ser_status, TXT_DB *db);
215 static int do_updatedb(TXT_DB *db);
216 static int check_time_format(char *str);
217 static LHASH *conf=NULL;
218 static char *section=NULL;
220 static int preserve=0;
221 static int msie_hack=0;
223 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
224 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
225 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
226 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
229 int MAIN(int, char **);
231 int MAIN(int argc, char **argv)
234 char *key=NULL,*passargin=NULL;
247 char *configfile=NULL;
252 int keyform=FORMAT_PEM;
254 char *spkac_file=NULL;
255 char *ss_cert_file=NULL;
256 char *ser_status=NULL;
261 char *serialfile=NULL;
262 char *extensions=NULL;
265 char *startdate=NULL;
272 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
276 X509_CRL_INFO *ci=NULL;
277 X509_REVOKED *r=NULL;
281 const EVP_MD *dgst=NULL;
282 STACK_OF(CONF_VALUE) *attribs=NULL;
283 STACK_OF(X509) *cert_sk=NULL;
287 MS_STATIC char buf[3][BSIZE];
306 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
307 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
313 if (strcmp(*argv,"-verbose") == 0)
315 else if (strcmp(*argv,"-config") == 0)
317 if (--argc < 1) goto bad;
318 configfile= *(++argv);
320 else if (strcmp(*argv,"-name") == 0)
322 if (--argc < 1) goto bad;
325 else if (strcmp(*argv,"-startdate") == 0)
327 if (--argc < 1) goto bad;
328 startdate= *(++argv);
330 else if (strcmp(*argv,"-enddate") == 0)
332 if (--argc < 1) goto bad;
335 else if (strcmp(*argv,"-days") == 0)
337 if (--argc < 1) goto bad;
338 days=atoi(*(++argv));
340 else if (strcmp(*argv,"-md") == 0)
342 if (--argc < 1) goto bad;
345 else if (strcmp(*argv,"-policy") == 0)
347 if (--argc < 1) goto bad;
350 else if (strcmp(*argv,"-keyfile") == 0)
352 if (--argc < 1) goto bad;
355 else if (strcmp(*argv,"-keyform") == 0)
357 if (--argc < 1) goto bad;
358 keyform=str2fmt(*(++argv));
360 else if (strcmp(*argv,"-passin") == 0)
362 if (--argc < 1) goto bad;
363 passargin= *(++argv);
365 else if (strcmp(*argv,"-key") == 0)
367 if (--argc < 1) goto bad;
370 else if (strcmp(*argv,"-cert") == 0)
372 if (--argc < 1) goto bad;
375 else if (strcmp(*argv,"-in") == 0)
377 if (--argc < 1) goto bad;
381 else if (strcmp(*argv,"-out") == 0)
383 if (--argc < 1) goto bad;
386 else if (strcmp(*argv,"-outdir") == 0)
388 if (--argc < 1) goto bad;
391 else if (strcmp(*argv,"-notext") == 0)
393 else if (strcmp(*argv,"-batch") == 0)
395 else if (strcmp(*argv,"-preserveDN") == 0)
397 else if (strcmp(*argv,"-gencrl") == 0)
399 else if (strcmp(*argv,"-msie_hack") == 0)
401 else if (strcmp(*argv,"-crldays") == 0)
403 if (--argc < 1) goto bad;
404 crldays= atol(*(++argv));
406 else if (strcmp(*argv,"-crlhours") == 0)
408 if (--argc < 1) goto bad;
409 crlhours= atol(*(++argv));
411 else if (strcmp(*argv,"-infiles") == 0)
418 else if (strcmp(*argv, "-ss_cert") == 0)
420 if (--argc < 1) goto bad;
421 ss_cert_file = *(++argv);
424 else if (strcmp(*argv, "-spkac") == 0)
426 if (--argc < 1) goto bad;
427 spkac_file = *(++argv);
430 else if (strcmp(*argv,"-revoke") == 0)
432 if (--argc < 1) goto bad;
436 else if (strcmp(*argv,"-extensions") == 0)
438 if (--argc < 1) goto bad;
439 extensions= *(++argv);
441 else if (strcmp(*argv,"-status") == 0)
443 if (--argc < 1) goto bad;
444 ser_status= *(++argv);
446 else if (strcmp(*argv,"-updatedb") == 0)
450 else if (strcmp(*argv,"-crlexts") == 0)
452 if (--argc < 1) goto bad;
455 else if (strcmp(*argv,"-engine") == 0)
457 if (--argc < 1) goto bad;
463 BIO_printf(bio_err,"unknown option %s\n",*argv);
473 for (pp=ca_usage; (*pp != NULL); pp++)
474 BIO_printf(bio_err,*pp);
478 ERR_load_crypto_strings();
482 if ((e = ENGINE_by_id(engine)) == NULL)
484 BIO_printf(bio_err,"invalid engine \"%s\"\n",
488 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
490 BIO_printf(bio_err,"can't use that engine\n");
493 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
494 /* Free our "structural" reference. */
498 /*****************************************************************/
499 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
500 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
501 if (configfile == NULL)
503 /* We will just use 'buf[0]' as a temporary buffer. */
505 strncpy(buf[0],X509_get_default_cert_area(),
506 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
508 strncpy(buf[0],X509_get_default_cert_area(),
509 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
512 strcat(buf[0],CONFIG_FILE);
516 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
517 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
520 BIO_printf(bio_err,"error loading the config file '%s'\n",
523 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
524 ,errorline,configfile);
528 /* Lets get the config section we are using */
531 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
534 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
541 p=CONF_get_string(conf,NULL,"oid_file");
548 oid_bio=BIO_new_file(p,"r");
552 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
553 ERR_print_errors(bio_err);
559 OBJ_create_objects(oid_bio);
563 if (!add_oid_section(bio_err,conf))
565 ERR_print_errors(bio_err);
570 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
571 if (randfile == NULL)
573 app_RAND_load_file(randfile, bio_err, 0);
575 in=BIO_new(BIO_s_file());
576 out=BIO_new(BIO_s_file());
577 Sout=BIO_new(BIO_s_file());
578 Cout=BIO_new(BIO_s_file());
579 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
581 ERR_print_errors(bio_err);
585 /*****************************************************************/
586 /* report status of cert with serial number given on command line */
589 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
591 lookup_fail(section,ENV_DATABASE);
594 if (BIO_read_filename(in,dbfile) <= 0)
597 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
600 db=TXT_DB_read(in,DB_NUMBER);
601 if (db == NULL) goto err;
603 if (!TXT_DB_create_index(db, DB_serial, NULL,
604 LHASH_HASH_FN(index_serial_hash),
605 LHASH_COMP_FN(index_serial_cmp)))
608 "error creating serial number index:(%ld,%ld,%ld)\n",
609 db->error,db->arg1,db->arg2);
613 if (get_certificate_status(ser_status,db) != 1)
614 BIO_printf(bio_err,"Error verifying serial %s!\n",
619 /*****************************************************************/
620 /* we definitely need a public key, so let's get it */
622 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
623 section,ENV_PRIVATE_KEY)) == NULL))
625 lookup_fail(section,ENV_PRIVATE_KEY);
628 if (!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
630 BIO_printf(bio_err,"Error getting password\n");
633 if (keyform == FORMAT_ENGINE)
637 BIO_printf(bio_err,"no engine specified\n");
640 pkey = ENGINE_load_private_key(e, keyfile, key);
642 else if (keyform == FORMAT_PEM)
644 if (BIO_read_filename(in,keyfile) <= 0)
647 BIO_printf(bio_err,"trying to load CA private key\n");
650 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
654 BIO_printf(bio_err,"bad input format specified for key file\n");
657 if (key) memset(key,0,strlen(key));
660 BIO_printf(bio_err,"unable to load CA private key\n");
664 /*****************************************************************/
665 /* we need a certificate */
666 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
667 section,ENV_CERTIFICATE)) == NULL))
669 lookup_fail(section,ENV_CERTIFICATE);
672 if (BIO_read_filename(in,certfile) <= 0)
675 BIO_printf(bio_err,"trying to load CA certificate\n");
678 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
681 BIO_printf(bio_err,"unable to load CA certificate\n");
685 if (!X509_check_private_key(x509,pkey))
687 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
691 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
694 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
696 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
699 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
702 /*****************************************************************/
703 /* lookup where to write new certificates */
704 if ((outdir == NULL) && (req))
708 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
711 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
714 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
715 filename. In any case, stat(), below, will catch the problem
716 if outdir is not a directory spec, and the fopen() or open()
717 will catch an error if there is no write access.
719 Presumably, this problem could also be solved by using the DEC
720 C routines to convert the directory syntax to Unixly, and give
721 that to access(). However, time's too short to do that just
724 if (access(outdir,R_OK|W_OK|X_OK) != 0)
726 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
731 if (stat(outdir,&sb) != 0)
733 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
738 if (!(sb.st_mode & S_IFDIR))
740 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
748 /*****************************************************************/
749 /* we need to load the database file */
750 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
752 lookup_fail(section,ENV_DATABASE);
755 if (BIO_read_filename(in,dbfile) <= 0)
758 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
761 db=TXT_DB_read(in,DB_NUMBER);
762 if (db == NULL) goto err;
764 /* Lets check some fields */
765 for (i=0; i<sk_num(db->data); i++)
767 pp=(char **)sk_value(db->data,i);
768 if ((pp[DB_type][0] != DB_TYPE_REV) &&
769 (pp[DB_rev_date][0] != '\0'))
771 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
774 if ((pp[DB_type][0] == DB_TYPE_REV) &&
775 !check_time_format(pp[DB_rev_date]))
777 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
781 if (!check_time_format(pp[DB_exp_date]))
783 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
788 if ((j&1) || (j < 2))
790 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
795 if (!( ((*p >= '0') && (*p <= '9')) ||
796 ((*p >= 'A') && (*p <= 'F')) ||
797 ((*p >= 'a') && (*p <= 'f'))) )
799 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);
807 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
810 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
811 out = BIO_push(tmpbio, out);
814 TXT_DB_write(out,db);
815 BIO_printf(bio_err,"%d entries loaded from the database\n",
817 BIO_printf(bio_err,"generating index\n");
820 if (!TXT_DB_create_index(db, DB_serial, NULL,
821 LHASH_HASH_FN(index_serial_hash),
822 LHASH_COMP_FN(index_serial_cmp)))
824 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
828 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
829 LHASH_HASH_FN(index_name_hash),
830 LHASH_COMP_FN(index_name_cmp)))
832 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
833 db->error,db->arg1,db->arg2);
837 /*****************************************************************/
838 /* Update the db file for expired certificates */
842 BIO_printf(bio_err, "Updating %s ...\n",
848 BIO_printf(bio_err,"Malloc failure\n");
853 if (verbose) BIO_printf(bio_err,
854 "No entries found to mark expired\n");
858 out = BIO_new(BIO_s_file());
861 ERR_print_errors(bio_err);
865 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
866 if (j < 0 || j >= sizeof buf[0])
868 BIO_printf(bio_err, "file name too long\n");
871 if (BIO_write_filename(out,buf[0]) <= 0)
874 BIO_printf(bio_err,"unable to open '%s'\n",
878 j=TXT_DB_write(out,db);
879 if (j <= 0) goto err;
883 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
884 if (j < 0 || j >= sizeof buf[1])
886 BIO_printf(bio_err, "file name too long\n");
889 if (rename(dbfile,buf[1]) < 0)
892 "unable to rename %s to %s\n",
897 if (rename(buf[0],dbfile) < 0)
900 "unable to rename %s to %s\n",
903 rename(buf[1],dbfile);
907 if (verbose) BIO_printf(bio_err,
908 "Done. %d entries marked as expired\n",i);
913 /*****************************************************************/
919 if (BIO_write_filename(Sout,outfile) <= 0)
927 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
930 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
931 Sout = BIO_push(tmpbio, Sout);
939 if ((md == NULL) && ((md=CONF_get_string(conf,
940 section,ENV_DEFAULT_MD)) == NULL))
942 lookup_fail(section,ENV_DEFAULT_MD);
945 if ((dgst=EVP_get_digestbyname(md)) == NULL)
947 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
951 BIO_printf(bio_err,"message digest is %s\n",
952 OBJ_nid2ln(dgst->type));
953 if ((policy == NULL) && ((policy=CONF_get_string(conf,
954 section,ENV_POLICY)) == NULL))
956 lookup_fail(section,ENV_POLICY);
960 BIO_printf(bio_err,"policy is %s\n",policy);
962 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
965 lookup_fail(section,ENV_SERIAL);
970 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
976 /* Check syntax of file */
978 X509V3_set_ctx_test(&ctx);
979 X509V3_set_conf_lhash(&ctx, conf);
980 if (!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL))
983 "Error Loading extension section %s\n",
990 if (startdate == NULL)
992 startdate=CONF_get_string(conf,section,
993 ENV_DEFAULT_STARTDATE);
994 if (startdate == NULL)
997 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
999 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1002 if (startdate == NULL) startdate="today";
1004 if (enddate == NULL)
1006 enddate=CONF_get_string(conf,section,
1007 ENV_DEFAULT_ENDDATE);
1008 if (enddate == NULL)
1011 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1013 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1019 days=(int)CONF_get_number(conf,section,
1022 if (!enddate && (days == 0))
1024 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1028 if ((serial=load_serial(serialfile)) == NULL)
1030 BIO_printf(bio_err,"error while loading serial number\n");
1035 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1036 BIO_printf(bio_err,"next serial number is %s\n",f);
1040 if ((attribs=CONF_get_section(conf,policy)) == NULL)
1042 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1046 if ((cert_sk=sk_X509_new_null()) == NULL)
1048 BIO_printf(bio_err,"Memory allocation failure\n");
1051 if (spkac_file != NULL)
1054 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1055 serial,startdate,enddate, days,extensions,conf,
1057 if (j < 0) goto err;
1061 BIO_printf(bio_err,"\n");
1062 if (!BN_add_word(serial,1)) goto err;
1063 if (!sk_X509_push(cert_sk,x))
1065 BIO_printf(bio_err,"Memory allocation failure\n");
1075 if (ss_cert_file != NULL)
1078 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1079 db,serial,startdate,enddate,days,batch,
1080 extensions,conf,verbose);
1081 if (j < 0) goto err;
1085 BIO_printf(bio_err,"\n");
1086 if (!BN_add_word(serial,1)) goto err;
1087 if (!sk_X509_push(cert_sk,x))
1089 BIO_printf(bio_err,"Memory allocation failure\n");
1097 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1098 serial,startdate,enddate,days,batch,
1099 extensions,conf,verbose);
1100 if (j < 0) goto err;
1104 BIO_printf(bio_err,"\n");
1105 if (!BN_add_word(serial,1)) goto err;
1106 if (!sk_X509_push(cert_sk,x))
1108 BIO_printf(bio_err,"Memory allocation failure\n");
1113 for (i=0; i<argc; i++)
1116 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1117 serial,startdate,enddate,days,batch,
1118 extensions,conf,verbose);
1119 if (j < 0) goto err;
1123 BIO_printf(bio_err,"\n");
1124 if (!BN_add_word(serial,1)) goto err;
1125 if (!sk_X509_push(cert_sk,x))
1127 BIO_printf(bio_err,"Memory allocation failure\n");
1132 /* we have a stack of newly certified certificates
1133 * and a data base and serial number that need
1136 if (sk_X509_num(cert_sk) > 0)
1140 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1141 (void)BIO_flush(bio_err);
1143 fgets(buf[0],10,stdin);
1144 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1146 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1152 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1154 strncpy(buf[0],serialfile,BSIZE-4);
1157 strcat(buf[0],"-new");
1159 strcat(buf[0],".new");
1162 if (!save_serial(buf[0],serial)) goto err;
1164 strncpy(buf[1],dbfile,BSIZE-4);
1167 strcat(buf[1],"-new");
1169 strcat(buf[1],".new");
1172 if (BIO_write_filename(out,buf[1]) <= 0)
1175 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1178 l=TXT_DB_write(out,db);
1179 if (l <= 0) goto err;
1183 BIO_printf(bio_err,"writing new certificates\n");
1184 for (i=0; i<sk_X509_num(cert_sk); i++)
1189 x=sk_X509_value(cert_sk,i);
1191 j=x->cert_info->serialNumber->length;
1192 p=(char *)x->cert_info->serialNumber->data;
1194 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1200 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1205 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1214 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1217 BIO_printf(bio_err,"writing %s\n",buf[2]);
1219 if (BIO_write_filename(Cout,buf[2]) <= 0)
1224 write_new_certificate(Cout,x, 0, notext);
1225 write_new_certificate(Sout,x, output_der, notext);
1228 if (sk_X509_num(cert_sk))
1230 /* Rename the database and the serial file */
1231 strncpy(buf[2],serialfile,BSIZE-4);
1234 strcat(buf[2],"-old");
1236 strcat(buf[2],".old");
1243 if (rename(serialfile,buf[2]) < 0)
1245 BIO_printf(bio_err,"unable to rename %s to %s\n",
1250 if (rename(buf[0],serialfile) < 0)
1252 BIO_printf(bio_err,"unable to rename %s to %s\n",
1255 rename(buf[2],serialfile);
1259 strncpy(buf[2],dbfile,BSIZE-4);
1262 strcat(buf[2],"-old");
1264 strcat(buf[2],".old");
1267 if (rename(dbfile,buf[2]) < 0)
1269 BIO_printf(bio_err,"unable to rename %s to %s\n",
1274 if (rename(buf[1],dbfile) < 0)
1276 BIO_printf(bio_err,"unable to rename %s to %s\n",
1279 rename(buf[2],dbfile);
1282 BIO_printf(bio_err,"Data Base Updated\n");
1286 /*****************************************************************/
1291 crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1297 /* Check syntax of file */
1299 X509V3_set_ctx_test(&ctx);
1300 X509V3_set_conf_lhash(&ctx, conf);
1301 if (!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL))
1304 "Error Loading CRL extension section %s\n",
1310 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1312 if (!crldays && !crlhours)
1314 crldays=CONF_get_number(conf,section,
1315 ENV_DEFAULT_CRL_DAYS);
1316 crlhours=CONF_get_number(conf,section,
1317 ENV_DEFAULT_CRL_HOURS);
1319 if ((crldays == 0) && (crlhours == 0))
1321 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1325 if (verbose) BIO_printf(bio_err,"making CRL\n");
1326 if ((crl=X509_CRL_new()) == NULL) goto err;
1328 X509_NAME_free(ci->issuer);
1329 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1330 if (ci->issuer == NULL) goto err;
1332 X509_gmtime_adj(ci->lastUpdate,0);
1333 if (ci->nextUpdate == NULL)
1334 ci->nextUpdate=ASN1_UTCTIME_new();
1335 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1337 for (i=0; i<sk_num(db->data); i++)
1339 pp=(char **)sk_value(db->data,i);
1340 if (pp[DB_type][0] == DB_TYPE_REV)
1342 if ((r=X509_REVOKED_new()) == NULL) goto err;
1343 ASN1_STRING_set((ASN1_STRING *)
1345 (unsigned char *)pp[DB_rev_date],
1346 strlen(pp[DB_rev_date]));
1347 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1349 (void)BIO_reset(hex);
1350 if (!BIO_puts(hex,pp[DB_serial]))
1352 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1353 buf[0],BSIZE)) goto err;
1355 X509_CRL_add0_revoked(crl,r);
1358 /* sort the data so it will be written in serial
1360 sk_X509_REVOKED_sort(ci->revoked);
1361 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1363 r=sk_X509_REVOKED_value(ci->revoked,i);
1367 /* we now have a CRL */
1368 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1371 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1373 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1380 if (pkey->type == EVP_PKEY_DSA)
1387 /* Add any extensions asked for */
1392 if (ci->version == NULL)
1393 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1394 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1395 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1396 X509V3_set_conf_lhash(&crlctx, conf);
1398 if (!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1399 crl_ext, crl)) goto err;
1402 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1404 PEM_write_bio_X509_CRL(Sout,crl);
1406 /*****************************************************************/
1411 BIO_printf(bio_err,"no input files\n");
1417 if (BIO_read_filename(in,infile) <= 0)
1420 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1423 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1424 if (revcert == NULL)
1426 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1429 j=do_revoke(revcert,db);
1430 if (j <= 0) goto err;
1433 strncpy(buf[0],dbfile,BSIZE-4);
1434 strcat(buf[0],".new");
1435 if (BIO_write_filename(out,buf[0]) <= 0)
1438 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1441 j=TXT_DB_write(out,db);
1442 if (j <= 0) goto err;
1443 strncpy(buf[1],dbfile,BSIZE-4);
1444 strcat(buf[1],".old");
1445 if (rename(dbfile,buf[1]) < 0)
1447 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1451 if (rename(buf[0],dbfile) < 0)
1453 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1455 rename(buf[1],dbfile);
1458 BIO_printf(bio_err,"Data Base Updated\n");
1461 /*****************************************************************/
1470 sk_X509_pop_free(cert_sk,X509_free);
1472 if (ret) ERR_print_errors(bio_err);
1473 app_RAND_write_file(randfile, bio_err);
1476 EVP_PKEY_free(pkey);
1484 static void lookup_fail(char *name, char *tag)
1486 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1489 static unsigned long index_serial_hash(const char **a)
1494 while (*n == '0') n++;
1495 return(lh_strhash(n));
1498 static int index_serial_cmp(const char **a, const char **b)
1502 for (aa=a[DB_serial]; *aa == '0'; aa++);
1503 for (bb=b[DB_serial]; *bb == '0'; bb++);
1504 return(strcmp(aa,bb));
1507 static unsigned long index_name_hash(const char **a)
1508 { return(lh_strhash(a[DB_name])); }
1510 static int index_name_qual(char **a)
1511 { return(a[0][0] == 'V'); }
1513 static int index_name_cmp(const char **a, const char **b)
1514 { return(strcmp(a[DB_name],
1517 static BIGNUM *load_serial(char *serialfile)
1521 MS_STATIC char buf[1024];
1522 ASN1_INTEGER *ai=NULL;
1524 if ((in=BIO_new(BIO_s_file())) == NULL)
1526 ERR_print_errors(bio_err);
1530 if (BIO_read_filename(in,serialfile) <= 0)
1535 ai=ASN1_INTEGER_new();
1536 if (ai == NULL) goto err;
1537 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1539 BIO_printf(bio_err,"unable to load number from %s\n",
1543 ret=ASN1_INTEGER_to_BN(ai,NULL);
1546 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1550 if (in != NULL) BIO_free(in);
1551 if (ai != NULL) ASN1_INTEGER_free(ai);
1555 static int save_serial(char *serialfile, BIGNUM *serial)
1559 ASN1_INTEGER *ai=NULL;
1561 out=BIO_new(BIO_s_file());
1564 ERR_print_errors(bio_err);
1567 if (BIO_write_filename(out,serialfile) <= 0)
1573 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1575 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1578 i2a_ASN1_INTEGER(out,ai);
1582 if (out != NULL) BIO_free_all(out);
1583 if (ai != NULL) ASN1_INTEGER_free(ai);
1587 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1588 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1589 BIGNUM *serial, char *startdate, char *enddate, int days,
1590 int batch, char *ext_sect, LHASH *lconf, int verbose)
1594 EVP_PKEY *pktmp=NULL;
1597 in=BIO_new(BIO_s_file());
1599 if (BIO_read_filename(in,infile) <= 0)
1604 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1606 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1611 X509_REQ_print(bio_err,req);
1613 BIO_printf(bio_err,"Check that the request matches the signature\n");
1615 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1617 BIO_printf(bio_err,"error unpacking public key\n");
1620 i=X509_REQ_verify(req,pktmp);
1621 EVP_PKEY_free(pktmp);
1625 BIO_printf(bio_err,"Signature verification problems....\n");
1631 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1635 BIO_printf(bio_err,"Signature ok\n");
1637 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1638 days,batch,verbose,req,ext_sect,lconf);
1641 if (req != NULL) X509_REQ_free(req);
1642 if (in != NULL) BIO_free(in);
1646 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1647 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1648 BIGNUM *serial, char *startdate, char *enddate, int days,
1649 int batch, char *ext_sect, LHASH *lconf, int verbose)
1652 X509_REQ *rreq=NULL;
1654 EVP_PKEY *pktmp=NULL;
1657 in=BIO_new(BIO_s_file());
1659 if (BIO_read_filename(in,infile) <= 0)
1664 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1666 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1670 X509_print(bio_err,req);
1672 BIO_printf(bio_err,"Check that the request matches the signature\n");
1674 if ((pktmp=X509_get_pubkey(req)) == NULL)
1676 BIO_printf(bio_err,"error unpacking public key\n");
1679 i=X509_verify(req,pktmp);
1680 EVP_PKEY_free(pktmp);
1684 BIO_printf(bio_err,"Signature verification problems....\n");
1690 BIO_printf(bio_err,"Signature did not match the certificate\n");
1694 BIO_printf(bio_err,"Signature ok\n");
1696 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1699 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1700 batch,verbose,rreq,ext_sect,lconf);
1703 if (rreq != NULL) X509_REQ_free(rreq);
1704 if (req != NULL) X509_free(req);
1705 if (in != NULL) BIO_free(in);
1709 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1710 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1711 char *startdate, char *enddate, int days, int batch, int verbose,
1712 X509_REQ *req, char *ext_sect, LHASH *lconf)
1714 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1715 ASN1_UTCTIME *tm,*tmptm;
1716 ASN1_STRING *str,*str2;
1720 X509_NAME_ENTRY *ne;
1721 X509_NAME_ENTRY *tne,*push;
1723 int ok= -1,i,j,last,nid;
1726 char *row[DB_NUMBER],**rrow,**irow=NULL;
1729 tmptm=ASN1_UTCTIME_new();
1732 BIO_printf(bio_err,"malloc error\n");
1736 for (i=0; i<DB_NUMBER; i++)
1739 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1740 name=X509_REQ_get_subject_name(req);
1741 for (i=0; i<X509_NAME_entry_count(name); i++)
1743 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1744 obj=X509_NAME_ENTRY_get_object(ne);
1745 j=i2a_ASN1_OBJECT(bio_err,obj);
1746 str=X509_NAME_ENTRY_get_data(ne);
1748 for (j=22-j; j>0; j--)
1752 BIO_puts(bio_err,buf);
1756 /* assume all type should be strings */
1757 nid=OBJ_obj2nid(ne->object);
1759 if (str->type == V_ASN1_UNIVERSALSTRING)
1760 ASN1_UNIVERSALSTRING_to_string(str);
1762 if ((str->type == V_ASN1_IA5STRING) &&
1763 (nid != NID_pkcs9_emailAddress))
1764 str->type=V_ASN1_T61STRING;
1766 if ((nid == NID_pkcs9_emailAddress) &&
1767 (str->type == V_ASN1_PRINTABLESTRING))
1768 str->type=V_ASN1_IA5STRING;
1771 if (str->type == V_ASN1_PRINTABLESTRING)
1772 BIO_printf(bio_err,"PRINTABLE:'");
1773 else if (str->type == V_ASN1_T61STRING)
1774 BIO_printf(bio_err,"T61STRING:'");
1775 else if (str->type == V_ASN1_IA5STRING)
1776 BIO_printf(bio_err,"IA5STRING:'");
1777 else if (str->type == V_ASN1_UNIVERSALSTRING)
1778 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1780 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1782 /* check some things */
1783 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1784 (str->type != V_ASN1_IA5STRING))
1786 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1789 j=ASN1_PRINTABLE_type(str->data,str->length);
1790 if ( ((j == V_ASN1_T61STRING) &&
1791 (str->type != V_ASN1_T61STRING)) ||
1792 ((j == V_ASN1_IA5STRING) &&
1793 (str->type == V_ASN1_PRINTABLESTRING)))
1795 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1799 p=(char *)str->data;
1800 for (j=str->length; j>0; j--)
1802 if ((*p >= ' ') && (*p <= '~'))
1803 BIO_printf(bio_err,"%c",*p);
1805 BIO_printf(bio_err,"\\0x%02X",*p);
1806 else if ((unsigned char)*p == 0xf7)
1807 BIO_printf(bio_err,"^?");
1808 else BIO_printf(bio_err,"^%c",*p+'@');
1811 BIO_printf(bio_err,"'\n");
1814 /* Ok, now we check the 'policy' stuff. */
1815 if ((subject=X509_NAME_new()) == NULL)
1817 BIO_printf(bio_err,"Memory allocation failure\n");
1821 /* take a copy of the issuer name before we mess with it. */
1822 CAname=X509_NAME_dup(x509->cert_info->subject);
1823 if (CAname == NULL) goto err;
1826 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1828 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1829 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1831 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1839 /* lookup the object in the supplied name list */
1840 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1843 if (last != -1) break;
1848 tne=X509_NAME_get_entry(name,j);
1852 /* depending on the 'policy', decide what to do. */
1854 if (strcmp(cv->value,"optional") == 0)
1859 else if (strcmp(cv->value,"supplied") == 0)
1863 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1869 else if (strcmp(cv->value,"match") == 0)
1875 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1882 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1883 if ((j < 0) && (last2 == -1))
1885 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1890 push=X509_NAME_get_entry(CAname,j);
1891 str=X509_NAME_ENTRY_get_data(tne);
1892 str2=X509_NAME_ENTRY_get_data(push);
1894 if (ASN1_STRING_cmp(str,str2) != 0)
1899 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));
1905 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1911 if (!X509_NAME_add_entry(subject,push, -1, 0))
1914 X509_NAME_ENTRY_free(push);
1915 BIO_printf(bio_err,"Memory allocation failure\n");
1925 X509_NAME_free(subject);
1926 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1927 if (subject == NULL) goto err;
1931 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1933 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1934 row[DB_serial]=BN_bn2hex(serial);
1935 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1937 BIO_printf(bio_err,"Memory allocation failure\n");
1941 rrow=TXT_DB_get_by_index(db,DB_name,row);
1944 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1949 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1952 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1954 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1961 "The matching entry has the following details\n");
1962 if (rrow[DB_type][0] == 'E')
1964 else if (rrow[DB_type][0] == 'R')
1966 else if (rrow[DB_type][0] == 'V')
1969 p="\ninvalid type, Data base error\n";
1970 BIO_printf(bio_err,"Type :%s\n",p);;
1971 if (rrow[DB_type][0] == 'R')
1973 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1974 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1976 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1977 BIO_printf(bio_err,"Expires on :%s\n",p);
1978 p=rrow[DB_serial]; if (p == NULL) p="undef";
1979 BIO_printf(bio_err,"Serial Number :%s\n",p);
1980 p=rrow[DB_file]; if (p == NULL) p="undef";
1981 BIO_printf(bio_err,"File name :%s\n",p);
1982 p=rrow[DB_name]; if (p == NULL) p="undef";
1983 BIO_printf(bio_err,"Subject Name :%s\n",p);
1984 ok= -1; /* This is now a 'bad' error. */
1988 /* We are now totally happy, lets make and sign the certificate */
1990 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1992 if ((ret=X509_new()) == NULL) goto err;
1996 /* Make it an X509 v3 certificate. */
1997 if (!X509_set_version(x509,2)) goto err;
2000 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2002 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2005 BIO_printf(bio_err,"Certificate is to be certified until ");
2006 if (strcmp(startdate,"today") == 0)
2007 X509_gmtime_adj(X509_get_notBefore(ret),0);
2008 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2010 if (enddate == NULL)
2011 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2012 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2014 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2015 if (days) BIO_printf(bio_err," (%d days)",days);
2016 BIO_printf(bio_err, "\n");
2018 if (!X509_set_subject_name(ret,subject)) goto err;
2020 pktmp=X509_REQ_get_pubkey(req);
2021 i = X509_set_pubkey(ret,pktmp);
2022 EVP_PKEY_free(pktmp);
2025 /* Lets add the extensions, if there are any */
2029 if (ci->version == NULL)
2030 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2032 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2034 /* Free the current entries if any, there should not
2035 * be any I believe */
2036 if (ci->extensions != NULL)
2037 sk_X509_EXTENSION_pop_free(ci->extensions,
2038 X509_EXTENSION_free);
2040 ci->extensions = NULL;
2042 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2043 X509V3_set_conf_lhash(&ctx, lconf);
2045 if (!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
2052 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2053 (void)BIO_flush(bio_err);
2055 fgets(buf,sizeof(buf)-1,stdin);
2056 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2058 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2066 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2067 pktmp=X509_get_pubkey(ret);
2068 if (EVP_PKEY_missing_parameters(pktmp) &&
2069 !EVP_PKEY_missing_parameters(pkey))
2070 EVP_PKEY_copy_parameters(pktmp,pkey);
2071 EVP_PKEY_free(pktmp);
2074 if (!X509_sign(ret,pkey,dgst))
2077 /* We now just add it to the database */
2078 row[DB_type]=(char *)OPENSSL_malloc(2);
2080 tm=X509_get_notAfter(ret);
2081 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2082 memcpy(row[DB_exp_date],tm->data,tm->length);
2083 row[DB_exp_date][tm->length]='\0';
2085 row[DB_rev_date]=NULL;
2087 /* row[DB_serial] done already */
2088 row[DB_file]=(char *)OPENSSL_malloc(8);
2089 /* row[DB_name] done already */
2091 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2092 (row[DB_file] == NULL))
2094 BIO_printf(bio_err,"Memory allocation failure\n");
2097 strcpy(row[DB_file],"unknown");
2098 row[DB_type][0]='V';
2099 row[DB_type][1]='\0';
2101 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2103 BIO_printf(bio_err,"Memory allocation failure\n");
2107 for (i=0; i<DB_NUMBER; i++)
2112 irow[DB_NUMBER]=NULL;
2114 if (!TXT_DB_insert(db,irow))
2116 BIO_printf(bio_err,"failed to update database\n");
2117 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2122 for (i=0; i<DB_NUMBER; i++)
2123 if (row[i] != NULL) OPENSSL_free(row[i]);
2126 X509_NAME_free(CAname);
2127 if (subject != NULL)
2128 X509_NAME_free(subject);
2130 ASN1_UTCTIME_free(tmptm);
2133 if (ret != NULL) X509_free(ret);
2141 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2146 (void)i2d_X509_bio(bp,x);
2150 /* ??? Not needed since X509_print prints all this stuff anyway */
2151 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2152 BIO_printf(bp,"issuer :%s\n",f);
2154 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2155 BIO_printf(bp,"subject:%s\n",f);
2157 BIO_puts(bp,"serial :");
2158 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2159 BIO_puts(bp,"\n\n");
2161 if (!notext)X509_print(bp,x);
2162 PEM_write_bio_X509(bp,x);
2165 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2166 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2167 BIGNUM *serial, char *startdate, char *enddate, int days,
2168 char *ext_sect, LHASH *lconf, int verbose)
2170 STACK_OF(CONF_VALUE) *sk=NULL;
2173 CONF_VALUE *cv=NULL;
2174 NETSCAPE_SPKI *spki = NULL;
2177 EVP_PKEY *pktmp=NULL;
2179 X509_NAME_ENTRY *ne=NULL;
2185 * Load input file into a hash table. (This is just an easy
2186 * way to read and parse the file, then put it into a convenient
2189 parms=CONF_load(NULL,infile,&errline);
2192 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2193 ERR_print_errors(bio_err);
2197 sk=CONF_get_section(parms, "default");
2198 if (sk_CONF_VALUE_num(sk) == 0)
2200 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2206 * Now create a dummy X509 request structure. We don't actually
2207 * have an X509 request, but we have many of the components
2208 * (a public key, various DN components). The idea is that we
2209 * put these components into the right X509 request structure
2210 * and we can use the same code as if you had a real X509 request.
2215 ERR_print_errors(bio_err);
2220 * Build up the subject name set.
2227 if (sk_CONF_VALUE_num(sk) <= i) break;
2229 cv=sk_CONF_VALUE_value(sk,i);
2231 /* Skip past any leading X. X: X, etc to allow for
2232 * multiple instances
2234 for (buf = cv->name; *buf ; buf++)
2235 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2238 if (*buf) type = buf;
2243 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2245 if (strcmp(type, "SPKAC") == 0)
2247 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2250 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2251 ERR_print_errors(bio_err);
2258 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2259 if (fix_data(nid, &j) == 0)
2262 "invalid characters in string %s\n",buf);
2266 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2267 (unsigned char *)buf,
2268 strlen(buf))) == NULL)
2271 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2275 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2281 * Now extract the key from the SPKI structure.
2284 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2286 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2288 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2292 j = NETSCAPE_SPKI_verify(spki, pktmp);
2295 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2298 BIO_printf(bio_err,"Signature ok\n");
2300 X509_REQ_set_pubkey(req,pktmp);
2301 EVP_PKEY_free(pktmp);
2302 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2303 days,1,verbose,req,ext_sect,lconf);
2305 if (req != NULL) X509_REQ_free(req);
2306 if (parms != NULL) CONF_free(parms);
2307 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2308 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2313 static int fix_data(int nid, int *type)
2315 if (nid == NID_pkcs9_emailAddress)
2316 *type=V_ASN1_IA5STRING;
2317 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2318 *type=V_ASN1_T61STRING;
2319 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2320 *type=V_ASN1_T61STRING;
2321 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2323 if (nid == NID_pkcs9_unstructuredName)
2324 *type=V_ASN1_IA5STRING;
2328 static int check_time_format(char *str)
2332 tm.data=(unsigned char *)str;
2333 tm.length=strlen(str);
2334 tm.type=V_ASN1_UTCTIME;
2335 return(ASN1_UTCTIME_check(&tm));
2338 static int do_revoke(X509 *x509, TXT_DB *db)
2340 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2341 char *row[DB_NUMBER],**rrow,**irow;
2345 for (i=0; i<DB_NUMBER; i++)
2347 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2348 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2349 row[DB_serial]=BN_bn2hex(bn);
2351 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2353 BIO_printf(bio_err,"Memory allocation failure\n");
2356 /* We have to lookup by serial number because name lookup
2357 * skips revoked certs
2359 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2362 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2364 /* We now just add it to the database */
2365 row[DB_type]=(char *)OPENSSL_malloc(2);
2367 tm=X509_get_notAfter(x509);
2368 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2369 memcpy(row[DB_exp_date],tm->data,tm->length);
2370 row[DB_exp_date][tm->length]='\0';
2372 row[DB_rev_date]=NULL;
2374 /* row[DB_serial] done already */
2375 row[DB_file]=(char *)OPENSSL_malloc(8);
2377 /* row[DB_name] done already */
2379 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2380 (row[DB_file] == NULL))
2382 BIO_printf(bio_err,"Memory allocation failure\n");
2385 strcpy(row[DB_file],"unknown");
2386 row[DB_type][0]='V';
2387 row[DB_type][1]='\0';
2389 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2391 BIO_printf(bio_err,"Memory allocation failure\n");
2395 for (i=0; i<DB_NUMBER; i++)
2400 irow[DB_NUMBER]=NULL;
2402 if (!TXT_DB_insert(db,irow))
2404 BIO_printf(bio_err,"failed to update database\n");
2405 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2409 /* Revoke Certificate */
2410 ok = do_revoke(x509,db);
2415 else if (index_name_cmp((const char **)row,(const char **)rrow))
2417 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2421 else if (rrow[DB_type][0]=='R')
2423 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2429 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2430 revtm = ASN1_UTCTIME_new();
2431 revtm=X509_gmtime_adj(revtm,0);
2432 rrow[DB_type][0]='R';
2433 rrow[DB_type][1]='\0';
2434 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2435 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2436 rrow[DB_rev_date][revtm->length]='\0';
2437 ASN1_UTCTIME_free(revtm);
2441 for (i=0; i<DB_NUMBER; i++)
2444 OPENSSL_free(row[i]);
2449 static int get_certificate_status(const char *serial, TXT_DB *db)
2451 unsigned char *row[DB_NUMBER],**rrow;
2454 /* Free Resources */
2455 for (i=0; i<DB_NUMBER; i++)
2458 /* Malloc needed char spaces */
2459 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2460 if (row[DB_serial] == NULL)
2462 BIO_printf(bio_err,"Malloc failure\n");
2466 if (strlen(serial) % 2)
2468 /* Set the first char to 0 */;
2469 row[DB_serial][0]='0';
2471 /* Copy String from serial to row[DB_serial] */
2472 memcpy(row[DB_serial]+1, serial, strlen(serial));
2473 row[DB_serial][strlen(serial)+1]='\0';
2477 /* Copy String from serial to row[DB_serial] */
2478 memcpy(row[DB_serial], serial, strlen(serial));
2479 row[DB_serial][strlen(serial)]='\0';
2482 /* Make it Upper Case */
2483 for (i=0; row[DB_serial][i] != '\0'; i++)
2484 row[DB_serial][i] = toupper(row[DB_serial][i]);
2488 /* Search for the certificate */
2489 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2492 BIO_printf(bio_err,"Serial %s not present in db.\n",
2497 else if (rrow[DB_type][0]=='V')
2499 BIO_printf(bio_err,"%s=Valid (%c)\n",
2500 row[DB_serial], rrow[DB_type][0]);
2503 else if (rrow[DB_type][0]=='R')
2505 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2506 row[DB_serial], rrow[DB_type][0]);
2509 else if (rrow[DB_type][0]=='E')
2511 BIO_printf(bio_err,"%s=Expired (%c)\n",
2512 row[DB_serial], rrow[DB_type][0]);
2515 else if (rrow[DB_type][0]=='S')
2517 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2518 row[DB_serial], rrow[DB_type][0]);
2523 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2524 row[DB_serial], rrow[DB_type][0]);
2528 for (i=0; i<DB_NUMBER; i++)
2531 OPENSSL_free(row[i]);
2536 static int do_updatedb (TXT_DB *db)
2538 ASN1_UTCTIME *a_tm = NULL;
2540 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2541 char **rrow, *a_tm_s;
2543 a_tm = ASN1_UTCTIME_new();
2545 /* get actual time and make a string */
2546 a_tm = X509_gmtime_adj(a_tm, 0);
2547 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2554 memcpy(a_tm_s, a_tm->data, a_tm->length);
2555 a_tm_s[a_tm->length] = '\0';
2557 if (strncmp(a_tm_s, "49", 2) <= 0)
2562 for (i = 0; i < sk_num(db->data); i++)
2564 rrow = (char **) sk_value(db->data, i);
2566 if (rrow[DB_type][0] == 'V')
2568 /* ignore entries that are not valid */
2569 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2574 if (db_y2k == a_y2k)
2576 /* all on the same y2k side */
2577 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2579 rrow[DB_type][0] = 'E';
2580 rrow[DB_type][1] = '\0';
2583 BIO_printf(bio_err, "%s=Expired\n",
2587 else if (db_y2k < a_y2k)
2589 rrow[DB_type][0] = 'E';
2590 rrow[DB_type][1] = '\0';
2593 BIO_printf(bio_err, "%s=Expired\n",
2602 ASN1_UTCTIME_free(a_tm);
2603 OPENSSL_free(a_tm_s);