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 - PEM private key file\n",
157 " -key arg - key to decode the private key if it is encrypted\n",
158 " -cert file - The CA certificate\n",
159 " -in file - The input PEM encoded certificate request(s)\n",
160 " -out file - Where to put the output file(s)\n",
161 " -outdir dir - Where to put output certificates\n",
162 " -infiles .... - The last argument, requests to process\n",
163 " -spkac file - File contains DN and signed public key and challenge\n",
164 " -ss_cert file - File contains a self signed cert to sign\n",
165 " -preserveDN - Don't re-order the DN\n",
166 " -batch - Don't ask questions\n",
167 " -msie_hack - msie modifications to handle all those universal strings\n",
168 " -revoke file - Revoke a certificate (given in file)\n",
169 " -extensions .. - Extension section (override value in config file)\n",
170 " -crlexts .. - CRL extension section (override value in config file)\n",
171 " -engine e - use engine e, possibly a hardware device.\n",
176 extern int EF_PROTECT_FREE;
177 extern int EF_PROTECT_BELOW;
178 extern int EF_ALIGNMENT;
181 static void lookup_fail(char *name,char *tag);
182 static unsigned long index_serial_hash(char **a);
183 static int index_serial_cmp(char **a, char **b);
184 static unsigned long index_name_hash(char **a);
185 static int index_name_qual(char **a);
186 static int index_name_cmp(char **a,char **b);
187 static BIGNUM *load_serial(char *serialfile);
188 static int save_serial(char *serialfile, BIGNUM *serial);
189 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
190 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
191 BIGNUM *serial, char *startdate,char *enddate, int days,
192 int batch, char *ext_sect, LHASH *conf,int verbose);
193 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
194 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
195 TXT_DB *db, BIGNUM *serial,char *startdate,
196 char *enddate, int days, int batch, char *ext_sect,
197 LHASH *conf,int verbose);
198 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
199 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
200 TXT_DB *db, BIGNUM *serial,char *startdate,
201 char *enddate, int days, char *ext_sect,LHASH *conf,
203 static int fix_data(int nid, int *type);
204 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
205 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
206 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
207 char *startdate, char *enddate, int days, int batch, int verbose,
208 X509_REQ *req, char *ext_sect, LHASH *conf);
209 static int do_revoke(X509 *x509, TXT_DB *db);
210 static int check_time_format(char *str);
211 static LHASH *conf=NULL;
212 static char *section=NULL;
214 static int preserve=0;
215 static int msie_hack=0;
217 int MAIN(int, char **);
219 int MAIN(int argc, char **argv)
222 char *key=NULL,*passargin=NULL;
234 char *configfile=NULL;
240 char *spkac_file=NULL;
241 char *ss_cert_file=NULL;
246 char *serialfile=NULL;
247 char *extensions=NULL;
250 char *startdate=NULL;
257 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
261 X509_CRL_INFO *ci=NULL;
262 X509_REVOKED *r=NULL;
266 const EVP_MD *dgst=NULL;
267 STACK_OF(CONF_VALUE) *attribs=NULL;
268 STACK_OF(X509) *cert_sk=NULL;
272 MS_STATIC char buf[3][BSIZE];
291 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
292 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
298 if (strcmp(*argv,"-verbose") == 0)
300 else if (strcmp(*argv,"-config") == 0)
302 if (--argc < 1) goto bad;
303 configfile= *(++argv);
305 else if (strcmp(*argv,"-name") == 0)
307 if (--argc < 1) goto bad;
310 else if (strcmp(*argv,"-startdate") == 0)
312 if (--argc < 1) goto bad;
313 startdate= *(++argv);
315 else if (strcmp(*argv,"-enddate") == 0)
317 if (--argc < 1) goto bad;
320 else if (strcmp(*argv,"-days") == 0)
322 if (--argc < 1) goto bad;
323 days=atoi(*(++argv));
325 else if (strcmp(*argv,"-md") == 0)
327 if (--argc < 1) goto bad;
330 else if (strcmp(*argv,"-policy") == 0)
332 if (--argc < 1) goto bad;
335 else if (strcmp(*argv,"-keyfile") == 0)
337 if (--argc < 1) goto bad;
340 else if (strcmp(*argv,"-passin") == 0)
342 if (--argc < 1) goto bad;
343 passargin= *(++argv);
345 else if (strcmp(*argv,"-key") == 0)
347 if (--argc < 1) goto bad;
350 else if (strcmp(*argv,"-cert") == 0)
352 if (--argc < 1) goto bad;
355 else if (strcmp(*argv,"-in") == 0)
357 if (--argc < 1) goto bad;
361 else if (strcmp(*argv,"-out") == 0)
363 if (--argc < 1) goto bad;
366 else if (strcmp(*argv,"-outdir") == 0)
368 if (--argc < 1) goto bad;
371 else if (strcmp(*argv,"-notext") == 0)
373 else if (strcmp(*argv,"-batch") == 0)
375 else if (strcmp(*argv,"-preserveDN") == 0)
377 else if (strcmp(*argv,"-gencrl") == 0)
379 else if (strcmp(*argv,"-msie_hack") == 0)
381 else if (strcmp(*argv,"-crldays") == 0)
383 if (--argc < 1) goto bad;
384 crldays= atol(*(++argv));
386 else if (strcmp(*argv,"-crlhours") == 0)
388 if (--argc < 1) goto bad;
389 crlhours= atol(*(++argv));
391 else if (strcmp(*argv,"-infiles") == 0)
398 else if (strcmp(*argv, "-ss_cert") == 0)
400 if (--argc < 1) goto bad;
401 ss_cert_file = *(++argv);
404 else if (strcmp(*argv, "-spkac") == 0)
406 if (--argc < 1) goto bad;
407 spkac_file = *(++argv);
410 else if (strcmp(*argv,"-revoke") == 0)
412 if (--argc < 1) goto bad;
416 else if (strcmp(*argv,"-extensions") == 0)
418 if (--argc < 1) goto bad;
419 extensions= *(++argv);
421 else if (strcmp(*argv,"-crlexts") == 0)
423 if (--argc < 1) goto bad;
426 else if (strcmp(*argv,"-engine") == 0)
428 if (--argc < 1) goto bad;
434 BIO_printf(bio_err,"unknown option %s\n",*argv);
444 for (pp=ca_usage; (*pp != NULL); pp++)
445 BIO_printf(bio_err,*pp);
449 ERR_load_crypto_strings();
453 if((e = ENGINE_by_id(engine)) == NULL)
455 BIO_printf(bio_err,"invalid engine \"%s\"\n",
459 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
461 BIO_printf(bio_err,"can't use that engine\n");
464 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
465 /* Free our "structural" reference. */
469 /*****************************************************************/
470 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
471 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
472 if (configfile == NULL)
474 /* We will just use 'buf[0]' as a temporary buffer. */
476 strncpy(buf[0],X509_get_default_cert_area(),
477 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
479 strncpy(buf[0],X509_get_default_cert_area(),
480 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
483 strcat(buf[0],CONFIG_FILE);
487 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
488 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
491 BIO_printf(bio_err,"error loading the config file '%s'\n",
494 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
495 ,errorline,configfile);
499 /* Lets get the config section we are using */
502 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
505 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
512 p=CONF_get_string(conf,NULL,"oid_file");
517 oid_bio=BIO_new_file(p,"r");
521 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
522 ERR_print_errors(bio_err);
528 OBJ_create_objects(oid_bio);
532 if(!add_oid_section(bio_err,conf))
534 ERR_print_errors(bio_err);
539 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
540 app_RAND_load_file(randfile, bio_err, 0);
542 in=BIO_new(BIO_s_file());
543 out=BIO_new(BIO_s_file());
544 Sout=BIO_new(BIO_s_file());
545 Cout=BIO_new(BIO_s_file());
546 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
548 ERR_print_errors(bio_err);
552 /*****************************************************************/
553 /* we definitely need an public key, so lets get it */
555 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
556 section,ENV_PRIVATE_KEY)) == NULL))
558 lookup_fail(section,ENV_PRIVATE_KEY);
561 if(!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
563 BIO_printf(bio_err,"Error getting password\n");
566 if (BIO_read_filename(in,keyfile) <= 0)
569 BIO_printf(bio_err,"trying to load CA private key\n");
572 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
573 if(key) memset(key,0,strlen(key));
576 BIO_printf(bio_err,"unable to load CA private key\n");
580 /*****************************************************************/
581 /* we need a certificate */
582 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
583 section,ENV_CERTIFICATE)) == NULL))
585 lookup_fail(section,ENV_CERTIFICATE);
588 if (BIO_read_filename(in,certfile) <= 0)
591 BIO_printf(bio_err,"trying to load CA certificate\n");
594 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
597 BIO_printf(bio_err,"unable to load CA certificate\n");
601 if (!X509_check_private_key(x509,pkey))
603 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
607 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
608 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
610 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
611 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
614 /*****************************************************************/
615 /* lookup where to write new certificates */
616 if ((outdir == NULL) && (req))
620 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
623 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
626 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
627 filename. In any case, stat(), below, will catch the problem
628 if outdir is not a directory spec, and the fopen() or open()
629 will catch an error if there is no write access.
631 Presumably, this problem could also be solved by using the DEC
632 C routines to convert the directory syntax to Unixly, and give
633 that to access(). However, time's too short to do that just
636 if (access(outdir,R_OK|W_OK|X_OK) != 0)
638 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
643 if (stat(outdir,&sb) != 0)
645 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
650 if (!(sb.st_mode & S_IFDIR))
652 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
660 /*****************************************************************/
661 /* we need to load the database file */
662 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
664 lookup_fail(section,ENV_DATABASE);
667 if (BIO_read_filename(in,dbfile) <= 0)
670 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
673 db=TXT_DB_read(in,DB_NUMBER);
674 if (db == NULL) goto err;
676 /* Lets check some fields */
677 for (i=0; i<sk_num(db->data); i++)
679 pp=(char **)sk_value(db->data,i);
680 if ((pp[DB_type][0] != DB_TYPE_REV) &&
681 (pp[DB_rev_date][0] != '\0'))
683 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
686 if ((pp[DB_type][0] == DB_TYPE_REV) &&
687 !check_time_format(pp[DB_rev_date]))
689 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
693 if (!check_time_format(pp[DB_exp_date]))
695 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
700 if ((j&1) || (j < 2))
702 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
707 if (!( ((*p >= '0') && (*p <= '9')) ||
708 ((*p >= 'A') && (*p <= 'F')) ||
709 ((*p >= 'a') && (*p <= 'f'))) )
711 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);
719 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
722 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
723 out = BIO_push(tmpbio, out);
726 TXT_DB_write(out,db);
727 BIO_printf(bio_err,"%d entries loaded from the database\n",
729 BIO_printf(bio_err,"generating index\n");
732 if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
735 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
739 if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
742 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
743 db->error,db->arg1,db->arg2);
747 /*****************************************************************/
753 if (BIO_write_filename(Sout,outfile) <= 0)
761 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
764 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
765 Sout = BIO_push(tmpbio, Sout);
773 if ((md == NULL) && ((md=CONF_get_string(conf,
774 section,ENV_DEFAULT_MD)) == NULL))
776 lookup_fail(section,ENV_DEFAULT_MD);
779 if ((dgst=EVP_get_digestbyname(md)) == NULL)
781 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
785 BIO_printf(bio_err,"message digest is %s\n",
786 OBJ_nid2ln(dgst->type));
787 if ((policy == NULL) && ((policy=CONF_get_string(conf,
788 section,ENV_POLICY)) == NULL))
790 lookup_fail(section,ENV_POLICY);
794 BIO_printf(bio_err,"policy is %s\n",policy);
796 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
799 lookup_fail(section,ENV_SERIAL);
803 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
805 /* Check syntax of file */
807 X509V3_set_ctx_test(&ctx);
808 X509V3_set_conf_lhash(&ctx, conf);
809 if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
811 "Error Loading extension section %s\n",
818 if (startdate == NULL)
820 startdate=CONF_get_string(conf,section,
821 ENV_DEFAULT_STARTDATE);
823 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
825 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
828 if (startdate == NULL) startdate="today";
832 enddate=CONF_get_string(conf,section,
833 ENV_DEFAULT_ENDDATE);
835 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
837 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
843 days=(int)CONF_get_number(conf,section,
846 if (!enddate && (days == 0))
848 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
852 if ((serial=load_serial(serialfile)) == NULL)
854 BIO_printf(bio_err,"error while loading serial number\n");
859 if ((f=BN_bn2hex(serial)) == NULL) goto err;
860 BIO_printf(bio_err,"next serial number is %s\n",f);
864 if ((attribs=CONF_get_section(conf,policy)) == NULL)
866 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
870 if ((cert_sk=sk_X509_new_null()) == NULL)
872 BIO_printf(bio_err,"Memory allocation failure\n");
875 if (spkac_file != NULL)
878 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
879 serial,startdate,enddate, days,extensions,conf,
885 BIO_printf(bio_err,"\n");
886 if (!BN_add_word(serial,1)) goto err;
887 if (!sk_X509_push(cert_sk,x))
889 BIO_printf(bio_err,"Memory allocation failure\n");
899 if (ss_cert_file != NULL)
902 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
903 db,serial,startdate,enddate,days,batch,
904 extensions,conf,verbose);
909 BIO_printf(bio_err,"\n");
910 if (!BN_add_word(serial,1)) goto err;
911 if (!sk_X509_push(cert_sk,x))
913 BIO_printf(bio_err,"Memory allocation failure\n");
921 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
922 serial,startdate,enddate,days,batch,
923 extensions,conf,verbose);
928 BIO_printf(bio_err,"\n");
929 if (!BN_add_word(serial,1)) goto err;
930 if (!sk_X509_push(cert_sk,x))
932 BIO_printf(bio_err,"Memory allocation failure\n");
937 for (i=0; i<argc; i++)
940 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
941 serial,startdate,enddate,days,batch,
942 extensions,conf,verbose);
947 BIO_printf(bio_err,"\n");
948 if (!BN_add_word(serial,1)) goto err;
949 if (!sk_X509_push(cert_sk,x))
951 BIO_printf(bio_err,"Memory allocation failure\n");
956 /* we have a stack of newly certified certificates
957 * and a data base and serial number that need
960 if (sk_X509_num(cert_sk) > 0)
964 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
965 (void)BIO_flush(bio_err);
967 fgets(buf[0],10,stdin);
968 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
970 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
976 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
978 strncpy(buf[0],serialfile,BSIZE-4);
981 strcat(buf[0],"-new");
983 strcat(buf[0],".new");
986 if (!save_serial(buf[0],serial)) goto err;
988 strncpy(buf[1],dbfile,BSIZE-4);
991 strcat(buf[1],"-new");
993 strcat(buf[1],".new");
996 if (BIO_write_filename(out,buf[1]) <= 0)
999 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1002 l=TXT_DB_write(out,db);
1003 if (l <= 0) goto err;
1007 BIO_printf(bio_err,"writing new certificates\n");
1008 for (i=0; i<sk_X509_num(cert_sk); i++)
1013 x=sk_X509_value(cert_sk,i);
1015 j=x->cert_info->serialNumber->length;
1016 p=(char *)x->cert_info->serialNumber->data;
1018 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1024 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1029 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1038 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1041 BIO_printf(bio_err,"writing %s\n",buf[2]);
1043 if (BIO_write_filename(Cout,buf[2]) <= 0)
1048 write_new_certificate(Cout,x, 0, notext);
1049 write_new_certificate(Sout,x, output_der, notext);
1052 if (sk_X509_num(cert_sk))
1054 /* Rename the database and the serial file */
1055 strncpy(buf[2],serialfile,BSIZE-4);
1058 strcat(buf[2],"-old");
1060 strcat(buf[2],".old");
1067 if (rename(serialfile,buf[2]) < 0)
1069 BIO_printf(bio_err,"unable to rename %s to %s\n",
1074 if (rename(buf[0],serialfile) < 0)
1076 BIO_printf(bio_err,"unable to rename %s to %s\n",
1079 rename(buf[2],serialfile);
1083 strncpy(buf[2],dbfile,BSIZE-4);
1086 strcat(buf[2],"-old");
1088 strcat(buf[2],".old");
1091 if (rename(dbfile,buf[2]) < 0)
1093 BIO_printf(bio_err,"unable to rename %s to %s\n",
1098 if (rename(buf[1],dbfile) < 0)
1100 BIO_printf(bio_err,"unable to rename %s to %s\n",
1103 rename(buf[2],dbfile);
1106 BIO_printf(bio_err,"Data Base Updated\n");
1110 /*****************************************************************/
1113 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1115 /* Check syntax of file */
1117 X509V3_set_ctx_test(&ctx);
1118 X509V3_set_conf_lhash(&ctx, conf);
1119 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1121 "Error Loading CRL extension section %s\n",
1127 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1129 if (!crldays && !crlhours)
1131 crldays=CONF_get_number(conf,section,
1132 ENV_DEFAULT_CRL_DAYS);
1133 crlhours=CONF_get_number(conf,section,
1134 ENV_DEFAULT_CRL_HOURS);
1136 if ((crldays == 0) && (crlhours == 0))
1138 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1142 if (verbose) BIO_printf(bio_err,"making CRL\n");
1143 if ((crl=X509_CRL_new()) == NULL) goto err;
1145 X509_NAME_free(ci->issuer);
1146 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1147 if (ci->issuer == NULL) goto err;
1149 X509_gmtime_adj(ci->lastUpdate,0);
1150 if (ci->nextUpdate == NULL)
1151 ci->nextUpdate=ASN1_UTCTIME_new();
1152 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1154 for (i=0; i<sk_num(db->data); i++)
1156 pp=(char **)sk_value(db->data,i);
1157 if (pp[DB_type][0] == DB_TYPE_REV)
1159 if ((r=X509_REVOKED_new()) == NULL) goto err;
1160 ASN1_STRING_set((ASN1_STRING *)
1162 (unsigned char *)pp[DB_rev_date],
1163 strlen(pp[DB_rev_date]));
1164 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1166 (void)BIO_reset(hex);
1167 if (!BIO_puts(hex,pp[DB_serial]))
1169 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1170 buf[0],BSIZE)) goto err;
1172 sk_X509_REVOKED_push(ci->revoked,r);
1175 /* sort the data so it will be written in serial
1177 sk_X509_REVOKED_sort(ci->revoked);
1178 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1180 r=sk_X509_REVOKED_value(ci->revoked,i);
1184 /* we now have a CRL */
1185 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1188 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1190 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1197 if (pkey->type == EVP_PKEY_DSA)
1204 /* Add any extensions asked for */
1208 if (ci->version == NULL)
1209 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1210 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1211 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1212 X509V3_set_conf_lhash(&crlctx, conf);
1214 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1215 crl_ext, crl)) goto err;
1218 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1220 PEM_write_bio_X509_CRL(Sout,crl);
1222 /*****************************************************************/
1227 BIO_printf(bio_err,"no input files\n");
1233 if (BIO_read_filename(in,infile) <= 0)
1236 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1239 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1240 if (revcert == NULL)
1242 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1245 j=do_revoke(revcert,db);
1246 if (j <= 0) goto err;
1249 strncpy(buf[0],dbfile,BSIZE-4);
1250 strcat(buf[0],".new");
1251 if (BIO_write_filename(out,buf[0]) <= 0)
1254 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1257 j=TXT_DB_write(out,db);
1258 if (j <= 0) goto err;
1259 strncpy(buf[1],dbfile,BSIZE-4);
1260 strcat(buf[1],".old");
1261 if (rename(dbfile,buf[1]) < 0)
1263 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1267 if (rename(buf[0],dbfile) < 0)
1269 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1271 rename(buf[1],dbfile);
1274 BIO_printf(bio_err,"Data Base Updated\n");
1277 /*****************************************************************/
1286 sk_X509_pop_free(cert_sk,X509_free);
1288 if (ret) ERR_print_errors(bio_err);
1289 app_RAND_write_file(randfile, bio_err);
1292 EVP_PKEY_free(pkey);
1300 static void lookup_fail(char *name, char *tag)
1302 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1305 static unsigned long index_serial_hash(char **a)
1310 while (*n == '0') n++;
1311 return(lh_strhash(n));
1314 static int index_serial_cmp(char **a, char **b)
1318 for (aa=a[DB_serial]; *aa == '0'; aa++);
1319 for (bb=b[DB_serial]; *bb == '0'; bb++);
1320 return(strcmp(aa,bb));
1323 static unsigned long index_name_hash(char **a)
1324 { return(lh_strhash(a[DB_name])); }
1326 static int index_name_qual(char **a)
1327 { return(a[0][0] == 'V'); }
1329 static int index_name_cmp(char **a, char **b)
1330 { return(strcmp(a[DB_name],
1333 static BIGNUM *load_serial(char *serialfile)
1337 MS_STATIC char buf[1024];
1338 ASN1_INTEGER *ai=NULL;
1340 if ((in=BIO_new(BIO_s_file())) == NULL)
1342 ERR_print_errors(bio_err);
1346 if (BIO_read_filename(in,serialfile) <= 0)
1351 ai=ASN1_INTEGER_new();
1352 if (ai == NULL) goto err;
1353 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1355 BIO_printf(bio_err,"unable to load number from %s\n",
1359 ret=ASN1_INTEGER_to_BN(ai,NULL);
1362 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1366 if (in != NULL) BIO_free(in);
1367 if (ai != NULL) ASN1_INTEGER_free(ai);
1371 static int save_serial(char *serialfile, BIGNUM *serial)
1375 ASN1_INTEGER *ai=NULL;
1377 out=BIO_new(BIO_s_file());
1380 ERR_print_errors(bio_err);
1383 if (BIO_write_filename(out,serialfile) <= 0)
1389 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1391 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1394 i2a_ASN1_INTEGER(out,ai);
1398 if (out != NULL) BIO_free_all(out);
1399 if (ai != NULL) ASN1_INTEGER_free(ai);
1403 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1404 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1405 BIGNUM *serial, char *startdate, char *enddate, int days,
1406 int batch, char *ext_sect, LHASH *lconf, int verbose)
1410 EVP_PKEY *pktmp=NULL;
1413 in=BIO_new(BIO_s_file());
1415 if (BIO_read_filename(in,infile) <= 0)
1420 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1422 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1427 X509_REQ_print(bio_err,req);
1429 BIO_printf(bio_err,"Check that the request matches the signature\n");
1431 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1433 BIO_printf(bio_err,"error unpacking public key\n");
1436 i=X509_REQ_verify(req,pktmp);
1437 EVP_PKEY_free(pktmp);
1441 BIO_printf(bio_err,"Signature verification problems....\n");
1447 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1451 BIO_printf(bio_err,"Signature ok\n");
1453 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1454 days,batch,verbose,req,ext_sect,lconf);
1457 if (req != NULL) X509_REQ_free(req);
1458 if (in != NULL) BIO_free(in);
1462 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1463 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1464 BIGNUM *serial, char *startdate, char *enddate, int days,
1465 int batch, char *ext_sect, LHASH *lconf, int verbose)
1468 X509_REQ *rreq=NULL;
1470 EVP_PKEY *pktmp=NULL;
1473 in=BIO_new(BIO_s_file());
1475 if (BIO_read_filename(in,infile) <= 0)
1480 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1482 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1486 X509_print(bio_err,req);
1488 BIO_printf(bio_err,"Check that the request matches the signature\n");
1490 if ((pktmp=X509_get_pubkey(req)) == NULL)
1492 BIO_printf(bio_err,"error unpacking public key\n");
1495 i=X509_verify(req,pktmp);
1496 EVP_PKEY_free(pktmp);
1500 BIO_printf(bio_err,"Signature verification problems....\n");
1506 BIO_printf(bio_err,"Signature did not match the certificate\n");
1510 BIO_printf(bio_err,"Signature ok\n");
1512 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1515 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1516 batch,verbose,rreq,ext_sect,lconf);
1519 if (rreq != NULL) X509_REQ_free(rreq);
1520 if (req != NULL) X509_free(req);
1521 if (in != NULL) BIO_free(in);
1525 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1526 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1527 char *startdate, char *enddate, int days, int batch, int verbose,
1528 X509_REQ *req, char *ext_sect, LHASH *lconf)
1530 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1531 ASN1_UTCTIME *tm,*tmptm;
1532 ASN1_STRING *str,*str2;
1536 X509_NAME_ENTRY *ne;
1537 X509_NAME_ENTRY *tne,*push;
1539 int ok= -1,i,j,last,nid;
1542 char *row[DB_NUMBER],**rrow,**irow=NULL;
1545 tmptm=ASN1_UTCTIME_new();
1548 BIO_printf(bio_err,"malloc error\n");
1552 for (i=0; i<DB_NUMBER; i++)
1555 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1556 name=X509_REQ_get_subject_name(req);
1557 for (i=0; i<X509_NAME_entry_count(name); i++)
1559 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1560 obj=X509_NAME_ENTRY_get_object(ne);
1561 j=i2a_ASN1_OBJECT(bio_err,obj);
1562 str=X509_NAME_ENTRY_get_data(ne);
1564 for (j=22-j; j>0; j--)
1568 BIO_puts(bio_err,buf);
1572 /* assume all type should be strings */
1573 nid=OBJ_obj2nid(ne->object);
1575 if (str->type == V_ASN1_UNIVERSALSTRING)
1576 ASN1_UNIVERSALSTRING_to_string(str);
1578 if ((str->type == V_ASN1_IA5STRING) &&
1579 (nid != NID_pkcs9_emailAddress))
1580 str->type=V_ASN1_T61STRING;
1582 if ((nid == NID_pkcs9_emailAddress) &&
1583 (str->type == V_ASN1_PRINTABLESTRING))
1584 str->type=V_ASN1_IA5STRING;
1587 if (str->type == V_ASN1_PRINTABLESTRING)
1588 BIO_printf(bio_err,"PRINTABLE:'");
1589 else if (str->type == V_ASN1_T61STRING)
1590 BIO_printf(bio_err,"T61STRING:'");
1591 else if (str->type == V_ASN1_IA5STRING)
1592 BIO_printf(bio_err,"IA5STRING:'");
1593 else if (str->type == V_ASN1_UNIVERSALSTRING)
1594 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1596 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1598 /* check some things */
1599 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1600 (str->type != V_ASN1_IA5STRING))
1602 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1605 j=ASN1_PRINTABLE_type(str->data,str->length);
1606 if ( ((j == V_ASN1_T61STRING) &&
1607 (str->type != V_ASN1_T61STRING)) ||
1608 ((j == V_ASN1_IA5STRING) &&
1609 (str->type == V_ASN1_PRINTABLESTRING)))
1611 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1615 p=(char *)str->data;
1616 for (j=str->length; j>0; j--)
1618 if ((*p >= ' ') && (*p <= '~'))
1619 BIO_printf(bio_err,"%c",*p);
1621 BIO_printf(bio_err,"\\0x%02X",*p);
1622 else if ((unsigned char)*p == 0xf7)
1623 BIO_printf(bio_err,"^?");
1624 else BIO_printf(bio_err,"^%c",*p+'@');
1627 BIO_printf(bio_err,"'\n");
1630 /* Ok, now we check the 'policy' stuff. */
1631 if ((subject=X509_NAME_new()) == NULL)
1633 BIO_printf(bio_err,"Memory allocation failure\n");
1637 /* take a copy of the issuer name before we mess with it. */
1638 CAname=X509_NAME_dup(x509->cert_info->subject);
1639 if (CAname == NULL) goto err;
1642 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1644 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1645 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1647 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1655 /* lookup the object in the supplied name list */
1656 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1659 if (last != -1) break;
1664 tne=X509_NAME_get_entry(name,j);
1668 /* depending on the 'policy', decide what to do. */
1670 if (strcmp(cv->value,"optional") == 0)
1675 else if (strcmp(cv->value,"supplied") == 0)
1679 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1685 else if (strcmp(cv->value,"match") == 0)
1691 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1698 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1699 if ((j < 0) && (last2 == -1))
1701 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1706 push=X509_NAME_get_entry(CAname,j);
1707 str=X509_NAME_ENTRY_get_data(tne);
1708 str2=X509_NAME_ENTRY_get_data(push);
1710 if (ASN1_STRING_cmp(str,str2) != 0)
1715 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));
1721 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1727 if (!X509_NAME_add_entry(subject,push, -1, 0))
1730 X509_NAME_ENTRY_free(push);
1731 BIO_printf(bio_err,"Memory allocation failure\n");
1741 X509_NAME_free(subject);
1742 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1743 if (subject == NULL) goto err;
1747 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1749 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1750 row[DB_serial]=BN_bn2hex(serial);
1751 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1753 BIO_printf(bio_err,"Memory allocation failure\n");
1757 rrow=TXT_DB_get_by_index(db,DB_name,row);
1760 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1765 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1768 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1770 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1777 "The matching entry has the following details\n");
1778 if (rrow[DB_type][0] == 'E')
1780 else if (rrow[DB_type][0] == 'R')
1782 else if (rrow[DB_type][0] == 'V')
1785 p="\ninvalid type, Data base error\n";
1786 BIO_printf(bio_err,"Type :%s\n",p);;
1787 if (rrow[DB_type][0] == 'R')
1789 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1790 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1792 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1793 BIO_printf(bio_err,"Expires on :%s\n",p);
1794 p=rrow[DB_serial]; if (p == NULL) p="undef";
1795 BIO_printf(bio_err,"Serial Number :%s\n",p);
1796 p=rrow[DB_file]; if (p == NULL) p="undef";
1797 BIO_printf(bio_err,"File name :%s\n",p);
1798 p=rrow[DB_name]; if (p == NULL) p="undef";
1799 BIO_printf(bio_err,"Subject Name :%s\n",p);
1800 ok= -1; /* This is now a 'bad' error. */
1804 /* We are now totally happy, lets make and sign the certificate */
1806 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1808 if ((ret=X509_new()) == NULL) goto err;
1812 /* Make it an X509 v3 certificate. */
1813 if (!X509_set_version(x509,2)) goto err;
1816 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1818 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1821 BIO_printf(bio_err,"Certificate is to be certified until ");
1822 if (strcmp(startdate,"today") == 0)
1823 X509_gmtime_adj(X509_get_notBefore(ret),0);
1824 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1826 if (enddate == NULL)
1827 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1828 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1830 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1831 if(days) BIO_printf(bio_err," (%d days)",days);
1832 BIO_printf(bio_err, "\n");
1834 if (!X509_set_subject_name(ret,subject)) goto err;
1836 pktmp=X509_REQ_get_pubkey(req);
1837 i = X509_set_pubkey(ret,pktmp);
1838 EVP_PKEY_free(pktmp);
1841 /* Lets add the extensions, if there are any */
1845 if (ci->version == NULL)
1846 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1848 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1850 /* Free the current entries if any, there should not
1851 * be any I believe */
1852 if (ci->extensions != NULL)
1853 sk_X509_EXTENSION_pop_free(ci->extensions,
1854 X509_EXTENSION_free);
1856 ci->extensions = NULL;
1858 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1859 X509V3_set_conf_lhash(&ctx, lconf);
1861 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1868 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1869 (void)BIO_flush(bio_err);
1871 fgets(buf,sizeof(buf)-1,stdin);
1872 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1874 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1882 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1883 pktmp=X509_get_pubkey(ret);
1884 if (EVP_PKEY_missing_parameters(pktmp) &&
1885 !EVP_PKEY_missing_parameters(pkey))
1886 EVP_PKEY_copy_parameters(pktmp,pkey);
1887 EVP_PKEY_free(pktmp);
1890 if (!X509_sign(ret,pkey,dgst))
1893 /* We now just add it to the database */
1894 row[DB_type]=(char *)OPENSSL_malloc(2);
1896 tm=X509_get_notAfter(ret);
1897 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1898 memcpy(row[DB_exp_date],tm->data,tm->length);
1899 row[DB_exp_date][tm->length]='\0';
1901 row[DB_rev_date]=NULL;
1903 /* row[DB_serial] done already */
1904 row[DB_file]=(char *)OPENSSL_malloc(8);
1905 /* row[DB_name] done already */
1907 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1908 (row[DB_file] == NULL))
1910 BIO_printf(bio_err,"Memory allocation failure\n");
1913 strcpy(row[DB_file],"unknown");
1914 row[DB_type][0]='V';
1915 row[DB_type][1]='\0';
1917 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1919 BIO_printf(bio_err,"Memory allocation failure\n");
1923 for (i=0; i<DB_NUMBER; i++)
1928 irow[DB_NUMBER]=NULL;
1930 if (!TXT_DB_insert(db,irow))
1932 BIO_printf(bio_err,"failed to update database\n");
1933 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1938 for (i=0; i<DB_NUMBER; i++)
1939 if (row[i] != NULL) OPENSSL_free(row[i]);
1942 X509_NAME_free(CAname);
1943 if (subject != NULL)
1944 X509_NAME_free(subject);
1946 ASN1_UTCTIME_free(tmptm);
1949 if (ret != NULL) X509_free(ret);
1957 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1962 (void)i2d_X509_bio(bp,x);
1966 /* ??? Not needed since X509_print prints all this stuff anyway */
1967 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1968 BIO_printf(bp,"issuer :%s\n",f);
1970 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1971 BIO_printf(bp,"subject:%s\n",f);
1973 BIO_puts(bp,"serial :");
1974 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1975 BIO_puts(bp,"\n\n");
1977 if(!notext)X509_print(bp,x);
1978 PEM_write_bio_X509(bp,x);
1981 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1982 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1983 BIGNUM *serial, char *startdate, char *enddate, int days,
1984 char *ext_sect, LHASH *lconf, int verbose)
1986 STACK_OF(CONF_VALUE) *sk=NULL;
1989 CONF_VALUE *cv=NULL;
1990 NETSCAPE_SPKI *spki = NULL;
1993 EVP_PKEY *pktmp=NULL;
1995 X509_NAME_ENTRY *ne=NULL;
2001 * Load input file into a hash table. (This is just an easy
2002 * way to read and parse the file, then put it into a convenient
2005 parms=CONF_load(NULL,infile,&errline);
2008 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2009 ERR_print_errors(bio_err);
2013 sk=CONF_get_section(parms, "default");
2014 if (sk_CONF_VALUE_num(sk) == 0)
2016 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2022 * Now create a dummy X509 request structure. We don't actually
2023 * have an X509 request, but we have many of the components
2024 * (a public key, various DN components). The idea is that we
2025 * put these components into the right X509 request structure
2026 * and we can use the same code as if you had a real X509 request.
2031 ERR_print_errors(bio_err);
2036 * Build up the subject name set.
2043 if (sk_CONF_VALUE_num(sk) <= i) break;
2045 cv=sk_CONF_VALUE_value(sk,i);
2047 /* Skip past any leading X. X: X, etc to allow for
2048 * multiple instances
2050 for(buf = cv->name; *buf ; buf++)
2051 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2053 if(*buf) type = buf;
2058 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2060 if (strcmp(type, "SPKAC") == 0)
2062 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2065 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2066 ERR_print_errors(bio_err);
2073 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2074 if (fix_data(nid, &j) == 0)
2077 "invalid characters in string %s\n",buf);
2081 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2082 (unsigned char *)buf,
2083 strlen(buf))) == NULL)
2086 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2090 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2096 * Now extract the key from the SPKI structure.
2099 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2101 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2103 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2107 j = NETSCAPE_SPKI_verify(spki, pktmp);
2110 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2113 BIO_printf(bio_err,"Signature ok\n");
2115 X509_REQ_set_pubkey(req,pktmp);
2116 EVP_PKEY_free(pktmp);
2117 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2118 days,1,verbose,req,ext_sect,lconf);
2120 if (req != NULL) X509_REQ_free(req);
2121 if (parms != NULL) CONF_free(parms);
2122 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2123 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2128 static int fix_data(int nid, int *type)
2130 if (nid == NID_pkcs9_emailAddress)
2131 *type=V_ASN1_IA5STRING;
2132 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2133 *type=V_ASN1_T61STRING;
2134 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2135 *type=V_ASN1_T61STRING;
2136 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2138 if (nid == NID_pkcs9_unstructuredName)
2139 *type=V_ASN1_IA5STRING;
2143 static int check_time_format(char *str)
2147 tm.data=(unsigned char *)str;
2148 tm.length=strlen(str);
2149 tm.type=V_ASN1_UTCTIME;
2150 return(ASN1_UTCTIME_check(&tm));
2153 static int do_revoke(X509 *x509, TXT_DB *db)
2155 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2156 char *row[DB_NUMBER],**rrow,**irow;
2160 for (i=0; i<DB_NUMBER; i++)
2162 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2163 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2164 row[DB_serial]=BN_bn2hex(bn);
2166 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2168 BIO_printf(bio_err,"Memory allocation failure\n");
2171 /* We have to lookup by serial number because name lookup
2172 * skips revoked certs
2174 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2177 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2179 /* We now just add it to the database */
2180 row[DB_type]=(char *)OPENSSL_malloc(2);
2182 tm=X509_get_notAfter(x509);
2183 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2184 memcpy(row[DB_exp_date],tm->data,tm->length);
2185 row[DB_exp_date][tm->length]='\0';
2187 row[DB_rev_date]=NULL;
2189 /* row[DB_serial] done already */
2190 row[DB_file]=(char *)OPENSSL_malloc(8);
2192 /* row[DB_name] done already */
2194 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2195 (row[DB_file] == NULL))
2197 BIO_printf(bio_err,"Memory allocation failure\n");
2200 strcpy(row[DB_file],"unknown");
2201 row[DB_type][0]='V';
2202 row[DB_type][1]='\0';
2204 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2206 BIO_printf(bio_err,"Memory allocation failure\n");
2210 for (i=0; i<DB_NUMBER; i++)
2215 irow[DB_NUMBER]=NULL;
2217 if (!TXT_DB_insert(db,irow))
2219 BIO_printf(bio_err,"failed to update database\n");
2220 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2224 /* Revoke Certificate */
2225 ok = do_revoke(x509,db);
2230 else if (index_name_cmp(row,rrow))
2232 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2236 else if (rrow[DB_type][0]=='R')
2238 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2244 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2245 revtm = ASN1_UTCTIME_new();
2246 revtm=X509_gmtime_adj(revtm,0);
2247 rrow[DB_type][0]='R';
2248 rrow[DB_type][1]='\0';
2249 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2250 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2251 rrow[DB_rev_date][revtm->length]='\0';
2252 ASN1_UTCTIME_free(revtm);
2256 for (i=0; i<DB_NUMBER; i++)
2259 OPENSSL_free(row[i]);