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(char **a);
184 static int index_serial_cmp(char **a, char **b);
185 static unsigned long index_name_hash(char **a);
186 static int index_name_qual(char **a);
187 static int index_name_cmp(char **a,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 int MAIN(int, char **);
220 int MAIN(int argc, char **argv)
223 char *key=NULL,*passargin=NULL;
235 char *configfile=NULL;
240 int keyform=FORMAT_PEM;
242 char *spkac_file=NULL;
243 char *ss_cert_file=NULL;
248 char *serialfile=NULL;
249 char *extensions=NULL;
252 char *startdate=NULL;
259 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
263 X509_CRL_INFO *ci=NULL;
264 X509_REVOKED *r=NULL;
268 const EVP_MD *dgst=NULL;
269 STACK_OF(CONF_VALUE) *attribs=NULL;
270 STACK_OF(X509) *cert_sk=NULL;
274 MS_STATIC char buf[3][BSIZE];
293 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
294 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
300 if (strcmp(*argv,"-verbose") == 0)
302 else if (strcmp(*argv,"-config") == 0)
304 if (--argc < 1) goto bad;
305 configfile= *(++argv);
307 else if (strcmp(*argv,"-name") == 0)
309 if (--argc < 1) goto bad;
312 else if (strcmp(*argv,"-startdate") == 0)
314 if (--argc < 1) goto bad;
315 startdate= *(++argv);
317 else if (strcmp(*argv,"-enddate") == 0)
319 if (--argc < 1) goto bad;
322 else if (strcmp(*argv,"-days") == 0)
324 if (--argc < 1) goto bad;
325 days=atoi(*(++argv));
327 else if (strcmp(*argv,"-md") == 0)
329 if (--argc < 1) goto bad;
332 else if (strcmp(*argv,"-policy") == 0)
334 if (--argc < 1) goto bad;
337 else if (strcmp(*argv,"-keyfile") == 0)
339 if (--argc < 1) goto bad;
342 else if (strcmp(*argv,"-keyform") == 0)
344 if (--argc < 1) goto bad;
345 keyform=str2fmt(*(++argv));
347 else if (strcmp(*argv,"-passin") == 0)
349 if (--argc < 1) goto bad;
350 passargin= *(++argv);
352 else if (strcmp(*argv,"-key") == 0)
354 if (--argc < 1) goto bad;
357 else if (strcmp(*argv,"-cert") == 0)
359 if (--argc < 1) goto bad;
362 else if (strcmp(*argv,"-in") == 0)
364 if (--argc < 1) goto bad;
368 else if (strcmp(*argv,"-out") == 0)
370 if (--argc < 1) goto bad;
373 else if (strcmp(*argv,"-outdir") == 0)
375 if (--argc < 1) goto bad;
378 else if (strcmp(*argv,"-notext") == 0)
380 else if (strcmp(*argv,"-batch") == 0)
382 else if (strcmp(*argv,"-preserveDN") == 0)
384 else if (strcmp(*argv,"-gencrl") == 0)
386 else if (strcmp(*argv,"-msie_hack") == 0)
388 else if (strcmp(*argv,"-crldays") == 0)
390 if (--argc < 1) goto bad;
391 crldays= atol(*(++argv));
393 else if (strcmp(*argv,"-crlhours") == 0)
395 if (--argc < 1) goto bad;
396 crlhours= atol(*(++argv));
398 else if (strcmp(*argv,"-infiles") == 0)
405 else if (strcmp(*argv, "-ss_cert") == 0)
407 if (--argc < 1) goto bad;
408 ss_cert_file = *(++argv);
411 else if (strcmp(*argv, "-spkac") == 0)
413 if (--argc < 1) goto bad;
414 spkac_file = *(++argv);
417 else if (strcmp(*argv,"-revoke") == 0)
419 if (--argc < 1) goto bad;
423 else if (strcmp(*argv,"-extensions") == 0)
425 if (--argc < 1) goto bad;
426 extensions= *(++argv);
428 else if (strcmp(*argv,"-crlexts") == 0)
430 if (--argc < 1) goto bad;
433 else if (strcmp(*argv,"-engine") == 0)
435 if (--argc < 1) goto bad;
441 BIO_printf(bio_err,"unknown option %s\n",*argv);
451 for (pp=ca_usage; (*pp != NULL); pp++)
452 BIO_printf(bio_err,*pp);
456 ERR_load_crypto_strings();
460 if((e = ENGINE_by_id(engine)) == NULL)
462 BIO_printf(bio_err,"invalid engine \"%s\"\n",
466 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
468 BIO_printf(bio_err,"can't use that engine\n");
471 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
472 /* Free our "structural" reference. */
476 /*****************************************************************/
477 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
478 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
479 if (configfile == NULL)
481 /* We will just use 'buf[0]' as a temporary buffer. */
483 strncpy(buf[0],X509_get_default_cert_area(),
484 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
486 strncpy(buf[0],X509_get_default_cert_area(),
487 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
490 strcat(buf[0],CONFIG_FILE);
494 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
495 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
498 BIO_printf(bio_err,"error loading the config file '%s'\n",
501 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
502 ,errorline,configfile);
506 /* Lets get the config section we are using */
509 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
512 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
519 p=CONF_get_string(conf,NULL,"oid_file");
524 oid_bio=BIO_new_file(p,"r");
528 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
529 ERR_print_errors(bio_err);
535 OBJ_create_objects(oid_bio);
539 if(!add_oid_section(bio_err,conf))
541 ERR_print_errors(bio_err);
546 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
547 app_RAND_load_file(randfile, bio_err, 0);
549 in=BIO_new(BIO_s_file());
550 out=BIO_new(BIO_s_file());
551 Sout=BIO_new(BIO_s_file());
552 Cout=BIO_new(BIO_s_file());
553 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
555 ERR_print_errors(bio_err);
559 /*****************************************************************/
560 /* we definitely need an public key, so lets get it */
562 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
563 section,ENV_PRIVATE_KEY)) == NULL))
565 lookup_fail(section,ENV_PRIVATE_KEY);
568 if(!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
570 BIO_printf(bio_err,"Error getting password\n");
573 if (keyform == FORMAT_ENGINE)
577 BIO_printf(bio_err,"no engine specified\n");
580 pkey = ENGINE_load_private_key(e, keyfile, key);
582 else if (keyform == FORMAT_PEM)
584 if (BIO_read_filename(in,keyfile) <= 0)
587 BIO_printf(bio_err,"trying to load CA private key\n");
590 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
594 BIO_printf(bio_err,"bad input format specified for key file\n");
597 if(key) memset(key,0,strlen(key));
600 BIO_printf(bio_err,"unable to load CA private key\n");
604 /*****************************************************************/
605 /* we need a certificate */
606 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
607 section,ENV_CERTIFICATE)) == NULL))
609 lookup_fail(section,ENV_CERTIFICATE);
612 if (BIO_read_filename(in,certfile) <= 0)
615 BIO_printf(bio_err,"trying to load CA certificate\n");
618 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
621 BIO_printf(bio_err,"unable to load CA certificate\n");
625 if (!X509_check_private_key(x509,pkey))
627 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
631 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
632 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
634 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
635 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
638 /*****************************************************************/
639 /* lookup where to write new certificates */
640 if ((outdir == NULL) && (req))
644 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
647 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
650 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
651 filename. In any case, stat(), below, will catch the problem
652 if outdir is not a directory spec, and the fopen() or open()
653 will catch an error if there is no write access.
655 Presumably, this problem could also be solved by using the DEC
656 C routines to convert the directory syntax to Unixly, and give
657 that to access(). However, time's too short to do that just
660 if (access(outdir,R_OK|W_OK|X_OK) != 0)
662 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
667 if (stat(outdir,&sb) != 0)
669 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
674 if (!(sb.st_mode & S_IFDIR))
676 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
684 /*****************************************************************/
685 /* we need to load the database file */
686 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
688 lookup_fail(section,ENV_DATABASE);
691 if (BIO_read_filename(in,dbfile) <= 0)
694 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
697 db=TXT_DB_read(in,DB_NUMBER);
698 if (db == NULL) goto err;
700 /* Lets check some fields */
701 for (i=0; i<sk_num(db->data); i++)
703 pp=(char **)sk_value(db->data,i);
704 if ((pp[DB_type][0] != DB_TYPE_REV) &&
705 (pp[DB_rev_date][0] != '\0'))
707 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
710 if ((pp[DB_type][0] == DB_TYPE_REV) &&
711 !check_time_format(pp[DB_rev_date]))
713 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
717 if (!check_time_format(pp[DB_exp_date]))
719 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
724 if ((j&1) || (j < 2))
726 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
731 if (!( ((*p >= '0') && (*p <= '9')) ||
732 ((*p >= 'A') && (*p <= 'F')) ||
733 ((*p >= 'a') && (*p <= 'f'))) )
735 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);
743 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
746 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
747 out = BIO_push(tmpbio, out);
750 TXT_DB_write(out,db);
751 BIO_printf(bio_err,"%d entries loaded from the database\n",
753 BIO_printf(bio_err,"generating index\n");
756 if (!TXT_DB_create_index(db, DB_serial, NULL,
757 (LHASH_HASH_FN_TYPE)index_serial_hash,
758 (LHASH_COMP_FN_TYPE)index_serial_cmp))
760 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
764 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
765 (LHASH_HASH_FN_TYPE)index_name_hash,
766 (LHASH_COMP_FN_TYPE)index_name_cmp))
768 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
769 db->error,db->arg1,db->arg2);
773 /*****************************************************************/
779 if (BIO_write_filename(Sout,outfile) <= 0)
787 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
790 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
791 Sout = BIO_push(tmpbio, Sout);
799 if ((md == NULL) && ((md=CONF_get_string(conf,
800 section,ENV_DEFAULT_MD)) == NULL))
802 lookup_fail(section,ENV_DEFAULT_MD);
805 if ((dgst=EVP_get_digestbyname(md)) == NULL)
807 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
811 BIO_printf(bio_err,"message digest is %s\n",
812 OBJ_nid2ln(dgst->type));
813 if ((policy == NULL) && ((policy=CONF_get_string(conf,
814 section,ENV_POLICY)) == NULL))
816 lookup_fail(section,ENV_POLICY);
820 BIO_printf(bio_err,"policy is %s\n",policy);
822 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
825 lookup_fail(section,ENV_SERIAL);
829 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
831 /* Check syntax of file */
833 X509V3_set_ctx_test(&ctx);
834 X509V3_set_conf_lhash(&ctx, conf);
835 if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
837 "Error Loading extension section %s\n",
844 if (startdate == NULL)
846 startdate=CONF_get_string(conf,section,
847 ENV_DEFAULT_STARTDATE);
849 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
851 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
854 if (startdate == NULL) startdate="today";
858 enddate=CONF_get_string(conf,section,
859 ENV_DEFAULT_ENDDATE);
861 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
863 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
869 days=(int)CONF_get_number(conf,section,
872 if (!enddate && (days == 0))
874 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
878 if ((serial=load_serial(serialfile)) == NULL)
880 BIO_printf(bio_err,"error while loading serial number\n");
885 if ((f=BN_bn2hex(serial)) == NULL) goto err;
886 BIO_printf(bio_err,"next serial number is %s\n",f);
890 if ((attribs=CONF_get_section(conf,policy)) == NULL)
892 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
896 if ((cert_sk=sk_X509_new_null()) == NULL)
898 BIO_printf(bio_err,"Memory allocation failure\n");
901 if (spkac_file != NULL)
904 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
905 serial,startdate,enddate, days,extensions,conf,
911 BIO_printf(bio_err,"\n");
912 if (!BN_add_word(serial,1)) goto err;
913 if (!sk_X509_push(cert_sk,x))
915 BIO_printf(bio_err,"Memory allocation failure\n");
925 if (ss_cert_file != NULL)
928 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
929 db,serial,startdate,enddate,days,batch,
930 extensions,conf,verbose);
935 BIO_printf(bio_err,"\n");
936 if (!BN_add_word(serial,1)) goto err;
937 if (!sk_X509_push(cert_sk,x))
939 BIO_printf(bio_err,"Memory allocation failure\n");
947 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
948 serial,startdate,enddate,days,batch,
949 extensions,conf,verbose);
954 BIO_printf(bio_err,"\n");
955 if (!BN_add_word(serial,1)) goto err;
956 if (!sk_X509_push(cert_sk,x))
958 BIO_printf(bio_err,"Memory allocation failure\n");
963 for (i=0; i<argc; i++)
966 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
967 serial,startdate,enddate,days,batch,
968 extensions,conf,verbose);
973 BIO_printf(bio_err,"\n");
974 if (!BN_add_word(serial,1)) goto err;
975 if (!sk_X509_push(cert_sk,x))
977 BIO_printf(bio_err,"Memory allocation failure\n");
982 /* we have a stack of newly certified certificates
983 * and a data base and serial number that need
986 if (sk_X509_num(cert_sk) > 0)
990 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
991 (void)BIO_flush(bio_err);
993 fgets(buf[0],10,stdin);
994 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
996 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1002 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1004 strncpy(buf[0],serialfile,BSIZE-4);
1007 strcat(buf[0],"-new");
1009 strcat(buf[0],".new");
1012 if (!save_serial(buf[0],serial)) goto err;
1014 strncpy(buf[1],dbfile,BSIZE-4);
1017 strcat(buf[1],"-new");
1019 strcat(buf[1],".new");
1022 if (BIO_write_filename(out,buf[1]) <= 0)
1025 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1028 l=TXT_DB_write(out,db);
1029 if (l <= 0) goto err;
1033 BIO_printf(bio_err,"writing new certificates\n");
1034 for (i=0; i<sk_X509_num(cert_sk); i++)
1039 x=sk_X509_value(cert_sk,i);
1041 j=x->cert_info->serialNumber->length;
1042 p=(char *)x->cert_info->serialNumber->data;
1044 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1050 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1055 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1064 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1067 BIO_printf(bio_err,"writing %s\n",buf[2]);
1069 if (BIO_write_filename(Cout,buf[2]) <= 0)
1074 write_new_certificate(Cout,x, 0, notext);
1075 write_new_certificate(Sout,x, output_der, notext);
1078 if (sk_X509_num(cert_sk))
1080 /* Rename the database and the serial file */
1081 strncpy(buf[2],serialfile,BSIZE-4);
1084 strcat(buf[2],"-old");
1086 strcat(buf[2],".old");
1093 if (rename(serialfile,buf[2]) < 0)
1095 BIO_printf(bio_err,"unable to rename %s to %s\n",
1100 if (rename(buf[0],serialfile) < 0)
1102 BIO_printf(bio_err,"unable to rename %s to %s\n",
1105 rename(buf[2],serialfile);
1109 strncpy(buf[2],dbfile,BSIZE-4);
1112 strcat(buf[2],"-old");
1114 strcat(buf[2],".old");
1117 if (rename(dbfile,buf[2]) < 0)
1119 BIO_printf(bio_err,"unable to rename %s to %s\n",
1124 if (rename(buf[1],dbfile) < 0)
1126 BIO_printf(bio_err,"unable to rename %s to %s\n",
1129 rename(buf[2],dbfile);
1132 BIO_printf(bio_err,"Data Base Updated\n");
1136 /*****************************************************************/
1139 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1141 /* Check syntax of file */
1143 X509V3_set_ctx_test(&ctx);
1144 X509V3_set_conf_lhash(&ctx, conf);
1145 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1147 "Error Loading CRL extension section %s\n",
1153 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1155 if (!crldays && !crlhours)
1157 crldays=CONF_get_number(conf,section,
1158 ENV_DEFAULT_CRL_DAYS);
1159 crlhours=CONF_get_number(conf,section,
1160 ENV_DEFAULT_CRL_HOURS);
1162 if ((crldays == 0) && (crlhours == 0))
1164 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1168 if (verbose) BIO_printf(bio_err,"making CRL\n");
1169 if ((crl=X509_CRL_new()) == NULL) goto err;
1171 X509_NAME_free(ci->issuer);
1172 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1173 if (ci->issuer == NULL) goto err;
1175 X509_gmtime_adj(ci->lastUpdate,0);
1176 if (ci->nextUpdate == NULL)
1177 ci->nextUpdate=ASN1_UTCTIME_new();
1178 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1180 for (i=0; i<sk_num(db->data); i++)
1182 pp=(char **)sk_value(db->data,i);
1183 if (pp[DB_type][0] == DB_TYPE_REV)
1185 if ((r=X509_REVOKED_new()) == NULL) goto err;
1186 ASN1_STRING_set((ASN1_STRING *)
1188 (unsigned char *)pp[DB_rev_date],
1189 strlen(pp[DB_rev_date]));
1190 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1192 (void)BIO_reset(hex);
1193 if (!BIO_puts(hex,pp[DB_serial]))
1195 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1196 buf[0],BSIZE)) goto err;
1198 sk_X509_REVOKED_push(ci->revoked,r);
1201 /* sort the data so it will be written in serial
1203 sk_X509_REVOKED_sort(ci->revoked);
1204 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1206 r=sk_X509_REVOKED_value(ci->revoked,i);
1210 /* we now have a CRL */
1211 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1214 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1216 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1223 if (pkey->type == EVP_PKEY_DSA)
1230 /* Add any extensions asked for */
1234 if (ci->version == NULL)
1235 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1236 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1237 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1238 X509V3_set_conf_lhash(&crlctx, conf);
1240 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1241 crl_ext, crl)) goto err;
1244 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1246 PEM_write_bio_X509_CRL(Sout,crl);
1248 /*****************************************************************/
1253 BIO_printf(bio_err,"no input files\n");
1259 if (BIO_read_filename(in,infile) <= 0)
1262 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1265 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1266 if (revcert == NULL)
1268 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1271 j=do_revoke(revcert,db);
1272 if (j <= 0) goto err;
1275 strncpy(buf[0],dbfile,BSIZE-4);
1276 strcat(buf[0],".new");
1277 if (BIO_write_filename(out,buf[0]) <= 0)
1280 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1283 j=TXT_DB_write(out,db);
1284 if (j <= 0) goto err;
1285 strncpy(buf[1],dbfile,BSIZE-4);
1286 strcat(buf[1],".old");
1287 if (rename(dbfile,buf[1]) < 0)
1289 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1293 if (rename(buf[0],dbfile) < 0)
1295 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1297 rename(buf[1],dbfile);
1300 BIO_printf(bio_err,"Data Base Updated\n");
1303 /*****************************************************************/
1312 sk_X509_pop_free(cert_sk,X509_free);
1314 if (ret) ERR_print_errors(bio_err);
1315 app_RAND_write_file(randfile, bio_err);
1318 EVP_PKEY_free(pkey);
1326 static void lookup_fail(char *name, char *tag)
1328 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1331 static unsigned long index_serial_hash(char **a)
1336 while (*n == '0') n++;
1337 return(lh_strhash(n));
1340 static int index_serial_cmp(char **a, char **b)
1344 for (aa=a[DB_serial]; *aa == '0'; aa++);
1345 for (bb=b[DB_serial]; *bb == '0'; bb++);
1346 return(strcmp(aa,bb));
1349 static unsigned long index_name_hash(char **a)
1350 { return(lh_strhash(a[DB_name])); }
1352 static int index_name_qual(char **a)
1353 { return(a[0][0] == 'V'); }
1355 static int index_name_cmp(char **a, char **b)
1356 { return(strcmp(a[DB_name],
1359 static BIGNUM *load_serial(char *serialfile)
1363 MS_STATIC char buf[1024];
1364 ASN1_INTEGER *ai=NULL;
1366 if ((in=BIO_new(BIO_s_file())) == NULL)
1368 ERR_print_errors(bio_err);
1372 if (BIO_read_filename(in,serialfile) <= 0)
1377 ai=ASN1_INTEGER_new();
1378 if (ai == NULL) goto err;
1379 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1381 BIO_printf(bio_err,"unable to load number from %s\n",
1385 ret=ASN1_INTEGER_to_BN(ai,NULL);
1388 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1392 if (in != NULL) BIO_free(in);
1393 if (ai != NULL) ASN1_INTEGER_free(ai);
1397 static int save_serial(char *serialfile, BIGNUM *serial)
1401 ASN1_INTEGER *ai=NULL;
1403 out=BIO_new(BIO_s_file());
1406 ERR_print_errors(bio_err);
1409 if (BIO_write_filename(out,serialfile) <= 0)
1415 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1417 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1420 i2a_ASN1_INTEGER(out,ai);
1424 if (out != NULL) BIO_free_all(out);
1425 if (ai != NULL) ASN1_INTEGER_free(ai);
1429 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1430 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1431 BIGNUM *serial, char *startdate, char *enddate, int days,
1432 int batch, char *ext_sect, LHASH *lconf, int verbose)
1436 EVP_PKEY *pktmp=NULL;
1439 in=BIO_new(BIO_s_file());
1441 if (BIO_read_filename(in,infile) <= 0)
1446 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1448 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1453 X509_REQ_print(bio_err,req);
1455 BIO_printf(bio_err,"Check that the request matches the signature\n");
1457 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1459 BIO_printf(bio_err,"error unpacking public key\n");
1462 i=X509_REQ_verify(req,pktmp);
1463 EVP_PKEY_free(pktmp);
1467 BIO_printf(bio_err,"Signature verification problems....\n");
1473 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1477 BIO_printf(bio_err,"Signature ok\n");
1479 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1480 days,batch,verbose,req,ext_sect,lconf);
1483 if (req != NULL) X509_REQ_free(req);
1484 if (in != NULL) BIO_free(in);
1488 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1489 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1490 BIGNUM *serial, char *startdate, char *enddate, int days,
1491 int batch, char *ext_sect, LHASH *lconf, int verbose)
1494 X509_REQ *rreq=NULL;
1496 EVP_PKEY *pktmp=NULL;
1499 in=BIO_new(BIO_s_file());
1501 if (BIO_read_filename(in,infile) <= 0)
1506 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1508 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1512 X509_print(bio_err,req);
1514 BIO_printf(bio_err,"Check that the request matches the signature\n");
1516 if ((pktmp=X509_get_pubkey(req)) == NULL)
1518 BIO_printf(bio_err,"error unpacking public key\n");
1521 i=X509_verify(req,pktmp);
1522 EVP_PKEY_free(pktmp);
1526 BIO_printf(bio_err,"Signature verification problems....\n");
1532 BIO_printf(bio_err,"Signature did not match the certificate\n");
1536 BIO_printf(bio_err,"Signature ok\n");
1538 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1541 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1542 batch,verbose,rreq,ext_sect,lconf);
1545 if (rreq != NULL) X509_REQ_free(rreq);
1546 if (req != NULL) X509_free(req);
1547 if (in != NULL) BIO_free(in);
1551 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1552 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1553 char *startdate, char *enddate, int days, int batch, int verbose,
1554 X509_REQ *req, char *ext_sect, LHASH *lconf)
1556 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1557 ASN1_UTCTIME *tm,*tmptm;
1558 ASN1_STRING *str,*str2;
1562 X509_NAME_ENTRY *ne;
1563 X509_NAME_ENTRY *tne,*push;
1565 int ok= -1,i,j,last,nid;
1568 char *row[DB_NUMBER],**rrow,**irow=NULL;
1571 tmptm=ASN1_UTCTIME_new();
1574 BIO_printf(bio_err,"malloc error\n");
1578 for (i=0; i<DB_NUMBER; i++)
1581 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1582 name=X509_REQ_get_subject_name(req);
1583 for (i=0; i<X509_NAME_entry_count(name); i++)
1585 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1586 obj=X509_NAME_ENTRY_get_object(ne);
1587 j=i2a_ASN1_OBJECT(bio_err,obj);
1588 str=X509_NAME_ENTRY_get_data(ne);
1590 for (j=22-j; j>0; j--)
1594 BIO_puts(bio_err,buf);
1598 /* assume all type should be strings */
1599 nid=OBJ_obj2nid(ne->object);
1601 if (str->type == V_ASN1_UNIVERSALSTRING)
1602 ASN1_UNIVERSALSTRING_to_string(str);
1604 if ((str->type == V_ASN1_IA5STRING) &&
1605 (nid != NID_pkcs9_emailAddress))
1606 str->type=V_ASN1_T61STRING;
1608 if ((nid == NID_pkcs9_emailAddress) &&
1609 (str->type == V_ASN1_PRINTABLESTRING))
1610 str->type=V_ASN1_IA5STRING;
1613 if (str->type == V_ASN1_PRINTABLESTRING)
1614 BIO_printf(bio_err,"PRINTABLE:'");
1615 else if (str->type == V_ASN1_T61STRING)
1616 BIO_printf(bio_err,"T61STRING:'");
1617 else if (str->type == V_ASN1_IA5STRING)
1618 BIO_printf(bio_err,"IA5STRING:'");
1619 else if (str->type == V_ASN1_UNIVERSALSTRING)
1620 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1622 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1624 /* check some things */
1625 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1626 (str->type != V_ASN1_IA5STRING))
1628 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1631 j=ASN1_PRINTABLE_type(str->data,str->length);
1632 if ( ((j == V_ASN1_T61STRING) &&
1633 (str->type != V_ASN1_T61STRING)) ||
1634 ((j == V_ASN1_IA5STRING) &&
1635 (str->type == V_ASN1_PRINTABLESTRING)))
1637 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1641 p=(char *)str->data;
1642 for (j=str->length; j>0; j--)
1644 if ((*p >= ' ') && (*p <= '~'))
1645 BIO_printf(bio_err,"%c",*p);
1647 BIO_printf(bio_err,"\\0x%02X",*p);
1648 else if ((unsigned char)*p == 0xf7)
1649 BIO_printf(bio_err,"^?");
1650 else BIO_printf(bio_err,"^%c",*p+'@');
1653 BIO_printf(bio_err,"'\n");
1656 /* Ok, now we check the 'policy' stuff. */
1657 if ((subject=X509_NAME_new()) == NULL)
1659 BIO_printf(bio_err,"Memory allocation failure\n");
1663 /* take a copy of the issuer name before we mess with it. */
1664 CAname=X509_NAME_dup(x509->cert_info->subject);
1665 if (CAname == NULL) goto err;
1668 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1670 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1671 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1673 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1681 /* lookup the object in the supplied name list */
1682 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1685 if (last != -1) break;
1690 tne=X509_NAME_get_entry(name,j);
1694 /* depending on the 'policy', decide what to do. */
1696 if (strcmp(cv->value,"optional") == 0)
1701 else if (strcmp(cv->value,"supplied") == 0)
1705 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1711 else if (strcmp(cv->value,"match") == 0)
1717 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1724 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1725 if ((j < 0) && (last2 == -1))
1727 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1732 push=X509_NAME_get_entry(CAname,j);
1733 str=X509_NAME_ENTRY_get_data(tne);
1734 str2=X509_NAME_ENTRY_get_data(push);
1736 if (ASN1_STRING_cmp(str,str2) != 0)
1741 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));
1747 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1753 if (!X509_NAME_add_entry(subject,push, -1, 0))
1756 X509_NAME_ENTRY_free(push);
1757 BIO_printf(bio_err,"Memory allocation failure\n");
1767 X509_NAME_free(subject);
1768 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1769 if (subject == NULL) goto err;
1773 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1775 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1776 row[DB_serial]=BN_bn2hex(serial);
1777 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1779 BIO_printf(bio_err,"Memory allocation failure\n");
1783 rrow=TXT_DB_get_by_index(db,DB_name,row);
1786 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1791 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1794 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1796 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1803 "The matching entry has the following details\n");
1804 if (rrow[DB_type][0] == 'E')
1806 else if (rrow[DB_type][0] == 'R')
1808 else if (rrow[DB_type][0] == 'V')
1811 p="\ninvalid type, Data base error\n";
1812 BIO_printf(bio_err,"Type :%s\n",p);;
1813 if (rrow[DB_type][0] == 'R')
1815 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1816 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1818 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1819 BIO_printf(bio_err,"Expires on :%s\n",p);
1820 p=rrow[DB_serial]; if (p == NULL) p="undef";
1821 BIO_printf(bio_err,"Serial Number :%s\n",p);
1822 p=rrow[DB_file]; if (p == NULL) p="undef";
1823 BIO_printf(bio_err,"File name :%s\n",p);
1824 p=rrow[DB_name]; if (p == NULL) p="undef";
1825 BIO_printf(bio_err,"Subject Name :%s\n",p);
1826 ok= -1; /* This is now a 'bad' error. */
1830 /* We are now totally happy, lets make and sign the certificate */
1832 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1834 if ((ret=X509_new()) == NULL) goto err;
1838 /* Make it an X509 v3 certificate. */
1839 if (!X509_set_version(x509,2)) goto err;
1842 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1844 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1847 BIO_printf(bio_err,"Certificate is to be certified until ");
1848 if (strcmp(startdate,"today") == 0)
1849 X509_gmtime_adj(X509_get_notBefore(ret),0);
1850 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1852 if (enddate == NULL)
1853 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1854 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1856 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1857 if(days) BIO_printf(bio_err," (%d days)",days);
1858 BIO_printf(bio_err, "\n");
1860 if (!X509_set_subject_name(ret,subject)) goto err;
1862 pktmp=X509_REQ_get_pubkey(req);
1863 i = X509_set_pubkey(ret,pktmp);
1864 EVP_PKEY_free(pktmp);
1867 /* Lets add the extensions, if there are any */
1871 if (ci->version == NULL)
1872 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1874 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1876 /* Free the current entries if any, there should not
1877 * be any I believe */
1878 if (ci->extensions != NULL)
1879 sk_X509_EXTENSION_pop_free(ci->extensions,
1880 X509_EXTENSION_free);
1882 ci->extensions = NULL;
1884 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1885 X509V3_set_conf_lhash(&ctx, lconf);
1887 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1894 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1895 (void)BIO_flush(bio_err);
1897 fgets(buf,sizeof(buf)-1,stdin);
1898 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1900 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1908 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1909 pktmp=X509_get_pubkey(ret);
1910 if (EVP_PKEY_missing_parameters(pktmp) &&
1911 !EVP_PKEY_missing_parameters(pkey))
1912 EVP_PKEY_copy_parameters(pktmp,pkey);
1913 EVP_PKEY_free(pktmp);
1916 if (!X509_sign(ret,pkey,dgst))
1919 /* We now just add it to the database */
1920 row[DB_type]=(char *)OPENSSL_malloc(2);
1922 tm=X509_get_notAfter(ret);
1923 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1924 memcpy(row[DB_exp_date],tm->data,tm->length);
1925 row[DB_exp_date][tm->length]='\0';
1927 row[DB_rev_date]=NULL;
1929 /* row[DB_serial] done already */
1930 row[DB_file]=(char *)OPENSSL_malloc(8);
1931 /* row[DB_name] done already */
1933 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1934 (row[DB_file] == NULL))
1936 BIO_printf(bio_err,"Memory allocation failure\n");
1939 strcpy(row[DB_file],"unknown");
1940 row[DB_type][0]='V';
1941 row[DB_type][1]='\0';
1943 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1945 BIO_printf(bio_err,"Memory allocation failure\n");
1949 for (i=0; i<DB_NUMBER; i++)
1954 irow[DB_NUMBER]=NULL;
1956 if (!TXT_DB_insert(db,irow))
1958 BIO_printf(bio_err,"failed to update database\n");
1959 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1964 for (i=0; i<DB_NUMBER; i++)
1965 if (row[i] != NULL) OPENSSL_free(row[i]);
1968 X509_NAME_free(CAname);
1969 if (subject != NULL)
1970 X509_NAME_free(subject);
1972 ASN1_UTCTIME_free(tmptm);
1975 if (ret != NULL) X509_free(ret);
1983 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1988 (void)i2d_X509_bio(bp,x);
1992 /* ??? Not needed since X509_print prints all this stuff anyway */
1993 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1994 BIO_printf(bp,"issuer :%s\n",f);
1996 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1997 BIO_printf(bp,"subject:%s\n",f);
1999 BIO_puts(bp,"serial :");
2000 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2001 BIO_puts(bp,"\n\n");
2003 if(!notext)X509_print(bp,x);
2004 PEM_write_bio_X509(bp,x);
2007 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2008 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2009 BIGNUM *serial, char *startdate, char *enddate, int days,
2010 char *ext_sect, LHASH *lconf, int verbose)
2012 STACK_OF(CONF_VALUE) *sk=NULL;
2015 CONF_VALUE *cv=NULL;
2016 NETSCAPE_SPKI *spki = NULL;
2019 EVP_PKEY *pktmp=NULL;
2021 X509_NAME_ENTRY *ne=NULL;
2027 * Load input file into a hash table. (This is just an easy
2028 * way to read and parse the file, then put it into a convenient
2031 parms=CONF_load(NULL,infile,&errline);
2034 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2035 ERR_print_errors(bio_err);
2039 sk=CONF_get_section(parms, "default");
2040 if (sk_CONF_VALUE_num(sk) == 0)
2042 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2048 * Now create a dummy X509 request structure. We don't actually
2049 * have an X509 request, but we have many of the components
2050 * (a public key, various DN components). The idea is that we
2051 * put these components into the right X509 request structure
2052 * and we can use the same code as if you had a real X509 request.
2057 ERR_print_errors(bio_err);
2062 * Build up the subject name set.
2069 if (sk_CONF_VALUE_num(sk) <= i) break;
2071 cv=sk_CONF_VALUE_value(sk,i);
2073 /* Skip past any leading X. X: X, etc to allow for
2074 * multiple instances
2076 for(buf = cv->name; *buf ; buf++)
2077 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2079 if(*buf) type = buf;
2084 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2086 if (strcmp(type, "SPKAC") == 0)
2088 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2091 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2092 ERR_print_errors(bio_err);
2099 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2100 if (fix_data(nid, &j) == 0)
2103 "invalid characters in string %s\n",buf);
2107 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2108 (unsigned char *)buf,
2109 strlen(buf))) == NULL)
2112 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2116 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2122 * Now extract the key from the SPKI structure.
2125 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2127 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2129 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2133 j = NETSCAPE_SPKI_verify(spki, pktmp);
2136 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2139 BIO_printf(bio_err,"Signature ok\n");
2141 X509_REQ_set_pubkey(req,pktmp);
2142 EVP_PKEY_free(pktmp);
2143 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2144 days,1,verbose,req,ext_sect,lconf);
2146 if (req != NULL) X509_REQ_free(req);
2147 if (parms != NULL) CONF_free(parms);
2148 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2149 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2154 static int fix_data(int nid, int *type)
2156 if (nid == NID_pkcs9_emailAddress)
2157 *type=V_ASN1_IA5STRING;
2158 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2159 *type=V_ASN1_T61STRING;
2160 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2161 *type=V_ASN1_T61STRING;
2162 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2164 if (nid == NID_pkcs9_unstructuredName)
2165 *type=V_ASN1_IA5STRING;
2169 static int check_time_format(char *str)
2173 tm.data=(unsigned char *)str;
2174 tm.length=strlen(str);
2175 tm.type=V_ASN1_UTCTIME;
2176 return(ASN1_UTCTIME_check(&tm));
2179 static int do_revoke(X509 *x509, TXT_DB *db)
2181 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2182 char *row[DB_NUMBER],**rrow,**irow;
2186 for (i=0; i<DB_NUMBER; i++)
2188 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2189 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2190 row[DB_serial]=BN_bn2hex(bn);
2192 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2194 BIO_printf(bio_err,"Memory allocation failure\n");
2197 /* We have to lookup by serial number because name lookup
2198 * skips revoked certs
2200 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2203 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2205 /* We now just add it to the database */
2206 row[DB_type]=(char *)OPENSSL_malloc(2);
2208 tm=X509_get_notAfter(x509);
2209 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2210 memcpy(row[DB_exp_date],tm->data,tm->length);
2211 row[DB_exp_date][tm->length]='\0';
2213 row[DB_rev_date]=NULL;
2215 /* row[DB_serial] done already */
2216 row[DB_file]=(char *)OPENSSL_malloc(8);
2218 /* row[DB_name] done already */
2220 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2221 (row[DB_file] == NULL))
2223 BIO_printf(bio_err,"Memory allocation failure\n");
2226 strcpy(row[DB_file],"unknown");
2227 row[DB_type][0]='V';
2228 row[DB_type][1]='\0';
2230 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2232 BIO_printf(bio_err,"Memory allocation failure\n");
2236 for (i=0; i<DB_NUMBER; i++)
2241 irow[DB_NUMBER]=NULL;
2243 if (!TXT_DB_insert(db,irow))
2245 BIO_printf(bio_err,"failed to update database\n");
2246 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2250 /* Revoke Certificate */
2251 ok = do_revoke(x509,db);
2256 else if (index_name_cmp(row,rrow))
2258 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2262 else if (rrow[DB_type][0]=='R')
2264 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2270 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2271 revtm = ASN1_UTCTIME_new();
2272 revtm=X509_gmtime_adj(revtm,0);
2273 rrow[DB_type][0]='R';
2274 rrow[DB_type][1]='\0';
2275 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2276 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2277 rrow[DB_rev_date][revtm->length]='\0';
2278 ASN1_UTCTIME_free(revtm);
2282 for (i=0; i<DB_NUMBER; i++)
2285 OPENSSL_free(row[i]);