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> */
64 #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/pem.h>
77 #include <openssl/engine.h>
87 # include <sys/file.h>
101 #define BASE_SECTION "ca"
102 #define CONFIG_FILE "openssl.cnf"
104 #define ENV_DEFAULT_CA "default_ca"
106 #define ENV_DIR "dir"
107 #define ENV_CERTS "certs"
108 #define ENV_CRL_DIR "crl_dir"
109 #define ENV_CA_DB "CA_DB"
110 #define ENV_NEW_CERTS_DIR "new_certs_dir"
111 #define ENV_CERTIFICATE "certificate"
112 #define ENV_SERIAL "serial"
113 #define ENV_CRL "crl"
114 #define ENV_PRIVATE_KEY "private_key"
115 #define ENV_RANDFILE "RANDFILE"
116 #define ENV_DEFAULT_DAYS "default_days"
117 #define ENV_DEFAULT_STARTDATE "default_startdate"
118 #define ENV_DEFAULT_ENDDATE "default_enddate"
119 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
120 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
121 #define ENV_DEFAULT_MD "default_md"
122 #define ENV_PRESERVE "preserve"
123 #define ENV_POLICY "policy"
124 #define ENV_EXTENSIONS "x509_extensions"
125 #define ENV_CRLEXT "crl_extensions"
126 #define ENV_MSIE_HACK "msie_hack"
128 #define ENV_DATABASE "database"
131 #define DB_exp_date 1
132 #define DB_rev_date 2
133 #define DB_serial 3 /* index - unique */
135 #define DB_name 5 /* index - unique for active */
138 #define DB_TYPE_REV 'R'
139 #define DB_TYPE_EXP 'E'
140 #define DB_TYPE_VAL 'V'
142 static char *ca_usage[]={
145 " -verbose - Talk alot while doing things\n",
146 " -config file - A config file\n",
147 " -name arg - The particular CA definition to use\n",
148 " -gencrl - Generate a new CRL\n",
149 " -crldays days - Days is when the next CRL is due\n",
150 " -crlhours hours - Hours is when the next CRL is due\n",
151 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
152 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
153 " -days arg - number of days to certify the certificate for\n",
154 " -md arg - md to use, one of md2, md5, sha or sha1\n",
155 " -policy arg - The CA 'policy' to support\n",
156 " -keyfile arg - private key file\n",
157 " -keyform arg - private key file format (PEM or ENGINE)\n",
158 " -key arg - key to decode the private key if it is encrypted\n",
159 " -cert file - The CA certificate\n",
160 " -in file - The input PEM encoded certificate request(s)\n",
161 " -out file - Where to put the output file(s)\n",
162 " -outdir dir - Where to put output certificates\n",
163 " -infiles .... - The last argument, requests to process\n",
164 " -spkac file - File contains DN and signed public key and challenge\n",
165 " -ss_cert file - File contains a self signed cert to sign\n",
166 " -preserveDN - Don't re-order the DN\n",
167 " -batch - Don't ask questions\n",
168 " -msie_hack - msie modifications to handle all those universal strings\n",
169 " -revoke file - Revoke a certificate (given in file)\n",
170 " -extensions .. - Extension section (override value in config file)\n",
171 " -crlexts .. - CRL extension section (override value in config file)\n",
172 " -engine e - use engine e, possibly a hardware device.\n",
177 extern int EF_PROTECT_FREE;
178 extern int EF_PROTECT_BELOW;
179 extern int EF_ALIGNMENT;
182 static void lookup_fail(char *name,char *tag);
183 static unsigned long index_serial_hash(const char **a);
184 static int index_serial_cmp(const char **a, const char **b);
185 static unsigned long index_name_hash(const char **a);
186 static int index_name_qual(char **a);
187 static int index_name_cmp(const char **a,const char **b);
188 static BIGNUM *load_serial(char *serialfile);
189 static int save_serial(char *serialfile, BIGNUM *serial);
190 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
191 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
192 BIGNUM *serial, char *startdate,char *enddate, int days,
193 int batch, char *ext_sect, LHASH *conf,int verbose);
194 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
195 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
196 TXT_DB *db, BIGNUM *serial,char *startdate,
197 char *enddate, int days, int batch, char *ext_sect,
198 LHASH *conf,int verbose);
199 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
200 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
201 TXT_DB *db, BIGNUM *serial,char *startdate,
202 char *enddate, int days, char *ext_sect,LHASH *conf,
204 static int fix_data(int nid, int *type);
205 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
206 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
207 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
208 char *startdate, char *enddate, int days, int batch, int verbose,
209 X509_REQ *req, char *ext_sect, LHASH *conf);
210 static int do_revoke(X509 *x509, TXT_DB *db);
211 static int check_time_format(char *str);
212 static LHASH *conf=NULL;
213 static char *section=NULL;
215 static int preserve=0;
216 static int msie_hack=0;
218 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
219 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
220 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
221 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
224 int MAIN(int, char **);
226 int MAIN(int argc, char **argv)
229 char *key=NULL,*passargin=NULL;
241 char *configfile=NULL;
246 int keyform=FORMAT_PEM;
248 char *spkac_file=NULL;
249 char *ss_cert_file=NULL;
254 char *serialfile=NULL;
255 char *extensions=NULL;
258 char *startdate=NULL;
265 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
269 X509_CRL_INFO *ci=NULL;
270 X509_REVOKED *r=NULL;
274 const EVP_MD *dgst=NULL;
275 STACK_OF(CONF_VALUE) *attribs=NULL;
276 STACK_OF(X509) *cert_sk=NULL;
280 MS_STATIC char buf[3][BSIZE];
299 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
300 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
306 if (strcmp(*argv,"-verbose") == 0)
308 else if (strcmp(*argv,"-config") == 0)
310 if (--argc < 1) goto bad;
311 configfile= *(++argv);
313 else if (strcmp(*argv,"-name") == 0)
315 if (--argc < 1) goto bad;
318 else if (strcmp(*argv,"-startdate") == 0)
320 if (--argc < 1) goto bad;
321 startdate= *(++argv);
323 else if (strcmp(*argv,"-enddate") == 0)
325 if (--argc < 1) goto bad;
328 else if (strcmp(*argv,"-days") == 0)
330 if (--argc < 1) goto bad;
331 days=atoi(*(++argv));
333 else if (strcmp(*argv,"-md") == 0)
335 if (--argc < 1) goto bad;
338 else if (strcmp(*argv,"-policy") == 0)
340 if (--argc < 1) goto bad;
343 else if (strcmp(*argv,"-keyfile") == 0)
345 if (--argc < 1) goto bad;
348 else if (strcmp(*argv,"-keyform") == 0)
350 if (--argc < 1) goto bad;
351 keyform=str2fmt(*(++argv));
353 else if (strcmp(*argv,"-passin") == 0)
355 if (--argc < 1) goto bad;
356 passargin= *(++argv);
358 else if (strcmp(*argv,"-key") == 0)
360 if (--argc < 1) goto bad;
363 else if (strcmp(*argv,"-cert") == 0)
365 if (--argc < 1) goto bad;
368 else if (strcmp(*argv,"-in") == 0)
370 if (--argc < 1) goto bad;
374 else if (strcmp(*argv,"-out") == 0)
376 if (--argc < 1) goto bad;
379 else if (strcmp(*argv,"-outdir") == 0)
381 if (--argc < 1) goto bad;
384 else if (strcmp(*argv,"-notext") == 0)
386 else if (strcmp(*argv,"-batch") == 0)
388 else if (strcmp(*argv,"-preserveDN") == 0)
390 else if (strcmp(*argv,"-gencrl") == 0)
392 else if (strcmp(*argv,"-msie_hack") == 0)
394 else if (strcmp(*argv,"-crldays") == 0)
396 if (--argc < 1) goto bad;
397 crldays= atol(*(++argv));
399 else if (strcmp(*argv,"-crlhours") == 0)
401 if (--argc < 1) goto bad;
402 crlhours= atol(*(++argv));
404 else if (strcmp(*argv,"-infiles") == 0)
411 else if (strcmp(*argv, "-ss_cert") == 0)
413 if (--argc < 1) goto bad;
414 ss_cert_file = *(++argv);
417 else if (strcmp(*argv, "-spkac") == 0)
419 if (--argc < 1) goto bad;
420 spkac_file = *(++argv);
423 else if (strcmp(*argv,"-revoke") == 0)
425 if (--argc < 1) goto bad;
429 else if (strcmp(*argv,"-extensions") == 0)
431 if (--argc < 1) goto bad;
432 extensions= *(++argv);
434 else if (strcmp(*argv,"-crlexts") == 0)
436 if (--argc < 1) goto bad;
439 else if (strcmp(*argv,"-engine") == 0)
441 if (--argc < 1) goto bad;
447 BIO_printf(bio_err,"unknown option %s\n",*argv);
457 for (pp=ca_usage; (*pp != NULL); pp++)
458 BIO_printf(bio_err,*pp);
462 ERR_load_crypto_strings();
466 if((e = ENGINE_by_id(engine)) == NULL)
468 BIO_printf(bio_err,"invalid engine \"%s\"\n",
472 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
474 BIO_printf(bio_err,"can't use that engine\n");
477 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
478 /* Free our "structural" reference. */
482 /*****************************************************************/
483 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
484 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
485 if (configfile == NULL)
487 /* We will just use 'buf[0]' as a temporary buffer. */
489 strncpy(buf[0],X509_get_default_cert_area(),
490 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
492 strncpy(buf[0],X509_get_default_cert_area(),
493 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
496 strcat(buf[0],CONFIG_FILE);
500 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
501 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
504 BIO_printf(bio_err,"error loading the config file '%s'\n",
507 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
508 ,errorline,configfile);
512 /* Lets get the config section we are using */
515 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
518 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
525 p=CONF_get_string(conf,NULL,"oid_file");
530 oid_bio=BIO_new_file(p,"r");
534 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
535 ERR_print_errors(bio_err);
541 OBJ_create_objects(oid_bio);
545 if(!add_oid_section(bio_err,conf))
547 ERR_print_errors(bio_err);
552 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
553 app_RAND_load_file(randfile, bio_err, 0);
555 in=BIO_new(BIO_s_file());
556 out=BIO_new(BIO_s_file());
557 Sout=BIO_new(BIO_s_file());
558 Cout=BIO_new(BIO_s_file());
559 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
561 ERR_print_errors(bio_err);
565 /*****************************************************************/
566 /* we definitely need an public key, so lets get it */
568 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
569 section,ENV_PRIVATE_KEY)) == NULL))
571 lookup_fail(section,ENV_PRIVATE_KEY);
574 if(!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
576 BIO_printf(bio_err,"Error getting password\n");
579 if (keyform == FORMAT_ENGINE)
583 BIO_printf(bio_err,"no engine specified\n");
586 pkey = ENGINE_load_private_key(e, keyfile, key);
588 else if (keyform == FORMAT_PEM)
590 if (BIO_read_filename(in,keyfile) <= 0)
593 BIO_printf(bio_err,"trying to load CA private key\n");
596 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
600 BIO_printf(bio_err,"bad input format specified for key file\n");
603 if(key) memset(key,0,strlen(key));
606 BIO_printf(bio_err,"unable to load CA private key\n");
610 /*****************************************************************/
611 /* we need a certificate */
612 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
613 section,ENV_CERTIFICATE)) == NULL))
615 lookup_fail(section,ENV_CERTIFICATE);
618 if (BIO_read_filename(in,certfile) <= 0)
621 BIO_printf(bio_err,"trying to load CA certificate\n");
624 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
627 BIO_printf(bio_err,"unable to load CA certificate\n");
631 if (!X509_check_private_key(x509,pkey))
633 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
637 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
638 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
640 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
641 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
644 /*****************************************************************/
645 /* lookup where to write new certificates */
646 if ((outdir == NULL) && (req))
650 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
653 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
656 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
657 filename. In any case, stat(), below, will catch the problem
658 if outdir is not a directory spec, and the fopen() or open()
659 will catch an error if there is no write access.
661 Presumably, this problem could also be solved by using the DEC
662 C routines to convert the directory syntax to Unixly, and give
663 that to access(). However, time's too short to do that just
666 if (access(outdir,R_OK|W_OK|X_OK) != 0)
668 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
673 if (stat(outdir,&sb) != 0)
675 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
680 if (!(sb.st_mode & S_IFDIR))
682 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
690 /*****************************************************************/
691 /* we need to load the database file */
692 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
694 lookup_fail(section,ENV_DATABASE);
697 if (BIO_read_filename(in,dbfile) <= 0)
700 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
703 db=TXT_DB_read(in,DB_NUMBER);
704 if (db == NULL) goto err;
706 /* Lets check some fields */
707 for (i=0; i<sk_num(db->data); i++)
709 pp=(char **)sk_value(db->data,i);
710 if ((pp[DB_type][0] != DB_TYPE_REV) &&
711 (pp[DB_rev_date][0] != '\0'))
713 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
716 if ((pp[DB_type][0] == DB_TYPE_REV) &&
717 !check_time_format(pp[DB_rev_date]))
719 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
723 if (!check_time_format(pp[DB_exp_date]))
725 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
730 if ((j&1) || (j < 2))
732 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
737 if (!( ((*p >= '0') && (*p <= '9')) ||
738 ((*p >= 'A') && (*p <= 'F')) ||
739 ((*p >= 'a') && (*p <= 'f'))) )
741 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);
749 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
752 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
753 out = BIO_push(tmpbio, out);
756 TXT_DB_write(out,db);
757 BIO_printf(bio_err,"%d entries loaded from the database\n",
759 BIO_printf(bio_err,"generating index\n");
762 if (!TXT_DB_create_index(db, DB_serial, NULL,
763 LHASH_HASH_FN(index_serial_hash),
764 LHASH_COMP_FN(index_serial_cmp)))
766 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
770 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
771 LHASH_HASH_FN(index_name_hash),
772 LHASH_COMP_FN(index_name_cmp)))
774 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
775 db->error,db->arg1,db->arg2);
779 /*****************************************************************/
785 if (BIO_write_filename(Sout,outfile) <= 0)
793 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
796 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
797 Sout = BIO_push(tmpbio, Sout);
805 if ((md == NULL) && ((md=CONF_get_string(conf,
806 section,ENV_DEFAULT_MD)) == NULL))
808 lookup_fail(section,ENV_DEFAULT_MD);
811 if ((dgst=EVP_get_digestbyname(md)) == NULL)
813 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
817 BIO_printf(bio_err,"message digest is %s\n",
818 OBJ_nid2ln(dgst->type));
819 if ((policy == NULL) && ((policy=CONF_get_string(conf,
820 section,ENV_POLICY)) == NULL))
822 lookup_fail(section,ENV_POLICY);
826 BIO_printf(bio_err,"policy is %s\n",policy);
828 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
831 lookup_fail(section,ENV_SERIAL);
835 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
837 /* Check syntax of file */
839 X509V3_set_ctx_test(&ctx);
840 X509V3_set_conf_lhash(&ctx, conf);
841 if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
843 "Error Loading extension section %s\n",
850 if (startdate == NULL)
852 startdate=CONF_get_string(conf,section,
853 ENV_DEFAULT_STARTDATE);
855 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
857 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
860 if (startdate == NULL) startdate="today";
864 enddate=CONF_get_string(conf,section,
865 ENV_DEFAULT_ENDDATE);
867 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
869 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
875 days=(int)CONF_get_number(conf,section,
878 if (!enddate && (days == 0))
880 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
884 if ((serial=load_serial(serialfile)) == NULL)
886 BIO_printf(bio_err,"error while loading serial number\n");
891 if ((f=BN_bn2hex(serial)) == NULL) goto err;
892 BIO_printf(bio_err,"next serial number is %s\n",f);
896 if ((attribs=CONF_get_section(conf,policy)) == NULL)
898 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
902 if ((cert_sk=sk_X509_new_null()) == NULL)
904 BIO_printf(bio_err,"Memory allocation failure\n");
907 if (spkac_file != NULL)
910 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
911 serial,startdate,enddate, days,extensions,conf,
917 BIO_printf(bio_err,"\n");
918 if (!BN_add_word(serial,1)) goto err;
919 if (!sk_X509_push(cert_sk,x))
921 BIO_printf(bio_err,"Memory allocation failure\n");
931 if (ss_cert_file != NULL)
934 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
935 db,serial,startdate,enddate,days,batch,
936 extensions,conf,verbose);
941 BIO_printf(bio_err,"\n");
942 if (!BN_add_word(serial,1)) goto err;
943 if (!sk_X509_push(cert_sk,x))
945 BIO_printf(bio_err,"Memory allocation failure\n");
953 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
954 serial,startdate,enddate,days,batch,
955 extensions,conf,verbose);
960 BIO_printf(bio_err,"\n");
961 if (!BN_add_word(serial,1)) goto err;
962 if (!sk_X509_push(cert_sk,x))
964 BIO_printf(bio_err,"Memory allocation failure\n");
969 for (i=0; i<argc; i++)
972 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
973 serial,startdate,enddate,days,batch,
974 extensions,conf,verbose);
979 BIO_printf(bio_err,"\n");
980 if (!BN_add_word(serial,1)) goto err;
981 if (!sk_X509_push(cert_sk,x))
983 BIO_printf(bio_err,"Memory allocation failure\n");
988 /* we have a stack of newly certified certificates
989 * and a data base and serial number that need
992 if (sk_X509_num(cert_sk) > 0)
996 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
997 (void)BIO_flush(bio_err);
999 fgets(buf[0],10,stdin);
1000 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1002 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1008 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1010 strncpy(buf[0],serialfile,BSIZE-4);
1013 strcat(buf[0],"-new");
1015 strcat(buf[0],".new");
1018 if (!save_serial(buf[0],serial)) goto err;
1020 strncpy(buf[1],dbfile,BSIZE-4);
1023 strcat(buf[1],"-new");
1025 strcat(buf[1],".new");
1028 if (BIO_write_filename(out,buf[1]) <= 0)
1031 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1034 l=TXT_DB_write(out,db);
1035 if (l <= 0) goto err;
1039 BIO_printf(bio_err,"writing new certificates\n");
1040 for (i=0; i<sk_X509_num(cert_sk); i++)
1045 x=sk_X509_value(cert_sk,i);
1047 j=x->cert_info->serialNumber->length;
1048 p=(char *)x->cert_info->serialNumber->data;
1050 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1056 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1061 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1070 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1073 BIO_printf(bio_err,"writing %s\n",buf[2]);
1075 if (BIO_write_filename(Cout,buf[2]) <= 0)
1080 write_new_certificate(Cout,x, 0, notext);
1081 write_new_certificate(Sout,x, output_der, notext);
1084 if (sk_X509_num(cert_sk))
1086 /* Rename the database and the serial file */
1087 strncpy(buf[2],serialfile,BSIZE-4);
1090 strcat(buf[2],"-old");
1092 strcat(buf[2],".old");
1099 if (rename(serialfile,buf[2]) < 0)
1101 BIO_printf(bio_err,"unable to rename %s to %s\n",
1106 if (rename(buf[0],serialfile) < 0)
1108 BIO_printf(bio_err,"unable to rename %s to %s\n",
1111 rename(buf[2],serialfile);
1115 strncpy(buf[2],dbfile,BSIZE-4);
1118 strcat(buf[2],"-old");
1120 strcat(buf[2],".old");
1123 if (rename(dbfile,buf[2]) < 0)
1125 BIO_printf(bio_err,"unable to rename %s to %s\n",
1130 if (rename(buf[1],dbfile) < 0)
1132 BIO_printf(bio_err,"unable to rename %s to %s\n",
1135 rename(buf[2],dbfile);
1138 BIO_printf(bio_err,"Data Base Updated\n");
1142 /*****************************************************************/
1145 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1147 /* Check syntax of file */
1149 X509V3_set_ctx_test(&ctx);
1150 X509V3_set_conf_lhash(&ctx, conf);
1151 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1153 "Error Loading CRL extension section %s\n",
1159 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1161 if (!crldays && !crlhours)
1163 crldays=CONF_get_number(conf,section,
1164 ENV_DEFAULT_CRL_DAYS);
1165 crlhours=CONF_get_number(conf,section,
1166 ENV_DEFAULT_CRL_HOURS);
1168 if ((crldays == 0) && (crlhours == 0))
1170 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1174 if (verbose) BIO_printf(bio_err,"making CRL\n");
1175 if ((crl=X509_CRL_new()) == NULL) goto err;
1177 X509_NAME_free(ci->issuer);
1178 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1179 if (ci->issuer == NULL) goto err;
1181 X509_gmtime_adj(ci->lastUpdate,0);
1182 if (ci->nextUpdate == NULL)
1183 ci->nextUpdate=ASN1_UTCTIME_new();
1184 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1186 for (i=0; i<sk_num(db->data); i++)
1188 pp=(char **)sk_value(db->data,i);
1189 if (pp[DB_type][0] == DB_TYPE_REV)
1191 if ((r=X509_REVOKED_new()) == NULL) goto err;
1192 ASN1_STRING_set((ASN1_STRING *)
1194 (unsigned char *)pp[DB_rev_date],
1195 strlen(pp[DB_rev_date]));
1196 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1198 (void)BIO_reset(hex);
1199 if (!BIO_puts(hex,pp[DB_serial]))
1201 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1202 buf[0],BSIZE)) goto err;
1204 X509_CRL_add0_revoked(crl,r);
1207 /* sort the data so it will be written in serial
1209 sk_X509_REVOKED_sort(ci->revoked);
1210 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1212 r=sk_X509_REVOKED_value(ci->revoked,i);
1216 /* we now have a CRL */
1217 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1220 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1222 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1229 if (pkey->type == EVP_PKEY_DSA)
1236 /* Add any extensions asked for */
1240 if (ci->version == NULL)
1241 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1242 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1243 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1244 X509V3_set_conf_lhash(&crlctx, conf);
1246 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1247 crl_ext, crl)) goto err;
1250 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1252 PEM_write_bio_X509_CRL(Sout,crl);
1254 /*****************************************************************/
1259 BIO_printf(bio_err,"no input files\n");
1265 if (BIO_read_filename(in,infile) <= 0)
1268 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1271 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1272 if (revcert == NULL)
1274 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1277 j=do_revoke(revcert,db);
1278 if (j <= 0) goto err;
1281 strncpy(buf[0],dbfile,BSIZE-4);
1282 strcat(buf[0],".new");
1283 if (BIO_write_filename(out,buf[0]) <= 0)
1286 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1289 j=TXT_DB_write(out,db);
1290 if (j <= 0) goto err;
1291 strncpy(buf[1],dbfile,BSIZE-4);
1292 strcat(buf[1],".old");
1293 if (rename(dbfile,buf[1]) < 0)
1295 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1299 if (rename(buf[0],dbfile) < 0)
1301 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1303 rename(buf[1],dbfile);
1306 BIO_printf(bio_err,"Data Base Updated\n");
1309 /*****************************************************************/
1318 sk_X509_pop_free(cert_sk,X509_free);
1320 if (ret) ERR_print_errors(bio_err);
1321 app_RAND_write_file(randfile, bio_err);
1324 EVP_PKEY_free(pkey);
1332 static void lookup_fail(char *name, char *tag)
1334 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1337 static unsigned long index_serial_hash(const char **a)
1342 while (*n == '0') n++;
1343 return(lh_strhash(n));
1346 static int index_serial_cmp(const char **a, const char **b)
1350 for (aa=a[DB_serial]; *aa == '0'; aa++);
1351 for (bb=b[DB_serial]; *bb == '0'; bb++);
1352 return(strcmp(aa,bb));
1355 static unsigned long index_name_hash(const char **a)
1356 { return(lh_strhash(a[DB_name])); }
1358 static int index_name_qual(char **a)
1359 { return(a[0][0] == 'V'); }
1361 static int index_name_cmp(const char **a, const char **b)
1362 { return(strcmp(a[DB_name],
1365 static BIGNUM *load_serial(char *serialfile)
1369 MS_STATIC char buf[1024];
1370 ASN1_INTEGER *ai=NULL;
1372 if ((in=BIO_new(BIO_s_file())) == NULL)
1374 ERR_print_errors(bio_err);
1378 if (BIO_read_filename(in,serialfile) <= 0)
1383 ai=ASN1_INTEGER_new();
1384 if (ai == NULL) goto err;
1385 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1387 BIO_printf(bio_err,"unable to load number from %s\n",
1391 ret=ASN1_INTEGER_to_BN(ai,NULL);
1394 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1398 if (in != NULL) BIO_free(in);
1399 if (ai != NULL) ASN1_INTEGER_free(ai);
1403 static int save_serial(char *serialfile, BIGNUM *serial)
1407 ASN1_INTEGER *ai=NULL;
1409 out=BIO_new(BIO_s_file());
1412 ERR_print_errors(bio_err);
1415 if (BIO_write_filename(out,serialfile) <= 0)
1421 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1423 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1426 i2a_ASN1_INTEGER(out,ai);
1430 if (out != NULL) BIO_free_all(out);
1431 if (ai != NULL) ASN1_INTEGER_free(ai);
1435 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1436 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1437 BIGNUM *serial, char *startdate, char *enddate, int days,
1438 int batch, char *ext_sect, LHASH *lconf, int verbose)
1442 EVP_PKEY *pktmp=NULL;
1445 in=BIO_new(BIO_s_file());
1447 if (BIO_read_filename(in,infile) <= 0)
1452 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1454 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1459 X509_REQ_print(bio_err,req);
1461 BIO_printf(bio_err,"Check that the request matches the signature\n");
1463 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1465 BIO_printf(bio_err,"error unpacking public key\n");
1468 i=X509_REQ_verify(req,pktmp);
1469 EVP_PKEY_free(pktmp);
1473 BIO_printf(bio_err,"Signature verification problems....\n");
1479 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1483 BIO_printf(bio_err,"Signature ok\n");
1485 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1486 days,batch,verbose,req,ext_sect,lconf);
1489 if (req != NULL) X509_REQ_free(req);
1490 if (in != NULL) BIO_free(in);
1494 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1495 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1496 BIGNUM *serial, char *startdate, char *enddate, int days,
1497 int batch, char *ext_sect, LHASH *lconf, int verbose)
1500 X509_REQ *rreq=NULL;
1502 EVP_PKEY *pktmp=NULL;
1505 in=BIO_new(BIO_s_file());
1507 if (BIO_read_filename(in,infile) <= 0)
1512 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1514 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1518 X509_print(bio_err,req);
1520 BIO_printf(bio_err,"Check that the request matches the signature\n");
1522 if ((pktmp=X509_get_pubkey(req)) == NULL)
1524 BIO_printf(bio_err,"error unpacking public key\n");
1527 i=X509_verify(req,pktmp);
1528 EVP_PKEY_free(pktmp);
1532 BIO_printf(bio_err,"Signature verification problems....\n");
1538 BIO_printf(bio_err,"Signature did not match the certificate\n");
1542 BIO_printf(bio_err,"Signature ok\n");
1544 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1547 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1548 batch,verbose,rreq,ext_sect,lconf);
1551 if (rreq != NULL) X509_REQ_free(rreq);
1552 if (req != NULL) X509_free(req);
1553 if (in != NULL) BIO_free(in);
1557 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1558 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1559 char *startdate, char *enddate, int days, int batch, int verbose,
1560 X509_REQ *req, char *ext_sect, LHASH *lconf)
1562 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1563 ASN1_UTCTIME *tm,*tmptm;
1564 ASN1_STRING *str,*str2;
1568 X509_NAME_ENTRY *ne;
1569 X509_NAME_ENTRY *tne,*push;
1571 int ok= -1,i,j,last,nid;
1574 char *row[DB_NUMBER],**rrow,**irow=NULL;
1577 tmptm=ASN1_UTCTIME_new();
1580 BIO_printf(bio_err,"malloc error\n");
1584 for (i=0; i<DB_NUMBER; i++)
1587 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1588 name=X509_REQ_get_subject_name(req);
1589 for (i=0; i<X509_NAME_entry_count(name); i++)
1591 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1592 obj=X509_NAME_ENTRY_get_object(ne);
1593 j=i2a_ASN1_OBJECT(bio_err,obj);
1594 str=X509_NAME_ENTRY_get_data(ne);
1596 for (j=22-j; j>0; j--)
1600 BIO_puts(bio_err,buf);
1604 /* assume all type should be strings */
1605 nid=OBJ_obj2nid(ne->object);
1607 if (str->type == V_ASN1_UNIVERSALSTRING)
1608 ASN1_UNIVERSALSTRING_to_string(str);
1610 if ((str->type == V_ASN1_IA5STRING) &&
1611 (nid != NID_pkcs9_emailAddress))
1612 str->type=V_ASN1_T61STRING;
1614 if ((nid == NID_pkcs9_emailAddress) &&
1615 (str->type == V_ASN1_PRINTABLESTRING))
1616 str->type=V_ASN1_IA5STRING;
1619 if (str->type == V_ASN1_PRINTABLESTRING)
1620 BIO_printf(bio_err,"PRINTABLE:'");
1621 else if (str->type == V_ASN1_T61STRING)
1622 BIO_printf(bio_err,"T61STRING:'");
1623 else if (str->type == V_ASN1_IA5STRING)
1624 BIO_printf(bio_err,"IA5STRING:'");
1625 else if (str->type == V_ASN1_UNIVERSALSTRING)
1626 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1628 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1630 /* check some things */
1631 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1632 (str->type != V_ASN1_IA5STRING))
1634 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1637 j=ASN1_PRINTABLE_type(str->data,str->length);
1638 if ( ((j == V_ASN1_T61STRING) &&
1639 (str->type != V_ASN1_T61STRING)) ||
1640 ((j == V_ASN1_IA5STRING) &&
1641 (str->type == V_ASN1_PRINTABLESTRING)))
1643 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1647 p=(char *)str->data;
1648 for (j=str->length; j>0; j--)
1650 if ((*p >= ' ') && (*p <= '~'))
1651 BIO_printf(bio_err,"%c",*p);
1653 BIO_printf(bio_err,"\\0x%02X",*p);
1654 else if ((unsigned char)*p == 0xf7)
1655 BIO_printf(bio_err,"^?");
1656 else BIO_printf(bio_err,"^%c",*p+'@');
1659 BIO_printf(bio_err,"'\n");
1662 /* Ok, now we check the 'policy' stuff. */
1663 if ((subject=X509_NAME_new()) == NULL)
1665 BIO_printf(bio_err,"Memory allocation failure\n");
1669 /* take a copy of the issuer name before we mess with it. */
1670 CAname=X509_NAME_dup(x509->cert_info->subject);
1671 if (CAname == NULL) goto err;
1674 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1676 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1677 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1679 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1687 /* lookup the object in the supplied name list */
1688 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1691 if (last != -1) break;
1696 tne=X509_NAME_get_entry(name,j);
1700 /* depending on the 'policy', decide what to do. */
1702 if (strcmp(cv->value,"optional") == 0)
1707 else if (strcmp(cv->value,"supplied") == 0)
1711 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1717 else if (strcmp(cv->value,"match") == 0)
1723 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1730 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1731 if ((j < 0) && (last2 == -1))
1733 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1738 push=X509_NAME_get_entry(CAname,j);
1739 str=X509_NAME_ENTRY_get_data(tne);
1740 str2=X509_NAME_ENTRY_get_data(push);
1742 if (ASN1_STRING_cmp(str,str2) != 0)
1747 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));
1753 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1759 if (!X509_NAME_add_entry(subject,push, -1, 0))
1762 X509_NAME_ENTRY_free(push);
1763 BIO_printf(bio_err,"Memory allocation failure\n");
1773 X509_NAME_free(subject);
1774 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1775 if (subject == NULL) goto err;
1779 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1781 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1782 row[DB_serial]=BN_bn2hex(serial);
1783 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1785 BIO_printf(bio_err,"Memory allocation failure\n");
1789 rrow=TXT_DB_get_by_index(db,DB_name,row);
1792 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1797 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1800 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1802 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1809 "The matching entry has the following details\n");
1810 if (rrow[DB_type][0] == 'E')
1812 else if (rrow[DB_type][0] == 'R')
1814 else if (rrow[DB_type][0] == 'V')
1817 p="\ninvalid type, Data base error\n";
1818 BIO_printf(bio_err,"Type :%s\n",p);;
1819 if (rrow[DB_type][0] == 'R')
1821 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1822 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1824 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1825 BIO_printf(bio_err,"Expires on :%s\n",p);
1826 p=rrow[DB_serial]; if (p == NULL) p="undef";
1827 BIO_printf(bio_err,"Serial Number :%s\n",p);
1828 p=rrow[DB_file]; if (p == NULL) p="undef";
1829 BIO_printf(bio_err,"File name :%s\n",p);
1830 p=rrow[DB_name]; if (p == NULL) p="undef";
1831 BIO_printf(bio_err,"Subject Name :%s\n",p);
1832 ok= -1; /* This is now a 'bad' error. */
1836 /* We are now totally happy, lets make and sign the certificate */
1838 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1840 if ((ret=X509_new()) == NULL) goto err;
1844 /* Make it an X509 v3 certificate. */
1845 if (!X509_set_version(x509,2)) goto err;
1848 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1850 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1853 BIO_printf(bio_err,"Certificate is to be certified until ");
1854 if (strcmp(startdate,"today") == 0)
1855 X509_gmtime_adj(X509_get_notBefore(ret),0);
1856 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1858 if (enddate == NULL)
1859 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1860 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1862 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1863 if(days) BIO_printf(bio_err," (%d days)",days);
1864 BIO_printf(bio_err, "\n");
1866 if (!X509_set_subject_name(ret,subject)) goto err;
1868 pktmp=X509_REQ_get_pubkey(req);
1869 i = X509_set_pubkey(ret,pktmp);
1870 EVP_PKEY_free(pktmp);
1873 /* Lets add the extensions, if there are any */
1877 if (ci->version == NULL)
1878 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1880 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1882 /* Free the current entries if any, there should not
1883 * be any I believe */
1884 if (ci->extensions != NULL)
1885 sk_X509_EXTENSION_pop_free(ci->extensions,
1886 X509_EXTENSION_free);
1888 ci->extensions = NULL;
1890 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1891 X509V3_set_conf_lhash(&ctx, lconf);
1893 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1900 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1901 (void)BIO_flush(bio_err);
1903 fgets(buf,sizeof(buf)-1,stdin);
1904 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1906 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1914 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1915 pktmp=X509_get_pubkey(ret);
1916 if (EVP_PKEY_missing_parameters(pktmp) &&
1917 !EVP_PKEY_missing_parameters(pkey))
1918 EVP_PKEY_copy_parameters(pktmp,pkey);
1919 EVP_PKEY_free(pktmp);
1922 if (!X509_sign(ret,pkey,dgst))
1925 /* We now just add it to the database */
1926 row[DB_type]=(char *)OPENSSL_malloc(2);
1928 tm=X509_get_notAfter(ret);
1929 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1930 memcpy(row[DB_exp_date],tm->data,tm->length);
1931 row[DB_exp_date][tm->length]='\0';
1933 row[DB_rev_date]=NULL;
1935 /* row[DB_serial] done already */
1936 row[DB_file]=(char *)OPENSSL_malloc(8);
1937 /* row[DB_name] done already */
1939 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1940 (row[DB_file] == NULL))
1942 BIO_printf(bio_err,"Memory allocation failure\n");
1945 strcpy(row[DB_file],"unknown");
1946 row[DB_type][0]='V';
1947 row[DB_type][1]='\0';
1949 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1951 BIO_printf(bio_err,"Memory allocation failure\n");
1955 for (i=0; i<DB_NUMBER; i++)
1960 irow[DB_NUMBER]=NULL;
1962 if (!TXT_DB_insert(db,irow))
1964 BIO_printf(bio_err,"failed to update database\n");
1965 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1970 for (i=0; i<DB_NUMBER; i++)
1971 if (row[i] != NULL) OPENSSL_free(row[i]);
1974 X509_NAME_free(CAname);
1975 if (subject != NULL)
1976 X509_NAME_free(subject);
1978 ASN1_UTCTIME_free(tmptm);
1981 if (ret != NULL) X509_free(ret);
1989 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1994 (void)i2d_X509_bio(bp,x);
1998 /* ??? Not needed since X509_print prints all this stuff anyway */
1999 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2000 BIO_printf(bp,"issuer :%s\n",f);
2002 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2003 BIO_printf(bp,"subject:%s\n",f);
2005 BIO_puts(bp,"serial :");
2006 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2007 BIO_puts(bp,"\n\n");
2009 if(!notext)X509_print(bp,x);
2010 PEM_write_bio_X509(bp,x);
2013 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2014 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2015 BIGNUM *serial, char *startdate, char *enddate, int days,
2016 char *ext_sect, LHASH *lconf, int verbose)
2018 STACK_OF(CONF_VALUE) *sk=NULL;
2021 CONF_VALUE *cv=NULL;
2022 NETSCAPE_SPKI *spki = NULL;
2025 EVP_PKEY *pktmp=NULL;
2027 X509_NAME_ENTRY *ne=NULL;
2033 * Load input file into a hash table. (This is just an easy
2034 * way to read and parse the file, then put it into a convenient
2037 parms=CONF_load(NULL,infile,&errline);
2040 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2041 ERR_print_errors(bio_err);
2045 sk=CONF_get_section(parms, "default");
2046 if (sk_CONF_VALUE_num(sk) == 0)
2048 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2054 * Now create a dummy X509 request structure. We don't actually
2055 * have an X509 request, but we have many of the components
2056 * (a public key, various DN components). The idea is that we
2057 * put these components into the right X509 request structure
2058 * and we can use the same code as if you had a real X509 request.
2063 ERR_print_errors(bio_err);
2068 * Build up the subject name set.
2075 if (sk_CONF_VALUE_num(sk) <= i) break;
2077 cv=sk_CONF_VALUE_value(sk,i);
2079 /* Skip past any leading X. X: X, etc to allow for
2080 * multiple instances
2082 for(buf = cv->name; *buf ; buf++)
2083 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2085 if(*buf) type = buf;
2090 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2092 if (strcmp(type, "SPKAC") == 0)
2094 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2097 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2098 ERR_print_errors(bio_err);
2105 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2106 if (fix_data(nid, &j) == 0)
2109 "invalid characters in string %s\n",buf);
2113 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2114 (unsigned char *)buf,
2115 strlen(buf))) == NULL)
2118 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2122 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2128 * Now extract the key from the SPKI structure.
2131 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2133 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2135 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2139 j = NETSCAPE_SPKI_verify(spki, pktmp);
2142 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2145 BIO_printf(bio_err,"Signature ok\n");
2147 X509_REQ_set_pubkey(req,pktmp);
2148 EVP_PKEY_free(pktmp);
2149 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2150 days,1,verbose,req,ext_sect,lconf);
2152 if (req != NULL) X509_REQ_free(req);
2153 if (parms != NULL) CONF_free(parms);
2154 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2155 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2160 static int fix_data(int nid, int *type)
2162 if (nid == NID_pkcs9_emailAddress)
2163 *type=V_ASN1_IA5STRING;
2164 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2165 *type=V_ASN1_T61STRING;
2166 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2167 *type=V_ASN1_T61STRING;
2168 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2170 if (nid == NID_pkcs9_unstructuredName)
2171 *type=V_ASN1_IA5STRING;
2175 static int check_time_format(char *str)
2179 tm.data=(unsigned char *)str;
2180 tm.length=strlen(str);
2181 tm.type=V_ASN1_UTCTIME;
2182 return(ASN1_UTCTIME_check(&tm));
2185 static int do_revoke(X509 *x509, TXT_DB *db)
2187 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2188 char *row[DB_NUMBER],**rrow,**irow;
2192 for (i=0; i<DB_NUMBER; i++)
2194 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2195 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2196 row[DB_serial]=BN_bn2hex(bn);
2198 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2200 BIO_printf(bio_err,"Memory allocation failure\n");
2203 /* We have to lookup by serial number because name lookup
2204 * skips revoked certs
2206 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2209 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2211 /* We now just add it to the database */
2212 row[DB_type]=(char *)OPENSSL_malloc(2);
2214 tm=X509_get_notAfter(x509);
2215 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2216 memcpy(row[DB_exp_date],tm->data,tm->length);
2217 row[DB_exp_date][tm->length]='\0';
2219 row[DB_rev_date]=NULL;
2221 /* row[DB_serial] done already */
2222 row[DB_file]=(char *)OPENSSL_malloc(8);
2224 /* row[DB_name] done already */
2226 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2227 (row[DB_file] == NULL))
2229 BIO_printf(bio_err,"Memory allocation failure\n");
2232 strcpy(row[DB_file],"unknown");
2233 row[DB_type][0]='V';
2234 row[DB_type][1]='\0';
2236 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2238 BIO_printf(bio_err,"Memory allocation failure\n");
2242 for (i=0; i<DB_NUMBER; i++)
2247 irow[DB_NUMBER]=NULL;
2249 if (!TXT_DB_insert(db,irow))
2251 BIO_printf(bio_err,"failed to update database\n");
2252 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2256 /* Revoke Certificate */
2257 ok = do_revoke(x509,db);
2262 else if (index_name_cmp((const char **)row,(const char **)rrow))
2264 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2268 else if (rrow[DB_type][0]=='R')
2270 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2276 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2277 revtm = ASN1_UTCTIME_new();
2278 revtm=X509_gmtime_adj(revtm,0);
2279 rrow[DB_type][0]='R';
2280 rrow[DB_type][1]='\0';
2281 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2282 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2283 rrow[DB_rev_date][revtm->length]='\0';
2284 ASN1_UTCTIME_free(revtm);
2288 for (i=0; i<DB_NUMBER; i++)
2291 OPENSSL_free(row[i]);