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> */
65 #include <sys/types.h>
68 #include <openssl/conf.h>
69 #include <openssl/bio.h>
70 #include <openssl/err.h>
71 #include <openssl/bn.h>
72 #include <openssl/txt_db.h>
73 #include <openssl/evp.h>
74 #include <openssl/x509.h>
75 #include <openssl/x509v3.h>
76 #include <openssl/objects.h>
77 #include <openssl/ocsp.h>
78 #include <openssl/pem.h>
79 #include <openssl/engine.h>
81 #ifdef OPENSSL_SYS_WINDOWS
82 #define strcasecmp _stricmp
88 # ifdef OPENSSL_SYS_VMS
95 # include <sys/file.h>
109 #define BASE_SECTION "ca"
110 #define CONFIG_FILE "openssl.cnf"
112 #define ENV_DEFAULT_CA "default_ca"
114 #define ENV_DIR "dir"
115 #define ENV_CERTS "certs"
116 #define ENV_CRL_DIR "crl_dir"
117 #define ENV_CA_DB "CA_DB"
118 #define ENV_NEW_CERTS_DIR "new_certs_dir"
119 #define ENV_CERTIFICATE "certificate"
120 #define ENV_SERIAL "serial"
121 #define ENV_CRL "crl"
122 #define ENV_PRIVATE_KEY "private_key"
123 #define ENV_RANDFILE "RANDFILE"
124 #define ENV_DEFAULT_DAYS "default_days"
125 #define ENV_DEFAULT_STARTDATE "default_startdate"
126 #define ENV_DEFAULT_ENDDATE "default_enddate"
127 #define ENV_DEFAULT_CRL_DAYS "default_crl_days"
128 #define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
129 #define ENV_DEFAULT_MD "default_md"
130 #define ENV_PRESERVE "preserve"
131 #define ENV_POLICY "policy"
132 #define ENV_EXTENSIONS "x509_extensions"
133 #define ENV_CRLEXT "crl_extensions"
134 #define ENV_MSIE_HACK "msie_hack"
135 #define ENV_NAMEOPT "name_opt"
136 #define ENV_CERTOPT "cert_opt"
138 #define ENV_DATABASE "database"
141 #define DB_exp_date 1
142 #define DB_rev_date 2
143 #define DB_serial 3 /* index - unique */
145 #define DB_name 5 /* index - unique for active */
148 #define DB_TYPE_REV 'R'
149 #define DB_TYPE_EXP 'E'
150 #define DB_TYPE_VAL 'V'
152 /* Additional revocation information types */
154 #define REV_NONE 0 /* No addditional information */
155 #define REV_CRL_REASON 1 /* Value is CRL reason code */
156 #define REV_HOLD 2 /* Value is hold instruction */
157 #define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
158 #define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
160 static char *ca_usage[]={
163 " -verbose - Talk alot while doing things\n",
164 " -config file - A config file\n",
165 " -name arg - The particular CA definition to use\n",
166 " -gencrl - Generate a new CRL\n",
167 " -crldays days - Days is when the next CRL is due\n",
168 " -crlhours hours - Hours is when the next CRL is due\n",
169 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
170 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
171 " -days arg - number of days to certify the certificate for\n",
172 " -md arg - md to use, one of md2, md5, sha or sha1\n",
173 " -policy arg - The CA 'policy' to support\n",
174 " -keyfile arg - private key file\n",
175 " -keyform arg - private key file format (PEM or ENGINE)\n",
176 " -key arg - key to decode the private key if it is encrypted\n",
177 " -cert file - The CA certificate\n",
178 " -in file - The input PEM encoded certificate request(s)\n",
179 " -out file - Where to put the output file(s)\n",
180 " -outdir dir - Where to put output certificates\n",
181 " -infiles .... - The last argument, requests to process\n",
182 " -spkac file - File contains DN and signed public key and challenge\n",
183 " -ss_cert file - File contains a self signed cert to sign\n",
184 " -preserveDN - Don't re-order the DN\n",
185 " -batch - Don't ask questions\n",
186 " -msie_hack - msie modifications to handle all those universal strings\n",
187 " -revoke file - Revoke a certificate (given in file)\n",
188 " -subj arg - Use arg instead of request's subject\n",
189 " -extensions .. - Extension section (override value in config file)\n",
190 " -extfile file - Configuration file with X509v3 extentions to add\n",
191 " -crlexts .. - CRL extension section (override value in config file)\n",
192 " -engine e - use engine e, possibly a hardware device.\n",
193 " -status serial - Shows certificate status given the serial number\n",
194 " -updatedb - Updates db for expired certificates\n",
199 extern int EF_PROTECT_FREE;
200 extern int EF_PROTECT_BELOW;
201 extern int EF_ALIGNMENT;
204 static void lookup_fail(char *name,char *tag);
205 static unsigned long index_serial_hash(const char **a);
206 static int index_serial_cmp(const char **a, const char **b);
207 static unsigned long index_name_hash(const char **a);
208 static int index_name_qual(char **a);
209 static int index_name_cmp(const char **a,const char **b);
210 static BIGNUM *load_serial(char *serialfile);
211 static int save_serial(char *serialfile, BIGNUM *serial);
212 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
213 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
214 BIGNUM *serial, char *subj, char *startdate,char *enddate,
215 int days, int batch, char *ext_sect, LHASH *conf,int verbose,
216 unsigned long certopt, unsigned long nameopt, int default_op,
218 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
219 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
220 TXT_DB *db, BIGNUM *serial, char *subj, char *startdate,
221 char *enddate, int days, int batch, char *ext_sect,
222 LHASH *conf,int verbose, unsigned long certopt,
223 unsigned long nameopt, int default_op, int ext_copy);
224 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
225 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
226 TXT_DB *db, BIGNUM *serial,char *subj, char *startdate,
227 char *enddate, int days, char *ext_sect,LHASH *conf,
228 int verbose, unsigned long certopt, unsigned long nameopt,
229 int default_op, int ext_copy);
230 static int fix_data(int nid, int *type);
231 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
232 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
233 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
234 char *startdate, char *enddate, int days, int batch, int verbose,
235 X509_REQ *req, char *ext_sect, LHASH *conf,
236 unsigned long certopt, unsigned long nameopt, int default_op,
238 static X509_NAME *do_subject(char *subject);
239 static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
240 static int get_certificate_status(const char *ser_status, TXT_DB *db);
241 static int do_updatedb(TXT_DB *db);
242 static int check_time_format(char *str);
243 char *make_revocation_str(int rev_type, char *rev_arg);
244 int make_revoked(X509_REVOKED *rev, char *str);
245 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
246 static LHASH *conf=NULL;
247 static LHASH *extconf=NULL;
248 static char *section=NULL;
250 static int preserve=0;
251 static int msie_hack=0;
253 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
254 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
255 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
256 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
259 int MAIN(int, char **);
261 int MAIN(int argc, char **argv)
264 char *key=NULL,*passargin=NULL;
277 char *configfile=NULL;
282 int keyform=FORMAT_PEM;
284 char *spkac_file=NULL;
285 char *ss_cert_file=NULL;
286 char *ser_status=NULL;
291 char *serialfile=NULL;
292 char *extensions=NULL;
296 int rev_type = REV_NONE;
297 char *rev_arg = NULL;
299 char *startdate=NULL;
304 unsigned long nameopt = 0, certopt = 0;
309 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
313 X509_CRL_INFO *ci=NULL;
314 X509_REVOKED *r=NULL;
318 const EVP_MD *dgst=NULL;
319 STACK_OF(CONF_VALUE) *attribs=NULL;
320 STACK_OF(X509) *cert_sk=NULL;
323 MS_STATIC char buf[3][BSIZE];
342 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
343 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
349 if (strcmp(*argv,"-verbose") == 0)
351 else if (strcmp(*argv,"-config") == 0)
353 if (--argc < 1) goto bad;
354 configfile= *(++argv);
356 else if (strcmp(*argv,"-name") == 0)
358 if (--argc < 1) goto bad;
361 else if (strcmp(*argv,"-subj") == 0)
363 if (--argc < 1) goto bad;
367 else if (strcmp(*argv,"-startdate") == 0)
369 if (--argc < 1) goto bad;
370 startdate= *(++argv);
372 else if (strcmp(*argv,"-enddate") == 0)
374 if (--argc < 1) goto bad;
377 else if (strcmp(*argv,"-days") == 0)
379 if (--argc < 1) goto bad;
380 days=atoi(*(++argv));
382 else if (strcmp(*argv,"-md") == 0)
384 if (--argc < 1) goto bad;
387 else if (strcmp(*argv,"-policy") == 0)
389 if (--argc < 1) goto bad;
392 else if (strcmp(*argv,"-keyfile") == 0)
394 if (--argc < 1) goto bad;
397 else if (strcmp(*argv,"-keyform") == 0)
399 if (--argc < 1) goto bad;
400 keyform=str2fmt(*(++argv));
402 else if (strcmp(*argv,"-passin") == 0)
404 if (--argc < 1) goto bad;
405 passargin= *(++argv);
407 else if (strcmp(*argv,"-key") == 0)
409 if (--argc < 1) goto bad;
412 else if (strcmp(*argv,"-cert") == 0)
414 if (--argc < 1) goto bad;
417 else if (strcmp(*argv,"-in") == 0)
419 if (--argc < 1) goto bad;
423 else if (strcmp(*argv,"-out") == 0)
425 if (--argc < 1) goto bad;
428 else if (strcmp(*argv,"-outdir") == 0)
430 if (--argc < 1) goto bad;
433 else if (strcmp(*argv,"-notext") == 0)
435 else if (strcmp(*argv,"-batch") == 0)
437 else if (strcmp(*argv,"-preserveDN") == 0)
439 else if (strcmp(*argv,"-gencrl") == 0)
441 else if (strcmp(*argv,"-msie_hack") == 0)
443 else if (strcmp(*argv,"-crldays") == 0)
445 if (--argc < 1) goto bad;
446 crldays= atol(*(++argv));
448 else if (strcmp(*argv,"-crlhours") == 0)
450 if (--argc < 1) goto bad;
451 crlhours= atol(*(++argv));
453 else if (strcmp(*argv,"-infiles") == 0)
460 else if (strcmp(*argv, "-ss_cert") == 0)
462 if (--argc < 1) goto bad;
463 ss_cert_file = *(++argv);
466 else if (strcmp(*argv, "-spkac") == 0)
468 if (--argc < 1) goto bad;
469 spkac_file = *(++argv);
472 else if (strcmp(*argv,"-revoke") == 0)
474 if (--argc < 1) goto bad;
478 else if (strcmp(*argv,"-extensions") == 0)
480 if (--argc < 1) goto bad;
481 extensions= *(++argv);
483 else if (strcmp(*argv,"-extfile") == 0)
485 if (--argc < 1) goto bad;
488 else if (strcmp(*argv,"-status") == 0)
490 if (--argc < 1) goto bad;
491 ser_status= *(++argv);
493 else if (strcmp(*argv,"-updatedb") == 0)
497 else if (strcmp(*argv,"-crlexts") == 0)
499 if (--argc < 1) goto bad;
502 else if (strcmp(*argv,"-crl_reason") == 0)
504 if (--argc < 1) goto bad;
506 rev_type = REV_CRL_REASON;
508 else if (strcmp(*argv,"-crl_hold") == 0)
510 if (--argc < 1) goto bad;
514 else if (strcmp(*argv,"-crl_compromise") == 0)
516 if (--argc < 1) goto bad;
518 rev_type = REV_KEY_COMPROMISE;
520 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
522 if (--argc < 1) goto bad;
524 rev_type = REV_CA_COMPROMISE;
526 else if (strcmp(*argv,"-engine") == 0)
528 if (--argc < 1) goto bad;
534 BIO_printf(bio_err,"unknown option %s\n",*argv);
544 for (pp=ca_usage; (*pp != NULL); pp++)
545 BIO_printf(bio_err,"%s",*pp);
549 ERR_load_crypto_strings();
553 if ((e = ENGINE_by_id(engine)) == NULL)
555 BIO_printf(bio_err,"invalid engine \"%s\"\n",
559 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
561 BIO_printf(bio_err,"can't use that engine\n");
564 BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
565 /* Free our "structural" reference. */
569 /*****************************************************************/
570 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
571 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
572 if (configfile == NULL)
574 /* We will just use 'buf[0]' as a temporary buffer. */
575 #ifdef OPENSSL_SYS_VMS
576 strncpy(buf[0],X509_get_default_cert_area(),
577 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
579 strncpy(buf[0],X509_get_default_cert_area(),
580 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
583 strcat(buf[0],CONFIG_FILE);
587 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
588 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
591 BIO_printf(bio_err,"error loading the config file '%s'\n",
594 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
595 ,errorline,configfile);
599 /* Lets get the config section we are using */
602 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
605 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
612 p=CONF_get_string(conf,NULL,"oid_file");
619 oid_bio=BIO_new_file(p,"r");
623 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
624 ERR_print_errors(bio_err);
630 OBJ_create_objects(oid_bio);
634 if (!add_oid_section(bio_err,conf))
636 ERR_print_errors(bio_err);
641 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
642 if (randfile == NULL)
644 app_RAND_load_file(randfile, bio_err, 0);
646 in=BIO_new(BIO_s_file());
647 out=BIO_new(BIO_s_file());
648 Sout=BIO_new(BIO_s_file());
649 Cout=BIO_new(BIO_s_file());
650 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
652 ERR_print_errors(bio_err);
656 /*****************************************************************/
657 /* report status of cert with serial number given on command line */
660 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
662 lookup_fail(section,ENV_DATABASE);
665 if (BIO_read_filename(in,dbfile) <= 0)
668 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
671 db=TXT_DB_read(in,DB_NUMBER);
672 if (db == NULL) goto err;
674 if (!TXT_DB_create_index(db, DB_serial, NULL,
675 LHASH_HASH_FN(index_serial_hash),
676 LHASH_COMP_FN(index_serial_cmp)))
679 "error creating serial number index:(%ld,%ld,%ld)\n",
680 db->error,db->arg1,db->arg2);
684 if (get_certificate_status(ser_status,db) != 1)
685 BIO_printf(bio_err,"Error verifying serial %s!\n",
690 /*****************************************************************/
691 /* we definitely need a public key, so let's get it */
693 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
694 section,ENV_PRIVATE_KEY)) == NULL))
696 lookup_fail(section,ENV_PRIVATE_KEY);
699 if (!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
701 BIO_printf(bio_err,"Error getting password\n");
704 if (keyform == FORMAT_ENGINE)
708 BIO_printf(bio_err,"no engine specified\n");
711 pkey = ENGINE_load_private_key(e, keyfile, key);
713 else if (keyform == FORMAT_PEM)
715 if (BIO_read_filename(in,keyfile) <= 0)
718 BIO_printf(bio_err,"trying to load CA private key\n");
721 pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key);
725 BIO_printf(bio_err,"bad input format specified for key file\n");
728 if (key) memset(key,0,strlen(key));
731 BIO_printf(bio_err,"unable to load CA private key\n");
735 /*****************************************************************/
736 /* we need a certificate */
737 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
738 section,ENV_CERTIFICATE)) == NULL))
740 lookup_fail(section,ENV_CERTIFICATE);
743 if (BIO_read_filename(in,certfile) <= 0)
746 BIO_printf(bio_err,"trying to load CA certificate\n");
749 x509=PEM_read_bio_X509(in,NULL,NULL,NULL);
752 BIO_printf(bio_err,"unable to load CA certificate\n");
756 if (!X509_check_private_key(x509,pkey))
758 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
762 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
765 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
767 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
770 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
773 f=CONF_get_string(conf,section,ENV_NAMEOPT);
777 if (!set_name_ex(&nameopt, f))
779 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
787 f=CONF_get_string(conf,section,ENV_CERTOPT);
791 if (!set_cert_ex(&certopt, f))
793 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
802 /*****************************************************************/
803 /* lookup where to write new certificates */
804 if ((outdir == NULL) && (req))
808 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
811 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
814 #ifndef OPENSSL_SYS_VMS
815 /* outdir is a directory spec, but access() for VMS demands a
816 filename. In any case, stat(), below, will catch the problem
817 if outdir is not a directory spec, and the fopen() or open()
818 will catch an error if there is no write access.
820 Presumably, this problem could also be solved by using the DEC
821 C routines to convert the directory syntax to Unixly, and give
822 that to access(). However, time's too short to do that just
825 if (access(outdir,R_OK|W_OK|X_OK) != 0)
827 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
832 if (stat(outdir,&sb) != 0)
834 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
839 if (!(sb.st_mode & S_IFDIR))
841 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
849 /*****************************************************************/
850 /* we need to load the database file */
851 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
853 lookup_fail(section,ENV_DATABASE);
856 if (BIO_read_filename(in,dbfile) <= 0)
859 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
862 db=TXT_DB_read(in,DB_NUMBER);
863 if (db == NULL) goto err;
865 /* Lets check some fields */
866 for (i=0; i<sk_num(db->data); i++)
868 pp=(char **)sk_value(db->data,i);
869 if ((pp[DB_type][0] != DB_TYPE_REV) &&
870 (pp[DB_rev_date][0] != '\0'))
872 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
875 if ((pp[DB_type][0] == DB_TYPE_REV) &&
876 !make_revoked(NULL, pp[DB_rev_date]))
878 BIO_printf(bio_err," in entry %d\n", i+1);
881 if (!check_time_format(pp[DB_exp_date]))
883 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
893 if ((j&1) || (j < 2))
895 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
900 if (!( ((*p >= '0') && (*p <= '9')) ||
901 ((*p >= 'A') && (*p <= 'F')) ||
902 ((*p >= 'a') && (*p <= 'f'))) )
904 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);
912 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
913 #ifdef OPENSSL_SYS_VMS
915 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
916 out = BIO_push(tmpbio, out);
919 TXT_DB_write(out,db);
920 BIO_printf(bio_err,"%d entries loaded from the database\n",
922 BIO_printf(bio_err,"generating index\n");
925 if (!TXT_DB_create_index(db, DB_serial, NULL,
926 LHASH_HASH_FN(index_serial_hash),
927 LHASH_COMP_FN(index_serial_cmp)))
929 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
933 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
934 LHASH_HASH_FN(index_name_hash),
935 LHASH_COMP_FN(index_name_cmp)))
937 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
938 db->error,db->arg1,db->arg2);
942 /*****************************************************************/
943 /* Update the db file for expired certificates */
947 BIO_printf(bio_err, "Updating %s ...\n",
953 BIO_printf(bio_err,"Malloc failure\n");
958 if (verbose) BIO_printf(bio_err,
959 "No entries found to mark expired\n");
963 out = BIO_new(BIO_s_file());
966 ERR_print_errors(bio_err);
970 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
971 if (j < 0 || j >= sizeof buf[0])
973 BIO_printf(bio_err, "file name too long\n");
976 if (BIO_write_filename(out,buf[0]) <= 0)
979 BIO_printf(bio_err,"unable to open '%s'\n",
983 j=TXT_DB_write(out,db);
984 if (j <= 0) goto err;
988 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
989 if (j < 0 || j >= sizeof buf[1])
991 BIO_printf(bio_err, "file name too long\n");
994 if (rename(dbfile,buf[1]) < 0)
997 "unable to rename %s to %s\n",
1002 if (rename(buf[0],dbfile) < 0)
1005 "unable to rename %s to %s\n",
1008 rename(buf[1],dbfile);
1012 if (verbose) BIO_printf(bio_err,
1013 "Done. %d entries marked as expired\n",i);
1018 /*****************************************************************/
1019 /* Read extentions config file */
1022 if (!(extconf=CONF_load(NULL,extfile,&errorline)))
1025 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
1028 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
1035 BIO_printf(bio_err, "Succesfully loaded extensions file %s\n", extfile);
1037 /* We can have sections in the ext file */
1038 if (!extensions && !(extensions = CONF_get_string(extconf, "default", "extensions")))
1039 extensions = "default";
1042 /*****************************************************************/
1045 if (outfile != NULL)
1047 if (BIO_write_filename(Sout,outfile) <= 0)
1055 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1056 #ifdef OPENSSL_SYS_VMS
1058 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1059 Sout = BIO_push(tmpbio, Sout);
1067 if ((md == NULL) && ((md=CONF_get_string(conf,
1068 section,ENV_DEFAULT_MD)) == NULL))
1070 lookup_fail(section,ENV_DEFAULT_MD);
1073 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1075 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1079 BIO_printf(bio_err,"message digest is %s\n",
1080 OBJ_nid2ln(dgst->type));
1081 if ((policy == NULL) && ((policy=CONF_get_string(conf,
1082 section,ENV_POLICY)) == NULL))
1084 lookup_fail(section,ENV_POLICY);
1088 BIO_printf(bio_err,"policy is %s\n",policy);
1090 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
1093 lookup_fail(section,ENV_SERIAL);
1099 /* no '-extfile' option, so we look for extensions
1100 * in the main configuration file */
1103 extensions=CONF_get_string(conf,section,
1110 /* Check syntax of file */
1112 X509V3_set_ctx_test(&ctx);
1113 X509V3_set_conf_lhash(&ctx, conf);
1114 if (!X509V3_EXT_add_conf(conf, &ctx, extensions,
1118 "Error Loading extension section %s\n",
1126 if (startdate == NULL)
1128 startdate=CONF_get_string(conf,section,
1129 ENV_DEFAULT_STARTDATE);
1130 if (startdate == NULL)
1133 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1135 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1138 if (startdate == NULL) startdate="today";
1140 if (enddate == NULL)
1142 enddate=CONF_get_string(conf,section,
1143 ENV_DEFAULT_ENDDATE);
1144 if (enddate == NULL)
1147 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1149 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1155 days=(int)CONF_get_number(conf,section,
1158 if (!enddate && (days == 0))
1160 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1164 if ((serial=load_serial(serialfile)) == NULL)
1166 BIO_printf(bio_err,"error while loading serial number\n");
1171 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1172 BIO_printf(bio_err,"next serial number is %s\n",f);
1176 if ((attribs=CONF_get_section(conf,policy)) == NULL)
1178 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1182 if ((cert_sk=sk_X509_new_null()) == NULL)
1184 BIO_printf(bio_err,"Memory allocation failure\n");
1187 if (spkac_file != NULL)
1190 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1191 serial,subj,startdate,enddate, days,extensions,conf,
1192 verbose, certopt, nameopt, default_op, ext_copy);
1193 if (j < 0) goto err;
1197 BIO_printf(bio_err,"\n");
1198 if (!BN_add_word(serial,1)) goto err;
1199 if (!sk_X509_push(cert_sk,x))
1201 BIO_printf(bio_err,"Memory allocation failure\n");
1211 if (ss_cert_file != NULL)
1214 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1215 db,serial,subj,startdate,enddate,days,batch,
1216 extensions,conf,verbose, certopt, nameopt,
1217 default_op, ext_copy);
1218 if (j < 0) goto err;
1222 BIO_printf(bio_err,"\n");
1223 if (!BN_add_word(serial,1)) goto err;
1224 if (!sk_X509_push(cert_sk,x))
1226 BIO_printf(bio_err,"Memory allocation failure\n");
1234 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1235 serial,subj,startdate,enddate,days,batch,
1236 extensions,conf,verbose, certopt, nameopt,
1237 default_op, ext_copy);
1238 if (j < 0) goto err;
1242 BIO_printf(bio_err,"\n");
1243 if (!BN_add_word(serial,1)) goto err;
1244 if (!sk_X509_push(cert_sk,x))
1246 BIO_printf(bio_err,"Memory allocation failure\n");
1251 for (i=0; i<argc; i++)
1254 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1255 serial,subj,startdate,enddate,days,batch,
1256 extensions,conf,verbose, certopt, nameopt,
1257 default_op, ext_copy);
1258 if (j < 0) goto err;
1262 BIO_printf(bio_err,"\n");
1263 if (!BN_add_word(serial,1)) goto err;
1264 if (!sk_X509_push(cert_sk,x))
1266 BIO_printf(bio_err,"Memory allocation failure\n");
1271 /* we have a stack of newly certified certificates
1272 * and a data base and serial number that need
1275 if (sk_X509_num(cert_sk) > 0)
1279 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1280 (void)BIO_flush(bio_err);
1282 fgets(buf[0],10,stdin);
1283 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1285 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1291 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1293 strncpy(buf[0],serialfile,BSIZE-4);
1295 #ifdef OPENSSL_SYS_VMS
1296 strcat(buf[0],"-new");
1298 strcat(buf[0],".new");
1301 if (!save_serial(buf[0],serial)) goto err;
1303 strncpy(buf[1],dbfile,BSIZE-4);
1305 #ifdef OPENSSL_SYS_VMS
1306 strcat(buf[1],"-new");
1308 strcat(buf[1],".new");
1311 if (BIO_write_filename(out,buf[1]) <= 0)
1314 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1317 l=TXT_DB_write(out,db);
1318 if (l <= 0) goto err;
1322 BIO_printf(bio_err,"writing new certificates\n");
1323 for (i=0; i<sk_X509_num(cert_sk); i++)
1328 x=sk_X509_value(cert_sk,i);
1330 j=x->cert_info->serialNumber->length;
1331 p=(char *)x->cert_info->serialNumber->data;
1333 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1335 #ifndef OPENSSL_SYS_VMS
1339 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1344 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1353 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1356 BIO_printf(bio_err,"writing %s\n",buf[2]);
1358 if (BIO_write_filename(Cout,buf[2]) <= 0)
1363 write_new_certificate(Cout,x, 0, notext);
1364 write_new_certificate(Sout,x, output_der, notext);
1367 if (sk_X509_num(cert_sk))
1369 /* Rename the database and the serial file */
1370 strncpy(buf[2],serialfile,BSIZE-4);
1372 #ifdef OPENSSL_SYS_VMS
1373 strcat(buf[2],"-old");
1375 strcat(buf[2],".old");
1382 if (rename(serialfile,buf[2]) < 0)
1384 BIO_printf(bio_err,"unable to rename %s to %s\n",
1389 if (rename(buf[0],serialfile) < 0)
1391 BIO_printf(bio_err,"unable to rename %s to %s\n",
1394 rename(buf[2],serialfile);
1398 strncpy(buf[2],dbfile,BSIZE-4);
1400 #ifdef OPENSSL_SYS_VMS
1401 strcat(buf[2],"-old");
1403 strcat(buf[2],".old");
1406 if (rename(dbfile,buf[2]) < 0)
1408 BIO_printf(bio_err,"unable to rename %s to %s\n",
1413 if (rename(buf[1],dbfile) < 0)
1415 BIO_printf(bio_err,"unable to rename %s to %s\n",
1418 rename(buf[2],dbfile);
1421 BIO_printf(bio_err,"Data Base Updated\n");
1425 /*****************************************************************/
1431 crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1437 /* Check syntax of file */
1439 X509V3_set_ctx_test(&ctx);
1440 X509V3_set_conf_lhash(&ctx, conf);
1441 if (!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL))
1444 "Error Loading CRL extension section %s\n",
1451 if (!crldays && !crlhours)
1453 crldays=CONF_get_number(conf,section,
1454 ENV_DEFAULT_CRL_DAYS);
1455 crlhours=CONF_get_number(conf,section,
1456 ENV_DEFAULT_CRL_HOURS);
1458 if ((crldays == 0) && (crlhours == 0))
1460 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1464 if (verbose) BIO_printf(bio_err,"making CRL\n");
1465 if ((crl=X509_CRL_new()) == NULL) goto err;
1467 X509_NAME_free(ci->issuer);
1468 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1469 if (ci->issuer == NULL) goto err;
1471 X509_gmtime_adj(ci->lastUpdate,0);
1472 if (ci->nextUpdate == NULL)
1473 ci->nextUpdate=ASN1_UTCTIME_new();
1474 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1476 for (i=0; i<sk_num(db->data); i++)
1478 pp=(char **)sk_value(db->data,i);
1479 if (pp[DB_type][0] == DB_TYPE_REV)
1481 if ((r=X509_REVOKED_new()) == NULL) goto err;
1482 j = make_revoked(r, pp[DB_rev_date]);
1484 if (j == 2) crl_v2 = 1;
1485 if (!BN_hex2bn(&serial, pp[DB_serial]))
1487 r->serialNumber = BN_to_ASN1_INTEGER(serial, r->serialNumber);
1490 if (!r->serialNumber)
1492 X509_CRL_add0_revoked(crl,r);
1495 /* sort the data so it will be written in serial
1497 sk_X509_REVOKED_sort(ci->revoked);
1498 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1500 r=sk_X509_REVOKED_value(ci->revoked,i);
1504 /* we now have a CRL */
1505 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1508 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1510 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1516 #ifndef OPENSSL_NO_DSA
1517 if (pkey->type == EVP_PKEY_DSA)
1524 /* Add any extensions asked for */
1529 if (ci->version == NULL)
1530 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1531 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1532 X509V3_set_conf_lhash(&crlctx, conf);
1534 if (!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1535 crl_ext, crl)) goto err;
1537 if (crl_ext || crl_v2)
1539 if (ci->version == NULL)
1540 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1541 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1544 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1546 PEM_write_bio_X509_CRL(Sout,crl);
1548 /*****************************************************************/
1553 BIO_printf(bio_err,"no input files\n");
1559 if (BIO_read_filename(in,infile) <= 0)
1562 BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile);
1565 revcert=PEM_read_bio_X509(in,NULL,NULL,NULL);
1566 if (revcert == NULL)
1568 BIO_printf(bio_err,"unable to load '%s' certificate\n",infile);
1571 j=do_revoke(revcert,db, rev_type, rev_arg);
1572 if (j <= 0) goto err;
1575 strncpy(buf[0],dbfile,BSIZE-4);
1576 strcat(buf[0],".new");
1577 if (BIO_write_filename(out,buf[0]) <= 0)
1580 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1583 j=TXT_DB_write(out,db);
1584 if (j <= 0) goto err;
1585 strncpy(buf[1],dbfile,BSIZE-4);
1586 strcat(buf[1],".old");
1587 if (rename(dbfile,buf[1]) < 0)
1589 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1593 if (rename(buf[0],dbfile) < 0)
1595 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1597 rename(buf[1],dbfile);
1600 BIO_printf(bio_err,"Data Base Updated\n");
1603 /*****************************************************************/
1611 sk_X509_pop_free(cert_sk,X509_free);
1613 if (ret) ERR_print_errors(bio_err);
1614 app_RAND_write_file(randfile, bio_err);
1617 EVP_PKEY_free(pkey);
1625 static void lookup_fail(char *name, char *tag)
1627 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1630 static unsigned long index_serial_hash(const char **a)
1635 while (*n == '0') n++;
1636 return(lh_strhash(n));
1639 static int index_serial_cmp(const char **a, const char **b)
1643 for (aa=a[DB_serial]; *aa == '0'; aa++);
1644 for (bb=b[DB_serial]; *bb == '0'; bb++);
1645 return(strcmp(aa,bb));
1648 static unsigned long index_name_hash(const char **a)
1649 { return(lh_strhash(a[DB_name])); }
1651 static int index_name_qual(char **a)
1652 { return(a[0][0] == 'V'); }
1654 static int index_name_cmp(const char **a, const char **b)
1655 { return(strcmp(a[DB_name],
1658 static BIGNUM *load_serial(char *serialfile)
1662 MS_STATIC char buf[1024];
1663 ASN1_INTEGER *ai=NULL;
1665 if ((in=BIO_new(BIO_s_file())) == NULL)
1667 ERR_print_errors(bio_err);
1671 if (BIO_read_filename(in,serialfile) <= 0)
1676 ai=ASN1_INTEGER_new();
1677 if (ai == NULL) goto err;
1678 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1680 BIO_printf(bio_err,"unable to load number from %s\n",
1684 ret=ASN1_INTEGER_to_BN(ai,NULL);
1687 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1691 if (in != NULL) BIO_free(in);
1692 if (ai != NULL) ASN1_INTEGER_free(ai);
1696 static int save_serial(char *serialfile, BIGNUM *serial)
1700 ASN1_INTEGER *ai=NULL;
1702 out=BIO_new(BIO_s_file());
1705 ERR_print_errors(bio_err);
1708 if (BIO_write_filename(out,serialfile) <= 0)
1714 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1716 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1719 i2a_ASN1_INTEGER(out,ai);
1723 if (out != NULL) BIO_free_all(out);
1724 if (ai != NULL) ASN1_INTEGER_free(ai);
1728 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1729 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1730 BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
1731 int batch, char *ext_sect, LHASH *lconf, int verbose,
1732 unsigned long certopt, unsigned long nameopt, int default_op,
1737 EVP_PKEY *pktmp=NULL;
1740 in=BIO_new(BIO_s_file());
1742 if (BIO_read_filename(in,infile) <= 0)
1747 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1749 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1754 X509_REQ_print(bio_err,req);
1756 BIO_printf(bio_err,"Check that the request matches the signature\n");
1758 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1760 BIO_printf(bio_err,"error unpacking public key\n");
1763 i=X509_REQ_verify(req,pktmp);
1764 EVP_PKEY_free(pktmp);
1768 BIO_printf(bio_err,"Signature verification problems....\n");
1774 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1778 BIO_printf(bio_err,"Signature ok\n");
1780 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate, enddate,
1781 days,batch,verbose,req,ext_sect,lconf,
1782 certopt, nameopt, default_op, ext_copy);
1785 if (req != NULL) X509_REQ_free(req);
1786 if (in != NULL) BIO_free(in);
1790 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1791 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1792 BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
1793 int batch, char *ext_sect, LHASH *lconf, int verbose,
1794 unsigned long certopt, unsigned long nameopt, int default_op,
1798 X509_REQ *rreq=NULL;
1800 EVP_PKEY *pktmp=NULL;
1803 in=BIO_new(BIO_s_file());
1805 if (BIO_read_filename(in,infile) <= 0)
1810 if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1812 BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile);
1816 X509_print(bio_err,req);
1818 BIO_printf(bio_err,"Check that the request matches the signature\n");
1820 if ((pktmp=X509_get_pubkey(req)) == NULL)
1822 BIO_printf(bio_err,"error unpacking public key\n");
1825 i=X509_verify(req,pktmp);
1826 EVP_PKEY_free(pktmp);
1830 BIO_printf(bio_err,"Signature verification problems....\n");
1836 BIO_printf(bio_err,"Signature did not match the certificate\n");
1840 BIO_printf(bio_err,"Signature ok\n");
1842 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1845 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,days,
1846 batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1850 if (rreq != NULL) X509_REQ_free(rreq);
1851 if (req != NULL) X509_free(req);
1852 if (in != NULL) BIO_free(in);
1856 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1857 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1858 char *startdate, char *enddate, int days, int batch, int verbose,
1859 X509_REQ *req, char *ext_sect, LHASH *lconf,
1860 unsigned long certopt, unsigned long nameopt, int default_op,
1863 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1864 ASN1_UTCTIME *tm,*tmptm;
1865 ASN1_STRING *str,*str2;
1869 X509_NAME_ENTRY *ne;
1870 X509_NAME_ENTRY *tne,*push;
1872 int ok= -1,i,j,last,nid;
1875 char *row[DB_NUMBER],**rrow,**irow=NULL;
1878 tmptm=ASN1_UTCTIME_new();
1881 BIO_printf(bio_err,"malloc error\n");
1885 for (i=0; i<DB_NUMBER; i++)
1890 X509_NAME *n = do_subject(subj);
1894 ERR_print_errors(bio_err);
1897 X509_REQ_set_subject_name(req,n);
1898 req->req_info->enc.modified = 1;
1903 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1904 name=X509_REQ_get_subject_name(req);
1905 for (i=0; i<X509_NAME_entry_count(name); i++)
1907 ne= X509_NAME_get_entry(name,i);
1908 str=X509_NAME_ENTRY_get_data(ne);
1909 obj=X509_NAME_ENTRY_get_object(ne);
1913 /* assume all type should be strings */
1914 nid=OBJ_obj2nid(ne->object);
1916 if (str->type == V_ASN1_UNIVERSALSTRING)
1917 ASN1_UNIVERSALSTRING_to_string(str);
1919 if ((str->type == V_ASN1_IA5STRING) &&
1920 (nid != NID_pkcs9_emailAddress))
1921 str->type=V_ASN1_T61STRING;
1923 if ((nid == NID_pkcs9_emailAddress) &&
1924 (str->type == V_ASN1_PRINTABLESTRING))
1925 str->type=V_ASN1_IA5STRING;
1928 /* check some things */
1929 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1930 (str->type != V_ASN1_IA5STRING))
1932 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1935 j=ASN1_PRINTABLE_type(str->data,str->length);
1936 if ( ((j == V_ASN1_T61STRING) &&
1937 (str->type != V_ASN1_T61STRING)) ||
1938 ((j == V_ASN1_IA5STRING) &&
1939 (str->type == V_ASN1_PRINTABLESTRING)))
1941 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1946 old_entry_print(bio_err, obj, str);
1948 j=i2a_ASN1_OBJECT(bio_err,obj);
1950 for (j=22-j; j>0; j--)
1954 BIO_puts(bio_err,buf);
1956 if (str->type == V_ASN1_PRINTABLESTRING)
1957 BIO_printf(bio_err,"PRINTABLE:'");
1958 else if (str->type == V_ASN1_T61STRING)
1959 BIO_printf(bio_err,"T61STRING:'");
1960 else if (str->type == V_ASN1_IA5STRING)
1961 BIO_printf(bio_err,"IA5STRING:'");
1962 else if (str->type == V_ASN1_UNIVERSALSTRING)
1963 BIO_printf(bio_err,"UNIVERSALSTRING:'");
1965 BIO_printf(bio_err,"ASN.1 %2d:'",str->type);
1967 p=(char *)str->data;
1968 for (j=str->length; j>0; j--)
1970 if ((*p >= ' ') && (*p <= '~'))
1971 BIO_printf(bio_err,"%c",*p);
1973 BIO_printf(bio_err,"\\0x%02X",*p);
1974 else if ((unsigned char)*p == 0xf7)
1975 BIO_printf(bio_err,"^?");
1976 else BIO_printf(bio_err,"^%c",*p+'@');
1979 BIO_printf(bio_err,"'\n");
1983 /* Ok, now we check the 'policy' stuff. */
1984 if ((subject=X509_NAME_new()) == NULL)
1986 BIO_printf(bio_err,"Memory allocation failure\n");
1990 /* take a copy of the issuer name before we mess with it. */
1991 CAname=X509_NAME_dup(x509->cert_info->subject);
1992 if (CAname == NULL) goto err;
1995 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1997 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1998 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
2000 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
2008 /* lookup the object in the supplied name list */
2009 j=X509_NAME_get_index_by_OBJ(name,obj,last);
2012 if (last != -1) break;
2017 tne=X509_NAME_get_entry(name,j);
2021 /* depending on the 'policy', decide what to do. */
2023 if (strcmp(cv->value,"optional") == 0)
2028 else if (strcmp(cv->value,"supplied") == 0)
2032 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2038 else if (strcmp(cv->value,"match") == 0)
2044 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2051 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2052 if ((j < 0) && (last2 == -1))
2054 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2059 push=X509_NAME_get_entry(CAname,j);
2060 str=X509_NAME_ENTRY_get_data(tne);
2061 str2=X509_NAME_ENTRY_get_data(push);
2063 if (ASN1_STRING_cmp(str,str2) != 0)
2068 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));
2074 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2080 if (!X509_NAME_add_entry(subject,push, -1, 0))
2083 X509_NAME_ENTRY_free(push);
2084 BIO_printf(bio_err,"Memory allocation failure\n");
2094 X509_NAME_free(subject);
2095 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
2096 if (subject == NULL) goto err;
2100 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2102 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
2103 row[DB_serial]=BN_bn2hex(serial);
2104 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2106 BIO_printf(bio_err,"Memory allocation failure\n");
2110 rrow=TXT_DB_get_by_index(db,DB_name,row);
2113 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2118 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2121 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2123 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2130 "The matching entry has the following details\n");
2131 if (rrow[DB_type][0] == 'E')
2133 else if (rrow[DB_type][0] == 'R')
2135 else if (rrow[DB_type][0] == 'V')
2138 p="\ninvalid type, Data base error\n";
2139 BIO_printf(bio_err,"Type :%s\n",p);;
2140 if (rrow[DB_type][0] == 'R')
2142 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2143 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2145 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2146 BIO_printf(bio_err,"Expires on :%s\n",p);
2147 p=rrow[DB_serial]; if (p == NULL) p="undef";
2148 BIO_printf(bio_err,"Serial Number :%s\n",p);
2149 p=rrow[DB_file]; if (p == NULL) p="undef";
2150 BIO_printf(bio_err,"File name :%s\n",p);
2151 p=rrow[DB_name]; if (p == NULL) p="undef";
2152 BIO_printf(bio_err,"Subject Name :%s\n",p);
2153 ok= -1; /* This is now a 'bad' error. */
2157 /* We are now totally happy, lets make and sign the certificate */
2159 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2161 if ((ret=X509_new()) == NULL) goto err;
2165 /* Make it an X509 v3 certificate. */
2166 if (!X509_set_version(x509,2)) goto err;
2169 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2171 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2174 BIO_printf(bio_err,"Certificate is to be certified until ");
2175 if (strcmp(startdate,"today") == 0)
2176 X509_gmtime_adj(X509_get_notBefore(ret),0);
2177 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2179 if (enddate == NULL)
2180 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2181 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2183 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2184 if (days) BIO_printf(bio_err," (%d days)",days);
2185 BIO_printf(bio_err, "\n");
2187 if (!X509_set_subject_name(ret,subject)) goto err;
2189 pktmp=X509_REQ_get_pubkey(req);
2190 i = X509_set_pubkey(ret,pktmp);
2191 EVP_PKEY_free(pktmp);
2194 /* Lets add the extensions, if there are any */
2198 if (ci->version == NULL)
2199 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2201 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2203 /* Free the current entries if any, there should not
2204 * be any I believe */
2205 if (ci->extensions != NULL)
2206 sk_X509_EXTENSION_pop_free(ci->extensions,
2207 X509_EXTENSION_free);
2209 ci->extensions = NULL;
2211 /* Initialize the context structure */
2212 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2217 BIO_printf(bio_err, "Extra configuration file found\n");
2219 /* Use the extconf configuration db LHASH */
2220 X509V3_set_conf_lhash(&ctx, extconf);
2222 /* Test the structure (needed?) */
2223 /* X509V3_set_ctx_test(&ctx); */
2225 /* Adds exts contained in the configuration file */
2226 if (!X509V3_EXT_add_conf(extconf, &ctx, ext_sect,ret))
2229 "ERROR: adding extensions in section %s\n",
2231 ERR_print_errors(bio_err);
2235 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2239 /* We found extensions to be set from config file */
2240 X509V3_set_conf_lhash(&ctx, lconf);
2242 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret))
2244 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2245 ERR_print_errors(bio_err);
2250 BIO_printf(bio_err, "Successfully added extensions from config\n");
2259 BIO_printf(bio_err, "Certificate Details:\n");
2260 /* Never print signature details because signature not present */
2261 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2262 X509_print_ex(bio_err, ret, nameopt, certopt);
2264 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2265 (void)BIO_flush(bio_err);
2267 fgets(buf,sizeof(buf)-1,stdin);
2268 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2270 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2277 #ifndef OPENSSL_NO_DSA
2278 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2279 pktmp=X509_get_pubkey(ret);
2280 if (EVP_PKEY_missing_parameters(pktmp) &&
2281 !EVP_PKEY_missing_parameters(pkey))
2282 EVP_PKEY_copy_parameters(pktmp,pkey);
2283 EVP_PKEY_free(pktmp);
2286 if (!X509_sign(ret,pkey,dgst))
2289 /* We now just add it to the database */
2290 row[DB_type]=(char *)OPENSSL_malloc(2);
2292 tm=X509_get_notAfter(ret);
2293 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2294 memcpy(row[DB_exp_date],tm->data,tm->length);
2295 row[DB_exp_date][tm->length]='\0';
2297 row[DB_rev_date]=NULL;
2299 /* row[DB_serial] done already */
2300 row[DB_file]=(char *)OPENSSL_malloc(8);
2301 /* row[DB_name] done already */
2303 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2304 (row[DB_file] == NULL))
2306 BIO_printf(bio_err,"Memory allocation failure\n");
2309 strcpy(row[DB_file],"unknown");
2310 row[DB_type][0]='V';
2311 row[DB_type][1]='\0';
2313 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2315 BIO_printf(bio_err,"Memory allocation failure\n");
2319 for (i=0; i<DB_NUMBER; i++)
2324 irow[DB_NUMBER]=NULL;
2326 if (!TXT_DB_insert(db,irow))
2328 BIO_printf(bio_err,"failed to update database\n");
2329 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2334 for (i=0; i<DB_NUMBER; i++)
2335 if (row[i] != NULL) OPENSSL_free(row[i]);
2338 X509_NAME_free(CAname);
2339 if (subject != NULL)
2340 X509_NAME_free(subject);
2342 ASN1_UTCTIME_free(tmptm);
2345 if (ret != NULL) X509_free(ret);
2353 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2358 (void)i2d_X509_bio(bp,x);
2362 /* ??? Not needed since X509_print prints all this stuff anyway */
2363 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2364 BIO_printf(bp,"issuer :%s\n",f);
2366 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2367 BIO_printf(bp,"subject:%s\n",f);
2369 BIO_puts(bp,"serial :");
2370 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2371 BIO_puts(bp,"\n\n");
2373 if (!notext)X509_print(bp,x);
2374 PEM_write_bio_X509(bp,x);
2377 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2378 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2379 BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
2380 char *ext_sect, LHASH *lconf, int verbose, unsigned long certopt,
2381 unsigned long nameopt, int default_op, int ext_copy)
2383 STACK_OF(CONF_VALUE) *sk=NULL;
2386 CONF_VALUE *cv=NULL;
2387 NETSCAPE_SPKI *spki = NULL;
2390 EVP_PKEY *pktmp=NULL;
2392 X509_NAME_ENTRY *ne=NULL;
2398 * Load input file into a hash table. (This is just an easy
2399 * way to read and parse the file, then put it into a convenient
2402 parms=CONF_load(NULL,infile,&errline);
2405 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2406 ERR_print_errors(bio_err);
2410 sk=CONF_get_section(parms, "default");
2411 if (sk_CONF_VALUE_num(sk) == 0)
2413 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2419 * Now create a dummy X509 request structure. We don't actually
2420 * have an X509 request, but we have many of the components
2421 * (a public key, various DN components). The idea is that we
2422 * put these components into the right X509 request structure
2423 * and we can use the same code as if you had a real X509 request.
2428 ERR_print_errors(bio_err);
2433 * Build up the subject name set.
2440 if (sk_CONF_VALUE_num(sk) <= i) break;
2442 cv=sk_CONF_VALUE_value(sk,i);
2444 /* Skip past any leading X. X: X, etc to allow for
2445 * multiple instances
2447 for (buf = cv->name; *buf ; buf++)
2448 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2451 if (*buf) type = buf;
2456 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2458 if (strcmp(type, "SPKAC") == 0)
2460 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2463 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2464 ERR_print_errors(bio_err);
2471 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2472 if (fix_data(nid, &j) == 0)
2475 "invalid characters in string %s\n",buf);
2479 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2480 (unsigned char *)buf,
2481 strlen(buf))) == NULL)
2484 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2488 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2494 * Now extract the key from the SPKI structure.
2497 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2499 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2501 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2505 j = NETSCAPE_SPKI_verify(spki, pktmp);
2508 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2511 BIO_printf(bio_err,"Signature ok\n");
2513 X509_REQ_set_pubkey(req,pktmp);
2514 EVP_PKEY_free(pktmp);
2515 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,
2516 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2519 if (req != NULL) X509_REQ_free(req);
2520 if (parms != NULL) CONF_free(parms);
2521 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2522 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2527 static int fix_data(int nid, int *type)
2529 if (nid == NID_pkcs9_emailAddress)
2530 *type=V_ASN1_IA5STRING;
2531 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2532 *type=V_ASN1_T61STRING;
2533 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2534 *type=V_ASN1_T61STRING;
2535 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2537 if (nid == NID_pkcs9_unstructuredName)
2538 *type=V_ASN1_IA5STRING;
2542 static int check_time_format(char *str)
2546 tm.data=(unsigned char *)str;
2547 tm.length=strlen(str);
2548 tm.type=V_ASN1_UTCTIME;
2549 return(ASN1_UTCTIME_check(&tm));
2552 static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2554 ASN1_UTCTIME *tm=NULL;
2555 char *row[DB_NUMBER],**rrow,**irow;
2556 char *rev_str = NULL;
2560 for (i=0; i<DB_NUMBER; i++)
2562 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2563 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2564 row[DB_serial]=BN_bn2hex(bn);
2566 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2568 BIO_printf(bio_err,"Memory allocation failure\n");
2571 /* We have to lookup by serial number because name lookup
2572 * skips revoked certs
2574 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2577 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2579 /* We now just add it to the database */
2580 row[DB_type]=(char *)OPENSSL_malloc(2);
2582 tm=X509_get_notAfter(x509);
2583 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2584 memcpy(row[DB_exp_date],tm->data,tm->length);
2585 row[DB_exp_date][tm->length]='\0';
2587 row[DB_rev_date]=NULL;
2589 /* row[DB_serial] done already */
2590 row[DB_file]=(char *)OPENSSL_malloc(8);
2592 /* row[DB_name] done already */
2594 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2595 (row[DB_file] == NULL))
2597 BIO_printf(bio_err,"Memory allocation failure\n");
2600 strcpy(row[DB_file],"unknown");
2601 row[DB_type][0]='V';
2602 row[DB_type][1]='\0';
2604 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2606 BIO_printf(bio_err,"Memory allocation failure\n");
2610 for (i=0; i<DB_NUMBER; i++)
2615 irow[DB_NUMBER]=NULL;
2617 if (!TXT_DB_insert(db,irow))
2619 BIO_printf(bio_err,"failed to update database\n");
2620 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2624 /* Revoke Certificate */
2625 ok = do_revoke(x509,db, type, value);
2630 else if (index_name_cmp((const char **)row,(const char **)rrow))
2632 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2636 else if (rrow[DB_type][0]=='R')
2638 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2644 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2645 rev_str = make_revocation_str(type, value);
2648 BIO_printf(bio_err, "Error in revocation arguments\n");
2651 rrow[DB_type][0]='R';
2652 rrow[DB_type][1]='\0';
2653 rrow[DB_rev_date] = rev_str;
2657 for (i=0; i<DB_NUMBER; i++)
2660 OPENSSL_free(row[i]);
2665 static int get_certificate_status(const char *serial, TXT_DB *db)
2667 char *row[DB_NUMBER],**rrow;
2670 /* Free Resources */
2671 for (i=0; i<DB_NUMBER; i++)
2674 /* Malloc needed char spaces */
2675 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2676 if (row[DB_serial] == NULL)
2678 BIO_printf(bio_err,"Malloc failure\n");
2682 if (strlen(serial) % 2)
2684 /* Set the first char to 0 */;
2685 row[DB_serial][0]='0';
2687 /* Copy String from serial to row[DB_serial] */
2688 memcpy(row[DB_serial]+1, serial, strlen(serial));
2689 row[DB_serial][strlen(serial)+1]='\0';
2693 /* Copy String from serial to row[DB_serial] */
2694 memcpy(row[DB_serial], serial, strlen(serial));
2695 row[DB_serial][strlen(serial)]='\0';
2698 /* Make it Upper Case */
2699 for (i=0; row[DB_serial][i] != '\0'; i++)
2700 row[DB_serial][i] = toupper(row[DB_serial][i]);
2705 /* Search for the certificate */
2706 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2709 BIO_printf(bio_err,"Serial %s not present in db.\n",
2714 else if (rrow[DB_type][0]=='V')
2716 BIO_printf(bio_err,"%s=Valid (%c)\n",
2717 row[DB_serial], rrow[DB_type][0]);
2720 else if (rrow[DB_type][0]=='R')
2722 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2723 row[DB_serial], rrow[DB_type][0]);
2726 else if (rrow[DB_type][0]=='E')
2728 BIO_printf(bio_err,"%s=Expired (%c)\n",
2729 row[DB_serial], rrow[DB_type][0]);
2732 else if (rrow[DB_type][0]=='S')
2734 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2735 row[DB_serial], rrow[DB_type][0]);
2740 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2741 row[DB_serial], rrow[DB_type][0]);
2745 for (i=0; i<DB_NUMBER; i++)
2748 OPENSSL_free(row[i]);
2753 static int do_updatedb (TXT_DB *db)
2755 ASN1_UTCTIME *a_tm = NULL;
2757 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2758 char **rrow, *a_tm_s;
2760 a_tm = ASN1_UTCTIME_new();
2762 /* get actual time and make a string */
2763 a_tm = X509_gmtime_adj(a_tm, 0);
2764 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2771 memcpy(a_tm_s, a_tm->data, a_tm->length);
2772 a_tm_s[a_tm->length] = '\0';
2774 if (strncmp(a_tm_s, "49", 2) <= 0)
2779 for (i = 0; i < sk_num(db->data); i++)
2781 rrow = (char **) sk_value(db->data, i);
2783 if (rrow[DB_type][0] == 'V')
2785 /* ignore entries that are not valid */
2786 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2791 if (db_y2k == a_y2k)
2793 /* all on the same y2k side */
2794 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2796 rrow[DB_type][0] = 'E';
2797 rrow[DB_type][1] = '\0';
2800 BIO_printf(bio_err, "%s=Expired\n",
2804 else if (db_y2k < a_y2k)
2806 rrow[DB_type][0] = 'E';
2807 rrow[DB_type][1] = '\0';
2810 BIO_printf(bio_err, "%s=Expired\n",
2819 ASN1_UTCTIME_free(a_tm);
2820 OPENSSL_free(a_tm_s);
2825 static char *crl_reasons[] = {
2826 /* CRL reason strings */
2830 "affiliationChanged",
2832 "cessationOfOperation",
2835 /* Additional pseudo reasons */
2841 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2843 /* Given revocation information convert to a DB string.
2844 * The format of the string is:
2845 * revtime[,reason,extra]. Where 'revtime' is the
2846 * revocation time (the current time). 'reason' is the
2847 * optional CRL reason and 'extra' is any additional
2851 char *make_revocation_str(int rev_type, char *rev_arg)
2853 char *reason = NULL, *other = NULL, *str;
2855 ASN1_UTCTIME *revtm = NULL;
2862 case REV_CRL_REASON:
2863 for (i = 0; i < 8; i++)
2865 if (!strcasecmp(rev_arg, crl_reasons[i]))
2867 reason = crl_reasons[i];
2873 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2879 /* Argument is an OID */
2881 otmp = OBJ_txt2obj(rev_arg, 0);
2882 ASN1_OBJECT_free(otmp);
2886 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2890 reason = "holdInstruction";
2894 case REV_KEY_COMPROMISE:
2895 case REV_CA_COMPROMISE:
2897 /* Argument is the key compromise time */
2898 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2900 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2904 if (rev_type == REV_KEY_COMPROMISE)
2907 reason = "CAkeyTime";
2913 revtm = X509_gmtime_adj(NULL, 0);
2915 i = revtm->length + 1;
2917 if (reason) i += strlen(reason) + 1;
2918 if (other) i += strlen(other) + 1;
2920 str = OPENSSL_malloc(i);
2922 if (!str) return NULL;
2924 strcpy(str, (char *)revtm->data);
2928 strcat(str, reason);
2935 ASN1_UTCTIME_free(revtm);
2939 /* Convert revocation field to X509_REVOKED entry
2943 * 2 OK and some extensions added (i.e. V2 CRL)
2946 int make_revoked(X509_REVOKED *rev, char *str)
2949 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2950 int reason_code = -1;
2952 ASN1_OBJECT *hold = NULL;
2953 ASN1_GENERALIZEDTIME *comp_time = NULL;
2954 ASN1_ENUMERATED *rtmp = NULL;
2955 tmp = BUF_strdup(str);
2957 p = strchr(tmp, ',');
2974 if (rev && !ASN1_UTCTIME_set_string(rev->revocationDate, rtime_str))
2976 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2981 for (i = 0; i < NUM_REASONS; i++)
2983 if(!strcasecmp(reason_str, crl_reasons[i]))
2989 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
2991 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2995 if (reason_code == 7)
2996 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2997 else if (reason_code == 8) /* Hold instruction */
3001 BIO_printf(bio_err, "missing hold instruction\n");
3004 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3005 hold = OBJ_txt2obj(arg_str, 0);
3009 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3013 else if ((reason_code == 9) || (reason_code == 10))
3017 BIO_printf(bio_err, "missing compromised time\n");
3020 comp_time = ASN1_GENERALIZEDTIME_new();
3021 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3023 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3026 if (reason_code == 9)
3027 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3029 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3033 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3035 rtmp = ASN1_ENUMERATED_new();
3036 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3038 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3042 if (rev && comp_time)
3044 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3049 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3053 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3059 if (tmp) OPENSSL_free(tmp);
3060 ASN1_OBJECT_free(hold);
3061 ASN1_GENERALIZEDTIME_free(comp_time);
3062 ASN1_ENUMERATED_free(rtmp);
3067 static X509_NAME *do_subject(char *subject)
3069 X509_NAME *n = NULL;
3071 int i, nid, ne_num=0;
3073 char *ne_name = NULL;
3074 char *ne_value = NULL;
3079 char *str_list[256];
3084 n = X509_NAME_new();
3086 tmp = strtok(subject, p[0]);
3087 while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list)))
3091 while (token[0] == ' ')
3093 str_list[ne_num] = token;
3095 tmp = strtok(NULL, p[0]);
3099 for (i = 0; i < ne_num; i++)
3101 ne_name = strtok(str_list[i], p[1]);
3102 ne_value = strtok(NULL, p[1]);
3104 if ((nid=OBJ_txt2nid(ne_name)) == NID_undef)
3106 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name);
3110 if (ne_value == NULL)
3112 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name);
3116 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char*)ne_value, -1,-1,0))
3127 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3129 char buf[25],*pbuf, *p;
3131 j=i2a_ASN1_OBJECT(bp,obj);
3133 for (j=22-j; j>0; j--)
3139 if (str->type == V_ASN1_PRINTABLESTRING)
3140 BIO_printf(bp,"PRINTABLE:'");
3141 else if (str->type == V_ASN1_T61STRING)
3142 BIO_printf(bp,"T61STRING:'");
3143 else if (str->type == V_ASN1_IA5STRING)
3144 BIO_printf(bp,"IA5STRING:'");
3145 else if (str->type == V_ASN1_UNIVERSALSTRING)
3146 BIO_printf(bp,"UNIVERSALSTRING:'");
3148 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3150 p=(char *)str->data;
3151 for (j=str->length; j>0; j--)
3153 if ((*p >= ' ') && (*p <= '~'))
3154 BIO_printf(bp,"%c",*p);
3156 BIO_printf(bp,"\\0x%02X",*p);
3157 else if ((unsigned char)*p == 0xf7)
3158 BIO_printf(bp,"^?");
3159 else BIO_printf(bp,"^%c",*p+'@');
3162 BIO_printf(bp,"'\n");