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"
137 #define ENV_EXTCOPY "copy_extensions"
139 #define ENV_DATABASE "database"
142 #define DB_exp_date 1
143 #define DB_rev_date 2
144 #define DB_serial 3 /* index - unique */
146 #define DB_name 5 /* index - unique for active */
149 #define DB_TYPE_REV 'R'
150 #define DB_TYPE_EXP 'E'
151 #define DB_TYPE_VAL 'V'
153 /* Additional revocation information types */
155 #define REV_NONE 0 /* No addditional information */
156 #define REV_CRL_REASON 1 /* Value is CRL reason code */
157 #define REV_HOLD 2 /* Value is hold instruction */
158 #define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
159 #define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
161 static char *ca_usage[]={
164 " -verbose - Talk alot while doing things\n",
165 " -config file - A config file\n",
166 " -name arg - The particular CA definition to use\n",
167 " -gencrl - Generate a new CRL\n",
168 " -crldays days - Days is when the next CRL is due\n",
169 " -crlhours hours - Hours is when the next CRL is due\n",
170 " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
171 " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
172 " -days arg - number of days to certify the certificate for\n",
173 " -md arg - md to use, one of md2, md5, sha or sha1\n",
174 " -policy arg - The CA 'policy' to support\n",
175 " -keyfile arg - private key file\n",
176 " -keyform arg - private key file format (PEM or ENGINE)\n",
177 " -key arg - key to decode the private key if it is encrypted\n",
178 " -cert file - The CA certificate\n",
179 " -in file - The input PEM encoded certificate request(s)\n",
180 " -out file - Where to put the output file(s)\n",
181 " -outdir dir - Where to put output certificates\n",
182 " -infiles .... - The last argument, requests to process\n",
183 " -spkac file - File contains DN and signed public key and challenge\n",
184 " -ss_cert file - File contains a self signed cert to sign\n",
185 " -preserveDN - Don't re-order the DN\n",
186 " -batch - Don't ask questions\n",
187 " -msie_hack - msie modifications to handle all those universal strings\n",
188 " -revoke file - Revoke a certificate (given in file)\n",
189 " -subj arg - Use arg instead of request's subject\n",
190 " -extensions .. - Extension section (override value in config file)\n",
191 " -extfile file - Configuration file with X509v3 extentions to add\n",
192 " -crlexts .. - CRL extension section (override value in config file)\n",
193 " -engine e - use engine e, possibly a hardware device.\n",
194 " -status serial - Shows certificate status given the serial number\n",
195 " -updatedb - Updates db for expired certificates\n",
200 extern int EF_PROTECT_FREE;
201 extern int EF_PROTECT_BELOW;
202 extern int EF_ALIGNMENT;
205 static void lookup_fail(char *name,char *tag);
206 static unsigned long index_serial_hash(const char **a);
207 static int index_serial_cmp(const char **a, const char **b);
208 static unsigned long index_name_hash(const char **a);
209 static int index_name_qual(char **a);
210 static int index_name_cmp(const char **a,const char **b);
211 static BIGNUM *load_serial(char *serialfile);
212 static int save_serial(char *serialfile, BIGNUM *serial);
213 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
214 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
215 BIGNUM *serial, char *subj, char *startdate,char *enddate,
216 int days, int batch, char *ext_sect, LHASH *conf,int verbose,
217 unsigned long certopt, unsigned long nameopt, int default_op,
219 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
220 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
221 TXT_DB *db, BIGNUM *serial, char *subj, char *startdate,
222 char *enddate, int days, int batch, char *ext_sect,
223 LHASH *conf,int verbose, unsigned long certopt,
224 unsigned long nameopt, int default_op, int ext_copy,
226 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
227 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
228 TXT_DB *db, BIGNUM *serial,char *subj, char *startdate,
229 char *enddate, int days, char *ext_sect,LHASH *conf,
230 int verbose, unsigned long certopt, unsigned long nameopt,
231 int default_op, int ext_copy);
232 static int fix_data(int nid, int *type);
233 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
234 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
235 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
236 char *startdate, char *enddate, int days, int batch, int verbose,
237 X509_REQ *req, char *ext_sect, LHASH *conf,
238 unsigned long certopt, unsigned long nameopt, int default_op,
240 static X509_NAME *do_subject(char *subject);
241 static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
242 static int get_certificate_status(const char *ser_status, TXT_DB *db);
243 static int do_updatedb(TXT_DB *db);
244 static int check_time_format(char *str);
245 char *make_revocation_str(int rev_type, char *rev_arg);
246 int make_revoked(X509_REVOKED *rev, char *str);
247 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
248 static LHASH *conf=NULL;
249 static LHASH *extconf=NULL;
250 static char *section=NULL;
252 static int preserve=0;
253 static int msie_hack=0;
255 static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
256 static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
257 static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
258 static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
261 int MAIN(int, char **);
263 int MAIN(int argc, char **argv)
266 char *key=NULL,*passargin=NULL;
279 char *configfile=NULL;
284 int keyform=FORMAT_PEM;
286 char *spkac_file=NULL;
287 char *ss_cert_file=NULL;
288 char *ser_status=NULL;
293 char *serialfile=NULL;
294 char *extensions=NULL;
298 int rev_type = REV_NONE;
299 char *rev_arg = NULL;
301 char *startdate=NULL;
306 unsigned long nameopt = 0, certopt = 0;
308 int ext_copy = EXT_COPY_NONE;
311 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
315 X509_CRL_INFO *ci=NULL;
316 X509_REVOKED *r=NULL;
320 const EVP_MD *dgst=NULL;
321 STACK_OF(CONF_VALUE) *attribs=NULL;
322 STACK_OF(X509) *cert_sk=NULL;
325 MS_STATIC char buf[3][BSIZE];
344 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
345 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
351 if (strcmp(*argv,"-verbose") == 0)
353 else if (strcmp(*argv,"-config") == 0)
355 if (--argc < 1) goto bad;
356 configfile= *(++argv);
358 else if (strcmp(*argv,"-name") == 0)
360 if (--argc < 1) goto bad;
363 else if (strcmp(*argv,"-subj") == 0)
365 if (--argc < 1) goto bad;
369 else if (strcmp(*argv,"-startdate") == 0)
371 if (--argc < 1) goto bad;
372 startdate= *(++argv);
374 else if (strcmp(*argv,"-enddate") == 0)
376 if (--argc < 1) goto bad;
379 else if (strcmp(*argv,"-days") == 0)
381 if (--argc < 1) goto bad;
382 days=atoi(*(++argv));
384 else if (strcmp(*argv,"-md") == 0)
386 if (--argc < 1) goto bad;
389 else if (strcmp(*argv,"-policy") == 0)
391 if (--argc < 1) goto bad;
394 else if (strcmp(*argv,"-keyfile") == 0)
396 if (--argc < 1) goto bad;
399 else if (strcmp(*argv,"-keyform") == 0)
401 if (--argc < 1) goto bad;
402 keyform=str2fmt(*(++argv));
404 else if (strcmp(*argv,"-passin") == 0)
406 if (--argc < 1) goto bad;
407 passargin= *(++argv);
409 else if (strcmp(*argv,"-key") == 0)
411 if (--argc < 1) goto bad;
414 else if (strcmp(*argv,"-cert") == 0)
416 if (--argc < 1) goto bad;
419 else if (strcmp(*argv,"-in") == 0)
421 if (--argc < 1) goto bad;
425 else if (strcmp(*argv,"-out") == 0)
427 if (--argc < 1) goto bad;
430 else if (strcmp(*argv,"-outdir") == 0)
432 if (--argc < 1) goto bad;
435 else if (strcmp(*argv,"-notext") == 0)
437 else if (strcmp(*argv,"-batch") == 0)
439 else if (strcmp(*argv,"-preserveDN") == 0)
441 else if (strcmp(*argv,"-gencrl") == 0)
443 else if (strcmp(*argv,"-msie_hack") == 0)
445 else if (strcmp(*argv,"-crldays") == 0)
447 if (--argc < 1) goto bad;
448 crldays= atol(*(++argv));
450 else if (strcmp(*argv,"-crlhours") == 0)
452 if (--argc < 1) goto bad;
453 crlhours= atol(*(++argv));
455 else if (strcmp(*argv,"-infiles") == 0)
462 else if (strcmp(*argv, "-ss_cert") == 0)
464 if (--argc < 1) goto bad;
465 ss_cert_file = *(++argv);
468 else if (strcmp(*argv, "-spkac") == 0)
470 if (--argc < 1) goto bad;
471 spkac_file = *(++argv);
474 else if (strcmp(*argv,"-revoke") == 0)
476 if (--argc < 1) goto bad;
480 else if (strcmp(*argv,"-extensions") == 0)
482 if (--argc < 1) goto bad;
483 extensions= *(++argv);
485 else if (strcmp(*argv,"-extfile") == 0)
487 if (--argc < 1) goto bad;
490 else if (strcmp(*argv,"-status") == 0)
492 if (--argc < 1) goto bad;
493 ser_status= *(++argv);
495 else if (strcmp(*argv,"-updatedb") == 0)
499 else if (strcmp(*argv,"-crlexts") == 0)
501 if (--argc < 1) goto bad;
504 else if (strcmp(*argv,"-crl_reason") == 0)
506 if (--argc < 1) goto bad;
508 rev_type = REV_CRL_REASON;
510 else if (strcmp(*argv,"-crl_hold") == 0)
512 if (--argc < 1) goto bad;
516 else if (strcmp(*argv,"-crl_compromise") == 0)
518 if (--argc < 1) goto bad;
520 rev_type = REV_KEY_COMPROMISE;
522 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
524 if (--argc < 1) goto bad;
526 rev_type = REV_CA_COMPROMISE;
528 else if (strcmp(*argv,"-engine") == 0)
530 if (--argc < 1) goto bad;
536 BIO_printf(bio_err,"unknown option %s\n",*argv);
546 for (pp=ca_usage; (*pp != NULL); pp++)
547 BIO_printf(bio_err,"%s",*pp);
551 ERR_load_crypto_strings();
553 e = setup_engine(bio_err, engine, 0);
555 /*****************************************************************/
556 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
557 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
558 if (configfile == NULL)
560 /* We will just use 'buf[0]' as a temporary buffer. */
561 #ifdef OPENSSL_SYS_VMS
562 strncpy(buf[0],X509_get_default_cert_area(),
563 sizeof(buf[0])-1-sizeof(CONFIG_FILE));
565 strncpy(buf[0],X509_get_default_cert_area(),
566 sizeof(buf[0])-2-sizeof(CONFIG_FILE));
569 strcat(buf[0],CONFIG_FILE);
573 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
574 if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
577 BIO_printf(bio_err,"error loading the config file '%s'\n",
580 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
581 ,errorline,configfile);
585 /* Lets get the config section we are using */
588 section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
591 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
598 p=CONF_get_string(conf,NULL,"oid_file");
605 oid_bio=BIO_new_file(p,"r");
609 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
610 ERR_print_errors(bio_err);
616 OBJ_create_objects(oid_bio);
620 if (!add_oid_section(bio_err,conf))
622 ERR_print_errors(bio_err);
627 randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE");
628 if (randfile == NULL)
630 app_RAND_load_file(randfile, bio_err, 0);
632 in=BIO_new(BIO_s_file());
633 out=BIO_new(BIO_s_file());
634 Sout=BIO_new(BIO_s_file());
635 Cout=BIO_new(BIO_s_file());
636 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
638 ERR_print_errors(bio_err);
642 /*****************************************************************/
643 /* report status of cert with serial number given on command line */
646 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
648 lookup_fail(section,ENV_DATABASE);
651 if (BIO_read_filename(in,dbfile) <= 0)
654 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
657 db=TXT_DB_read(in,DB_NUMBER);
658 if (db == NULL) goto err;
660 if (!TXT_DB_create_index(db, DB_serial, NULL,
661 LHASH_HASH_FN(index_serial_hash),
662 LHASH_COMP_FN(index_serial_cmp)))
665 "error creating serial number index:(%ld,%ld,%ld)\n",
666 db->error,db->arg1,db->arg2);
670 if (get_certificate_status(ser_status,db) != 1)
671 BIO_printf(bio_err,"Error verifying serial %s!\n",
676 /*****************************************************************/
677 /* we definitely need a public key, so let's get it */
679 if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
680 section,ENV_PRIVATE_KEY)) == NULL))
682 lookup_fail(section,ENV_PRIVATE_KEY);
685 if (!key && !app_passwd(bio_err, passargin, NULL, &key, NULL))
687 BIO_printf(bio_err,"Error getting password\n");
690 pkey = load_key(bio_err, keyfile, keyform, key, e,
692 if (key) memset(key,0,strlen(key));
695 /* load_key() has already printed an appropriate message */
699 /*****************************************************************/
700 /* we need a certificate */
701 if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
702 section,ENV_CERTIFICATE)) == NULL))
704 lookup_fail(section,ENV_CERTIFICATE);
707 x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
712 if (!X509_check_private_key(x509,pkey))
714 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
718 f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
721 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
723 f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
726 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
729 f=CONF_get_string(conf,section,ENV_NAMEOPT);
733 if (!set_name_ex(&nameopt, f))
735 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
743 f=CONF_get_string(conf,section,ENV_CERTOPT);
747 if (!set_cert_ex(&certopt, f))
749 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
757 f=CONF_get_string(conf,section,ENV_EXTCOPY);
761 if (!set_ext_copy(&ext_copy, f))
763 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
770 /*****************************************************************/
771 /* lookup where to write new certificates */
772 if ((outdir == NULL) && (req))
776 if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
779 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
782 #ifndef OPENSSL_SYS_VMS
783 /* outdir is a directory spec, but access() for VMS demands a
784 filename. In any case, stat(), below, will catch the problem
785 if outdir is not a directory spec, and the fopen() or open()
786 will catch an error if there is no write access.
788 Presumably, this problem could also be solved by using the DEC
789 C routines to convert the directory syntax to Unixly, and give
790 that to access(). However, time's too short to do that just
793 if (access(outdir,R_OK|W_OK|X_OK) != 0)
795 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
800 if (stat(outdir,&sb) != 0)
802 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
807 if (!(sb.st_mode & S_IFDIR))
809 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
817 /*****************************************************************/
818 /* we need to load the database file */
819 if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
821 lookup_fail(section,ENV_DATABASE);
824 if (BIO_read_filename(in,dbfile) <= 0)
827 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
830 db=TXT_DB_read(in,DB_NUMBER);
831 if (db == NULL) goto err;
833 /* Lets check some fields */
834 for (i=0; i<sk_num(db->data); i++)
836 pp=(char **)sk_value(db->data,i);
837 if ((pp[DB_type][0] != DB_TYPE_REV) &&
838 (pp[DB_rev_date][0] != '\0'))
840 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
843 if ((pp[DB_type][0] == DB_TYPE_REV) &&
844 !make_revoked(NULL, pp[DB_rev_date]))
846 BIO_printf(bio_err," in entry %d\n", i+1);
849 if (!check_time_format(pp[DB_exp_date]))
851 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
861 if ((j&1) || (j < 2))
863 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
868 if (!( ((*p >= '0') && (*p <= '9')) ||
869 ((*p >= 'A') && (*p <= 'F')) ||
870 ((*p >= 'a') && (*p <= 'f'))) )
872 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);
880 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
881 #ifdef OPENSSL_SYS_VMS
883 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
884 out = BIO_push(tmpbio, out);
887 TXT_DB_write(out,db);
888 BIO_printf(bio_err,"%d entries loaded from the database\n",
890 BIO_printf(bio_err,"generating index\n");
893 if (!TXT_DB_create_index(db, DB_serial, NULL,
894 LHASH_HASH_FN(index_serial_hash),
895 LHASH_COMP_FN(index_serial_cmp)))
897 BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
901 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
902 LHASH_HASH_FN(index_name_hash),
903 LHASH_COMP_FN(index_name_cmp)))
905 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
906 db->error,db->arg1,db->arg2);
910 /*****************************************************************/
911 /* Update the db file for expired certificates */
915 BIO_printf(bio_err, "Updating %s ...\n",
921 BIO_printf(bio_err,"Malloc failure\n");
926 if (verbose) BIO_printf(bio_err,
927 "No entries found to mark expired\n");
931 out = BIO_new(BIO_s_file());
934 ERR_print_errors(bio_err);
938 #ifndef OPENSSL_SYS_VMS
939 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
941 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-new", dbfile);
943 if (j < 0 || j >= sizeof buf[0])
945 BIO_printf(bio_err, "file name too long\n");
948 if (BIO_write_filename(out,buf[0]) <= 0)
951 BIO_printf(bio_err,"unable to open '%s'\n",
955 j=TXT_DB_write(out,db);
956 if (j <= 0) goto err;
960 #ifndef OPENSSL_SYS_VMS
961 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
963 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-old", dbfile);
965 if (j < 0 || j >= sizeof buf[1])
967 BIO_printf(bio_err, "file name too long\n");
970 if (rename(dbfile,buf[1]) < 0)
973 "unable to rename %s to %s\n",
978 if (rename(buf[0],dbfile) < 0)
981 "unable to rename %s to %s\n",
984 rename(buf[1],dbfile);
988 if (verbose) BIO_printf(bio_err,
989 "Done. %d entries marked as expired\n",i);
994 /*****************************************************************/
995 /* Read extentions config file */
998 if (!(extconf=CONF_load(NULL,extfile,&errorline)))
1001 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
1004 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
1011 BIO_printf(bio_err, "Succesfully loaded extensions file %s\n", extfile);
1013 /* We can have sections in the ext file */
1014 if (!extensions && !(extensions = CONF_get_string(extconf, "default", "extensions")))
1015 extensions = "default";
1018 /*****************************************************************/
1021 if (outfile != NULL)
1023 if (BIO_write_filename(Sout,outfile) <= 0)
1031 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1032 #ifdef OPENSSL_SYS_VMS
1034 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1035 Sout = BIO_push(tmpbio, Sout);
1043 if ((md == NULL) && ((md=CONF_get_string(conf,
1044 section,ENV_DEFAULT_MD)) == NULL))
1046 lookup_fail(section,ENV_DEFAULT_MD);
1049 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1051 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1055 BIO_printf(bio_err,"message digest is %s\n",
1056 OBJ_nid2ln(dgst->type));
1057 if ((policy == NULL) && ((policy=CONF_get_string(conf,
1058 section,ENV_POLICY)) == NULL))
1060 lookup_fail(section,ENV_POLICY);
1064 BIO_printf(bio_err,"policy is %s\n",policy);
1066 if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
1069 lookup_fail(section,ENV_SERIAL);
1075 /* no '-extfile' option, so we look for extensions
1076 * in the main configuration file */
1079 extensions=CONF_get_string(conf,section,
1086 /* Check syntax of file */
1088 X509V3_set_ctx_test(&ctx);
1089 X509V3_set_conf_lhash(&ctx, conf);
1090 if (!X509V3_EXT_add_conf(conf, &ctx, extensions,
1094 "Error Loading extension section %s\n",
1102 if (startdate == NULL)
1104 startdate=CONF_get_string(conf,section,
1105 ENV_DEFAULT_STARTDATE);
1106 if (startdate == NULL)
1109 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1111 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1114 if (startdate == NULL) startdate="today";
1116 if (enddate == NULL)
1118 enddate=CONF_get_string(conf,section,
1119 ENV_DEFAULT_ENDDATE);
1120 if (enddate == NULL)
1123 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1125 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1131 days=(int)CONF_get_number(conf,section,
1134 if (!enddate && (days == 0))
1136 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1140 if ((serial=load_serial(serialfile)) == NULL)
1142 BIO_printf(bio_err,"error while loading serial number\n");
1147 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1148 BIO_printf(bio_err,"next serial number is %s\n",f);
1152 if ((attribs=CONF_get_section(conf,policy)) == NULL)
1154 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1158 if ((cert_sk=sk_X509_new_null()) == NULL)
1160 BIO_printf(bio_err,"Memory allocation failure\n");
1163 if (spkac_file != NULL)
1166 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1167 serial,subj,startdate,enddate, days,extensions,conf,
1168 verbose, certopt, nameopt, default_op, ext_copy);
1169 if (j < 0) goto err;
1173 BIO_printf(bio_err,"\n");
1174 if (!BN_add_word(serial,1)) goto err;
1175 if (!sk_X509_push(cert_sk,x))
1177 BIO_printf(bio_err,"Memory allocation failure\n");
1187 if (ss_cert_file != NULL)
1190 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1191 db,serial,subj,startdate,enddate,days,batch,
1192 extensions,conf,verbose, certopt, nameopt,
1193 default_op, ext_copy, e);
1194 if (j < 0) goto err;
1198 BIO_printf(bio_err,"\n");
1199 if (!BN_add_word(serial,1)) goto err;
1200 if (!sk_X509_push(cert_sk,x))
1202 BIO_printf(bio_err,"Memory allocation failure\n");
1210 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1211 serial,subj,startdate,enddate,days,batch,
1212 extensions,conf,verbose, certopt, nameopt,
1213 default_op, ext_copy);
1214 if (j < 0) goto err;
1218 BIO_printf(bio_err,"\n");
1219 if (!BN_add_word(serial,1)) goto err;
1220 if (!sk_X509_push(cert_sk,x))
1222 BIO_printf(bio_err,"Memory allocation failure\n");
1227 for (i=0; i<argc; i++)
1230 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1231 serial,subj,startdate,enddate,days,batch,
1232 extensions,conf,verbose, certopt, nameopt,
1233 default_op, ext_copy);
1234 if (j < 0) goto err;
1238 BIO_printf(bio_err,"\n");
1239 if (!BN_add_word(serial,1)) goto err;
1240 if (!sk_X509_push(cert_sk,x))
1242 BIO_printf(bio_err,"Memory allocation failure\n");
1247 /* we have a stack of newly certified certificates
1248 * and a data base and serial number that need
1251 if (sk_X509_num(cert_sk) > 0)
1255 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1256 (void)BIO_flush(bio_err);
1258 fgets(buf[0],10,stdin);
1259 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1261 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1267 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1269 strncpy(buf[0],serialfile,BSIZE-4);
1271 #ifdef OPENSSL_SYS_VMS
1272 strcat(buf[0],"-new");
1274 strcat(buf[0],".new");
1277 if (!save_serial(buf[0],serial)) goto err;
1279 strncpy(buf[1],dbfile,BSIZE-4);
1281 #ifdef OPENSSL_SYS_VMS
1282 strcat(buf[1],"-new");
1284 strcat(buf[1],".new");
1287 if (BIO_write_filename(out,buf[1]) <= 0)
1290 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1293 l=TXT_DB_write(out,db);
1294 if (l <= 0) goto err;
1298 BIO_printf(bio_err,"writing new certificates\n");
1299 for (i=0; i<sk_X509_num(cert_sk); i++)
1304 x=sk_X509_value(cert_sk,i);
1306 j=x->cert_info->serialNumber->length;
1307 p=(char *)x->cert_info->serialNumber->data;
1309 strncpy(buf[2],outdir,BSIZE-(j*2)-6);
1311 #ifndef OPENSSL_SYS_VMS
1315 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1320 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1329 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1332 BIO_printf(bio_err,"writing %s\n",buf[2]);
1334 if (BIO_write_filename(Cout,buf[2]) <= 0)
1339 write_new_certificate(Cout,x, 0, notext);
1340 write_new_certificate(Sout,x, output_der, notext);
1343 if (sk_X509_num(cert_sk))
1345 /* Rename the database and the serial file */
1346 strncpy(buf[2],serialfile,BSIZE-4);
1348 #ifdef OPENSSL_SYS_VMS
1349 strcat(buf[2],"-old");
1351 strcat(buf[2],".old");
1358 if (rename(serialfile,buf[2]) < 0)
1360 BIO_printf(bio_err,"unable to rename %s to %s\n",
1365 if (rename(buf[0],serialfile) < 0)
1367 BIO_printf(bio_err,"unable to rename %s to %s\n",
1370 rename(buf[2],serialfile);
1374 strncpy(buf[2],dbfile,BSIZE-4);
1376 #ifdef OPENSSL_SYS_VMS
1377 strcat(buf[2],"-old");
1379 strcat(buf[2],".old");
1382 if (rename(dbfile,buf[2]) < 0)
1384 BIO_printf(bio_err,"unable to rename %s to %s\n",
1389 if (rename(buf[1],dbfile) < 0)
1391 BIO_printf(bio_err,"unable to rename %s to %s\n",
1394 rename(buf[2],dbfile);
1397 BIO_printf(bio_err,"Data Base Updated\n");
1401 /*****************************************************************/
1407 crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
1413 /* Check syntax of file */
1415 X509V3_set_ctx_test(&ctx);
1416 X509V3_set_conf_lhash(&ctx, conf);
1417 if (!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL))
1420 "Error Loading CRL extension section %s\n",
1427 if (!crldays && !crlhours)
1429 crldays=CONF_get_number(conf,section,
1430 ENV_DEFAULT_CRL_DAYS);
1431 crlhours=CONF_get_number(conf,section,
1432 ENV_DEFAULT_CRL_HOURS);
1434 if ((crldays == 0) && (crlhours == 0))
1436 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
1440 if (verbose) BIO_printf(bio_err,"making CRL\n");
1441 if ((crl=X509_CRL_new()) == NULL) goto err;
1443 X509_NAME_free(ci->issuer);
1444 ci->issuer=X509_NAME_dup(x509->cert_info->subject);
1445 if (ci->issuer == NULL) goto err;
1447 X509_gmtime_adj(ci->lastUpdate,0);
1448 if (ci->nextUpdate == NULL)
1449 ci->nextUpdate=ASN1_UTCTIME_new();
1450 X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
1452 for (i=0; i<sk_num(db->data); i++)
1454 pp=(char **)sk_value(db->data,i);
1455 if (pp[DB_type][0] == DB_TYPE_REV)
1457 if ((r=X509_REVOKED_new()) == NULL) goto err;
1458 j = make_revoked(r, pp[DB_rev_date]);
1460 if (j == 2) crl_v2 = 1;
1461 if (!BN_hex2bn(&serial, pp[DB_serial]))
1463 r->serialNumber = BN_to_ASN1_INTEGER(serial, r->serialNumber);
1466 if (!r->serialNumber)
1468 X509_CRL_add0_revoked(crl,r);
1471 /* sort the data so it will be written in serial
1473 sk_X509_REVOKED_sort(ci->revoked);
1474 for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
1476 r=sk_X509_REVOKED_value(ci->revoked,i);
1480 /* we now have a CRL */
1481 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1484 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1486 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1492 #ifndef OPENSSL_NO_DSA
1493 if (pkey->type == EVP_PKEY_DSA)
1500 /* Add any extensions asked for */
1505 if (ci->version == NULL)
1506 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1507 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1508 X509V3_set_conf_lhash(&crlctx, conf);
1510 if (!X509V3_EXT_CRL_add_conf(conf, &crlctx,
1511 crl_ext, crl)) goto err;
1513 if (crl_ext || crl_v2)
1515 if (ci->version == NULL)
1516 if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
1517 ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
1520 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1522 PEM_write_bio_X509_CRL(Sout,crl);
1524 /*****************************************************************/
1529 BIO_printf(bio_err,"no input files\n");
1535 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1537 if (revcert == NULL)
1539 j=do_revoke(revcert,db, rev_type, rev_arg);
1540 if (j <= 0) goto err;
1543 strncpy(buf[0],dbfile,BSIZE-4);
1544 #ifndef OPENSSL_SYS_VMS
1545 strcat(buf[0],".new");
1547 strcat(buf[0],"-new");
1549 if (BIO_write_filename(out,buf[0]) <= 0)
1552 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1555 j=TXT_DB_write(out,db);
1556 if (j <= 0) goto err;
1557 strncpy(buf[1],dbfile,BSIZE-4);
1558 #ifndef OPENSSL_SYS_VMS
1559 strcat(buf[1],".old");
1561 strcat(buf[1],"-old");
1563 if (rename(dbfile,buf[1]) < 0)
1565 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1569 if (rename(buf[0],dbfile) < 0)
1571 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1573 rename(buf[1],dbfile);
1576 BIO_printf(bio_err,"Data Base Updated\n");
1579 /*****************************************************************/
1587 sk_X509_pop_free(cert_sk,X509_free);
1589 if (ret) ERR_print_errors(bio_err);
1590 app_RAND_write_file(randfile, bio_err);
1593 EVP_PKEY_free(pkey);
1602 static void lookup_fail(char *name, char *tag)
1604 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1607 static unsigned long index_serial_hash(const char **a)
1612 while (*n == '0') n++;
1613 return(lh_strhash(n));
1616 static int index_serial_cmp(const char **a, const char **b)
1620 for (aa=a[DB_serial]; *aa == '0'; aa++);
1621 for (bb=b[DB_serial]; *bb == '0'; bb++);
1622 return(strcmp(aa,bb));
1625 static unsigned long index_name_hash(const char **a)
1626 { return(lh_strhash(a[DB_name])); }
1628 static int index_name_qual(char **a)
1629 { return(a[0][0] == 'V'); }
1631 static int index_name_cmp(const char **a, const char **b)
1632 { return(strcmp(a[DB_name],
1635 static BIGNUM *load_serial(char *serialfile)
1639 MS_STATIC char buf[1024];
1640 ASN1_INTEGER *ai=NULL;
1642 if ((in=BIO_new(BIO_s_file())) == NULL)
1644 ERR_print_errors(bio_err);
1648 if (BIO_read_filename(in,serialfile) <= 0)
1653 ai=ASN1_INTEGER_new();
1654 if (ai == NULL) goto err;
1655 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1657 BIO_printf(bio_err,"unable to load number from %s\n",
1661 ret=ASN1_INTEGER_to_BN(ai,NULL);
1664 BIO_printf(bio_err,"error converting number from bin to BIGNUM");
1668 if (in != NULL) BIO_free(in);
1669 if (ai != NULL) ASN1_INTEGER_free(ai);
1673 static int save_serial(char *serialfile, BIGNUM *serial)
1677 ASN1_INTEGER *ai=NULL;
1679 out=BIO_new(BIO_s_file());
1682 ERR_print_errors(bio_err);
1685 if (BIO_write_filename(out,serialfile) <= 0)
1691 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1693 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1696 i2a_ASN1_INTEGER(out,ai);
1700 if (out != NULL) BIO_free_all(out);
1701 if (ai != NULL) ASN1_INTEGER_free(ai);
1705 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1706 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1707 BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
1708 int batch, char *ext_sect, LHASH *lconf, int verbose,
1709 unsigned long certopt, unsigned long nameopt, int default_op,
1714 EVP_PKEY *pktmp=NULL;
1717 in=BIO_new(BIO_s_file());
1719 if (BIO_read_filename(in,infile) <= 0)
1724 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1726 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1731 X509_REQ_print(bio_err,req);
1733 BIO_printf(bio_err,"Check that the request matches the signature\n");
1735 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1737 BIO_printf(bio_err,"error unpacking public key\n");
1740 i=X509_REQ_verify(req,pktmp);
1741 EVP_PKEY_free(pktmp);
1745 BIO_printf(bio_err,"Signature verification problems....\n");
1751 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1755 BIO_printf(bio_err,"Signature ok\n");
1757 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate, enddate,
1758 days,batch,verbose,req,ext_sect,lconf,
1759 certopt, nameopt, default_op, ext_copy);
1762 if (req != NULL) X509_REQ_free(req);
1763 if (in != NULL) BIO_free(in);
1767 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1768 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1769 BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
1770 int batch, char *ext_sect, LHASH *lconf, int verbose,
1771 unsigned long certopt, unsigned long nameopt, int default_op,
1772 int ext_copy, ENGINE *e)
1775 X509_REQ *rreq=NULL;
1776 EVP_PKEY *pktmp=NULL;
1779 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1782 X509_print(bio_err,req);
1784 BIO_printf(bio_err,"Check that the request matches the signature\n");
1786 if ((pktmp=X509_get_pubkey(req)) == NULL)
1788 BIO_printf(bio_err,"error unpacking public key\n");
1791 i=X509_verify(req,pktmp);
1792 EVP_PKEY_free(pktmp);
1796 BIO_printf(bio_err,"Signature verification problems....\n");
1802 BIO_printf(bio_err,"Signature did not match the certificate\n");
1806 BIO_printf(bio_err,"Signature ok\n");
1808 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1811 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,days,
1812 batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1816 if (rreq != NULL) X509_REQ_free(rreq);
1817 if (req != NULL) X509_free(req);
1821 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1822 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1823 char *startdate, char *enddate, int days, int batch, int verbose,
1824 X509_REQ *req, char *ext_sect, LHASH *lconf,
1825 unsigned long certopt, unsigned long nameopt, int default_op,
1828 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL;
1829 ASN1_UTCTIME *tm,*tmptm;
1830 ASN1_STRING *str,*str2;
1834 X509_NAME_ENTRY *ne;
1835 X509_NAME_ENTRY *tne,*push;
1837 int ok= -1,i,j,last,nid;
1840 char *row[DB_NUMBER],**rrow,**irow=NULL;
1843 tmptm=ASN1_UTCTIME_new();
1846 BIO_printf(bio_err,"malloc error\n");
1850 for (i=0; i<DB_NUMBER; i++)
1855 X509_NAME *n = do_subject(subj);
1859 ERR_print_errors(bio_err);
1862 X509_REQ_set_subject_name(req,n);
1863 req->req_info->enc.modified = 1;
1868 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1869 name=X509_REQ_get_subject_name(req);
1870 for (i=0; i<X509_NAME_entry_count(name); i++)
1872 ne= X509_NAME_get_entry(name,i);
1873 str=X509_NAME_ENTRY_get_data(ne);
1874 obj=X509_NAME_ENTRY_get_object(ne);
1878 /* assume all type should be strings */
1879 nid=OBJ_obj2nid(ne->object);
1881 if (str->type == V_ASN1_UNIVERSALSTRING)
1882 ASN1_UNIVERSALSTRING_to_string(str);
1884 if ((str->type == V_ASN1_IA5STRING) &&
1885 (nid != NID_pkcs9_emailAddress))
1886 str->type=V_ASN1_T61STRING;
1888 if ((nid == NID_pkcs9_emailAddress) &&
1889 (str->type == V_ASN1_PRINTABLESTRING))
1890 str->type=V_ASN1_IA5STRING;
1893 /* check some things */
1894 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1895 (str->type != V_ASN1_IA5STRING))
1897 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1900 j=ASN1_PRINTABLE_type(str->data,str->length);
1901 if ( ((j == V_ASN1_T61STRING) &&
1902 (str->type != V_ASN1_T61STRING)) ||
1903 ((j == V_ASN1_IA5STRING) &&
1904 (str->type == V_ASN1_PRINTABLESTRING)))
1906 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1911 old_entry_print(bio_err, obj, str);
1914 /* Ok, now we check the 'policy' stuff. */
1915 if ((subject=X509_NAME_new()) == NULL)
1917 BIO_printf(bio_err,"Memory allocation failure\n");
1921 /* take a copy of the issuer name before we mess with it. */
1922 CAname=X509_NAME_dup(x509->cert_info->subject);
1923 if (CAname == NULL) goto err;
1926 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1928 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1929 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1931 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1939 /* lookup the object in the supplied name list */
1940 j=X509_NAME_get_index_by_OBJ(name,obj,last);
1943 if (last != -1) break;
1948 tne=X509_NAME_get_entry(name,j);
1952 /* depending on the 'policy', decide what to do. */
1954 if (strcmp(cv->value,"optional") == 0)
1959 else if (strcmp(cv->value,"supplied") == 0)
1963 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
1969 else if (strcmp(cv->value,"match") == 0)
1975 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
1982 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
1983 if ((j < 0) && (last2 == -1))
1985 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
1990 push=X509_NAME_get_entry(CAname,j);
1991 str=X509_NAME_ENTRY_get_data(tne);
1992 str2=X509_NAME_ENTRY_get_data(push);
1994 if (ASN1_STRING_cmp(str,str2) != 0)
1999 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));
2005 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2011 if (!X509_NAME_add_entry(subject,push, -1, 0))
2014 X509_NAME_ENTRY_free(push);
2015 BIO_printf(bio_err,"Memory allocation failure\n");
2025 X509_NAME_free(subject);
2026 subject=X509_NAME_dup(X509_REQ_get_subject_name(req));
2027 if (subject == NULL) goto err;
2031 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2033 row[DB_name]=X509_NAME_oneline(subject,NULL,0);
2034 row[DB_serial]=BN_bn2hex(serial);
2035 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2037 BIO_printf(bio_err,"Memory allocation failure\n");
2041 rrow=TXT_DB_get_by_index(db,DB_name,row);
2044 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2049 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2052 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2054 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2061 "The matching entry has the following details\n");
2062 if (rrow[DB_type][0] == 'E')
2064 else if (rrow[DB_type][0] == 'R')
2066 else if (rrow[DB_type][0] == 'V')
2069 p="\ninvalid type, Data base error\n";
2070 BIO_printf(bio_err,"Type :%s\n",p);;
2071 if (rrow[DB_type][0] == 'R')
2073 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2074 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2076 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2077 BIO_printf(bio_err,"Expires on :%s\n",p);
2078 p=rrow[DB_serial]; if (p == NULL) p="undef";
2079 BIO_printf(bio_err,"Serial Number :%s\n",p);
2080 p=rrow[DB_file]; if (p == NULL) p="undef";
2081 BIO_printf(bio_err,"File name :%s\n",p);
2082 p=rrow[DB_name]; if (p == NULL) p="undef";
2083 BIO_printf(bio_err,"Subject Name :%s\n",p);
2084 ok= -1; /* This is now a 'bad' error. */
2088 /* We are now totally happy, lets make and sign the certificate */
2090 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2092 if ((ret=X509_new()) == NULL) goto err;
2096 /* Make it an X509 v3 certificate. */
2097 if (!X509_set_version(x509,2)) goto err;
2100 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2102 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2105 if (strcmp(startdate,"today") == 0)
2106 X509_gmtime_adj(X509_get_notBefore(ret),0);
2107 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2109 if (enddate == NULL)
2110 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2111 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2113 if (!X509_set_subject_name(ret,subject)) goto err;
2115 pktmp=X509_REQ_get_pubkey(req);
2116 i = X509_set_pubkey(ret,pktmp);
2117 EVP_PKEY_free(pktmp);
2120 /* Lets add the extensions, if there are any */
2124 if (ci->version == NULL)
2125 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2127 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2129 /* Free the current entries if any, there should not
2130 * be any I believe */
2131 if (ci->extensions != NULL)
2132 sk_X509_EXTENSION_pop_free(ci->extensions,
2133 X509_EXTENSION_free);
2135 ci->extensions = NULL;
2137 /* Initialize the context structure */
2138 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2143 BIO_printf(bio_err, "Extra configuration file found\n");
2145 /* Use the extconf configuration db LHASH */
2146 X509V3_set_conf_lhash(&ctx, extconf);
2148 /* Test the structure (needed?) */
2149 /* X509V3_set_ctx_test(&ctx); */
2151 /* Adds exts contained in the configuration file */
2152 if (!X509V3_EXT_add_conf(extconf, &ctx, ext_sect,ret))
2155 "ERROR: adding extensions in section %s\n",
2157 ERR_print_errors(bio_err);
2161 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2165 /* We found extensions to be set from config file */
2166 X509V3_set_conf_lhash(&ctx, lconf);
2168 if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret))
2170 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2171 ERR_print_errors(bio_err);
2176 BIO_printf(bio_err, "Successfully added extensions from config\n");
2180 /* Copy extensions from request (if any) */
2182 if (!copy_extensions(ret, req, ext_copy))
2184 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2185 ERR_print_errors(bio_err);
2192 BIO_printf(bio_err, "Certificate Details:\n");
2193 /* Never print signature details because signature not present */
2194 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2195 X509_print_ex(bio_err, ret, nameopt, certopt);
2198 BIO_printf(bio_err,"Certificate is to be certified until ");
2199 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2200 if (days) BIO_printf(bio_err," (%d days)",days);
2201 BIO_printf(bio_err, "\n");
2206 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2207 (void)BIO_flush(bio_err);
2209 fgets(buf,sizeof(buf)-1,stdin);
2210 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2212 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2219 #ifndef OPENSSL_NO_DSA
2220 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2221 pktmp=X509_get_pubkey(ret);
2222 if (EVP_PKEY_missing_parameters(pktmp) &&
2223 !EVP_PKEY_missing_parameters(pkey))
2224 EVP_PKEY_copy_parameters(pktmp,pkey);
2225 EVP_PKEY_free(pktmp);
2228 if (!X509_sign(ret,pkey,dgst))
2231 /* We now just add it to the database */
2232 row[DB_type]=(char *)OPENSSL_malloc(2);
2234 tm=X509_get_notAfter(ret);
2235 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2236 memcpy(row[DB_exp_date],tm->data,tm->length);
2237 row[DB_exp_date][tm->length]='\0';
2239 row[DB_rev_date]=NULL;
2241 /* row[DB_serial] done already */
2242 row[DB_file]=(char *)OPENSSL_malloc(8);
2243 /* row[DB_name] done already */
2245 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2246 (row[DB_file] == NULL))
2248 BIO_printf(bio_err,"Memory allocation failure\n");
2251 strcpy(row[DB_file],"unknown");
2252 row[DB_type][0]='V';
2253 row[DB_type][1]='\0';
2255 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2257 BIO_printf(bio_err,"Memory allocation failure\n");
2261 for (i=0; i<DB_NUMBER; i++)
2266 irow[DB_NUMBER]=NULL;
2268 if (!TXT_DB_insert(db,irow))
2270 BIO_printf(bio_err,"failed to update database\n");
2271 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2276 for (i=0; i<DB_NUMBER; i++)
2277 if (row[i] != NULL) OPENSSL_free(row[i]);
2280 X509_NAME_free(CAname);
2281 if (subject != NULL)
2282 X509_NAME_free(subject);
2284 ASN1_UTCTIME_free(tmptm);
2287 if (ret != NULL) X509_free(ret);
2295 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2300 (void)i2d_X509_bio(bp,x);
2304 /* ??? Not needed since X509_print prints all this stuff anyway */
2305 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2306 BIO_printf(bp,"issuer :%s\n",f);
2308 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2309 BIO_printf(bp,"subject:%s\n",f);
2311 BIO_puts(bp,"serial :");
2312 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2313 BIO_puts(bp,"\n\n");
2315 if (!notext)X509_print(bp,x);
2316 PEM_write_bio_X509(bp,x);
2319 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2320 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2321 BIGNUM *serial, char *subj, char *startdate, char *enddate, int days,
2322 char *ext_sect, LHASH *lconf, int verbose, unsigned long certopt,
2323 unsigned long nameopt, int default_op, int ext_copy)
2325 STACK_OF(CONF_VALUE) *sk=NULL;
2328 CONF_VALUE *cv=NULL;
2329 NETSCAPE_SPKI *spki = NULL;
2332 EVP_PKEY *pktmp=NULL;
2334 X509_NAME_ENTRY *ne=NULL;
2340 * Load input file into a hash table. (This is just an easy
2341 * way to read and parse the file, then put it into a convenient
2344 parms=CONF_load(NULL,infile,&errline);
2347 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2348 ERR_print_errors(bio_err);
2352 sk=CONF_get_section(parms, "default");
2353 if (sk_CONF_VALUE_num(sk) == 0)
2355 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2361 * Now create a dummy X509 request structure. We don't actually
2362 * have an X509 request, but we have many of the components
2363 * (a public key, various DN components). The idea is that we
2364 * put these components into the right X509 request structure
2365 * and we can use the same code as if you had a real X509 request.
2370 ERR_print_errors(bio_err);
2375 * Build up the subject name set.
2382 if (sk_CONF_VALUE_num(sk) <= i) break;
2384 cv=sk_CONF_VALUE_value(sk,i);
2386 /* Skip past any leading X. X: X, etc to allow for
2387 * multiple instances
2389 for (buf = cv->name; *buf ; buf++)
2390 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2393 if (*buf) type = buf;
2398 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2400 if (strcmp(type, "SPKAC") == 0)
2402 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2405 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2406 ERR_print_errors(bio_err);
2413 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2414 if (fix_data(nid, &j) == 0)
2417 "invalid characters in string %s\n",buf);
2421 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2422 (unsigned char *)buf,
2423 strlen(buf))) == NULL)
2426 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2430 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2436 * Now extract the key from the SPKI structure.
2439 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2441 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2443 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2447 j = NETSCAPE_SPKI_verify(spki, pktmp);
2450 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2453 BIO_printf(bio_err,"Signature ok\n");
2455 X509_REQ_set_pubkey(req,pktmp);
2456 EVP_PKEY_free(pktmp);
2457 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,
2458 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2461 if (req != NULL) X509_REQ_free(req);
2462 if (parms != NULL) CONF_free(parms);
2463 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2464 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2469 static int fix_data(int nid, int *type)
2471 if (nid == NID_pkcs9_emailAddress)
2472 *type=V_ASN1_IA5STRING;
2473 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2474 *type=V_ASN1_T61STRING;
2475 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2476 *type=V_ASN1_T61STRING;
2477 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2479 if (nid == NID_pkcs9_unstructuredName)
2480 *type=V_ASN1_IA5STRING;
2484 static int check_time_format(char *str)
2488 tm.data=(unsigned char *)str;
2489 tm.length=strlen(str);
2490 tm.type=V_ASN1_UTCTIME;
2491 return(ASN1_UTCTIME_check(&tm));
2494 static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2496 ASN1_UTCTIME *tm=NULL;
2497 char *row[DB_NUMBER],**rrow,**irow;
2498 char *rev_str = NULL;
2502 for (i=0; i<DB_NUMBER; i++)
2504 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2505 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2506 row[DB_serial]=BN_bn2hex(bn);
2508 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2510 BIO_printf(bio_err,"Memory allocation failure\n");
2513 /* We have to lookup by serial number because name lookup
2514 * skips revoked certs
2516 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2519 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2521 /* We now just add it to the database */
2522 row[DB_type]=(char *)OPENSSL_malloc(2);
2524 tm=X509_get_notAfter(x509);
2525 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2526 memcpy(row[DB_exp_date],tm->data,tm->length);
2527 row[DB_exp_date][tm->length]='\0';
2529 row[DB_rev_date]=NULL;
2531 /* row[DB_serial] done already */
2532 row[DB_file]=(char *)OPENSSL_malloc(8);
2534 /* row[DB_name] done already */
2536 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2537 (row[DB_file] == NULL))
2539 BIO_printf(bio_err,"Memory allocation failure\n");
2542 strcpy(row[DB_file],"unknown");
2543 row[DB_type][0]='V';
2544 row[DB_type][1]='\0';
2546 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2548 BIO_printf(bio_err,"Memory allocation failure\n");
2552 for (i=0; i<DB_NUMBER; i++)
2557 irow[DB_NUMBER]=NULL;
2559 if (!TXT_DB_insert(db,irow))
2561 BIO_printf(bio_err,"failed to update database\n");
2562 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2566 /* Revoke Certificate */
2567 ok = do_revoke(x509,db, type, value);
2572 else if (index_name_cmp((const char **)row,(const char **)rrow))
2574 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2578 else if (rrow[DB_type][0]=='R')
2580 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2586 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2587 rev_str = make_revocation_str(type, value);
2590 BIO_printf(bio_err, "Error in revocation arguments\n");
2593 rrow[DB_type][0]='R';
2594 rrow[DB_type][1]='\0';
2595 rrow[DB_rev_date] = rev_str;
2599 for (i=0; i<DB_NUMBER; i++)
2602 OPENSSL_free(row[i]);
2607 static int get_certificate_status(const char *serial, TXT_DB *db)
2609 char *row[DB_NUMBER],**rrow;
2612 /* Free Resources */
2613 for (i=0; i<DB_NUMBER; i++)
2616 /* Malloc needed char spaces */
2617 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2618 if (row[DB_serial] == NULL)
2620 BIO_printf(bio_err,"Malloc failure\n");
2624 if (strlen(serial) % 2)
2626 /* Set the first char to 0 */;
2627 row[DB_serial][0]='0';
2629 /* Copy String from serial to row[DB_serial] */
2630 memcpy(row[DB_serial]+1, serial, strlen(serial));
2631 row[DB_serial][strlen(serial)+1]='\0';
2635 /* Copy String from serial to row[DB_serial] */
2636 memcpy(row[DB_serial], serial, strlen(serial));
2637 row[DB_serial][strlen(serial)]='\0';
2640 /* Make it Upper Case */
2641 for (i=0; row[DB_serial][i] != '\0'; i++)
2642 row[DB_serial][i] = toupper(row[DB_serial][i]);
2647 /* Search for the certificate */
2648 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2651 BIO_printf(bio_err,"Serial %s not present in db.\n",
2656 else if (rrow[DB_type][0]=='V')
2658 BIO_printf(bio_err,"%s=Valid (%c)\n",
2659 row[DB_serial], rrow[DB_type][0]);
2662 else if (rrow[DB_type][0]=='R')
2664 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2665 row[DB_serial], rrow[DB_type][0]);
2668 else if (rrow[DB_type][0]=='E')
2670 BIO_printf(bio_err,"%s=Expired (%c)\n",
2671 row[DB_serial], rrow[DB_type][0]);
2674 else if (rrow[DB_type][0]=='S')
2676 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2677 row[DB_serial], rrow[DB_type][0]);
2682 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2683 row[DB_serial], rrow[DB_type][0]);
2687 for (i=0; i<DB_NUMBER; i++)
2690 OPENSSL_free(row[i]);
2695 static int do_updatedb (TXT_DB *db)
2697 ASN1_UTCTIME *a_tm = NULL;
2699 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2700 char **rrow, *a_tm_s;
2702 a_tm = ASN1_UTCTIME_new();
2704 /* get actual time and make a string */
2705 a_tm = X509_gmtime_adj(a_tm, 0);
2706 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2713 memcpy(a_tm_s, a_tm->data, a_tm->length);
2714 a_tm_s[a_tm->length] = '\0';
2716 if (strncmp(a_tm_s, "49", 2) <= 0)
2721 for (i = 0; i < sk_num(db->data); i++)
2723 rrow = (char **) sk_value(db->data, i);
2725 if (rrow[DB_type][0] == 'V')
2727 /* ignore entries that are not valid */
2728 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2733 if (db_y2k == a_y2k)
2735 /* all on the same y2k side */
2736 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2738 rrow[DB_type][0] = 'E';
2739 rrow[DB_type][1] = '\0';
2742 BIO_printf(bio_err, "%s=Expired\n",
2746 else if (db_y2k < a_y2k)
2748 rrow[DB_type][0] = 'E';
2749 rrow[DB_type][1] = '\0';
2752 BIO_printf(bio_err, "%s=Expired\n",
2761 ASN1_UTCTIME_free(a_tm);
2762 OPENSSL_free(a_tm_s);
2767 static char *crl_reasons[] = {
2768 /* CRL reason strings */
2772 "affiliationChanged",
2774 "cessationOfOperation",
2777 /* Additional pseudo reasons */
2783 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2785 /* Given revocation information convert to a DB string.
2786 * The format of the string is:
2787 * revtime[,reason,extra]. Where 'revtime' is the
2788 * revocation time (the current time). 'reason' is the
2789 * optional CRL reason and 'extra' is any additional
2793 char *make_revocation_str(int rev_type, char *rev_arg)
2795 char *reason = NULL, *other = NULL, *str;
2797 ASN1_UTCTIME *revtm = NULL;
2804 case REV_CRL_REASON:
2805 for (i = 0; i < 8; i++)
2807 if (!strcasecmp(rev_arg, crl_reasons[i]))
2809 reason = crl_reasons[i];
2815 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2821 /* Argument is an OID */
2823 otmp = OBJ_txt2obj(rev_arg, 0);
2824 ASN1_OBJECT_free(otmp);
2828 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2832 reason = "holdInstruction";
2836 case REV_KEY_COMPROMISE:
2837 case REV_CA_COMPROMISE:
2839 /* Argument is the key compromise time */
2840 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2842 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2846 if (rev_type == REV_KEY_COMPROMISE)
2849 reason = "CAkeyTime";
2855 revtm = X509_gmtime_adj(NULL, 0);
2857 i = revtm->length + 1;
2859 if (reason) i += strlen(reason) + 1;
2860 if (other) i += strlen(other) + 1;
2862 str = OPENSSL_malloc(i);
2864 if (!str) return NULL;
2866 strcpy(str, (char *)revtm->data);
2870 strcat(str, reason);
2877 ASN1_UTCTIME_free(revtm);
2881 /* Convert revocation field to X509_REVOKED entry
2885 * 2 OK and some extensions added (i.e. V2 CRL)
2888 int make_revoked(X509_REVOKED *rev, char *str)
2891 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2892 int reason_code = -1;
2894 ASN1_OBJECT *hold = NULL;
2895 ASN1_GENERALIZEDTIME *comp_time = NULL;
2896 ASN1_ENUMERATED *rtmp = NULL;
2897 tmp = BUF_strdup(str);
2899 p = strchr(tmp, ',');
2916 if (rev && !ASN1_UTCTIME_set_string(rev->revocationDate, rtime_str))
2918 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2923 for (i = 0; i < NUM_REASONS; i++)
2925 if(!strcasecmp(reason_str, crl_reasons[i]))
2931 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
2933 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2937 if (reason_code == 7)
2938 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2939 else if (reason_code == 8) /* Hold instruction */
2943 BIO_printf(bio_err, "missing hold instruction\n");
2946 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2947 hold = OBJ_txt2obj(arg_str, 0);
2951 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
2955 else if ((reason_code == 9) || (reason_code == 10))
2959 BIO_printf(bio_err, "missing compromised time\n");
2962 comp_time = ASN1_GENERALIZEDTIME_new();
2963 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
2965 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
2968 if (reason_code == 9)
2969 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2971 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2975 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
2977 rtmp = ASN1_ENUMERATED_new();
2978 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
2980 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2984 if (rev && comp_time)
2986 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
2991 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
2995 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3001 if (tmp) OPENSSL_free(tmp);
3002 ASN1_OBJECT_free(hold);
3003 ASN1_GENERALIZEDTIME_free(comp_time);
3004 ASN1_ENUMERATED_free(rtmp);
3009 static X509_NAME *do_subject(char *subject)
3011 X509_NAME *n = NULL;
3013 int i, nid, ne_num=0;
3015 char *ne_name = NULL;
3016 char *ne_value = NULL;
3021 char *str_list[256];
3026 n = X509_NAME_new();
3028 tmp = strtok(subject, p[0]);
3029 while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list)))
3033 while (token[0] == ' ')
3035 str_list[ne_num] = token;
3037 tmp = strtok(NULL, p[0]);
3041 for (i = 0; i < ne_num; i++)
3043 ne_name = strtok(str_list[i], p[1]);
3044 ne_value = strtok(NULL, p[1]);
3046 if ((nid=OBJ_txt2nid(ne_name)) == NID_undef)
3048 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name);
3052 if (ne_value == NULL)
3054 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name);
3058 if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char*)ne_value, -1,-1,0))
3069 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3071 char buf[25],*pbuf, *p;
3073 j=i2a_ASN1_OBJECT(bp,obj);
3075 for (j=22-j; j>0; j--)
3081 if (str->type == V_ASN1_PRINTABLESTRING)
3082 BIO_printf(bp,"PRINTABLE:'");
3083 else if (str->type == V_ASN1_T61STRING)
3084 BIO_printf(bp,"T61STRING:'");
3085 else if (str->type == V_ASN1_IA5STRING)
3086 BIO_printf(bp,"IA5STRING:'");
3087 else if (str->type == V_ASN1_UNIVERSALSTRING)
3088 BIO_printf(bp,"UNIVERSALSTRING:'");
3090 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3092 p=(char *)str->data;
3093 for (j=str->length; j>0; j--)
3095 if ((*p >= ' ') && (*p <= '~'))
3096 BIO_printf(bp,"%c",*p);
3098 BIO_printf(bp,"\\0x%02X",*p);
3099 else if ((unsigned char)*p == 0xf7)
3100 BIO_printf(bp,"^?");
3101 else BIO_printf(bp,"^%c",*p+'@');
3104 BIO_printf(bp,"'\n");