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>
86 # include <sys/file.h>
100 #define BASE_SECTION "ca"
101 #define CONFIG_FILE "openssl.cnf"
103 #define ENV_DEFAULT_CA "default_ca"
105 #define ENV_DIR "dir"
106 #define ENV_CERTS "certs"
107 #define ENV_CRL_DIR "crl_dir"
108 #define ENV_CA_DB "CA_DB"
109 #define ENV_NEW_CERTS_DIR "new_certs_dir"
110 #define ENV_CERTIFICATE "certificate"
111 #define ENV_SERIAL "serial"
112 #define ENV_CRL "crl"
113 #define ENV_PRIVATE_KEY "private_key"
114 #define ENV_RANDFILE "RANDFILE"
115 #define ENV_DEFAULT_DAYS "default_days"
116 #define ENV_DEFAULT_STARTDATE "default_startdate"
117 #define ENV_DEFAULT_ENDDATE "default_enddate"
118 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
119 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
120 #define ENV_DEFAULT_MD "default_md"
121 #define ENV_PRESERVE "preserve"
122 #define ENV_POLICY "policy"
123 #define ENV_EXTENSIONS "x509_extensions"
124 #define ENV_CRLEXT "crl_extensions"
125 #define ENV_MSIE_HACK "msie_hack"
127 #define ENV_DATABASE "database"
130 #define DB_exp_date 1
131 #define DB_rev_date 2
132 #define DB_serial 3 /* index - unique */
134 #define DB_name 5 /* index - unique for active */
137 #define DB_TYPE_REV 'R'
138 #define DB_TYPE_EXP 'E'
139 #define DB_TYPE_VAL 'V'
141 static char *ca_usage[]={
144 " -verbose - Talk alot while doing things\n",
145 " -config file - A config file\n",
146 " -name arg - The particular CA definition to use\n",
147 " -gencrl - Generate a new CRL\n",
148 " -crldays days - Days is when the next CRL is due\n",
149 " -crlhours hours - Hours is when the next CRL is due\n",
150 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
151 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
152 " -days arg - number of days to certify the certificate for\n",
153 " -md arg - md to use, one of md2, md5, sha or sha1\n",
154 " -policy arg - The CA 'policy' to support\n",
155 " -keyfile arg - PEM private key file\n",
156 " -key arg - key to decode the private key if it is encrypted\n",
157 " -cert file - The CA certificate\n",
158 " -in file - The input PEM encoded certificate request(s)\n",
159 " -out file - Where to put the output file(s)\n",
160 " -outdir dir - Where to put output certificates\n",
161 " -infiles .... - The last argument, requests to process\n",
162 " -spkac file - File contains DN and signed public key and challenge\n",
163 " -ss_cert file - File contains a self signed cert to sign\n",
164 " -preserveDN - Don't re-order the DN\n",
165 " -batch - Don't ask questions\n",
166 " -msie_hack - msie modifications to handle all those universal strings\n",
167 " -revoke file - Revoke a certificate (given in file)\n",
168 " -extensions .. - Extension section (override value in config file)\n",
169 " -crlexts .. - CRL extension section (override value in config file)\n",
174 extern int EF_PROTECT_FREE;
175 extern int EF_PROTECT_BELOW;
176 extern int EF_ALIGNMENT;
179 static int add_oid_section(LHASH *conf);
180 static void lookup_fail(char *name,char *tag);
181 static unsigned long index_serial_hash(char **a);
182 static int index_serial_cmp(char **a, char **b);
183 static unsigned long index_name_hash(char **a);
184 static int index_name_qual(char **a);
185 static int index_name_cmp(char **a,char **b);
186 static BIGNUM *load_serial(char *serialfile);
187 static int save_serial(char *serialfile, BIGNUM *serial);
188 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
189 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
190 BIGNUM *serial, char *startdate,char *enddate, int days,
191 int batch, char *ext_sect, LHASH *conf,int verbose);
192 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
193 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
194 TXT_DB *db, BIGNUM *serial,char *startdate,
195 char *enddate, int days, int batch, char *ext_sect,
196 LHASH *conf,int verbose);
197 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
198 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
199 TXT_DB *db, BIGNUM *serial,char *startdate,
200 char *enddate, int days, char *ext_sect,LHASH *conf,
202 static int fix_data(int nid, int *type);
203 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
204 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
205 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
206 char *startdate, char *enddate, int days, int batch, int verbose,
207 X509_REQ *req, char *ext_sect, LHASH *conf);
208 static int do_revoke(X509 *x509, TXT_DB *db);
209 static int check_time_format(char *str);
210 static LHASH *conf=NULL;
211 static char *section=NULL;
213 static int preserve=0;
214 static int msie_hack=0;
216 int MAIN(int, char **);
218 int MAIN(int argc, char **argv)
232 char *configfile=NULL;
238 char *spkac_file=NULL;
239 char *ss_cert_file=NULL;
244 char *serialfile=NULL;
245 char *extensions=NULL;
248 char *startdate=NULL;
255 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
259 X509_CRL_INFO *ci=NULL;
260 X509_REVOKED *r=NULL;
264 const EVP_MD *dgst=NULL;
265 STACK_OF(CONF_VALUE) *attribs=NULL;
270 MS_STATIC char buf[3][BSIZE];
288 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
289 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
295 if (strcmp(*argv,"-verbose") == 0)
297 else if (strcmp(*argv,"-config") == 0)
299 if (--argc < 1) goto bad;
300 configfile= *(++argv);
302 else if (strcmp(*argv,"-name") == 0)
304 if (--argc < 1) goto bad;
307 else if (strcmp(*argv,"-startdate") == 0)
309 if (--argc < 1) goto bad;
310 startdate= *(++argv);
312 else if (strcmp(*argv,"-enddate") == 0)
314 if (--argc < 1) goto bad;
317 else if (strcmp(*argv,"-days") == 0)
319 if (--argc < 1) goto bad;
320 days=atoi(*(++argv));
322 else if (strcmp(*argv,"-md") == 0)
324 if (--argc < 1) goto bad;
327 else if (strcmp(*argv,"-policy") == 0)
329 if (--argc < 1) goto bad;
332 else if (strcmp(*argv,"-keyfile") == 0)
334 if (--argc < 1) goto bad;
337 else if (strcmp(*argv,"-key") == 0)
339 if (--argc < 1) goto bad;
342 else if (strcmp(*argv,"-cert") == 0)
344 if (--argc < 1) goto bad;
347 else if (strcmp(*argv,"-in") == 0)
349 if (--argc < 1) goto bad;
353 else if (strcmp(*argv,"-out") == 0)
355 if (--argc < 1) goto bad;
358 else if (strcmp(*argv,"-outdir") == 0)
360 if (--argc < 1) goto bad;
363 else if (strcmp(*argv,"-notext") == 0)
365 else if (strcmp(*argv,"-batch") == 0)
367 else if (strcmp(*argv,"-preserveDN") == 0)
369 else if (strcmp(*argv,"-gencrl") == 0)
371 else if (strcmp(*argv,"-msie_hack") == 0)
373 else if (strcmp(*argv,"-crldays") == 0)
375 if (--argc < 1) goto bad;
376 crldays= atol(*(++argv));
378 else if (strcmp(*argv,"-crlhours") == 0)
380 if (--argc < 1) goto bad;
381 crlhours= atol(*(++argv));
383 else if (strcmp(*argv,"-infiles") == 0)
390 else if (strcmp(*argv, "-ss_cert") == 0)
392 if (--argc < 1) goto bad;
393 ss_cert_file = *(++argv);
396 else if (strcmp(*argv, "-spkac") == 0)
398 if (--argc < 1) goto bad;
399 spkac_file = *(++argv);
402 else if (strcmp(*argv,"-revoke") == 0)
404 if (--argc < 1) goto bad;
408 else if (strcmp(*argv,"-extensions") == 0)
410 if (--argc < 1) goto bad;
411 extensions= *(++argv);
413 else if (strcmp(*argv,"-crlexts") == 0)
415 if (--argc < 1) goto bad;
421 BIO_printf(bio_err,"unknown option %s\n",*argv);
431 for (pp=ca_usage; (*pp != NULL); pp++)
432 BIO_printf(bio_err,*pp);
436 ERR_load_crypto_strings();
438 /*****************************************************************/
439 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
440 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
441 if (configfile == NULL)
443 /* We will just use 'buf[0]' as a temporary buffer. */
445 strncpy(buf[0],X509_get_default_cert_area(),
446 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
448 strncpy(buf[0],X509_get_default_cert_area(),
449 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
452 strcat(buf[0],CONFIG_FILE);
456 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
457 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
460 BIO_printf(bio_err,"error loading the config file '%s'\n",
463 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
464 ,errorline,configfile);
468 /* Lets get the config section we are using */
471 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
474 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
481 p=CONF_get_string(conf,NULL,"oid_file");
486 oid_bio=BIO_new_file(p,"r");
490 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
491 ERR_print_errors(bio_err);
497 OBJ_create_objects(oid_bio);
501 if(!add_oid_section(conf))
503 ERR_print_errors(bio_err);
508 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
509 app_RAND_load_file(randfile, bio_err, 0);
511 in=BIO_new(BIO_s_file());
512 out=BIO_new(BIO_s_file());
513 Sout=BIO_new(BIO_s_file());
514 Cout=BIO_new(BIO_s_file());
515 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
517 ERR_print_errors(bio_err);
521 /*****************************************************************/
522 /* we definitely need an public key, so lets get it */
524 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
525 section,ENV_PRIVATE_KEY)) == NULL))
527 lookup_fail(section,ENV_PRIVATE_KEY);
530 if (BIO_read_filename(in,keyfile) <= 0)
533 BIO_printf(bio_err,"trying to load CA private key\n");
536 pkey=PEM_read_bio_PrivateKey(in,NULL,PEM_cb,key);
537 if(key) memset(key,0,strlen(key));
540 BIO_printf(bio_err,"unable to load CA private key\n");
544 /*****************************************************************/
545 /* we need a certificate */
546 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
547 section,ENV_CERTIFICATE)) == NULL))
549 lookup_fail(section,ENV_CERTIFICATE);
552 if (BIO_read_filename(in,certfile) <= 0)
555 BIO_printf(bio_err,"trying to load CA certificate\n");
558 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
561 BIO_printf(bio_err,"unable to load CA certificate\n");
565 if (!X509_check_private_key(x509,pkey))
567 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
571 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
572 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
574 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
575 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
578 /*****************************************************************/
579 /* lookup where to write new certificates */
580 if ((outdir == NULL) && (req))
584 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
587 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
590 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
591 filename. In any case, stat(), below, will catch the problem
592 if outdir is not a directory spec, and the fopen() or open()
593 will catch an error if there is no write access.
595 Presumably, this problem could also be solved by using the DEC
596 C routines to convert the directory syntax to Unixly, and give
597 that to access(). However, time's too short to do that just
600 if (access(outdir,R_OK|W_OK|X_OK) != 0)
602 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
608 if (stat(outdir,&sb) != 0)
610 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
615 if (!(sb.st_mode & S_IFDIR))
617 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
624 /*****************************************************************/
625 /* we need to load the database file */
626 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
628 lookup_fail(section,ENV_DATABASE);
631 if (BIO_read_filename(in,dbfile) <= 0)
634 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
637 db=TXT_DB_read(in,DB_NUMBER);
638 if (db == NULL) goto err;
640 /* Lets check some fields */
641 for (i=0; i<sk_num(db->data); i++)
643 pp=(char **)sk_value(db->data,i);
644 if ((pp[DB_type][0] != DB_TYPE_REV) &&
645 (pp[DB_rev_date][0] != '\0'))
647 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
650 if ((pp[DB_type][0] == DB_TYPE_REV) &&
651 !check_time_format(pp[DB_rev_date]))
653 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
657 if (!check_time_format(pp[DB_exp_date]))
659 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
664 if ((j&1) || (j < 2))
666 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
671 if (!( ((*p >= '0') && (*p <= '9')) ||
672 ((*p >= 'A') && (*p <= 'F')) ||
673 ((*p >= 'a') && (*p <= 'f'))) )
675 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);
683 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
684 TXT_DB_write(out,db);
685 BIO_printf(bio_err,"%d entries loaded from the database\n",
687 BIO_printf(bio_err,"generating index\n");
690 if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
693 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
697 if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
700 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
701 db->error,db->arg1,db->arg2);
705 /*****************************************************************/
711 if (BIO_write_filename(Sout,outfile) <= 0)
718 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
723 if ((md == NULL) && ((md=CONF_get_string(conf,
724 section,ENV_DEFAULT_MD)) == NULL))
726 lookup_fail(section,ENV_DEFAULT_MD);
729 if ((dgst=EVP_get_digestbyname(md)) == NULL)
731 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
735 BIO_printf(bio_err,"message digest is %s\n",
736 OBJ_nid2ln(dgst->type));
737 if ((policy == NULL) && ((policy=CONF_get_string(conf,
738 section,ENV_POLICY)) == NULL))
740 lookup_fail(section,ENV_POLICY);
744 BIO_printf(bio_err,"policy is %s\n",policy);
746 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
749 lookup_fail(section,ENV_SERIAL);
753 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
755 /* Check syntax of file */
757 X509V3_set_ctx_test(&ctx);
758 X509V3_set_conf_lhash(&ctx, conf);
759 if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
761 "Error Loading extension section %s\n",
768 if (startdate == NULL)
770 startdate=CONF_get_string(conf,section,
771 ENV_DEFAULT_STARTDATE);
773 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
775 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
778 if (startdate == NULL) startdate="today";
782 enddate=CONF_get_string(conf,section,
783 ENV_DEFAULT_ENDDATE);
785 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
787 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
793 days=(int)CONF_get_number(conf,section,
796 if (!enddate && (days == 0))
798 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
802 if ((serial=load_serial(serialfile)) == NULL)
804 BIO_printf(bio_err,"error while loading serial number\n");
809 if ((f=BN_bn2hex(serial)) == NULL) goto err;
810 BIO_printf(bio_err,"next serial number is %s\n",f);
814 if ((attribs=CONF_get_section(conf,policy)) == NULL)
816 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
820 if ((cert_sk=sk_new_null()) == NULL)
822 BIO_printf(bio_err,"Malloc failure\n");
825 if (spkac_file != NULL)
828 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
829 serial,startdate,enddate, days,extensions,conf,
835 BIO_printf(bio_err,"\n");
836 if (!BN_add_word(serial,1)) goto err;
837 if (!sk_push(cert_sk,(char *)x))
839 BIO_printf(bio_err,"Malloc failure\n");
849 if (ss_cert_file != NULL)
852 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
853 db,serial,startdate,enddate,days,batch,
854 extensions,conf,verbose);
859 BIO_printf(bio_err,"\n");
860 if (!BN_add_word(serial,1)) goto err;
861 if (!sk_push(cert_sk,(char *)x))
863 BIO_printf(bio_err,"Malloc failure\n");
871 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
872 serial,startdate,enddate,days,batch,
873 extensions,conf,verbose);
878 BIO_printf(bio_err,"\n");
879 if (!BN_add_word(serial,1)) goto err;
880 if (!sk_push(cert_sk,(char *)x))
882 BIO_printf(bio_err,"Malloc failure\n");
887 for (i=0; i<argc; i++)
890 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
891 serial,startdate,enddate,days,batch,
892 extensions,conf,verbose);
897 BIO_printf(bio_err,"\n");
898 if (!BN_add_word(serial,1)) goto err;
899 if (!sk_push(cert_sk,(char *)x))
901 BIO_printf(bio_err,"Malloc failure\n");
906 /* we have a stack of newly certified certificates
907 * and a data base and serial number that need
910 if (sk_num(cert_sk) > 0)
914 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
915 (void)BIO_flush(bio_err);
917 fgets(buf[0],10,stdin);
918 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
920 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
926 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_num(cert_sk));
928 strncpy(buf[0],serialfile,BSIZE-4);
931 strcat(buf[0],"-new");
933 strcat(buf[0],".new");
936 if (!save_serial(buf[0],serial)) goto err;
938 strncpy(buf[1],dbfile,BSIZE-4);
941 strcat(buf[1],"-new");
943 strcat(buf[1],".new");
946 if (BIO_write_filename(out,buf[1]) <= 0)
949 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
952 l=TXT_DB_write(out,db);
953 if (l <= 0) goto err;
957 BIO_printf(bio_err,"writing new certificates\n");
958 for (i=0; i<sk_num(cert_sk); i++)
963 x=(X509 *)sk_value(cert_sk,i);
965 j=x->cert_info->serialNumber->length;
966 p=(char *)x->cert_info->serialNumber->data;
968 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
974 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
979 sprintf((char *)n,"%02X",(unsigned char)*(p++));
988 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
991 BIO_printf(bio_err,"writing %s\n",buf[2]);
993 if (BIO_write_filename(Cout,buf[2]) <= 0)
998 write_new_certificate(Cout,x, 0, notext);
999 write_new_certificate(Sout,x, output_der, notext);
1002 if (sk_num(cert_sk))
1004 /* Rename the database and the serial file */
1005 strncpy(buf[2],serialfile,BSIZE-4);
1008 strcat(buf[2],"-old");
1010 strcat(buf[2],".old");
1017 if (rename(serialfile,buf[2]) < 0)
1019 BIO_printf(bio_err,"unable to rename %s to %s\n",
1024 if (rename(buf[0],serialfile) < 0)
1026 BIO_printf(bio_err,"unable to rename %s to %s\n",
1029 rename(buf[2],serialfile);
1033 strncpy(buf[2],dbfile,BSIZE-4);
1036 strcat(buf[2],"-old");
1038 strcat(buf[2],".old");
1041 if (rename(dbfile,buf[2]) < 0)
1043 BIO_printf(bio_err,"unable to rename %s to %s\n",
1048 if (rename(buf[1],dbfile) < 0)
1050 BIO_printf(bio_err,"unable to rename %s to %s\n",
1053 rename(buf[2],dbfile);
1056 BIO_printf(bio_err,"Data Base Updated\n");
1060 /*****************************************************************/
1063 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1065 /* Check syntax of file */
1067 X509V3_set_ctx_test(&ctx);
1068 X509V3_set_conf_lhash(&ctx, conf);
1069 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1071 "Error Loading CRL extension section %s\n",
1077 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1079 if (!crldays && !crlhours)
1081 crldays=CONF_get_number(conf,section,
1082 ENV_DEFAULT_CRL_DAYS);
1083 crlhours=CONF_get_number(conf,section,
1084 ENV_DEFAULT_CRL_HOURS);
1086 if ((crldays == 0) && (crlhours == 0))
1088 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1092 if (verbose) BIO_printf(bio_err,"making CRL\n");
1093 if ((crl=X509_CRL_new()) == NULL) goto err;
1095 X509_NAME_free(ci->issuer);
1096 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1097 if (ci->issuer == NULL) goto err;
1099 X509_gmtime_adj(ci->lastUpdate,0);
1100 if (ci->nextUpdate == NULL)
1101 ci->nextUpdate=ASN1_UTCTIME_new();
1102 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1104 for (i=0; i<sk_num(db->data); i++)
1106 pp=(char **)sk_value(db->data,i);
1107 if (pp[DB_type][0] == DB_TYPE_REV)
1109 if ((r=X509_REVOKED_new()) == NULL) goto err;
1110 ASN1_STRING_set((ASN1_STRING *)
1112 (unsigned char *)pp[DB_rev_date],
1113 strlen(pp[DB_rev_date]));
1114 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1116 (void)BIO_reset(hex);
1117 if (!BIO_puts(hex,pp[DB_serial]))
1119 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1120 buf[0],BSIZE)) goto err;
1122 sk_X509_REVOKED_push(ci->revoked,r);
1125 /* sort the data so it will be written in serial
1127 sk_X509_REVOKED_sort(ci->revoked);
1128 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1130 r=sk_X509_REVOKED_value(ci->revoked,i);
1134 /* we now have a CRL */
1135 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1138 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1140 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1147 if (pkey->type == EVP_PKEY_DSA)
1154 /* Add any extensions asked for */
1158 if (ci->version == NULL)
1159 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1160 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1161 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1162 X509V3_set_conf_lhash(&crlctx, conf);
1164 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1165 crl_ext, crl)) goto err;
1168 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1170 PEM_write_bio_X509_CRL(Sout,crl);
1172 /*****************************************************************/
1177 BIO_printf(bio_err,"no input files\n");
1183 if (BIO_read_filename(in,infile) <= 0)
1186 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1189 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1190 if (revcert == NULL)
1192 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1195 j=do_revoke(revcert,db);
1196 if (j <= 0) goto err;
1199 strncpy(buf[0],dbfile,BSIZE-4);
1200 strcat(buf[0],".new");
1201 if (BIO_write_filename(out,buf[0]) <= 0)
1204 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1207 j=TXT_DB_write(out,db);
1208 if (j <= 0) goto err;
1209 strncpy(buf[1],dbfile,BSIZE-4);
1210 strcat(buf[1],".old");
1211 if (rename(dbfile,buf[1]) < 0)
1213 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1217 if (rename(buf[0],dbfile) < 0)
1219 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1221 rename(buf[1],dbfile);
1224 BIO_printf(bio_err,"Data Base Updated\n");
1227 /*****************************************************************/
1236 sk_pop_free(cert_sk,X509_free);
1238 if (ret) ERR_print_errors(bio_err);
1239 app_RAND_write_file(randfile, bio_err);
1242 EVP_PKEY_free(pkey);
1250 static void lookup_fail(char *name, char *tag)
1252 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1255 static unsigned long index_serial_hash(char **a)
1260 while (*n == '0') n++;
1261 return(lh_strhash(n));
1264 static int index_serial_cmp(char **a, char **b)
1268 for (aa=a[DB_serial]; *aa == '0'; aa++);
1269 for (bb=b[DB_serial]; *bb == '0'; bb++);
1270 return(strcmp(aa,bb));
1273 static unsigned long index_name_hash(char **a)
1274 { return(lh_strhash(a[DB_name])); }
1276 static int index_name_qual(char **a)
1277 { return(a[0][0] == 'V'); }
1279 static int index_name_cmp(char **a, char **b)
1280 { return(strcmp(a[DB_name],
1283 static BIGNUM *load_serial(char *serialfile)
1287 MS_STATIC char buf[1024];
1288 ASN1_INTEGER *ai=NULL;
1290 if ((in=BIO_new(BIO_s_file())) == NULL)
1292 ERR_print_errors(bio_err);
1296 if (BIO_read_filename(in,serialfile) <= 0)
1301 ai=ASN1_INTEGER_new();
1302 if (ai == NULL) goto err;
1303 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1305 BIO_printf(bio_err,"unable to load number from %s\n",
1309 ret=ASN1_INTEGER_to_BN(ai,NULL);
1312 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1316 if (in != NULL) BIO_free(in);
1317 if (ai != NULL) ASN1_INTEGER_free(ai);
1321 static int save_serial(char *serialfile, BIGNUM *serial)
1325 ASN1_INTEGER *ai=NULL;
1327 out=BIO_new(BIO_s_file());
1330 ERR_print_errors(bio_err);
1333 if (BIO_write_filename(out,serialfile) <= 0)
1339 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1341 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1344 i2a_ASN1_INTEGER(out,ai);
1348 if (out != NULL) BIO_free(out);
1349 if (ai != NULL) ASN1_INTEGER_free(ai);
1353 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1354 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1355 BIGNUM *serial, char *startdate, char *enddate, int days,
1356 int batch, char *ext_sect, LHASH *lconf, int verbose)
1360 EVP_PKEY *pktmp=NULL;
1363 in=BIO_new(BIO_s_file());
1365 if (BIO_read_filename(in,infile) <= 0)
1370 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1372 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1377 X509_REQ_print(bio_err,req);
1379 BIO_printf(bio_err,"Check that the request matches the signature\n");
1381 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1383 BIO_printf(bio_err,"error unpacking public key\n");
1386 i=X509_REQ_verify(req,pktmp);
1387 EVP_PKEY_free(pktmp);
1391 BIO_printf(bio_err,"Signature verification problems....\n");
1397 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1401 BIO_printf(bio_err,"Signature ok\n");
1403 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1404 days,batch,verbose,req,ext_sect,lconf);
1407 if (req != NULL) X509_REQ_free(req);
1408 if (in != NULL) BIO_free(in);
1412 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1413 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1414 BIGNUM *serial, char *startdate, char *enddate, int days,
1415 int batch, char *ext_sect, LHASH *lconf, int verbose)
1418 X509_REQ *rreq=NULL;
1420 EVP_PKEY *pktmp=NULL;
1423 in=BIO_new(BIO_s_file());
1425 if (BIO_read_filename(in,infile) <= 0)
1430 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1432 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1436 X509_print(bio_err,req);
1438 BIO_printf(bio_err,"Check that the request matches the signature\n");
1440 if ((pktmp=X509_get_pubkey(req)) == NULL)
1442 BIO_printf(bio_err,"error unpacking public key\n");
1445 i=X509_verify(req,pktmp);
1446 EVP_PKEY_free(pktmp);
1450 BIO_printf(bio_err,"Signature verification problems....\n");
1456 BIO_printf(bio_err,"Signature did not match the certificate\n");
1460 BIO_printf(bio_err,"Signature ok\n");
1462 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1465 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1466 batch,verbose,rreq,ext_sect,lconf);
1469 if (rreq != NULL) X509_REQ_free(rreq);
1470 if (req != NULL) X509_free(req);
1471 if (in != NULL) BIO_free(in);
1475 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1476 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1477 char *startdate, char *enddate, int days, int batch, int verbose,
1478 X509_REQ *req, char *ext_sect, LHASH *lconf)
1480 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1481 ASN1_UTCTIME *tm,*tmptm;
1482 ASN1_STRING *str,*str2;
1486 X509_NAME_ENTRY *ne;
1487 X509_NAME_ENTRY *tne,*push;
1489 int ok= -1,i,j,last,nid;
1492 char *row[DB_NUMBER],**rrow,**irow=NULL;
1495 tmptm=ASN1_UTCTIME_new();
1498 BIO_printf(bio_err,"malloc error\n");
1502 for (i=0; i<DB_NUMBER; i++)
1505 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1506 name=X509_REQ_get_subject_name(req);
1507 for (i=0; i<X509_NAME_entry_count(name); i++)
1509 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1510 obj=X509_NAME_ENTRY_get_object(ne);
1511 j=i2a_ASN1_OBJECT(bio_err,obj);
1512 str=X509_NAME_ENTRY_get_data(ne);
1514 for (j=22-j; j>0; j--)
1518 BIO_puts(bio_err,buf);
1522 /* assume all type should be strings */
1523 nid=OBJ_obj2nid(ne->object);
1525 if (str->type == V_ASN1_UNIVERSALSTRING)
1526 ASN1_UNIVERSALSTRING_to_string(str);
1528 if ((str->type == V_ASN1_IA5STRING) &&
1529 (nid != NID_pkcs9_emailAddress))
1530 str->type=V_ASN1_T61STRING;
1532 if ((nid == NID_pkcs9_emailAddress) &&
1533 (str->type == V_ASN1_PRINTABLESTRING))
1534 str->type=V_ASN1_IA5STRING;
1537 if (str->type == V_ASN1_PRINTABLESTRING)
1538 BIO_printf(bio_err,"PRINTABLE:'");
1539 else if (str->type == V_ASN1_T61STRING)
1540 BIO_printf(bio_err,"T61STRING:'");
1541 else if (str->type == V_ASN1_IA5STRING)
1542 BIO_printf(bio_err,"IA5STRING:'");
1543 else if (str->type == V_ASN1_UNIVERSALSTRING)
1544 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1546 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1548 /* check some things */
1549 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1550 (str->type != V_ASN1_IA5STRING))
1552 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1555 j=ASN1_PRINTABLE_type(str->data,str->length);
1556 if ( ((j == V_ASN1_T61STRING) &&
1557 (str->type != V_ASN1_T61STRING)) ||
1558 ((j == V_ASN1_IA5STRING) &&
1559 (str->type == V_ASN1_PRINTABLESTRING)))
1561 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1565 p=(char *)str->data;
1566 for (j=str->length; j>0; j--)
1568 if ((*p >= ' ') && (*p <= '~'))
1569 BIO_printf(bio_err,"%c",*p);
1571 BIO_printf(bio_err,"\\0x%02X",*p);
1572 else if ((unsigned char)*p == 0xf7)
1573 BIO_printf(bio_err,"^?");
1574 else BIO_printf(bio_err,"^%c",*p+'@');
1577 BIO_printf(bio_err,"'\n");
1580 /* Ok, now we check the 'policy' stuff. */
1581 if ((subject=X509_NAME_new()) == NULL)
1583 BIO_printf(bio_err,"Malloc failure\n");
1587 /* take a copy of the issuer name before we mess with it. */
1588 CAname=X509_NAME_dup(x509->cert_info->subject);
1589 if (CAname == NULL) goto err;
1592 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1594 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1595 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1597 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1605 /* lookup the object in the supplied name list */
1606 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1609 if (last != -1) break;
1614 tne=X509_NAME_get_entry(name,j);
1618 /* depending on the 'policy', decide what to do. */
1620 if (strcmp(cv->value,"optional") == 0)
1625 else if (strcmp(cv->value,"supplied") == 0)
1629 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1635 else if (strcmp(cv->value,"match") == 0)
1641 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1648 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1649 if ((j < 0) && (last2 == -1))
1651 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1656 push=X509_NAME_get_entry(CAname,j);
1657 str=X509_NAME_ENTRY_get_data(tne);
1658 str2=X509_NAME_ENTRY_get_data(push);
1660 if (ASN1_STRING_cmp(str,str2) != 0)
1665 BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str == NULL)?"NULL":(char *)str->data),((str2 == NULL)?"NULL":(char *)str2->data));
1671 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1677 if (!X509_NAME_add_entry(subject,push, -1, 0))
1680 X509_NAME_ENTRY_free(push);
1681 BIO_printf(bio_err,"Malloc failure\n");
1691 X509_NAME_free(subject);
1692 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1693 if (subject == NULL) goto err;
1697 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1699 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1700 row[DB_serial]=BN_bn2hex(serial);
1701 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1703 BIO_printf(bio_err,"Malloc failure\n");
1707 rrow=TXT_DB_get_by_index(db,DB_name,row);
1710 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1715 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1718 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1720 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1727 "The matching entry has the following details\n");
1728 if (rrow[DB_type][0] == 'E')
1730 else if (rrow[DB_type][0] == 'R')
1732 else if (rrow[DB_type][0] == 'V')
1735 p="\ninvalid type, Data base error\n";
1736 BIO_printf(bio_err,"Type :%s\n",p);;
1737 if (rrow[DB_type][0] == 'R')
1739 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1740 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1742 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1743 BIO_printf(bio_err,"Expires on :%s\n",p);
1744 p=rrow[DB_serial]; if (p == NULL) p="undef";
1745 BIO_printf(bio_err,"Serial Number :%s\n",p);
1746 p=rrow[DB_file]; if (p == NULL) p="undef";
1747 BIO_printf(bio_err,"File name :%s\n",p);
1748 p=rrow[DB_name]; if (p == NULL) p="undef";
1749 BIO_printf(bio_err,"Subject Name :%s\n",p);
1750 ok= -1; /* This is now a 'bad' error. */
1754 /* We are now totally happy, lets make and sign the certificate */
1756 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1758 if ((ret=X509_new()) == NULL) goto err;
1762 /* Make it an X509 v3 certificate. */
1763 if (!X509_set_version(x509,2)) goto err;
1766 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1768 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1771 BIO_printf(bio_err,"Certificate is to be certified until ");
1772 if (strcmp(startdate,"today") == 0)
1773 X509_gmtime_adj(X509_get_notBefore(ret),0);
1774 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1776 if (enddate == NULL)
1777 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1778 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1780 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1781 if(days) BIO_printf(bio_err," (%d days)",days);
1782 BIO_printf(bio_err, "\n");
1784 if (!X509_set_subject_name(ret,subject)) goto err;
1786 pktmp=X509_REQ_get_pubkey(req);
1787 i = X509_set_pubkey(ret,pktmp);
1788 EVP_PKEY_free(pktmp);
1791 /* Lets add the extensions, if there are any */
1795 if (ci->version == NULL)
1796 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1798 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1800 /* Free the current entries if any, there should not
1801 * be any I believe */
1802 if (ci->extensions != NULL)
1803 sk_X509_EXTENSION_pop_free(ci->extensions,
1804 X509_EXTENSION_free);
1806 ci->extensions = NULL;
1808 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1809 X509V3_set_conf_lhash(&ctx, lconf);
1811 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1818 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1819 (void)BIO_flush(bio_err);
1821 fgets(buf,sizeof(buf)-1,stdin);
1822 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1824 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1832 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1833 pktmp=X509_get_pubkey(ret);
1834 if (EVP_PKEY_missing_parameters(pktmp) &&
1835 !EVP_PKEY_missing_parameters(pkey))
1836 EVP_PKEY_copy_parameters(pktmp,pkey);
1837 EVP_PKEY_free(pktmp);
1840 if (!X509_sign(ret,pkey,dgst))
1843 /* We now just add it to the database */
1844 row[DB_type]=(char *)Malloc(2);
1846 tm=X509_get_notAfter(ret);
1847 row[DB_exp_date]=(char *)Malloc(tm->length+1);
1848 memcpy(row[DB_exp_date],tm->data,tm->length);
1849 row[DB_exp_date][tm->length]='\0';
1851 row[DB_rev_date]=NULL;
1853 /* row[DB_serial] done already */
1854 row[DB_file]=(char *)Malloc(8);
1855 /* row[DB_name] done already */
1857 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1858 (row[DB_file] == NULL))
1860 BIO_printf(bio_err,"Malloc failure\n");
1863 strcpy(row[DB_file],"unknown");
1864 row[DB_type][0]='V';
1865 row[DB_type][1]='\0';
1867 if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1869 BIO_printf(bio_err,"Malloc failure\n");
1873 for (i=0; i<DB_NUMBER; i++)
1878 irow[DB_NUMBER]=NULL;
1880 if (!TXT_DB_insert(db,irow))
1882 BIO_printf(bio_err,"failed to update database\n");
1883 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1888 for (i=0; i<DB_NUMBER; i++)
1889 if (row[i] != NULL) Free(row[i]);
1892 X509_NAME_free(CAname);
1893 if (subject != NULL)
1894 X509_NAME_free(subject);
1896 ASN1_UTCTIME_free(tmptm);
1899 if (ret != NULL) X509_free(ret);
1907 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1912 (void)i2d_X509_bio(bp,x);
1916 /* ??? Not needed since X509_print prints all this stuff anyway */
1917 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1918 BIO_printf(bp,"issuer :%s\n",f);
1920 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1921 BIO_printf(bp,"subject:%s\n",f);
1923 BIO_puts(bp,"serial :");
1924 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1925 BIO_puts(bp,"\n\n");
1927 if(!notext)X509_print(bp,x);
1928 PEM_write_bio_X509(bp,x);
1931 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1932 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1933 BIGNUM *serial, char *startdate, char *enddate, int days,
1934 char *ext_sect, LHASH *lconf, int verbose)
1936 STACK_OF(CONF_VALUE) *sk=NULL;
1939 CONF_VALUE *cv=NULL;
1940 NETSCAPE_SPKI *spki = NULL;
1943 EVP_PKEY *pktmp=NULL;
1945 X509_NAME_ENTRY *ne=NULL;
1951 * Load input file into a hash table. (This is just an easy
1952 * way to read and parse the file, then put it into a convenient
1955 parms=CONF_load(NULL,infile,&errline);
1958 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
1959 ERR_print_errors(bio_err);
1963 sk=CONF_get_section(parms, "default");
1964 if (sk_CONF_VALUE_num(sk) == 0)
1966 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
1972 * Now create a dummy X509 request structure. We don't actually
1973 * have an X509 request, but we have many of the components
1974 * (a public key, various DN components). The idea is that we
1975 * put these components into the right X509 request structure
1976 * and we can use the same code as if you had a real X509 request.
1981 ERR_print_errors(bio_err);
1986 * Build up the subject name set.
1993 if (sk_CONF_VALUE_num(sk) <= i) break;
1995 cv=sk_CONF_VALUE_value(sk,i);
1997 /* Skip past any leading X. X: X, etc to allow for
1998 * multiple instances
2000 for(buf = cv->name; *buf ; buf++)
2001 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2003 if(*buf) type = buf;
2008 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2010 if (strcmp(type, "SPKAC") == 0)
2012 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2015 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2016 ERR_print_errors(bio_err);
2023 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2024 if (fix_data(nid, &j) == 0)
2027 "invalid characters in string %s\n",buf);
2031 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2032 (unsigned char *)buf,
2033 strlen(buf))) == NULL)
2036 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2040 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2046 * Now extract the key from the SPKI structure.
2049 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2051 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2053 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2057 j = NETSCAPE_SPKI_verify(spki, pktmp);
2060 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2063 BIO_printf(bio_err,"Signature ok\n");
2065 X509_REQ_set_pubkey(req,pktmp);
2066 EVP_PKEY_free(pktmp);
2067 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2068 days,1,verbose,req,ext_sect,lconf);
2070 if (req != NULL) X509_REQ_free(req);
2071 if (parms != NULL) CONF_free(parms);
2072 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2073 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2078 static int fix_data(int nid, int *type)
2080 if (nid == NID_pkcs9_emailAddress)
2081 *type=V_ASN1_IA5STRING;
2082 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2083 *type=V_ASN1_T61STRING;
2084 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2085 *type=V_ASN1_T61STRING;
2086 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2088 if (nid == NID_pkcs9_unstructuredName)
2089 *type=V_ASN1_IA5STRING;
2093 static int check_time_format(char *str)
2097 tm.data=(unsigned char *)str;
2098 tm.length=strlen(str);
2099 tm.type=V_ASN1_UTCTIME;
2100 return(ASN1_UTCTIME_check(&tm));
2103 static int add_oid_section(LHASH *hconf)
2106 STACK_OF(CONF_VALUE) *sktmp;
2109 if(!(p=CONF_get_string(hconf,NULL,"oid_section"))) return 1;
2110 if(!(sktmp = CONF_get_section(hconf, p))) {
2111 BIO_printf(bio_err, "problem loading oid section %s\n", p);
2114 for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
2115 cnf = sk_CONF_VALUE_value(sktmp, i);
2116 if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
2117 BIO_printf(bio_err, "problem creating object %s=%s\n",
2118 cnf->name, cnf->value);
2125 static int do_revoke(X509 *x509, TXT_DB *db)
2127 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2128 char *row[DB_NUMBER],**rrow,**irow;
2132 for (i=0; i<DB_NUMBER; i++)
2134 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2135 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2136 row[DB_serial]=BN_bn2hex(bn);
2138 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2140 BIO_printf(bio_err,"Malloc failure\n");
2143 /* We have to lookup by serial number because name lookup
2144 * skips revoked certs
2146 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2149 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2151 /* We now just add it to the database */
2152 row[DB_type]=(char *)Malloc(2);
2154 tm=X509_get_notAfter(x509);
2155 row[DB_exp_date]=(char *)Malloc(tm->length+1);
2156 memcpy(row[DB_exp_date],tm->data,tm->length);
2157 row[DB_exp_date][tm->length]='\0';
2159 row[DB_rev_date]=NULL;
2161 /* row[DB_serial] done already */
2162 row[DB_file]=(char *)Malloc(8);
2164 /* row[DB_name] done already */
2166 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2167 (row[DB_file] == NULL))
2169 BIO_printf(bio_err,"Malloc failure\n");
2172 strcpy(row[DB_file],"unknown");
2173 row[DB_type][0]='V';
2174 row[DB_type][1]='\0';
2176 if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2178 BIO_printf(bio_err,"Malloc failure\n");
2182 for (i=0; i<DB_NUMBER; i++)
2187 irow[DB_NUMBER]=NULL;
2189 if (!TXT_DB_insert(db,irow))
2191 BIO_printf(bio_err,"failed to update database\n");
2192 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2196 /* Revoke Certificate */
2197 ok = do_revoke(x509,db);
2202 else if (index_name_cmp(row,rrow))
2204 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2208 else if (rrow[DB_type][0]=='R')
2210 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2216 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2217 revtm = ASN1_UTCTIME_new();
2218 revtm=X509_gmtime_adj(revtm,0);
2219 rrow[DB_type][0]='R';
2220 rrow[DB_type][1]='\0';
2221 rrow[DB_rev_date]=(char *)Malloc(revtm->length+1);
2222 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2223 rrow[DB_rev_date][revtm->length]='\0';
2224 ASN1_UTCTIME_free(revtm);
2228 for (i=0; i<DB_NUMBER; i++)