2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
59 /* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
64 #include <sys/types.h>
67 #include <openssl/conf.h>
68 #include <openssl/bio.h>
69 #include <openssl/err.h>
70 #include <openssl/bn.h>
71 #include <openssl/txt_db.h>
72 #include <openssl/evp.h>
73 #include <openssl/x509.h>
74 #include <openssl/x509v3.h>
75 #include <openssl/objects.h>
76 #include <openssl/pem.h>
77 #include <openssl/engine.h>
87 # include <sys/file.h>
101 #define BASE_SECTION "ca"
102 #define CONFIG_FILE "openssl.cnf"
104 #define ENV_DEFAULT_CA "default_ca"
106 #define ENV_DIR "dir"
107 #define ENV_CERTS "certs"
108 #define ENV_CRL_DIR "crl_dir"
109 #define ENV_CA_DB "CA_DB"
110 #define ENV_NEW_CERTS_DIR "new_certs_dir"
111 #define ENV_CERTIFICATE "certificate"
112 #define ENV_SERIAL "serial"
113 #define ENV_CRL "crl"
114 #define ENV_PRIVATE_KEY "private_key"
115 #define ENV_RANDFILE "RANDFILE"
116 #define ENV_DEFAULT_DAYS "default_days"
117 #define ENV_DEFAULT_STARTDATE "default_startdate"
118 #define ENV_DEFAULT_ENDDATE "default_enddate"
119 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
120 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
121 #define ENV_DEFAULT_MD "default_md"
122 #define ENV_PRESERVE "preserve"
123 #define ENV_POLICY "policy"
124 #define ENV_EXTENSIONS "x509_extensions"
125 #define ENV_CRLEXT "crl_extensions"
126 #define ENV_MSIE_HACK "msie_hack"
128 #define ENV_DATABASE "database"
131 #define DB_exp_date 1
132 #define DB_rev_date 2
133 #define DB_serial 3 /* index - unique */
135 #define DB_name 5 /* index - unique for active */
138 #define DB_TYPE_REV 'R'
139 #define DB_TYPE_EXP 'E'
140 #define DB_TYPE_VAL 'V'
142 static char *ca_usage[]={
145 " -verbose - Talk alot while doing things\n",
146 " -config file - A config file\n",
147 " -name arg - The particular CA definition to use\n",
148 " -gencrl - Generate a new CRL\n",
149 " -crldays days - Days is when the next CRL is due\n",
150 " -crlhours hours - Hours is when the next CRL is due\n",
151 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
152 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
153 " -days arg - number of days to certify the certificate for\n",
154 " -md arg - md to use, one of md2, md5, sha or sha1\n",
155 " -policy arg - The CA 'policy' to support\n",
156 " -keyfile arg - private key file\n",
157 " -keyform arg - private key file format (PEM or ENGINE)\n",
158 " -key arg - key to decode the private key if it is encrypted\n",
159 " -cert file - The CA certificate\n",
160 " -in file - The input PEM encoded certificate request(s)\n",
161 " -out file - Where to put the output file(s)\n",
162 " -outdir dir - Where to put output certificates\n",
163 " -infiles .... - The last argument, requests to process\n",
164 " -spkac file - File contains DN and signed public key and challenge\n",
165 " -ss_cert file - File contains a self signed cert to sign\n",
166 " -preserveDN - Don't re-order the DN\n",
167 " -batch - Don't ask questions\n",
168 " -msie_hack - msie modifications to handle all those universal strings\n",
169 " -revoke file - Revoke a certificate (given in file)\n",
170 " -extensions .. - Extension section (override value in config file)\n",
171 " -crlexts .. - CRL extension section (override value in config file)\n",
172 " -engine e - use engine e, possibly a hardware device.\n",
177 extern int EF_PROTECT_FREE;
178 extern int EF_PROTECT_BELOW;
179 extern int EF_ALIGNMENT;
182 static void lookup_fail(char *name,char *tag);
183 static unsigned long index_serial_hash(const char **a);
184 static int index_serial_cmp(const char **a, const char **b);
185 static unsigned long index_name_hash(const char **a);
186 static int index_name_qual(char **a);
187 static int index_name_cmp(const char **a,const char **b);
188 static BIGNUM *load_serial(char *serialfile);
189 static int save_serial(char *serialfile, BIGNUM *serial);
190 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
191 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
192 BIGNUM *serial, char *startdate,char *enddate, int days,
193 int batch, char *ext_sect, LHASH *conf,int verbose);
194 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
195 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
196 TXT_DB *db, BIGNUM *serial,char *startdate,
197 char *enddate, int days, int batch, char *ext_sect,
198 LHASH *conf,int verbose);
199 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
200 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
201 TXT_DB *db, BIGNUM *serial,char *startdate,
202 char *enddate, int days, char *ext_sect,LHASH *conf,
204 static int fix_data(int nid, int *type);
205 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
206 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
207 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
208 char *startdate, char *enddate, int days, int batch, int verbose,
209 X509_REQ *req, char *ext_sect, LHASH *conf);
210 static int do_revoke(X509 *x509, TXT_DB *db);
211 static int check_time_format(char *str);
212 static LHASH *conf=NULL;
213 static char *section=NULL;
215 static int preserve=0;
216 static int msie_hack=0;
218 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
219 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
220 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
221 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
224 int MAIN(int, char **);
226 int MAIN(int argc, char **argv)
229 char *key=NULL,*passargin=NULL;
241 char *configfile=NULL;
246 int keyform=FORMAT_PEM;
248 char *spkac_file=NULL;
249 char *ss_cert_file=NULL;
254 char *serialfile=NULL;
255 char *extensions=NULL;
258 char *startdate=NULL;
265 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
269 X509_CRL_INFO *ci=NULL;
270 X509_REVOKED *r=NULL;
274 const EVP_MD *dgst=NULL;
275 STACK_OF(CONF_VALUE) *attribs=NULL;
276 STACK_OF(X509) *cert_sk=NULL;
280 MS_STATIC char buf[3][BSIZE];
299 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
300 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
306 if (strcmp(*argv,"-verbose") == 0)
308 else if (strcmp(*argv,"-config") == 0)
310 if (--argc < 1) goto bad;
311 configfile= *(++argv);
313 else if (strcmp(*argv,"-name") == 0)
315 if (--argc < 1) goto bad;
318 else if (strcmp(*argv,"-startdate") == 0)
320 if (--argc < 1) goto bad;
321 startdate= *(++argv);
323 else if (strcmp(*argv,"-enddate") == 0)
325 if (--argc < 1) goto bad;
328 else if (strcmp(*argv,"-days") == 0)
330 if (--argc < 1) goto bad;
331 days=atoi(*(++argv));
333 else if (strcmp(*argv,"-md") == 0)
335 if (--argc < 1) goto bad;
338 else if (strcmp(*argv,"-policy") == 0)
340 if (--argc < 1) goto bad;
343 else if (strcmp(*argv,"-keyfile") == 0)
345 if (--argc < 1) goto bad;
348 else if (strcmp(*argv,"-keyform") == 0)
350 if (--argc < 1) goto bad;
351 keyform=str2fmt(*(++argv));
353 else if (strcmp(*argv,"-passin") == 0)
355 if (--argc < 1) goto bad;
356 passargin= *(++argv);
358 else if (strcmp(*argv,"-key") == 0)
360 if (--argc < 1) goto bad;
363 else if (strcmp(*argv,"-cert") == 0)
365 if (--argc < 1) goto bad;
368 else if (strcmp(*argv,"-in") == 0)
370 if (--argc < 1) goto bad;
374 else if (strcmp(*argv,"-out") == 0)
376 if (--argc < 1) goto bad;
379 else if (strcmp(*argv,"-outdir") == 0)
381 if (--argc < 1) goto bad;
384 else if (strcmp(*argv,"-notext") == 0)
386 else if (strcmp(*argv,"-batch") == 0)
388 else if (strcmp(*argv,"-preserveDN") == 0)
390 else if (strcmp(*argv,"-gencrl") == 0)
392 else if (strcmp(*argv,"-msie_hack") == 0)
394 else if (strcmp(*argv,"-crldays") == 0)
396 if (--argc < 1) goto bad;
397 crldays= atol(*(++argv));
399 else if (strcmp(*argv,"-crlhours") == 0)
401 if (--argc < 1) goto bad;
402 crlhours= atol(*(++argv));
404 else if (strcmp(*argv,"-infiles") == 0)
411 else if (strcmp(*argv, "-ss_cert") == 0)
413 if (--argc < 1) goto bad;
414 ss_cert_file = *(++argv);
417 else if (strcmp(*argv, "-spkac") == 0)
419 if (--argc < 1) goto bad;
420 spkac_file = *(++argv);
423 else if (strcmp(*argv,"-revoke") == 0)
425 if (--argc < 1) goto bad;
429 else if (strcmp(*argv,"-extensions") == 0)
431 if (--argc < 1) goto bad;
432 extensions= *(++argv);
434 else if (strcmp(*argv,"-crlexts") == 0)
436 if (--argc < 1) goto bad;
439 else if (strcmp(*argv,"-engine") == 0)
441 if (--argc < 1) goto bad;
447 BIO_printf(bio_err,"unknown option %s\n",*argv);
457 for (pp=ca_usage; (*pp != NULL); pp++)
458 BIO_printf(bio_err,*pp);
462 ERR_load_crypto_strings();
466 if((e = ENGINE_by_id(engine)) == NULL)
468 BIO_printf(bio_err,"invalid engine \"%s\"\n",
472 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
474 BIO_printf(bio_err,"can't use that engine\n");
477 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
478 /* Free our "structural" reference. */
482 /*****************************************************************/
483 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
484 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
485 if (configfile == NULL)
487 /* We will just use 'buf[0]' as a temporary buffer. */
489 strncpy(buf[0],X509_get_default_cert_area(),
490 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
492 strncpy(buf[0],X509_get_default_cert_area(),
493 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
496 strcat(buf[0],CONFIG_FILE);
500 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
501 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
504 BIO_printf(bio_err,"error loading the config file '%s'\n",
507 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
508 ,errorline,configfile);
512 /* Lets get the config section we are using */
515 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
518 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
525 p=CONF_get_string(conf,NULL,"oid_file");
532 oid_bio=BIO_new_file(p,"r");
536 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
537 ERR_print_errors(bio_err);
543 OBJ_create_objects(oid_bio);
547 if(!add_oid_section(bio_err,conf))
549 ERR_print_errors(bio_err);
554 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
555 if (randfile == NULL)
557 app_RAND_load_file(randfile, bio_err, 0);
559 in=BIO_new(BIO_s_file());
560 out=BIO_new(BIO_s_file());
561 Sout=BIO_new(BIO_s_file());
562 Cout=BIO_new(BIO_s_file());
563 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
565 ERR_print_errors(bio_err);
569 /*****************************************************************/
570 /* we definitely need an public key, so lets get it */
572 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
573 section,ENV_PRIVATE_KEY)) == NULL))
575 lookup_fail(section,ENV_PRIVATE_KEY);
578 if(!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
580 BIO_printf(bio_err,"Error getting password\n");
583 if (keyform == FORMAT_ENGINE)
587 BIO_printf(bio_err,"no engine specified\n");
590 pkey = ENGINE_load_private_key(e, keyfile, key);
592 else if (keyform == FORMAT_PEM)
594 if (BIO_read_filename(in,keyfile) <= 0)
597 BIO_printf(bio_err,"trying to load CA private key\n");
600 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
604 BIO_printf(bio_err,"bad input format specified for key file\n");
607 if(key) memset(key,0,strlen(key));
610 BIO_printf(bio_err,"unable to load CA private key\n");
614 /*****************************************************************/
615 /* we need a certificate */
616 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
617 section,ENV_CERTIFICATE)) == NULL))
619 lookup_fail(section,ENV_CERTIFICATE);
622 if (BIO_read_filename(in,certfile) <= 0)
625 BIO_printf(bio_err,"trying to load CA certificate\n");
628 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
631 BIO_printf(bio_err,"unable to load CA certificate\n");
635 if (!X509_check_private_key(x509,pkey))
637 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
641 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
644 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
646 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
649 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
652 /*****************************************************************/
653 /* lookup where to write new certificates */
654 if ((outdir == NULL) && (req))
658 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
661 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
664 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
665 filename. In any case, stat(), below, will catch the problem
666 if outdir is not a directory spec, and the fopen() or open()
667 will catch an error if there is no write access.
669 Presumably, this problem could also be solved by using the DEC
670 C routines to convert the directory syntax to Unixly, and give
671 that to access(). However, time's too short to do that just
674 if (access(outdir,R_OK|W_OK|X_OK) != 0)
676 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
681 if (stat(outdir,&sb) != 0)
683 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
688 if (!(sb.st_mode & S_IFDIR))
690 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
698 /*****************************************************************/
699 /* we need to load the database file */
700 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
702 lookup_fail(section,ENV_DATABASE);
705 if (BIO_read_filename(in,dbfile) <= 0)
708 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
711 db=TXT_DB_read(in,DB_NUMBER);
712 if (db == NULL) goto err;
714 /* Lets check some fields */
715 for (i=0; i<sk_num(db->data); i++)
717 pp=(char **)sk_value(db->data,i);
718 if ((pp[DB_type][0] != DB_TYPE_REV) &&
719 (pp[DB_rev_date][0] != '\0'))
721 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
724 if ((pp[DB_type][0] == DB_TYPE_REV) &&
725 !check_time_format(pp[DB_rev_date]))
727 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
731 if (!check_time_format(pp[DB_exp_date]))
733 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
738 if ((j&1) || (j < 2))
740 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
745 if (!( ((*p >= '0') && (*p <= '9')) ||
746 ((*p >= 'A') && (*p <= 'F')) ||
747 ((*p >= 'a') && (*p <= 'f'))) )
749 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);
757 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
760 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
761 out = BIO_push(tmpbio, out);
764 TXT_DB_write(out,db);
765 BIO_printf(bio_err,"%d entries loaded from the database\n",
767 BIO_printf(bio_err,"generating index\n");
770 if (!TXT_DB_create_index(db, DB_serial, NULL,
771 LHASH_HASH_FN(index_serial_hash),
772 LHASH_COMP_FN(index_serial_cmp)))
774 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
778 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
779 LHASH_HASH_FN(index_name_hash),
780 LHASH_COMP_FN(index_name_cmp)))
782 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
783 db->error,db->arg1,db->arg2);
787 /*****************************************************************/
793 if (BIO_write_filename(Sout,outfile) <= 0)
801 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
804 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
805 Sout = BIO_push(tmpbio, Sout);
813 if ((md == NULL) && ((md=CONF_get_string(conf,
814 section,ENV_DEFAULT_MD)) == NULL))
816 lookup_fail(section,ENV_DEFAULT_MD);
819 if ((dgst=EVP_get_digestbyname(md)) == NULL)
821 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
825 BIO_printf(bio_err,"message digest is %s\n",
826 OBJ_nid2ln(dgst->type));
827 if ((policy == NULL) && ((policy=CONF_get_string(conf,
828 section,ENV_POLICY)) == NULL))
830 lookup_fail(section,ENV_POLICY);
834 BIO_printf(bio_err,"policy is %s\n",policy);
836 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
839 lookup_fail(section,ENV_SERIAL);
844 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
850 /* Check syntax of file */
852 X509V3_set_ctx_test(&ctx);
853 X509V3_set_conf_lhash(&ctx, conf);
854 if (!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL))
857 "Error Loading extension section %s\n",
864 if (startdate == NULL)
866 startdate=CONF_get_string(conf,section,
867 ENV_DEFAULT_STARTDATE);
868 if (startdate == NULL)
871 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
873 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
876 if (startdate == NULL) startdate="today";
880 enddate=CONF_get_string(conf,section,
881 ENV_DEFAULT_ENDDATE);
885 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
887 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
893 days=(int)CONF_get_number(conf,section,
896 if (!enddate && (days == 0))
898 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
902 if ((serial=load_serial(serialfile)) == NULL)
904 BIO_printf(bio_err,"error while loading serial number\n");
909 if ((f=BN_bn2hex(serial)) == NULL) goto err;
910 BIO_printf(bio_err,"next serial number is %s\n",f);
914 if ((attribs=CONF_get_section(conf,policy)) == NULL)
916 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
920 if ((cert_sk=sk_X509_new_null()) == NULL)
922 BIO_printf(bio_err,"Memory allocation failure\n");
925 if (spkac_file != NULL)
928 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
929 serial,startdate,enddate, days,extensions,conf,
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");
949 if (ss_cert_file != NULL)
952 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
953 db,serial,startdate,enddate,days,batch,
954 extensions,conf,verbose);
959 BIO_printf(bio_err,"\n");
960 if (!BN_add_word(serial,1)) goto err;
961 if (!sk_X509_push(cert_sk,x))
963 BIO_printf(bio_err,"Memory allocation failure\n");
971 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
972 serial,startdate,enddate,days,batch,
973 extensions,conf,verbose);
978 BIO_printf(bio_err,"\n");
979 if (!BN_add_word(serial,1)) goto err;
980 if (!sk_X509_push(cert_sk,x))
982 BIO_printf(bio_err,"Memory allocation failure\n");
987 for (i=0; i<argc; i++)
990 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
991 serial,startdate,enddate,days,batch,
992 extensions,conf,verbose);
997 BIO_printf(bio_err,"\n");
998 if (!BN_add_word(serial,1)) goto err;
999 if (!sk_X509_push(cert_sk,x))
1001 BIO_printf(bio_err,"Memory allocation failure\n");
1006 /* we have a stack of newly certified certificates
1007 * and a data base and serial number that need
1010 if (sk_X509_num(cert_sk) > 0)
1014 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1015 (void)BIO_flush(bio_err);
1017 fgets(buf[0],10,stdin);
1018 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1020 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1026 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1028 strncpy(buf[0],serialfile,BSIZE-4);
1031 strcat(buf[0],"-new");
1033 strcat(buf[0],".new");
1036 if (!save_serial(buf[0],serial)) goto err;
1038 strncpy(buf[1],dbfile,BSIZE-4);
1041 strcat(buf[1],"-new");
1043 strcat(buf[1],".new");
1046 if (BIO_write_filename(out,buf[1]) <= 0)
1049 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1052 l=TXT_DB_write(out,db);
1053 if (l <= 0) goto err;
1057 BIO_printf(bio_err,"writing new certificates\n");
1058 for (i=0; i<sk_X509_num(cert_sk); i++)
1063 x=sk_X509_value(cert_sk,i);
1065 j=x->cert_info->serialNumber->length;
1066 p=(char *)x->cert_info->serialNumber->data;
1068 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1074 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1079 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1088 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1091 BIO_printf(bio_err,"writing %s\n",buf[2]);
1093 if (BIO_write_filename(Cout,buf[2]) <= 0)
1098 write_new_certificate(Cout,x, 0, notext);
1099 write_new_certificate(Sout,x, output_der, notext);
1102 if (sk_X509_num(cert_sk))
1104 /* Rename the database and the serial file */
1105 strncpy(buf[2],serialfile,BSIZE-4);
1108 strcat(buf[2],"-old");
1110 strcat(buf[2],".old");
1117 if (rename(serialfile,buf[2]) < 0)
1119 BIO_printf(bio_err,"unable to rename %s to %s\n",
1124 if (rename(buf[0],serialfile) < 0)
1126 BIO_printf(bio_err,"unable to rename %s to %s\n",
1129 rename(buf[2],serialfile);
1133 strncpy(buf[2],dbfile,BSIZE-4);
1136 strcat(buf[2],"-old");
1138 strcat(buf[2],".old");
1141 if (rename(dbfile,buf[2]) < 0)
1143 BIO_printf(bio_err,"unable to rename %s to %s\n",
1148 if (rename(buf[1],dbfile) < 0)
1150 BIO_printf(bio_err,"unable to rename %s to %s\n",
1153 rename(buf[2],dbfile);
1156 BIO_printf(bio_err,"Data Base Updated\n");
1160 /*****************************************************************/
1165 crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1171 /* Check syntax of file */
1173 X509V3_set_ctx_test(&ctx);
1174 X509V3_set_conf_lhash(&ctx, conf);
1175 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL))
1178 "Error Loading CRL extension section %s\n",
1184 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1186 if (!crldays && !crlhours)
1188 crldays=CONF_get_number(conf,section,
1189 ENV_DEFAULT_CRL_DAYS);
1190 crlhours=CONF_get_number(conf,section,
1191 ENV_DEFAULT_CRL_HOURS);
1193 if ((crldays == 0) && (crlhours == 0))
1195 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1199 if (verbose) BIO_printf(bio_err,"making CRL\n");
1200 if ((crl=X509_CRL_new()) == NULL) goto err;
1202 X509_NAME_free(ci->issuer);
1203 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1204 if (ci->issuer == NULL) goto err;
1206 X509_gmtime_adj(ci->lastUpdate,0);
1207 if (ci->nextUpdate == NULL)
1208 ci->nextUpdate=ASN1_UTCTIME_new();
1209 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1211 for (i=0; i<sk_num(db->data); i++)
1213 pp=(char **)sk_value(db->data,i);
1214 if (pp[DB_type][0] == DB_TYPE_REV)
1216 if ((r=X509_REVOKED_new()) == NULL) goto err;
1217 ASN1_STRING_set((ASN1_STRING *)
1219 (unsigned char *)pp[DB_rev_date],
1220 strlen(pp[DB_rev_date]));
1221 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1223 (void)BIO_reset(hex);
1224 if (!BIO_puts(hex,pp[DB_serial]))
1226 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1227 buf[0],BSIZE)) goto err;
1229 X509_CRL_add0_revoked(crl,r);
1232 /* sort the data so it will be written in serial
1234 sk_X509_REVOKED_sort(ci->revoked);
1235 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1237 r=sk_X509_REVOKED_value(ci->revoked,i);
1241 /* we now have a CRL */
1242 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1245 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1247 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1254 if (pkey->type == EVP_PKEY_DSA)
1261 /* Add any extensions asked for */
1265 if (ci->version == NULL)
1266 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1267 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1268 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1269 X509V3_set_conf_lhash(&crlctx, conf);
1271 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1272 crl_ext, crl)) goto err;
1275 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1277 PEM_write_bio_X509_CRL(Sout,crl);
1279 /*****************************************************************/
1284 BIO_printf(bio_err,"no input files\n");
1290 if (BIO_read_filename(in,infile) <= 0)
1293 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1296 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1297 if (revcert == NULL)
1299 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1302 j=do_revoke(revcert,db);
1303 if (j <= 0) goto err;
1306 strncpy(buf[0],dbfile,BSIZE-4);
1307 strcat(buf[0],".new");
1308 if (BIO_write_filename(out,buf[0]) <= 0)
1311 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1314 j=TXT_DB_write(out,db);
1315 if (j <= 0) goto err;
1316 strncpy(buf[1],dbfile,BSIZE-4);
1317 strcat(buf[1],".old");
1318 if (rename(dbfile,buf[1]) < 0)
1320 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1324 if (rename(buf[0],dbfile) < 0)
1326 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1328 rename(buf[1],dbfile);
1331 BIO_printf(bio_err,"Data Base Updated\n");
1334 /*****************************************************************/
1343 sk_X509_pop_free(cert_sk,X509_free);
1345 if (ret) ERR_print_errors(bio_err);
1346 app_RAND_write_file(randfile, bio_err);
1349 EVP_PKEY_free(pkey);
1357 static void lookup_fail(char *name, char *tag)
1359 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1362 static unsigned long index_serial_hash(const char **a)
1367 while (*n == '0') n++;
1368 return(lh_strhash(n));
1371 static int index_serial_cmp(const char **a, const char **b)
1375 for (aa=a[DB_serial]; *aa == '0'; aa++);
1376 for (bb=b[DB_serial]; *bb == '0'; bb++);
1377 return(strcmp(aa,bb));
1380 static unsigned long index_name_hash(const char **a)
1381 { return(lh_strhash(a[DB_name])); }
1383 static int index_name_qual(char **a)
1384 { return(a[0][0] == 'V'); }
1386 static int index_name_cmp(const char **a, const char **b)
1387 { return(strcmp(a[DB_name],
1390 static BIGNUM *load_serial(char *serialfile)
1394 MS_STATIC char buf[1024];
1395 ASN1_INTEGER *ai=NULL;
1397 if ((in=BIO_new(BIO_s_file())) == NULL)
1399 ERR_print_errors(bio_err);
1403 if (BIO_read_filename(in,serialfile) <= 0)
1408 ai=ASN1_INTEGER_new();
1409 if (ai == NULL) goto err;
1410 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1412 BIO_printf(bio_err,"unable to load number from %s\n",
1416 ret=ASN1_INTEGER_to_BN(ai,NULL);
1419 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1423 if (in != NULL) BIO_free(in);
1424 if (ai != NULL) ASN1_INTEGER_free(ai);
1428 static int save_serial(char *serialfile, BIGNUM *serial)
1432 ASN1_INTEGER *ai=NULL;
1434 out=BIO_new(BIO_s_file());
1437 ERR_print_errors(bio_err);
1440 if (BIO_write_filename(out,serialfile) <= 0)
1446 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1448 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1451 i2a_ASN1_INTEGER(out,ai);
1455 if (out != NULL) BIO_free_all(out);
1456 if (ai != NULL) ASN1_INTEGER_free(ai);
1460 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1461 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1462 BIGNUM *serial, char *startdate, char *enddate, int days,
1463 int batch, char *ext_sect, LHASH *lconf, int verbose)
1467 EVP_PKEY *pktmp=NULL;
1470 in=BIO_new(BIO_s_file());
1472 if (BIO_read_filename(in,infile) <= 0)
1477 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1479 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1484 X509_REQ_print(bio_err,req);
1486 BIO_printf(bio_err,"Check that the request matches the signature\n");
1488 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1490 BIO_printf(bio_err,"error unpacking public key\n");
1493 i=X509_REQ_verify(req,pktmp);
1494 EVP_PKEY_free(pktmp);
1498 BIO_printf(bio_err,"Signature verification problems....\n");
1504 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1508 BIO_printf(bio_err,"Signature ok\n");
1510 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1511 days,batch,verbose,req,ext_sect,lconf);
1514 if (req != NULL) X509_REQ_free(req);
1515 if (in != NULL) BIO_free(in);
1519 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1520 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1521 BIGNUM *serial, char *startdate, char *enddate, int days,
1522 int batch, char *ext_sect, LHASH *lconf, int verbose)
1525 X509_REQ *rreq=NULL;
1527 EVP_PKEY *pktmp=NULL;
1530 in=BIO_new(BIO_s_file());
1532 if (BIO_read_filename(in,infile) <= 0)
1537 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1539 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1543 X509_print(bio_err,req);
1545 BIO_printf(bio_err,"Check that the request matches the signature\n");
1547 if ((pktmp=X509_get_pubkey(req)) == NULL)
1549 BIO_printf(bio_err,"error unpacking public key\n");
1552 i=X509_verify(req,pktmp);
1553 EVP_PKEY_free(pktmp);
1557 BIO_printf(bio_err,"Signature verification problems....\n");
1563 BIO_printf(bio_err,"Signature did not match the certificate\n");
1567 BIO_printf(bio_err,"Signature ok\n");
1569 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1572 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1573 batch,verbose,rreq,ext_sect,lconf);
1576 if (rreq != NULL) X509_REQ_free(rreq);
1577 if (req != NULL) X509_free(req);
1578 if (in != NULL) BIO_free(in);
1582 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1583 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1584 char *startdate, char *enddate, int days, int batch, int verbose,
1585 X509_REQ *req, char *ext_sect, LHASH *lconf)
1587 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1588 ASN1_UTCTIME *tm,*tmptm;
1589 ASN1_STRING *str,*str2;
1593 X509_NAME_ENTRY *ne;
1594 X509_NAME_ENTRY *tne,*push;
1596 int ok= -1,i,j,last,nid;
1599 char *row[DB_NUMBER],**rrow,**irow=NULL;
1602 tmptm=ASN1_UTCTIME_new();
1605 BIO_printf(bio_err,"malloc error\n");
1609 for (i=0; i<DB_NUMBER; i++)
1612 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1613 name=X509_REQ_get_subject_name(req);
1614 for (i=0; i<X509_NAME_entry_count(name); i++)
1616 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1617 obj=X509_NAME_ENTRY_get_object(ne);
1618 j=i2a_ASN1_OBJECT(bio_err,obj);
1619 str=X509_NAME_ENTRY_get_data(ne);
1621 for (j=22-j; j>0; j--)
1625 BIO_puts(bio_err,buf);
1629 /* assume all type should be strings */
1630 nid=OBJ_obj2nid(ne->object);
1632 if (str->type == V_ASN1_UNIVERSALSTRING)
1633 ASN1_UNIVERSALSTRING_to_string(str);
1635 if ((str->type == V_ASN1_IA5STRING) &&
1636 (nid != NID_pkcs9_emailAddress))
1637 str->type=V_ASN1_T61STRING;
1639 if ((nid == NID_pkcs9_emailAddress) &&
1640 (str->type == V_ASN1_PRINTABLESTRING))
1641 str->type=V_ASN1_IA5STRING;
1644 if (str->type == V_ASN1_PRINTABLESTRING)
1645 BIO_printf(bio_err,"PRINTABLE:'");
1646 else if (str->type == V_ASN1_T61STRING)
1647 BIO_printf(bio_err,"T61STRING:'");
1648 else if (str->type == V_ASN1_IA5STRING)
1649 BIO_printf(bio_err,"IA5STRING:'");
1650 else if (str->type == V_ASN1_UNIVERSALSTRING)
1651 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1653 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1655 /* check some things */
1656 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1657 (str->type != V_ASN1_IA5STRING))
1659 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1662 j=ASN1_PRINTABLE_type(str->data,str->length);
1663 if ( ((j == V_ASN1_T61STRING) &&
1664 (str->type != V_ASN1_T61STRING)) ||
1665 ((j == V_ASN1_IA5STRING) &&
1666 (str->type == V_ASN1_PRINTABLESTRING)))
1668 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1672 p=(char *)str->data;
1673 for (j=str->length; j>0; j--)
1675 if ((*p >= ' ') && (*p <= '~'))
1676 BIO_printf(bio_err,"%c",*p);
1678 BIO_printf(bio_err,"\\0x%02X",*p);
1679 else if ((unsigned char)*p == 0xf7)
1680 BIO_printf(bio_err,"^?");
1681 else BIO_printf(bio_err,"^%c",*p+'@');
1684 BIO_printf(bio_err,"'\n");
1687 /* Ok, now we check the 'policy' stuff. */
1688 if ((subject=X509_NAME_new()) == NULL)
1690 BIO_printf(bio_err,"Memory allocation failure\n");
1694 /* take a copy of the issuer name before we mess with it. */
1695 CAname=X509_NAME_dup(x509->cert_info->subject);
1696 if (CAname == NULL) goto err;
1699 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1701 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1702 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1704 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1712 /* lookup the object in the supplied name list */
1713 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1716 if (last != -1) break;
1721 tne=X509_NAME_get_entry(name,j);
1725 /* depending on the 'policy', decide what to do. */
1727 if (strcmp(cv->value,"optional") == 0)
1732 else if (strcmp(cv->value,"supplied") == 0)
1736 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1742 else if (strcmp(cv->value,"match") == 0)
1748 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1755 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1756 if ((j < 0) && (last2 == -1))
1758 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1763 push=X509_NAME_get_entry(CAname,j);
1764 str=X509_NAME_ENTRY_get_data(tne);
1765 str2=X509_NAME_ENTRY_get_data(push);
1767 if (ASN1_STRING_cmp(str,str2) != 0)
1772 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));
1778 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1784 if (!X509_NAME_add_entry(subject,push, -1, 0))
1787 X509_NAME_ENTRY_free(push);
1788 BIO_printf(bio_err,"Memory allocation failure\n");
1798 X509_NAME_free(subject);
1799 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1800 if (subject == NULL) goto err;
1804 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1806 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1807 row[DB_serial]=BN_bn2hex(serial);
1808 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1810 BIO_printf(bio_err,"Memory allocation failure\n");
1814 rrow=TXT_DB_get_by_index(db,DB_name,row);
1817 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1822 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1825 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1827 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1834 "The matching entry has the following details\n");
1835 if (rrow[DB_type][0] == 'E')
1837 else if (rrow[DB_type][0] == 'R')
1839 else if (rrow[DB_type][0] == 'V')
1842 p="\ninvalid type, Data base error\n";
1843 BIO_printf(bio_err,"Type :%s\n",p);;
1844 if (rrow[DB_type][0] == 'R')
1846 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1847 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1849 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1850 BIO_printf(bio_err,"Expires on :%s\n",p);
1851 p=rrow[DB_serial]; if (p == NULL) p="undef";
1852 BIO_printf(bio_err,"Serial Number :%s\n",p);
1853 p=rrow[DB_file]; if (p == NULL) p="undef";
1854 BIO_printf(bio_err,"File name :%s\n",p);
1855 p=rrow[DB_name]; if (p == NULL) p="undef";
1856 BIO_printf(bio_err,"Subject Name :%s\n",p);
1857 ok= -1; /* This is now a 'bad' error. */
1861 /* We are now totally happy, lets make and sign the certificate */
1863 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1865 if ((ret=X509_new()) == NULL) goto err;
1869 /* Make it an X509 v3 certificate. */
1870 if (!X509_set_version(x509,2)) goto err;
1873 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1875 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1878 BIO_printf(bio_err,"Certificate is to be certified until ");
1879 if (strcmp(startdate,"today") == 0)
1880 X509_gmtime_adj(X509_get_notBefore(ret),0);
1881 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1883 if (enddate == NULL)
1884 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1885 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1887 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1888 if(days) BIO_printf(bio_err," (%d days)",days);
1889 BIO_printf(bio_err, "\n");
1891 if (!X509_set_subject_name(ret,subject)) goto err;
1893 pktmp=X509_REQ_get_pubkey(req);
1894 i = X509_set_pubkey(ret,pktmp);
1895 EVP_PKEY_free(pktmp);
1898 /* Lets add the extensions, if there are any */
1902 if (ci->version == NULL)
1903 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1905 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1907 /* Free the current entries if any, there should not
1908 * be any I believe */
1909 if (ci->extensions != NULL)
1910 sk_X509_EXTENSION_pop_free(ci->extensions,
1911 X509_EXTENSION_free);
1913 ci->extensions = NULL;
1915 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1916 X509V3_set_conf_lhash(&ctx, lconf);
1918 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1925 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1926 (void)BIO_flush(bio_err);
1928 fgets(buf,sizeof(buf)-1,stdin);
1929 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1931 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1939 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1940 pktmp=X509_get_pubkey(ret);
1941 if (EVP_PKEY_missing_parameters(pktmp) &&
1942 !EVP_PKEY_missing_parameters(pkey))
1943 EVP_PKEY_copy_parameters(pktmp,pkey);
1944 EVP_PKEY_free(pktmp);
1947 if (!X509_sign(ret,pkey,dgst))
1950 /* We now just add it to the database */
1951 row[DB_type]=(char *)OPENSSL_malloc(2);
1953 tm=X509_get_notAfter(ret);
1954 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1955 memcpy(row[DB_exp_date],tm->data,tm->length);
1956 row[DB_exp_date][tm->length]='\0';
1958 row[DB_rev_date]=NULL;
1960 /* row[DB_serial] done already */
1961 row[DB_file]=(char *)OPENSSL_malloc(8);
1962 /* row[DB_name] done already */
1964 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1965 (row[DB_file] == NULL))
1967 BIO_printf(bio_err,"Memory allocation failure\n");
1970 strcpy(row[DB_file],"unknown");
1971 row[DB_type][0]='V';
1972 row[DB_type][1]='\0';
1974 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1976 BIO_printf(bio_err,"Memory allocation failure\n");
1980 for (i=0; i<DB_NUMBER; i++)
1985 irow[DB_NUMBER]=NULL;
1987 if (!TXT_DB_insert(db,irow))
1989 BIO_printf(bio_err,"failed to update database\n");
1990 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1995 for (i=0; i<DB_NUMBER; i++)
1996 if (row[i] != NULL) OPENSSL_free(row[i]);
1999 X509_NAME_free(CAname);
2000 if (subject != NULL)
2001 X509_NAME_free(subject);
2003 ASN1_UTCTIME_free(tmptm);
2006 if (ret != NULL) X509_free(ret);
2014 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2019 (void)i2d_X509_bio(bp,x);
2023 /* ??? Not needed since X509_print prints all this stuff anyway */
2024 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2025 BIO_printf(bp,"issuer :%s\n",f);
2027 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2028 BIO_printf(bp,"subject:%s\n",f);
2030 BIO_puts(bp,"serial :");
2031 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2032 BIO_puts(bp,"\n\n");
2034 if(!notext)X509_print(bp,x);
2035 PEM_write_bio_X509(bp,x);
2038 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2039 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2040 BIGNUM *serial, char *startdate, char *enddate, int days,
2041 char *ext_sect, LHASH *lconf, int verbose)
2043 STACK_OF(CONF_VALUE) *sk=NULL;
2046 CONF_VALUE *cv=NULL;
2047 NETSCAPE_SPKI *spki = NULL;
2050 EVP_PKEY *pktmp=NULL;
2052 X509_NAME_ENTRY *ne=NULL;
2058 * Load input file into a hash table. (This is just an easy
2059 * way to read and parse the file, then put it into a convenient
2062 parms=CONF_load(NULL,infile,&errline);
2065 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2066 ERR_print_errors(bio_err);
2070 sk=CONF_get_section(parms, "default");
2071 if (sk_CONF_VALUE_num(sk) == 0)
2073 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2079 * Now create a dummy X509 request structure. We don't actually
2080 * have an X509 request, but we have many of the components
2081 * (a public key, various DN components). The idea is that we
2082 * put these components into the right X509 request structure
2083 * and we can use the same code as if you had a real X509 request.
2088 ERR_print_errors(bio_err);
2093 * Build up the subject name set.
2100 if (sk_CONF_VALUE_num(sk) <= i) break;
2102 cv=sk_CONF_VALUE_value(sk,i);
2104 /* Skip past any leading X. X: X, etc to allow for
2105 * multiple instances
2107 for(buf = cv->name; *buf ; buf++)
2108 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2110 if(*buf) type = buf;
2115 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2117 if (strcmp(type, "SPKAC") == 0)
2119 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2122 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2123 ERR_print_errors(bio_err);
2130 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2131 if (fix_data(nid, &j) == 0)
2134 "invalid characters in string %s\n",buf);
2138 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2139 (unsigned char *)buf,
2140 strlen(buf))) == NULL)
2143 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2147 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2153 * Now extract the key from the SPKI structure.
2156 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2158 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2160 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2164 j = NETSCAPE_SPKI_verify(spki, pktmp);
2167 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2170 BIO_printf(bio_err,"Signature ok\n");
2172 X509_REQ_set_pubkey(req,pktmp);
2173 EVP_PKEY_free(pktmp);
2174 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2175 days,1,verbose,req,ext_sect,lconf);
2177 if (req != NULL) X509_REQ_free(req);
2178 if (parms != NULL) CONF_free(parms);
2179 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2180 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2185 static int fix_data(int nid, int *type)
2187 if (nid == NID_pkcs9_emailAddress)
2188 *type=V_ASN1_IA5STRING;
2189 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2190 *type=V_ASN1_T61STRING;
2191 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2192 *type=V_ASN1_T61STRING;
2193 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2195 if (nid == NID_pkcs9_unstructuredName)
2196 *type=V_ASN1_IA5STRING;
2200 static int check_time_format(char *str)
2204 tm.data=(unsigned char *)str;
2205 tm.length=strlen(str);
2206 tm.type=V_ASN1_UTCTIME;
2207 return(ASN1_UTCTIME_check(&tm));
2210 static int do_revoke(X509 *x509, TXT_DB *db)
2212 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2213 char *row[DB_NUMBER],**rrow,**irow;
2217 for (i=0; i<DB_NUMBER; i++)
2219 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2220 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2221 row[DB_serial]=BN_bn2hex(bn);
2223 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2225 BIO_printf(bio_err,"Memory allocation failure\n");
2228 /* We have to lookup by serial number because name lookup
2229 * skips revoked certs
2231 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2234 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2236 /* We now just add it to the database */
2237 row[DB_type]=(char *)OPENSSL_malloc(2);
2239 tm=X509_get_notAfter(x509);
2240 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2241 memcpy(row[DB_exp_date],tm->data,tm->length);
2242 row[DB_exp_date][tm->length]='\0';
2244 row[DB_rev_date]=NULL;
2246 /* row[DB_serial] done already */
2247 row[DB_file]=(char *)OPENSSL_malloc(8);
2249 /* row[DB_name] done already */
2251 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2252 (row[DB_file] == NULL))
2254 BIO_printf(bio_err,"Memory allocation failure\n");
2257 strcpy(row[DB_file],"unknown");
2258 row[DB_type][0]='V';
2259 row[DB_type][1]='\0';
2261 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2263 BIO_printf(bio_err,"Memory allocation failure\n");
2267 for (i=0; i<DB_NUMBER; i++)
2272 irow[DB_NUMBER]=NULL;
2274 if (!TXT_DB_insert(db,irow))
2276 BIO_printf(bio_err,"failed to update database\n");
2277 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2281 /* Revoke Certificate */
2282 ok = do_revoke(x509,db);
2287 else if (index_name_cmp((const char **)row,(const char **)rrow))
2289 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2293 else if (rrow[DB_type][0]=='R')
2295 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2301 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2302 revtm = ASN1_UTCTIME_new();
2303 revtm=X509_gmtime_adj(revtm,0);
2304 rrow[DB_type][0]='R';
2305 rrow[DB_type][1]='\0';
2306 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2307 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2308 rrow[DB_rev_date][revtm->length]='\0';
2309 ASN1_UTCTIME_free(revtm);
2313 for (i=0; i<DB_NUMBER; i++)
2316 OPENSSL_free(row[i]);