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,index_serial_hash,
759 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
763 if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
766 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
767 db->error,db->arg1,db->arg2);
771 /*****************************************************************/
777 if (BIO_write_filename(Sout,outfile) <= 0)
785 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
788 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
789 Sout = BIO_push(tmpbio, Sout);
797 if ((md == NULL) && ((md=CONF_get_string(conf,
798 section,ENV_DEFAULT_MD)) == NULL))
800 lookup_fail(section,ENV_DEFAULT_MD);
803 if ((dgst=EVP_get_digestbyname(md)) == NULL)
805 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
809 BIO_printf(bio_err,"message digest is %s\n",
810 OBJ_nid2ln(dgst->type));
811 if ((policy == NULL) && ((policy=CONF_get_string(conf,
812 section,ENV_POLICY)) == NULL))
814 lookup_fail(section,ENV_POLICY);
818 BIO_printf(bio_err,"policy is %s\n",policy);
820 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
823 lookup_fail(section,ENV_SERIAL);
827 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
829 /* Check syntax of file */
831 X509V3_set_ctx_test(&ctx);
832 X509V3_set_conf_lhash(&ctx, conf);
833 if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
835 "Error Loading extension section %s\n",
842 if (startdate == NULL)
844 startdate=CONF_get_string(conf,section,
845 ENV_DEFAULT_STARTDATE);
847 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
849 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
852 if (startdate == NULL) startdate="today";
856 enddate=CONF_get_string(conf,section,
857 ENV_DEFAULT_ENDDATE);
859 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
861 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
867 days=(int)CONF_get_number(conf,section,
870 if (!enddate && (days == 0))
872 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
876 if ((serial=load_serial(serialfile)) == NULL)
878 BIO_printf(bio_err,"error while loading serial number\n");
883 if ((f=BN_bn2hex(serial)) == NULL) goto err;
884 BIO_printf(bio_err,"next serial number is %s\n",f);
888 if ((attribs=CONF_get_section(conf,policy)) == NULL)
890 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
894 if ((cert_sk=sk_X509_new_null()) == NULL)
896 BIO_printf(bio_err,"Memory allocation failure\n");
899 if (spkac_file != NULL)
902 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
903 serial,startdate,enddate, days,extensions,conf,
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");
923 if (ss_cert_file != NULL)
926 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
927 db,serial,startdate,enddate,days,batch,
928 extensions,conf,verbose);
933 BIO_printf(bio_err,"\n");
934 if (!BN_add_word(serial,1)) goto err;
935 if (!sk_X509_push(cert_sk,x))
937 BIO_printf(bio_err,"Memory allocation failure\n");
945 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
946 serial,startdate,enddate,days,batch,
947 extensions,conf,verbose);
952 BIO_printf(bio_err,"\n");
953 if (!BN_add_word(serial,1)) goto err;
954 if (!sk_X509_push(cert_sk,x))
956 BIO_printf(bio_err,"Memory allocation failure\n");
961 for (i=0; i<argc; i++)
964 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
965 serial,startdate,enddate,days,batch,
966 extensions,conf,verbose);
971 BIO_printf(bio_err,"\n");
972 if (!BN_add_word(serial,1)) goto err;
973 if (!sk_X509_push(cert_sk,x))
975 BIO_printf(bio_err,"Memory allocation failure\n");
980 /* we have a stack of newly certified certificates
981 * and a data base and serial number that need
984 if (sk_X509_num(cert_sk) > 0)
988 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
989 (void)BIO_flush(bio_err);
991 fgets(buf[0],10,stdin);
992 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
994 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1000 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1002 strncpy(buf[0],serialfile,BSIZE-4);
1005 strcat(buf[0],"-new");
1007 strcat(buf[0],".new");
1010 if (!save_serial(buf[0],serial)) goto err;
1012 strncpy(buf[1],dbfile,BSIZE-4);
1015 strcat(buf[1],"-new");
1017 strcat(buf[1],".new");
1020 if (BIO_write_filename(out,buf[1]) <= 0)
1023 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1026 l=TXT_DB_write(out,db);
1027 if (l <= 0) goto err;
1031 BIO_printf(bio_err,"writing new certificates\n");
1032 for (i=0; i<sk_X509_num(cert_sk); i++)
1037 x=sk_X509_value(cert_sk,i);
1039 j=x->cert_info->serialNumber->length;
1040 p=(char *)x->cert_info->serialNumber->data;
1042 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1048 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1053 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1062 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1065 BIO_printf(bio_err,"writing %s\n",buf[2]);
1067 if (BIO_write_filename(Cout,buf[2]) <= 0)
1072 write_new_certificate(Cout,x, 0, notext);
1073 write_new_certificate(Sout,x, output_der, notext);
1076 if (sk_X509_num(cert_sk))
1078 /* Rename the database and the serial file */
1079 strncpy(buf[2],serialfile,BSIZE-4);
1082 strcat(buf[2],"-old");
1084 strcat(buf[2],".old");
1091 if (rename(serialfile,buf[2]) < 0)
1093 BIO_printf(bio_err,"unable to rename %s to %s\n",
1098 if (rename(buf[0],serialfile) < 0)
1100 BIO_printf(bio_err,"unable to rename %s to %s\n",
1103 rename(buf[2],serialfile);
1107 strncpy(buf[2],dbfile,BSIZE-4);
1110 strcat(buf[2],"-old");
1112 strcat(buf[2],".old");
1115 if (rename(dbfile,buf[2]) < 0)
1117 BIO_printf(bio_err,"unable to rename %s to %s\n",
1122 if (rename(buf[1],dbfile) < 0)
1124 BIO_printf(bio_err,"unable to rename %s to %s\n",
1127 rename(buf[2],dbfile);
1130 BIO_printf(bio_err,"Data Base Updated\n");
1134 /*****************************************************************/
1137 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1139 /* Check syntax of file */
1141 X509V3_set_ctx_test(&ctx);
1142 X509V3_set_conf_lhash(&ctx, conf);
1143 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1145 "Error Loading CRL extension section %s\n",
1151 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1153 if (!crldays && !crlhours)
1155 crldays=CONF_get_number(conf,section,
1156 ENV_DEFAULT_CRL_DAYS);
1157 crlhours=CONF_get_number(conf,section,
1158 ENV_DEFAULT_CRL_HOURS);
1160 if ((crldays == 0) && (crlhours == 0))
1162 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1166 if (verbose) BIO_printf(bio_err,"making CRL\n");
1167 if ((crl=X509_CRL_new()) == NULL) goto err;
1169 X509_NAME_free(ci->issuer);
1170 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1171 if (ci->issuer == NULL) goto err;
1173 X509_gmtime_adj(ci->lastUpdate,0);
1174 if (ci->nextUpdate == NULL)
1175 ci->nextUpdate=ASN1_UTCTIME_new();
1176 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1178 for (i=0; i<sk_num(db->data); i++)
1180 pp=(char **)sk_value(db->data,i);
1181 if (pp[DB_type][0] == DB_TYPE_REV)
1183 if ((r=X509_REVOKED_new()) == NULL) goto err;
1184 ASN1_STRING_set((ASN1_STRING *)
1186 (unsigned char *)pp[DB_rev_date],
1187 strlen(pp[DB_rev_date]));
1188 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1190 (void)BIO_reset(hex);
1191 if (!BIO_puts(hex,pp[DB_serial]))
1193 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1194 buf[0],BSIZE)) goto err;
1196 sk_X509_REVOKED_push(ci->revoked,r);
1199 /* sort the data so it will be written in serial
1201 sk_X509_REVOKED_sort(ci->revoked);
1202 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1204 r=sk_X509_REVOKED_value(ci->revoked,i);
1208 /* we now have a CRL */
1209 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1212 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1214 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1221 if (pkey->type == EVP_PKEY_DSA)
1228 /* Add any extensions asked for */
1232 if (ci->version == NULL)
1233 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1234 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1235 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1236 X509V3_set_conf_lhash(&crlctx, conf);
1238 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1239 crl_ext, crl)) goto err;
1242 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1244 PEM_write_bio_X509_CRL(Sout,crl);
1246 /*****************************************************************/
1251 BIO_printf(bio_err,"no input files\n");
1257 if (BIO_read_filename(in,infile) <= 0)
1260 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1263 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1264 if (revcert == NULL)
1266 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1269 j=do_revoke(revcert,db);
1270 if (j <= 0) goto err;
1273 strncpy(buf[0],dbfile,BSIZE-4);
1274 strcat(buf[0],".new");
1275 if (BIO_write_filename(out,buf[0]) <= 0)
1278 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1281 j=TXT_DB_write(out,db);
1282 if (j <= 0) goto err;
1283 strncpy(buf[1],dbfile,BSIZE-4);
1284 strcat(buf[1],".old");
1285 if (rename(dbfile,buf[1]) < 0)
1287 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1291 if (rename(buf[0],dbfile) < 0)
1293 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1295 rename(buf[1],dbfile);
1298 BIO_printf(bio_err,"Data Base Updated\n");
1301 /*****************************************************************/
1310 sk_X509_pop_free(cert_sk,X509_free);
1312 if (ret) ERR_print_errors(bio_err);
1313 app_RAND_write_file(randfile, bio_err);
1316 EVP_PKEY_free(pkey);
1324 static void lookup_fail(char *name, char *tag)
1326 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1329 static unsigned long index_serial_hash(char **a)
1334 while (*n == '0') n++;
1335 return(lh_strhash(n));
1338 static int index_serial_cmp(char **a, char **b)
1342 for (aa=a[DB_serial]; *aa == '0'; aa++);
1343 for (bb=b[DB_serial]; *bb == '0'; bb++);
1344 return(strcmp(aa,bb));
1347 static unsigned long index_name_hash(char **a)
1348 { return(lh_strhash(a[DB_name])); }
1350 static int index_name_qual(char **a)
1351 { return(a[0][0] == 'V'); }
1353 static int index_name_cmp(char **a, char **b)
1354 { return(strcmp(a[DB_name],
1357 static BIGNUM *load_serial(char *serialfile)
1361 MS_STATIC char buf[1024];
1362 ASN1_INTEGER *ai=NULL;
1364 if ((in=BIO_new(BIO_s_file())) == NULL)
1366 ERR_print_errors(bio_err);
1370 if (BIO_read_filename(in,serialfile) <= 0)
1375 ai=ASN1_INTEGER_new();
1376 if (ai == NULL) goto err;
1377 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1379 BIO_printf(bio_err,"unable to load number from %s\n",
1383 ret=ASN1_INTEGER_to_BN(ai,NULL);
1386 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1390 if (in != NULL) BIO_free(in);
1391 if (ai != NULL) ASN1_INTEGER_free(ai);
1395 static int save_serial(char *serialfile, BIGNUM *serial)
1399 ASN1_INTEGER *ai=NULL;
1401 out=BIO_new(BIO_s_file());
1404 ERR_print_errors(bio_err);
1407 if (BIO_write_filename(out,serialfile) <= 0)
1413 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1415 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1418 i2a_ASN1_INTEGER(out,ai);
1422 if (out != NULL) BIO_free_all(out);
1423 if (ai != NULL) ASN1_INTEGER_free(ai);
1427 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1428 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1429 BIGNUM *serial, char *startdate, char *enddate, int days,
1430 int batch, char *ext_sect, LHASH *lconf, int verbose)
1434 EVP_PKEY *pktmp=NULL;
1437 in=BIO_new(BIO_s_file());
1439 if (BIO_read_filename(in,infile) <= 0)
1444 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1446 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1451 X509_REQ_print(bio_err,req);
1453 BIO_printf(bio_err,"Check that the request matches the signature\n");
1455 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1457 BIO_printf(bio_err,"error unpacking public key\n");
1460 i=X509_REQ_verify(req,pktmp);
1461 EVP_PKEY_free(pktmp);
1465 BIO_printf(bio_err,"Signature verification problems....\n");
1471 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1475 BIO_printf(bio_err,"Signature ok\n");
1477 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1478 days,batch,verbose,req,ext_sect,lconf);
1481 if (req != NULL) X509_REQ_free(req);
1482 if (in != NULL) BIO_free(in);
1486 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1487 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1488 BIGNUM *serial, char *startdate, char *enddate, int days,
1489 int batch, char *ext_sect, LHASH *lconf, int verbose)
1492 X509_REQ *rreq=NULL;
1494 EVP_PKEY *pktmp=NULL;
1497 in=BIO_new(BIO_s_file());
1499 if (BIO_read_filename(in,infile) <= 0)
1504 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1506 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1510 X509_print(bio_err,req);
1512 BIO_printf(bio_err,"Check that the request matches the signature\n");
1514 if ((pktmp=X509_get_pubkey(req)) == NULL)
1516 BIO_printf(bio_err,"error unpacking public key\n");
1519 i=X509_verify(req,pktmp);
1520 EVP_PKEY_free(pktmp);
1524 BIO_printf(bio_err,"Signature verification problems....\n");
1530 BIO_printf(bio_err,"Signature did not match the certificate\n");
1534 BIO_printf(bio_err,"Signature ok\n");
1536 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1539 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1540 batch,verbose,rreq,ext_sect,lconf);
1543 if (rreq != NULL) X509_REQ_free(rreq);
1544 if (req != NULL) X509_free(req);
1545 if (in != NULL) BIO_free(in);
1549 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1550 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1551 char *startdate, char *enddate, int days, int batch, int verbose,
1552 X509_REQ *req, char *ext_sect, LHASH *lconf)
1554 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1555 ASN1_UTCTIME *tm,*tmptm;
1556 ASN1_STRING *str,*str2;
1560 X509_NAME_ENTRY *ne;
1561 X509_NAME_ENTRY *tne,*push;
1563 int ok= -1,i,j,last,nid;
1566 char *row[DB_NUMBER],**rrow,**irow=NULL;
1569 tmptm=ASN1_UTCTIME_new();
1572 BIO_printf(bio_err,"malloc error\n");
1576 for (i=0; i<DB_NUMBER; i++)
1579 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1580 name=X509_REQ_get_subject_name(req);
1581 for (i=0; i<X509_NAME_entry_count(name); i++)
1583 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1584 obj=X509_NAME_ENTRY_get_object(ne);
1585 j=i2a_ASN1_OBJECT(bio_err,obj);
1586 str=X509_NAME_ENTRY_get_data(ne);
1588 for (j=22-j; j>0; j--)
1592 BIO_puts(bio_err,buf);
1596 /* assume all type should be strings */
1597 nid=OBJ_obj2nid(ne->object);
1599 if (str->type == V_ASN1_UNIVERSALSTRING)
1600 ASN1_UNIVERSALSTRING_to_string(str);
1602 if ((str->type == V_ASN1_IA5STRING) &&
1603 (nid != NID_pkcs9_emailAddress))
1604 str->type=V_ASN1_T61STRING;
1606 if ((nid == NID_pkcs9_emailAddress) &&
1607 (str->type == V_ASN1_PRINTABLESTRING))
1608 str->type=V_ASN1_IA5STRING;
1611 if (str->type == V_ASN1_PRINTABLESTRING)
1612 BIO_printf(bio_err,"PRINTABLE:'");
1613 else if (str->type == V_ASN1_T61STRING)
1614 BIO_printf(bio_err,"T61STRING:'");
1615 else if (str->type == V_ASN1_IA5STRING)
1616 BIO_printf(bio_err,"IA5STRING:'");
1617 else if (str->type == V_ASN1_UNIVERSALSTRING)
1618 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1620 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1622 /* check some things */
1623 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1624 (str->type != V_ASN1_IA5STRING))
1626 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1629 j=ASN1_PRINTABLE_type(str->data,str->length);
1630 if ( ((j == V_ASN1_T61STRING) &&
1631 (str->type != V_ASN1_T61STRING)) ||
1632 ((j == V_ASN1_IA5STRING) &&
1633 (str->type == V_ASN1_PRINTABLESTRING)))
1635 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1639 p=(char *)str->data;
1640 for (j=str->length; j>0; j--)
1642 if ((*p >= ' ') && (*p <= '~'))
1643 BIO_printf(bio_err,"%c",*p);
1645 BIO_printf(bio_err,"\\0x%02X",*p);
1646 else if ((unsigned char)*p == 0xf7)
1647 BIO_printf(bio_err,"^?");
1648 else BIO_printf(bio_err,"^%c",*p+'@');
1651 BIO_printf(bio_err,"'\n");
1654 /* Ok, now we check the 'policy' stuff. */
1655 if ((subject=X509_NAME_new()) == NULL)
1657 BIO_printf(bio_err,"Memory allocation failure\n");
1661 /* take a copy of the issuer name before we mess with it. */
1662 CAname=X509_NAME_dup(x509->cert_info->subject);
1663 if (CAname == NULL) goto err;
1666 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1668 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1669 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1671 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1679 /* lookup the object in the supplied name list */
1680 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1683 if (last != -1) break;
1688 tne=X509_NAME_get_entry(name,j);
1692 /* depending on the 'policy', decide what to do. */
1694 if (strcmp(cv->value,"optional") == 0)
1699 else if (strcmp(cv->value,"supplied") == 0)
1703 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1709 else if (strcmp(cv->value,"match") == 0)
1715 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1722 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1723 if ((j < 0) && (last2 == -1))
1725 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1730 push=X509_NAME_get_entry(CAname,j);
1731 str=X509_NAME_ENTRY_get_data(tne);
1732 str2=X509_NAME_ENTRY_get_data(push);
1734 if (ASN1_STRING_cmp(str,str2) != 0)
1739 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));
1745 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1751 if (!X509_NAME_add_entry(subject,push, -1, 0))
1754 X509_NAME_ENTRY_free(push);
1755 BIO_printf(bio_err,"Memory allocation failure\n");
1765 X509_NAME_free(subject);
1766 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1767 if (subject == NULL) goto err;
1771 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1773 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1774 row[DB_serial]=BN_bn2hex(serial);
1775 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1777 BIO_printf(bio_err,"Memory allocation failure\n");
1781 rrow=TXT_DB_get_by_index(db,DB_name,row);
1784 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1789 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1792 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1794 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1801 "The matching entry has the following details\n");
1802 if (rrow[DB_type][0] == 'E')
1804 else if (rrow[DB_type][0] == 'R')
1806 else if (rrow[DB_type][0] == 'V')
1809 p="\ninvalid type, Data base error\n";
1810 BIO_printf(bio_err,"Type :%s\n",p);;
1811 if (rrow[DB_type][0] == 'R')
1813 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1814 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1816 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1817 BIO_printf(bio_err,"Expires on :%s\n",p);
1818 p=rrow[DB_serial]; if (p == NULL) p="undef";
1819 BIO_printf(bio_err,"Serial Number :%s\n",p);
1820 p=rrow[DB_file]; if (p == NULL) p="undef";
1821 BIO_printf(bio_err,"File name :%s\n",p);
1822 p=rrow[DB_name]; if (p == NULL) p="undef";
1823 BIO_printf(bio_err,"Subject Name :%s\n",p);
1824 ok= -1; /* This is now a 'bad' error. */
1828 /* We are now totally happy, lets make and sign the certificate */
1830 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1832 if ((ret=X509_new()) == NULL) goto err;
1836 /* Make it an X509 v3 certificate. */
1837 if (!X509_set_version(x509,2)) goto err;
1840 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1842 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1845 BIO_printf(bio_err,"Certificate is to be certified until ");
1846 if (strcmp(startdate,"today") == 0)
1847 X509_gmtime_adj(X509_get_notBefore(ret),0);
1848 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1850 if (enddate == NULL)
1851 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1852 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1854 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1855 if(days) BIO_printf(bio_err," (%d days)",days);
1856 BIO_printf(bio_err, "\n");
1858 if (!X509_set_subject_name(ret,subject)) goto err;
1860 pktmp=X509_REQ_get_pubkey(req);
1861 i = X509_set_pubkey(ret,pktmp);
1862 EVP_PKEY_free(pktmp);
1865 /* Lets add the extensions, if there are any */
1869 if (ci->version == NULL)
1870 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1872 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1874 /* Free the current entries if any, there should not
1875 * be any I believe */
1876 if (ci->extensions != NULL)
1877 sk_X509_EXTENSION_pop_free(ci->extensions,
1878 X509_EXTENSION_free);
1880 ci->extensions = NULL;
1882 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1883 X509V3_set_conf_lhash(&ctx, lconf);
1885 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1892 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1893 (void)BIO_flush(bio_err);
1895 fgets(buf,sizeof(buf)-1,stdin);
1896 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1898 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1906 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1907 pktmp=X509_get_pubkey(ret);
1908 if (EVP_PKEY_missing_parameters(pktmp) &&
1909 !EVP_PKEY_missing_parameters(pkey))
1910 EVP_PKEY_copy_parameters(pktmp,pkey);
1911 EVP_PKEY_free(pktmp);
1914 if (!X509_sign(ret,pkey,dgst))
1917 /* We now just add it to the database */
1918 row[DB_type]=(char *)OPENSSL_malloc(2);
1920 tm=X509_get_notAfter(ret);
1921 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1922 memcpy(row[DB_exp_date],tm->data,tm->length);
1923 row[DB_exp_date][tm->length]='\0';
1925 row[DB_rev_date]=NULL;
1927 /* row[DB_serial] done already */
1928 row[DB_file]=(char *)OPENSSL_malloc(8);
1929 /* row[DB_name] done already */
1931 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1932 (row[DB_file] == NULL))
1934 BIO_printf(bio_err,"Memory allocation failure\n");
1937 strcpy(row[DB_file],"unknown");
1938 row[DB_type][0]='V';
1939 row[DB_type][1]='\0';
1941 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1943 BIO_printf(bio_err,"Memory allocation failure\n");
1947 for (i=0; i<DB_NUMBER; i++)
1952 irow[DB_NUMBER]=NULL;
1954 if (!TXT_DB_insert(db,irow))
1956 BIO_printf(bio_err,"failed to update database\n");
1957 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1962 for (i=0; i<DB_NUMBER; i++)
1963 if (row[i] != NULL) OPENSSL_free(row[i]);
1966 X509_NAME_free(CAname);
1967 if (subject != NULL)
1968 X509_NAME_free(subject);
1970 ASN1_UTCTIME_free(tmptm);
1973 if (ret != NULL) X509_free(ret);
1981 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1986 (void)i2d_X509_bio(bp,x);
1990 /* ??? Not needed since X509_print prints all this stuff anyway */
1991 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1992 BIO_printf(bp,"issuer :%s\n",f);
1994 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1995 BIO_printf(bp,"subject:%s\n",f);
1997 BIO_puts(bp,"serial :");
1998 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1999 BIO_puts(bp,"\n\n");
2001 if(!notext)X509_print(bp,x);
2002 PEM_write_bio_X509(bp,x);
2005 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2006 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2007 BIGNUM *serial, char *startdate, char *enddate, int days,
2008 char *ext_sect, LHASH *lconf, int verbose)
2010 STACK_OF(CONF_VALUE) *sk=NULL;
2013 CONF_VALUE *cv=NULL;
2014 NETSCAPE_SPKI *spki = NULL;
2017 EVP_PKEY *pktmp=NULL;
2019 X509_NAME_ENTRY *ne=NULL;
2025 * Load input file into a hash table. (This is just an easy
2026 * way to read and parse the file, then put it into a convenient
2029 parms=CONF_load(NULL,infile,&errline);
2032 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2033 ERR_print_errors(bio_err);
2037 sk=CONF_get_section(parms, "default");
2038 if (sk_CONF_VALUE_num(sk) == 0)
2040 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2046 * Now create a dummy X509 request structure. We don't actually
2047 * have an X509 request, but we have many of the components
2048 * (a public key, various DN components). The idea is that we
2049 * put these components into the right X509 request structure
2050 * and we can use the same code as if you had a real X509 request.
2055 ERR_print_errors(bio_err);
2060 * Build up the subject name set.
2067 if (sk_CONF_VALUE_num(sk) <= i) break;
2069 cv=sk_CONF_VALUE_value(sk,i);
2071 /* Skip past any leading X. X: X, etc to allow for
2072 * multiple instances
2074 for(buf = cv->name; *buf ; buf++)
2075 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2077 if(*buf) type = buf;
2082 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2084 if (strcmp(type, "SPKAC") == 0)
2086 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2089 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2090 ERR_print_errors(bio_err);
2097 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2098 if (fix_data(nid, &j) == 0)
2101 "invalid characters in string %s\n",buf);
2105 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2106 (unsigned char *)buf,
2107 strlen(buf))) == NULL)
2110 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2114 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2120 * Now extract the key from the SPKI structure.
2123 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2125 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2127 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2131 j = NETSCAPE_SPKI_verify(spki, pktmp);
2134 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2137 BIO_printf(bio_err,"Signature ok\n");
2139 X509_REQ_set_pubkey(req,pktmp);
2140 EVP_PKEY_free(pktmp);
2141 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2142 days,1,verbose,req,ext_sect,lconf);
2144 if (req != NULL) X509_REQ_free(req);
2145 if (parms != NULL) CONF_free(parms);
2146 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2147 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2152 static int fix_data(int nid, int *type)
2154 if (nid == NID_pkcs9_emailAddress)
2155 *type=V_ASN1_IA5STRING;
2156 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2157 *type=V_ASN1_T61STRING;
2158 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2159 *type=V_ASN1_T61STRING;
2160 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2162 if (nid == NID_pkcs9_unstructuredName)
2163 *type=V_ASN1_IA5STRING;
2167 static int check_time_format(char *str)
2171 tm.data=(unsigned char *)str;
2172 tm.length=strlen(str);
2173 tm.type=V_ASN1_UTCTIME;
2174 return(ASN1_UTCTIME_check(&tm));
2177 static int do_revoke(X509 *x509, TXT_DB *db)
2179 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2180 char *row[DB_NUMBER],**rrow,**irow;
2184 for (i=0; i<DB_NUMBER; i++)
2186 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2187 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2188 row[DB_serial]=BN_bn2hex(bn);
2190 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2192 BIO_printf(bio_err,"Memory allocation failure\n");
2195 /* We have to lookup by serial number because name lookup
2196 * skips revoked certs
2198 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2201 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2203 /* We now just add it to the database */
2204 row[DB_type]=(char *)OPENSSL_malloc(2);
2206 tm=X509_get_notAfter(x509);
2207 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2208 memcpy(row[DB_exp_date],tm->data,tm->length);
2209 row[DB_exp_date][tm->length]='\0';
2211 row[DB_rev_date]=NULL;
2213 /* row[DB_serial] done already */
2214 row[DB_file]=(char *)OPENSSL_malloc(8);
2216 /* row[DB_name] done already */
2218 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2219 (row[DB_file] == NULL))
2221 BIO_printf(bio_err,"Memory allocation failure\n");
2224 strcpy(row[DB_file],"unknown");
2225 row[DB_type][0]='V';
2226 row[DB_type][1]='\0';
2228 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2230 BIO_printf(bio_err,"Memory allocation failure\n");
2234 for (i=0; i<DB_NUMBER; i++)
2239 irow[DB_NUMBER]=NULL;
2241 if (!TXT_DB_insert(db,irow))
2243 BIO_printf(bio_err,"failed to update database\n");
2244 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2248 /* Revoke Certificate */
2249 ok = do_revoke(x509,db);
2254 else if (index_name_cmp(row,rrow))
2256 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2260 else if (rrow[DB_type][0]=='R')
2262 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2268 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2269 revtm = ASN1_UTCTIME_new();
2270 revtm=X509_gmtime_adj(revtm,0);
2271 rrow[DB_type][0]='R';
2272 rrow[DB_type][1]='\0';
2273 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2274 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2275 rrow[DB_rev_date][revtm->length]='\0';
2276 ASN1_UTCTIME_free(revtm);
2280 for (i=0; i<DB_NUMBER; i++)
2283 OPENSSL_free(row[i]);