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 void lookup_fail(char *name,char *tag);
180 static unsigned long index_serial_hash(char **a);
181 static int index_serial_cmp(char **a, char **b);
182 static unsigned long index_name_hash(char **a);
183 static int index_name_qual(char **a);
184 static int index_name_cmp(char **a,char **b);
185 static BIGNUM *load_serial(char *serialfile);
186 static int save_serial(char *serialfile, BIGNUM *serial);
187 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
188 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
189 BIGNUM *serial, char *startdate,char *enddate, int days,
190 int batch, char *ext_sect, LHASH *conf,int verbose);
191 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
192 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
193 TXT_DB *db, BIGNUM *serial,char *startdate,
194 char *enddate, int days, int batch, char *ext_sect,
195 LHASH *conf,int verbose);
196 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
197 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
198 TXT_DB *db, BIGNUM *serial,char *startdate,
199 char *enddate, int days, char *ext_sect,LHASH *conf,
201 static int fix_data(int nid, int *type);
202 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
203 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
204 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
205 char *startdate, char *enddate, int days, int batch, int verbose,
206 X509_REQ *req, char *ext_sect, LHASH *conf);
207 static int do_revoke(X509 *x509, TXT_DB *db);
208 static int check_time_format(char *str);
209 static LHASH *conf=NULL;
210 static char *section=NULL;
212 static int preserve=0;
213 static int msie_hack=0;
215 int MAIN(int, char **);
217 int MAIN(int argc, char **argv)
231 char *configfile=NULL;
237 char *spkac_file=NULL;
238 char *ss_cert_file=NULL;
243 char *serialfile=NULL;
244 char *extensions=NULL;
247 char *startdate=NULL;
254 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
258 X509_CRL_INFO *ci=NULL;
259 X509_REVOKED *r=NULL;
263 const EVP_MD *dgst=NULL;
264 STACK_OF(CONF_VALUE) *attribs=NULL;
265 STACK_OF(X509) *cert_sk=NULL;
269 MS_STATIC char buf[3][BSIZE];
287 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
288 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
294 if (strcmp(*argv,"-verbose") == 0)
296 else if (strcmp(*argv,"-config") == 0)
298 if (--argc < 1) goto bad;
299 configfile= *(++argv);
301 else if (strcmp(*argv,"-name") == 0)
303 if (--argc < 1) goto bad;
306 else if (strcmp(*argv,"-startdate") == 0)
308 if (--argc < 1) goto bad;
309 startdate= *(++argv);
311 else if (strcmp(*argv,"-enddate") == 0)
313 if (--argc < 1) goto bad;
316 else if (strcmp(*argv,"-days") == 0)
318 if (--argc < 1) goto bad;
319 days=atoi(*(++argv));
321 else if (strcmp(*argv,"-md") == 0)
323 if (--argc < 1) goto bad;
326 else if (strcmp(*argv,"-policy") == 0)
328 if (--argc < 1) goto bad;
331 else if (strcmp(*argv,"-keyfile") == 0)
333 if (--argc < 1) goto bad;
336 else if (strcmp(*argv,"-key") == 0)
338 if (--argc < 1) goto bad;
341 else if (strcmp(*argv,"-cert") == 0)
343 if (--argc < 1) goto bad;
346 else if (strcmp(*argv,"-in") == 0)
348 if (--argc < 1) goto bad;
352 else if (strcmp(*argv,"-out") == 0)
354 if (--argc < 1) goto bad;
357 else if (strcmp(*argv,"-outdir") == 0)
359 if (--argc < 1) goto bad;
362 else if (strcmp(*argv,"-notext") == 0)
364 else if (strcmp(*argv,"-batch") == 0)
366 else if (strcmp(*argv,"-preserveDN") == 0)
368 else if (strcmp(*argv,"-gencrl") == 0)
370 else if (strcmp(*argv,"-msie_hack") == 0)
372 else if (strcmp(*argv,"-crldays") == 0)
374 if (--argc < 1) goto bad;
375 crldays= atol(*(++argv));
377 else if (strcmp(*argv,"-crlhours") == 0)
379 if (--argc < 1) goto bad;
380 crlhours= atol(*(++argv));
382 else if (strcmp(*argv,"-infiles") == 0)
389 else if (strcmp(*argv, "-ss_cert") == 0)
391 if (--argc < 1) goto bad;
392 ss_cert_file = *(++argv);
395 else if (strcmp(*argv, "-spkac") == 0)
397 if (--argc < 1) goto bad;
398 spkac_file = *(++argv);
401 else if (strcmp(*argv,"-revoke") == 0)
403 if (--argc < 1) goto bad;
407 else if (strcmp(*argv,"-extensions") == 0)
409 if (--argc < 1) goto bad;
410 extensions= *(++argv);
412 else if (strcmp(*argv,"-crlexts") == 0)
414 if (--argc < 1) goto bad;
420 BIO_printf(bio_err,"unknown option %s\n",*argv);
430 for (pp=ca_usage; (*pp != NULL); pp++)
431 BIO_printf(bio_err,*pp);
435 ERR_load_crypto_strings();
437 /*****************************************************************/
438 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
439 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
440 if (configfile == NULL)
442 /* We will just use 'buf[0]' as a temporary buffer. */
444 strncpy(buf[0],X509_get_default_cert_area(),
445 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
447 strncpy(buf[0],X509_get_default_cert_area(),
448 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
451 strcat(buf[0],CONFIG_FILE);
455 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
456 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
459 BIO_printf(bio_err,"error loading the config file '%s'\n",
462 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
463 ,errorline,configfile);
467 /* Lets get the config section we are using */
470 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
473 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
480 p=CONF_get_string(conf,NULL,"oid_file");
485 oid_bio=BIO_new_file(p,"r");
489 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
490 ERR_print_errors(bio_err);
496 OBJ_create_objects(oid_bio);
500 if(!add_oid_section(bio_err,conf))
502 ERR_print_errors(bio_err);
507 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
508 app_RAND_load_file(randfile, bio_err, 0);
510 in=BIO_new(BIO_s_file());
511 out=BIO_new(BIO_s_file());
512 Sout=BIO_new(BIO_s_file());
513 Cout=BIO_new(BIO_s_file());
514 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
516 ERR_print_errors(bio_err);
520 /*****************************************************************/
521 /* we definitely need an public key, so lets get it */
523 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
524 section,ENV_PRIVATE_KEY)) == NULL))
526 lookup_fail(section,ENV_PRIVATE_KEY);
529 if (BIO_read_filename(in,keyfile) <= 0)
532 BIO_printf(bio_err,"trying to load CA private key\n");
535 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
536 if(key) memset(key,0,strlen(key));
539 BIO_printf(bio_err,"unable to load CA private key\n");
543 /*****************************************************************/
544 /* we need a certificate */
545 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
546 section,ENV_CERTIFICATE)) == NULL))
548 lookup_fail(section,ENV_CERTIFICATE);
551 if (BIO_read_filename(in,certfile) <= 0)
554 BIO_printf(bio_err,"trying to load CA certificate\n");
557 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
560 BIO_printf(bio_err,"unable to load CA certificate\n");
564 if (!X509_check_private_key(x509,pkey))
566 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
570 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
571 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
573 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
574 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
577 /*****************************************************************/
578 /* lookup where to write new certificates */
579 if ((outdir == NULL) && (req))
583 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
586 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
589 #ifndef VMS /* outdir is a directory spec, but access() for VMS demands a
590 filename. In any case, stat(), below, will catch the problem
591 if outdir is not a directory spec, and the fopen() or open()
592 will catch an error if there is no write access.
594 Presumably, this problem could also be solved by using the DEC
595 C routines to convert the directory syntax to Unixly, and give
596 that to access(). However, time's too short to do that just
599 if (access(outdir,R_OK|W_OK|X_OK) != 0)
601 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
606 if (stat(outdir,&sb) != 0)
608 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
613 if (!(sb.st_mode & S_IFDIR))
615 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
623 /*****************************************************************/
624 /* we need to load the database file */
625 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
627 lookup_fail(section,ENV_DATABASE);
630 if (BIO_read_filename(in,dbfile) <= 0)
633 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
636 db=TXT_DB_read(in,DB_NUMBER);
637 if (db == NULL) goto err;
639 /* Lets check some fields */
640 for (i=0; i<sk_num(db->data); i++)
642 pp=(char **)sk_value(db->data,i);
643 if ((pp[DB_type][0] != DB_TYPE_REV) &&
644 (pp[DB_rev_date][0] != '\0'))
646 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
649 if ((pp[DB_type][0] == DB_TYPE_REV) &&
650 !check_time_format(pp[DB_rev_date]))
652 BIO_printf(bio_err,"entry %d: invalid revocation date\n",
656 if (!check_time_format(pp[DB_exp_date]))
658 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
663 if ((j&1) || (j < 2))
665 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
670 if (!( ((*p >= '0') && (*p <= '9')) ||
671 ((*p >= 'A') && (*p <= 'F')) ||
672 ((*p >= 'a') && (*p <= 'f'))) )
674 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);
682 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
683 TXT_DB_write(out,db);
684 BIO_printf(bio_err,"%d entries loaded from the database\n",
686 BIO_printf(bio_err,"generating index\n");
689 if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
692 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
696 if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
699 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
700 db->error,db->arg1,db->arg2);
704 /*****************************************************************/
710 if (BIO_write_filename(Sout,outfile) <= 0)
717 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
722 if ((md == NULL) && ((md=CONF_get_string(conf,
723 section,ENV_DEFAULT_MD)) == NULL))
725 lookup_fail(section,ENV_DEFAULT_MD);
728 if ((dgst=EVP_get_digestbyname(md)) == NULL)
730 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
734 BIO_printf(bio_err,"message digest is %s\n",
735 OBJ_nid2ln(dgst->type));
736 if ((policy == NULL) && ((policy=CONF_get_string(conf,
737 section,ENV_POLICY)) == NULL))
739 lookup_fail(section,ENV_POLICY);
743 BIO_printf(bio_err,"policy is %s\n",policy);
745 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
748 lookup_fail(section,ENV_SERIAL);
752 extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
754 /* Check syntax of file */
756 X509V3_set_ctx_test(&ctx);
757 X509V3_set_conf_lhash(&ctx, conf);
758 if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
760 "Error Loading extension section %s\n",
767 if (startdate == NULL)
769 startdate=CONF_get_string(conf,section,
770 ENV_DEFAULT_STARTDATE);
772 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
774 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
777 if (startdate == NULL) startdate="today";
781 enddate=CONF_get_string(conf,section,
782 ENV_DEFAULT_ENDDATE);
784 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
786 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
792 days=(int)CONF_get_number(conf,section,
795 if (!enddate && (days == 0))
797 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
801 if ((serial=load_serial(serialfile)) == NULL)
803 BIO_printf(bio_err,"error while loading serial number\n");
808 if ((f=BN_bn2hex(serial)) == NULL) goto err;
809 BIO_printf(bio_err,"next serial number is %s\n",f);
813 if ((attribs=CONF_get_section(conf,policy)) == NULL)
815 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
819 if ((cert_sk=sk_X509_new_null()) == NULL)
821 BIO_printf(bio_err,"Memory allocation failure\n");
824 if (spkac_file != NULL)
827 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
828 serial,startdate,enddate, days,extensions,conf,
834 BIO_printf(bio_err,"\n");
835 if (!BN_add_word(serial,1)) goto err;
836 if (!sk_X509_push(cert_sk,x))
838 BIO_printf(bio_err,"Memory allocation failure\n");
848 if (ss_cert_file != NULL)
851 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
852 db,serial,startdate,enddate,days,batch,
853 extensions,conf,verbose);
858 BIO_printf(bio_err,"\n");
859 if (!BN_add_word(serial,1)) goto err;
860 if (!sk_X509_push(cert_sk,x))
862 BIO_printf(bio_err,"Memory allocation failure\n");
870 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
871 serial,startdate,enddate,days,batch,
872 extensions,conf,verbose);
877 BIO_printf(bio_err,"\n");
878 if (!BN_add_word(serial,1)) goto err;
879 if (!sk_X509_push(cert_sk,x))
881 BIO_printf(bio_err,"Memory allocation failure\n");
886 for (i=0; i<argc; i++)
889 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
890 serial,startdate,enddate,days,batch,
891 extensions,conf,verbose);
896 BIO_printf(bio_err,"\n");
897 if (!BN_add_word(serial,1)) goto err;
898 if (!sk_X509_push(cert_sk,x))
900 BIO_printf(bio_err,"Memory allocation failure\n");
905 /* we have a stack of newly certified certificates
906 * and a data base and serial number that need
909 if (sk_X509_num(cert_sk) > 0)
913 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
914 (void)BIO_flush(bio_err);
916 fgets(buf[0],10,stdin);
917 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
919 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
925 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
927 strncpy(buf[0],serialfile,BSIZE-4);
930 strcat(buf[0],"-new");
932 strcat(buf[0],".new");
935 if (!save_serial(buf[0],serial)) goto err;
937 strncpy(buf[1],dbfile,BSIZE-4);
940 strcat(buf[1],"-new");
942 strcat(buf[1],".new");
945 if (BIO_write_filename(out,buf[1]) <= 0)
948 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
951 l=TXT_DB_write(out,db);
952 if (l <= 0) goto err;
956 BIO_printf(bio_err,"writing new certificates\n");
957 for (i=0; i<sk_X509_num(cert_sk); i++)
962 x=sk_X509_value(cert_sk,i);
964 j=x->cert_info->serialNumber->length;
965 p=(char *)x->cert_info->serialNumber->data;
967 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
973 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
978 sprintf((char *)n,"%02X",(unsigned char)*(p++));
987 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
990 BIO_printf(bio_err,"writing %s\n",buf[2]);
992 if (BIO_write_filename(Cout,buf[2]) <= 0)
997 write_new_certificate(Cout,x, 0, notext);
998 write_new_certificate(Sout,x, output_der, notext);
1001 if (sk_X509_num(cert_sk))
1003 /* Rename the database and the serial file */
1004 strncpy(buf[2],serialfile,BSIZE-4);
1007 strcat(buf[2],"-old");
1009 strcat(buf[2],".old");
1016 if (rename(serialfile,buf[2]) < 0)
1018 BIO_printf(bio_err,"unable to rename %s to %s\n",
1023 if (rename(buf[0],serialfile) < 0)
1025 BIO_printf(bio_err,"unable to rename %s to %s\n",
1028 rename(buf[2],serialfile);
1032 strncpy(buf[2],dbfile,BSIZE-4);
1035 strcat(buf[2],"-old");
1037 strcat(buf[2],".old");
1040 if (rename(dbfile,buf[2]) < 0)
1042 BIO_printf(bio_err,"unable to rename %s to %s\n",
1047 if (rename(buf[1],dbfile) < 0)
1049 BIO_printf(bio_err,"unable to rename %s to %s\n",
1052 rename(buf[2],dbfile);
1055 BIO_printf(bio_err,"Data Base Updated\n");
1059 /*****************************************************************/
1062 if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1064 /* Check syntax of file */
1066 X509V3_set_ctx_test(&ctx);
1067 X509V3_set_conf_lhash(&ctx, conf);
1068 if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
1070 "Error Loading CRL extension section %s\n",
1076 if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
1078 if (!crldays && !crlhours)
1080 crldays=CONF_get_number(conf,section,
1081 ENV_DEFAULT_CRL_DAYS);
1082 crlhours=CONF_get_number(conf,section,
1083 ENV_DEFAULT_CRL_HOURS);
1085 if ((crldays == 0) && (crlhours == 0))
1087 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1091 if (verbose) BIO_printf(bio_err,"making CRL\n");
1092 if ((crl=X509_CRL_new()) == NULL) goto err;
1094 X509_NAME_free(ci->issuer);
1095 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1096 if (ci->issuer == NULL) goto err;
1098 X509_gmtime_adj(ci->lastUpdate,0);
1099 if (ci->nextUpdate == NULL)
1100 ci->nextUpdate=ASN1_UTCTIME_new();
1101 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1103 for (i=0; i<sk_num(db->data); i++)
1105 pp=(char **)sk_value(db->data,i);
1106 if (pp[DB_type][0] == DB_TYPE_REV)
1108 if ((r=X509_REVOKED_new()) == NULL) goto err;
1109 ASN1_STRING_set((ASN1_STRING *)
1111 (unsigned char *)pp[DB_rev_date],
1112 strlen(pp[DB_rev_date]));
1113 /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
1115 (void)BIO_reset(hex);
1116 if (!BIO_puts(hex,pp[DB_serial]))
1118 if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
1119 buf[0],BSIZE)) goto err;
1121 sk_X509_REVOKED_push(ci->revoked,r);
1124 /* sort the data so it will be written in serial
1126 sk_X509_REVOKED_sort(ci->revoked);
1127 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1129 r=sk_X509_REVOKED_value(ci->revoked,i);
1133 /* we now have a CRL */
1134 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1137 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1139 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1146 if (pkey->type == EVP_PKEY_DSA)
1153 /* Add any extensions asked for */
1157 if (ci->version == NULL)
1158 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1159 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1160 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1161 X509V3_set_conf_lhash(&crlctx, conf);
1163 if(!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1164 crl_ext, crl)) goto err;
1167 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1169 PEM_write_bio_X509_CRL(Sout,crl);
1171 /*****************************************************************/
1176 BIO_printf(bio_err,"no input files\n");
1182 if (BIO_read_filename(in,infile) <= 0)
1185 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1188 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1189 if (revcert == NULL)
1191 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1194 j=do_revoke(revcert,db);
1195 if (j <= 0) goto err;
1198 strncpy(buf[0],dbfile,BSIZE-4);
1199 strcat(buf[0],".new");
1200 if (BIO_write_filename(out,buf[0]) <= 0)
1203 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1206 j=TXT_DB_write(out,db);
1207 if (j <= 0) goto err;
1208 strncpy(buf[1],dbfile,BSIZE-4);
1209 strcat(buf[1],".old");
1210 if (rename(dbfile,buf[1]) < 0)
1212 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1216 if (rename(buf[0],dbfile) < 0)
1218 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1220 rename(buf[1],dbfile);
1223 BIO_printf(bio_err,"Data Base Updated\n");
1226 /*****************************************************************/
1235 sk_X509_pop_free(cert_sk,X509_free);
1237 if (ret) ERR_print_errors(bio_err);
1238 app_RAND_write_file(randfile, bio_err);
1241 EVP_PKEY_free(pkey);
1249 static void lookup_fail(char *name, char *tag)
1251 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1254 static unsigned long index_serial_hash(char **a)
1259 while (*n == '0') n++;
1260 return(lh_strhash(n));
1263 static int index_serial_cmp(char **a, char **b)
1267 for (aa=a[DB_serial]; *aa == '0'; aa++);
1268 for (bb=b[DB_serial]; *bb == '0'; bb++);
1269 return(strcmp(aa,bb));
1272 static unsigned long index_name_hash(char **a)
1273 { return(lh_strhash(a[DB_name])); }
1275 static int index_name_qual(char **a)
1276 { return(a[0][0] == 'V'); }
1278 static int index_name_cmp(char **a, char **b)
1279 { return(strcmp(a[DB_name],
1282 static BIGNUM *load_serial(char *serialfile)
1286 MS_STATIC char buf[1024];
1287 ASN1_INTEGER *ai=NULL;
1289 if ((in=BIO_new(BIO_s_file())) == NULL)
1291 ERR_print_errors(bio_err);
1295 if (BIO_read_filename(in,serialfile) <= 0)
1300 ai=ASN1_INTEGER_new();
1301 if (ai == NULL) goto err;
1302 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1304 BIO_printf(bio_err,"unable to load number from %s\n",
1308 ret=ASN1_INTEGER_to_BN(ai,NULL);
1311 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1315 if (in != NULL) BIO_free(in);
1316 if (ai != NULL) ASN1_INTEGER_free(ai);
1320 static int save_serial(char *serialfile, BIGNUM *serial)
1324 ASN1_INTEGER *ai=NULL;
1326 out=BIO_new(BIO_s_file());
1329 ERR_print_errors(bio_err);
1332 if (BIO_write_filename(out,serialfile) <= 0)
1338 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1340 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1343 i2a_ASN1_INTEGER(out,ai);
1347 if (out != NULL) BIO_free(out);
1348 if (ai != NULL) ASN1_INTEGER_free(ai);
1352 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1353 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1354 BIGNUM *serial, char *startdate, char *enddate, int days,
1355 int batch, char *ext_sect, LHASH *lconf, int verbose)
1359 EVP_PKEY *pktmp=NULL;
1362 in=BIO_new(BIO_s_file());
1364 if (BIO_read_filename(in,infile) <= 0)
1369 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1371 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1376 X509_REQ_print(bio_err,req);
1378 BIO_printf(bio_err,"Check that the request matches the signature\n");
1380 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1382 BIO_printf(bio_err,"error unpacking public key\n");
1385 i=X509_REQ_verify(req,pktmp);
1386 EVP_PKEY_free(pktmp);
1390 BIO_printf(bio_err,"Signature verification problems....\n");
1396 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1400 BIO_printf(bio_err,"Signature ok\n");
1402 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate,
1403 days,batch,verbose,req,ext_sect,lconf);
1406 if (req != NULL) X509_REQ_free(req);
1407 if (in != NULL) BIO_free(in);
1411 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1412 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1413 BIGNUM *serial, char *startdate, char *enddate, int days,
1414 int batch, char *ext_sect, LHASH *lconf, int verbose)
1417 X509_REQ *rreq=NULL;
1419 EVP_PKEY *pktmp=NULL;
1422 in=BIO_new(BIO_s_file());
1424 if (BIO_read_filename(in,infile) <= 0)
1429 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1431 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1435 X509_print(bio_err,req);
1437 BIO_printf(bio_err,"Check that the request matches the signature\n");
1439 if ((pktmp=X509_get_pubkey(req)) == NULL)
1441 BIO_printf(bio_err,"error unpacking public key\n");
1444 i=X509_verify(req,pktmp);
1445 EVP_PKEY_free(pktmp);
1449 BIO_printf(bio_err,"Signature verification problems....\n");
1455 BIO_printf(bio_err,"Signature did not match the certificate\n");
1459 BIO_printf(bio_err,"Signature ok\n");
1461 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1464 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days,
1465 batch,verbose,rreq,ext_sect,lconf);
1468 if (rreq != NULL) X509_REQ_free(rreq);
1469 if (req != NULL) X509_free(req);
1470 if (in != NULL) BIO_free(in);
1474 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1475 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,
1476 char *startdate, char *enddate, int days, int batch, int verbose,
1477 X509_REQ *req, char *ext_sect, LHASH *lconf)
1479 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1480 ASN1_UTCTIME *tm,*tmptm;
1481 ASN1_STRING *str,*str2;
1485 X509_NAME_ENTRY *ne;
1486 X509_NAME_ENTRY *tne,*push;
1488 int ok= -1,i,j,last,nid;
1491 char *row[DB_NUMBER],**rrow,**irow=NULL;
1494 tmptm=ASN1_UTCTIME_new();
1497 BIO_printf(bio_err,"malloc error\n");
1501 for (i=0; i<DB_NUMBER; i++)
1504 BIO_printf(bio_err,"The Subjects Distinguished Name is as follows\n");
1505 name=X509_REQ_get_subject_name(req);
1506 for (i=0; i<X509_NAME_entry_count(name); i++)
1508 ne=(X509_NAME_ENTRY *)X509_NAME_get_entry(name,i);
1509 obj=X509_NAME_ENTRY_get_object(ne);
1510 j=i2a_ASN1_OBJECT(bio_err,obj);
1511 str=X509_NAME_ENTRY_get_data(ne);
1513 for (j=22-j; j>0; j--)
1517 BIO_puts(bio_err,buf);
1521 /* assume all type should be strings */
1522 nid=OBJ_obj2nid(ne->object);
1524 if (str->type == V_ASN1_UNIVERSALSTRING)
1525 ASN1_UNIVERSALSTRING_to_string(str);
1527 if ((str->type == V_ASN1_IA5STRING) &&
1528 (nid != NID_pkcs9_emailAddress))
1529 str->type=V_ASN1_T61STRING;
1531 if ((nid == NID_pkcs9_emailAddress) &&
1532 (str->type == V_ASN1_PRINTABLESTRING))
1533 str->type=V_ASN1_IA5STRING;
1536 if (str->type == V_ASN1_PRINTABLESTRING)
1537 BIO_printf(bio_err,"PRINTABLE:'");
1538 else if (str->type == V_ASN1_T61STRING)
1539 BIO_printf(bio_err,"T61STRING:'");
1540 else if (str->type == V_ASN1_IA5STRING)
1541 BIO_printf(bio_err,"IA5STRING:'");
1542 else if (str->type == V_ASN1_UNIVERSALSTRING)
1543 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1545 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1547 /* check some things */
1548 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1549 (str->type != V_ASN1_IA5STRING))
1551 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1554 j=ASN1_PRINTABLE_type(str->data,str->length);
1555 if ( ((j == V_ASN1_T61STRING) &&
1556 (str->type != V_ASN1_T61STRING)) ||
1557 ((j == V_ASN1_IA5STRING) &&
1558 (str->type == V_ASN1_PRINTABLESTRING)))
1560 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1564 p=(char *)str->data;
1565 for (j=str->length; j>0; j--)
1567 if ((*p >= ' ') && (*p <= '~'))
1568 BIO_printf(bio_err,"%c",*p);
1570 BIO_printf(bio_err,"\\0x%02X",*p);
1571 else if ((unsigned char)*p == 0xf7)
1572 BIO_printf(bio_err,"^?");
1573 else BIO_printf(bio_err,"^%c",*p+'@');
1576 BIO_printf(bio_err,"'\n");
1579 /* Ok, now we check the 'policy' stuff. */
1580 if ((subject=X509_NAME_new()) == NULL)
1582 BIO_printf(bio_err,"Memory allocation failure\n");
1586 /* take a copy of the issuer name before we mess with it. */
1587 CAname=X509_NAME_dup(x509->cert_info->subject);
1588 if (CAname == NULL) goto err;
1591 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1593 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1594 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1596 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1604 /* lookup the object in the supplied name list */
1605 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1608 if (last != -1) break;
1613 tne=X509_NAME_get_entry(name,j);
1617 /* depending on the 'policy', decide what to do. */
1619 if (strcmp(cv->value,"optional") == 0)
1624 else if (strcmp(cv->value,"supplied") == 0)
1628 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1634 else if (strcmp(cv->value,"match") == 0)
1640 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1647 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1648 if ((j < 0) && (last2 == -1))
1650 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1655 push=X509_NAME_get_entry(CAname,j);
1656 str=X509_NAME_ENTRY_get_data(tne);
1657 str2=X509_NAME_ENTRY_get_data(push);
1659 if (ASN1_STRING_cmp(str,str2) != 0)
1664 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));
1670 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
1676 if (!X509_NAME_add_entry(subject,push, -1, 0))
1679 X509_NAME_ENTRY_free(push);
1680 BIO_printf(bio_err,"Memory allocation failure\n");
1690 X509_NAME_free(subject);
1691 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
1692 if (subject == NULL) goto err;
1696 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
1698 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
1699 row[DB_serial]=BN_bn2hex(serial);
1700 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
1702 BIO_printf(bio_err,"Memory allocation failure\n");
1706 rrow=TXT_DB_get_by_index(db,DB_name,row);
1709 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
1714 rrow=TXT_DB_get_by_index(db,DB_serial,row);
1717 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
1719 BIO_printf(bio_err," check the database/serial_file for corruption\n");
1726 "The matching entry has the following details\n");
1727 if (rrow[DB_type][0] == 'E')
1729 else if (rrow[DB_type][0] == 'R')
1731 else if (rrow[DB_type][0] == 'V')
1734 p="\ninvalid type, Data base error\n";
1735 BIO_printf(bio_err,"Type :%s\n",p);;
1736 if (rrow[DB_type][0] == 'R')
1738 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1739 BIO_printf(bio_err,"Was revoked on:%s\n",p);
1741 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
1742 BIO_printf(bio_err,"Expires on :%s\n",p);
1743 p=rrow[DB_serial]; if (p == NULL) p="undef";
1744 BIO_printf(bio_err,"Serial Number :%s\n",p);
1745 p=rrow[DB_file]; if (p == NULL) p="undef";
1746 BIO_printf(bio_err,"File name :%s\n",p);
1747 p=rrow[DB_name]; if (p == NULL) p="undef";
1748 BIO_printf(bio_err,"Subject Name :%s\n",p);
1749 ok= -1; /* This is now a 'bad' error. */
1753 /* We are now totally happy, lets make and sign the certificate */
1755 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
1757 if ((ret=X509_new()) == NULL) goto err;
1761 /* Make it an X509 v3 certificate. */
1762 if (!X509_set_version(x509,2)) goto err;
1765 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1767 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1770 BIO_printf(bio_err,"Certificate is to be certified until ");
1771 if (strcmp(startdate,"today") == 0)
1772 X509_gmtime_adj(X509_get_notBefore(ret),0);
1773 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
1775 if (enddate == NULL)
1776 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
1777 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
1779 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
1780 if(days) BIO_printf(bio_err," (%d days)",days);
1781 BIO_printf(bio_err, "\n");
1783 if (!X509_set_subject_name(ret,subject)) goto err;
1785 pktmp=X509_REQ_get_pubkey(req);
1786 i = X509_set_pubkey(ret,pktmp);
1787 EVP_PKEY_free(pktmp);
1790 /* Lets add the extensions, if there are any */
1794 if (ci->version == NULL)
1795 if ((ci->version=ASN1_INTEGER_new()) == NULL)
1797 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
1799 /* Free the current entries if any, there should not
1800 * be any I believe */
1801 if (ci->extensions != NULL)
1802 sk_X509_EXTENSION_pop_free(ci->extensions,
1803 X509_EXTENSION_free);
1805 ci->extensions = NULL;
1807 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1808 X509V3_set_conf_lhash(&ctx, lconf);
1810 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err;
1817 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
1818 (void)BIO_flush(bio_err);
1820 fgets(buf,sizeof(buf)-1,stdin);
1821 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
1823 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
1831 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
1832 pktmp=X509_get_pubkey(ret);
1833 if (EVP_PKEY_missing_parameters(pktmp) &&
1834 !EVP_PKEY_missing_parameters(pkey))
1835 EVP_PKEY_copy_parameters(pktmp,pkey);
1836 EVP_PKEY_free(pktmp);
1839 if (!X509_sign(ret,pkey,dgst))
1842 /* We now just add it to the database */
1843 row[DB_type]=(char *)OPENSSL_malloc(2);
1845 tm=X509_get_notAfter(ret);
1846 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
1847 memcpy(row[DB_exp_date],tm->data,tm->length);
1848 row[DB_exp_date][tm->length]='\0';
1850 row[DB_rev_date]=NULL;
1852 /* row[DB_serial] done already */
1853 row[DB_file]=(char *)OPENSSL_malloc(8);
1854 /* row[DB_name] done already */
1856 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
1857 (row[DB_file] == NULL))
1859 BIO_printf(bio_err,"Memory allocation failure\n");
1862 strcpy(row[DB_file],"unknown");
1863 row[DB_type][0]='V';
1864 row[DB_type][1]='\0';
1866 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
1868 BIO_printf(bio_err,"Memory allocation failure\n");
1872 for (i=0; i<DB_NUMBER; i++)
1877 irow[DB_NUMBER]=NULL;
1879 if (!TXT_DB_insert(db,irow))
1881 BIO_printf(bio_err,"failed to update database\n");
1882 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
1887 for (i=0; i<DB_NUMBER; i++)
1888 if (row[i] != NULL) OPENSSL_free(row[i]);
1891 X509_NAME_free(CAname);
1892 if (subject != NULL)
1893 X509_NAME_free(subject);
1895 ASN1_UTCTIME_free(tmptm);
1898 if (ret != NULL) X509_free(ret);
1906 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1911 (void)i2d_X509_bio(bp,x);
1915 /* ??? Not needed since X509_print prints all this stuff anyway */
1916 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
1917 BIO_printf(bp,"issuer :%s\n",f);
1919 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
1920 BIO_printf(bp,"subject:%s\n",f);
1922 BIO_puts(bp,"serial :");
1923 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
1924 BIO_puts(bp,"\n\n");
1926 if(!notext)X509_print(bp,x);
1927 PEM_write_bio_X509(bp,x);
1930 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1931 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1932 BIGNUM *serial, char *startdate, char *enddate, int days,
1933 char *ext_sect, LHASH *lconf, int verbose)
1935 STACK_OF(CONF_VALUE) *sk=NULL;
1938 CONF_VALUE *cv=NULL;
1939 NETSCAPE_SPKI *spki = NULL;
1942 EVP_PKEY *pktmp=NULL;
1944 X509_NAME_ENTRY *ne=NULL;
1950 * Load input file into a hash table. (This is just an easy
1951 * way to read and parse the file, then put it into a convenient
1954 parms=CONF_load(NULL,infile,&errline);
1957 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
1958 ERR_print_errors(bio_err);
1962 sk=CONF_get_section(parms, "default");
1963 if (sk_CONF_VALUE_num(sk) == 0)
1965 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
1971 * Now create a dummy X509 request structure. We don't actually
1972 * have an X509 request, but we have many of the components
1973 * (a public key, various DN components). The idea is that we
1974 * put these components into the right X509 request structure
1975 * and we can use the same code as if you had a real X509 request.
1980 ERR_print_errors(bio_err);
1985 * Build up the subject name set.
1992 if (sk_CONF_VALUE_num(sk) <= i) break;
1994 cv=sk_CONF_VALUE_value(sk,i);
1996 /* Skip past any leading X. X: X, etc to allow for
1997 * multiple instances
1999 for(buf = cv->name; *buf ; buf++)
2000 if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2002 if(*buf) type = buf;
2007 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2009 if (strcmp(type, "SPKAC") == 0)
2011 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2014 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2015 ERR_print_errors(bio_err);
2022 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2023 if (fix_data(nid, &j) == 0)
2026 "invalid characters in string %s\n",buf);
2030 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2031 (unsigned char *)buf,
2032 strlen(buf))) == NULL)
2035 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2039 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2045 * Now extract the key from the SPKI structure.
2048 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2050 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2052 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2056 j = NETSCAPE_SPKI_verify(spki, pktmp);
2059 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2062 BIO_printf(bio_err,"Signature ok\n");
2064 X509_REQ_set_pubkey(req,pktmp);
2065 EVP_PKEY_free(pktmp);
2066 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,
2067 days,1,verbose,req,ext_sect,lconf);
2069 if (req != NULL) X509_REQ_free(req);
2070 if (parms != NULL) CONF_free(parms);
2071 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2072 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2077 static int fix_data(int nid, int *type)
2079 if (nid == NID_pkcs9_emailAddress)
2080 *type=V_ASN1_IA5STRING;
2081 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2082 *type=V_ASN1_T61STRING;
2083 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2084 *type=V_ASN1_T61STRING;
2085 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2087 if (nid == NID_pkcs9_unstructuredName)
2088 *type=V_ASN1_IA5STRING;
2092 static int check_time_format(char *str)
2096 tm.data=(unsigned char *)str;
2097 tm.length=strlen(str);
2098 tm.type=V_ASN1_UTCTIME;
2099 return(ASN1_UTCTIME_check(&tm));
2102 static int do_revoke(X509 *x509, TXT_DB *db)
2104 ASN1_UTCTIME *tm=NULL, *revtm=NULL;
2105 char *row[DB_NUMBER],**rrow,**irow;
2109 for (i=0; i<DB_NUMBER; i++)
2111 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2112 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2113 row[DB_serial]=BN_bn2hex(bn);
2115 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2117 BIO_printf(bio_err,"Memory allocation failure\n");
2120 /* We have to lookup by serial number because name lookup
2121 * skips revoked certs
2123 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2126 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2128 /* We now just add it to the database */
2129 row[DB_type]=(char *)OPENSSL_malloc(2);
2131 tm=X509_get_notAfter(x509);
2132 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2133 memcpy(row[DB_exp_date],tm->data,tm->length);
2134 row[DB_exp_date][tm->length]='\0';
2136 row[DB_rev_date]=NULL;
2138 /* row[DB_serial] done already */
2139 row[DB_file]=(char *)OPENSSL_malloc(8);
2141 /* row[DB_name] done already */
2143 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2144 (row[DB_file] == NULL))
2146 BIO_printf(bio_err,"Memory allocation failure\n");
2149 strcpy(row[DB_file],"unknown");
2150 row[DB_type][0]='V';
2151 row[DB_type][1]='\0';
2153 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2155 BIO_printf(bio_err,"Memory allocation failure\n");
2159 for (i=0; i<DB_NUMBER; i++)
2164 irow[DB_NUMBER]=NULL;
2166 if (!TXT_DB_insert(db,irow))
2168 BIO_printf(bio_err,"failed to update database\n");
2169 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2173 /* Revoke Certificate */
2174 ok = do_revoke(x509,db);
2179 else if (index_name_cmp(row,rrow))
2181 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2185 else if (rrow[DB_type][0]=='R')
2187 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2193 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2194 revtm = ASN1_UTCTIME_new();
2195 revtm=X509_gmtime_adj(revtm,0);
2196 rrow[DB_type][0]='R';
2197 rrow[DB_type][1]='\0';
2198 rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1);
2199 memcpy(rrow[DB_rev_date],revtm->data,revtm->length);
2200 rrow[DB_rev_date][revtm->length]='\0';
2201 ASN1_UTCTIME_free(revtm);
2205 for (i=0; i<DB_NUMBER; i++)
2208 OPENSSL_free(row[i]);