Deleted Added
full compact
ca.c (109998) ca.c (111147)
1/* apps/ca.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
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.
8 *
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).
15 *
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.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
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)"
40 *
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
51 * SUCH DAMAGE.
52 *
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.]
57 */
58
59/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <ctype.h>
65#include <sys/types.h>
66#include <sys/stat.h>
67#include <openssl/conf.h>
68#include <openssl/bio.h>
69#include <openssl/err.h>
70#include <openssl/bn.h>
71#include <openssl/txt_db.h>
72#include <openssl/evp.h>
73#include <openssl/x509.h>
74#include <openssl/x509v3.h>
75#include <openssl/objects.h>
76#include <openssl/ocsp.h>
77#include <openssl/pem.h>
78
79#ifdef OPENSSL_SYS_WINDOWS
80#define strcasecmp _stricmp
81#else
82# ifdef NO_STRINGS_H
83 int strcasecmp();
84# else
85# include <strings.h>
86# endif /* NO_STRINGS_H */
87#endif
88
89#ifndef W_OK
90# ifdef OPENSSL_SYS_VMS
91# if defined(__DECC)
92# include <unistd.h>
93# else
94# include <unixlib.h>
95# endif
96# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
97# include <sys/file.h>
98# endif
99#endif
100
101#include "apps.h"
102
103#ifndef W_OK
104# define F_OK 0
105# define X_OK 1
106# define W_OK 2
107# define R_OK 4
108#endif
109
110#undef PROG
111#define PROG ca_main
112
113#define BASE_SECTION "ca"
114#define CONFIG_FILE "openssl.cnf"
115
116#define ENV_DEFAULT_CA "default_ca"
117
118#define ENV_DIR "dir"
119#define ENV_CERTS "certs"
120#define ENV_CRL_DIR "crl_dir"
121#define ENV_CA_DB "CA_DB"
122#define ENV_NEW_CERTS_DIR "new_certs_dir"
123#define ENV_CERTIFICATE "certificate"
124#define ENV_SERIAL "serial"
125#define ENV_CRL "crl"
126#define ENV_PRIVATE_KEY "private_key"
127#define ENV_RANDFILE "RANDFILE"
128#define ENV_DEFAULT_DAYS "default_days"
129#define ENV_DEFAULT_STARTDATE "default_startdate"
130#define ENV_DEFAULT_ENDDATE "default_enddate"
131#define ENV_DEFAULT_CRL_DAYS "default_crl_days"
132#define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
133#define ENV_DEFAULT_MD "default_md"
134#define ENV_DEFAULT_EMAIL_DN "email_in_dn"
135#define ENV_PRESERVE "preserve"
136#define ENV_POLICY "policy"
137#define ENV_EXTENSIONS "x509_extensions"
138#define ENV_CRLEXT "crl_extensions"
139#define ENV_MSIE_HACK "msie_hack"
140#define ENV_NAMEOPT "name_opt"
141#define ENV_CERTOPT "cert_opt"
142#define ENV_EXTCOPY "copy_extensions"
143
144#define ENV_DATABASE "database"
145
146#define DB_type 0
147#define DB_exp_date 1
148#define DB_rev_date 2
149#define DB_serial 3 /* index - unique */
150#define DB_file 4
151#define DB_name 5 /* index - unique for active */
152#define DB_NUMBER 6
153
154#define DB_TYPE_REV 'R'
155#define DB_TYPE_EXP 'E'
156#define DB_TYPE_VAL 'V'
157
158/* Additional revocation information types */
159
160#define REV_NONE 0 /* No addditional information */
161#define REV_CRL_REASON 1 /* Value is CRL reason code */
162#define REV_HOLD 2 /* Value is hold instruction */
163#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
164#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
165
166static char *ca_usage[]={
167"usage: ca args\n",
168"\n",
169" -verbose - Talk alot while doing things\n",
170" -config file - A config file\n",
171" -name arg - The particular CA definition to use\n",
172" -gencrl - Generate a new CRL\n",
173" -crldays days - Days is when the next CRL is due\n",
174" -crlhours hours - Hours is when the next CRL is due\n",
175" -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
176" -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
177" -days arg - number of days to certify the certificate for\n",
178" -md arg - md to use, one of md2, md5, sha or sha1\n",
179" -policy arg - The CA 'policy' to support\n",
180" -keyfile arg - private key file\n",
181" -keyform arg - private key file format (PEM or ENGINE)\n",
182" -key arg - key to decode the private key if it is encrypted\n",
183" -cert file - The CA certificate\n",
184" -in file - The input PEM encoded certificate request(s)\n",
185" -out file - Where to put the output file(s)\n",
186" -outdir dir - Where to put output certificates\n",
187" -infiles .... - The last argument, requests to process\n",
188" -spkac file - File contains DN and signed public key and challenge\n",
189" -ss_cert file - File contains a self signed cert to sign\n",
190" -preserveDN - Don't re-order the DN\n",
191" -noemailDN - Don't add the EMAIL field into certificate' subject\n",
192" -batch - Don't ask questions\n",
193" -msie_hack - msie modifications to handle all those universal strings\n",
194" -revoke file - Revoke a certificate (given in file)\n",
195" -subj arg - Use arg instead of request's subject\n",
196" -extensions .. - Extension section (override value in config file)\n",
197" -extfile file - Configuration file with X509v3 extentions to add\n",
198" -crlexts .. - CRL extension section (override value in config file)\n",
1/* apps/ca.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
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.
8 *
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).
15 *
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.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
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)"
40 *
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
51 * SUCH DAMAGE.
52 *
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.]
57 */
58
59/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <ctype.h>
65#include <sys/types.h>
66#include <sys/stat.h>
67#include <openssl/conf.h>
68#include <openssl/bio.h>
69#include <openssl/err.h>
70#include <openssl/bn.h>
71#include <openssl/txt_db.h>
72#include <openssl/evp.h>
73#include <openssl/x509.h>
74#include <openssl/x509v3.h>
75#include <openssl/objects.h>
76#include <openssl/ocsp.h>
77#include <openssl/pem.h>
78
79#ifdef OPENSSL_SYS_WINDOWS
80#define strcasecmp _stricmp
81#else
82# ifdef NO_STRINGS_H
83 int strcasecmp();
84# else
85# include <strings.h>
86# endif /* NO_STRINGS_H */
87#endif
88
89#ifndef W_OK
90# ifdef OPENSSL_SYS_VMS
91# if defined(__DECC)
92# include <unistd.h>
93# else
94# include <unixlib.h>
95# endif
96# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
97# include <sys/file.h>
98# endif
99#endif
100
101#include "apps.h"
102
103#ifndef W_OK
104# define F_OK 0
105# define X_OK 1
106# define W_OK 2
107# define R_OK 4
108#endif
109
110#undef PROG
111#define PROG ca_main
112
113#define BASE_SECTION "ca"
114#define CONFIG_FILE "openssl.cnf"
115
116#define ENV_DEFAULT_CA "default_ca"
117
118#define ENV_DIR "dir"
119#define ENV_CERTS "certs"
120#define ENV_CRL_DIR "crl_dir"
121#define ENV_CA_DB "CA_DB"
122#define ENV_NEW_CERTS_DIR "new_certs_dir"
123#define ENV_CERTIFICATE "certificate"
124#define ENV_SERIAL "serial"
125#define ENV_CRL "crl"
126#define ENV_PRIVATE_KEY "private_key"
127#define ENV_RANDFILE "RANDFILE"
128#define ENV_DEFAULT_DAYS "default_days"
129#define ENV_DEFAULT_STARTDATE "default_startdate"
130#define ENV_DEFAULT_ENDDATE "default_enddate"
131#define ENV_DEFAULT_CRL_DAYS "default_crl_days"
132#define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
133#define ENV_DEFAULT_MD "default_md"
134#define ENV_DEFAULT_EMAIL_DN "email_in_dn"
135#define ENV_PRESERVE "preserve"
136#define ENV_POLICY "policy"
137#define ENV_EXTENSIONS "x509_extensions"
138#define ENV_CRLEXT "crl_extensions"
139#define ENV_MSIE_HACK "msie_hack"
140#define ENV_NAMEOPT "name_opt"
141#define ENV_CERTOPT "cert_opt"
142#define ENV_EXTCOPY "copy_extensions"
143
144#define ENV_DATABASE "database"
145
146#define DB_type 0
147#define DB_exp_date 1
148#define DB_rev_date 2
149#define DB_serial 3 /* index - unique */
150#define DB_file 4
151#define DB_name 5 /* index - unique for active */
152#define DB_NUMBER 6
153
154#define DB_TYPE_REV 'R'
155#define DB_TYPE_EXP 'E'
156#define DB_TYPE_VAL 'V'
157
158/* Additional revocation information types */
159
160#define REV_NONE 0 /* No addditional information */
161#define REV_CRL_REASON 1 /* Value is CRL reason code */
162#define REV_HOLD 2 /* Value is hold instruction */
163#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
164#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
165
166static char *ca_usage[]={
167"usage: ca args\n",
168"\n",
169" -verbose - Talk alot while doing things\n",
170" -config file - A config file\n",
171" -name arg - The particular CA definition to use\n",
172" -gencrl - Generate a new CRL\n",
173" -crldays days - Days is when the next CRL is due\n",
174" -crlhours hours - Hours is when the next CRL is due\n",
175" -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n",
176" -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n",
177" -days arg - number of days to certify the certificate for\n",
178" -md arg - md to use, one of md2, md5, sha or sha1\n",
179" -policy arg - The CA 'policy' to support\n",
180" -keyfile arg - private key file\n",
181" -keyform arg - private key file format (PEM or ENGINE)\n",
182" -key arg - key to decode the private key if it is encrypted\n",
183" -cert file - The CA certificate\n",
184" -in file - The input PEM encoded certificate request(s)\n",
185" -out file - Where to put the output file(s)\n",
186" -outdir dir - Where to put output certificates\n",
187" -infiles .... - The last argument, requests to process\n",
188" -spkac file - File contains DN and signed public key and challenge\n",
189" -ss_cert file - File contains a self signed cert to sign\n",
190" -preserveDN - Don't re-order the DN\n",
191" -noemailDN - Don't add the EMAIL field into certificate' subject\n",
192" -batch - Don't ask questions\n",
193" -msie_hack - msie modifications to handle all those universal strings\n",
194" -revoke file - Revoke a certificate (given in file)\n",
195" -subj arg - Use arg instead of request's subject\n",
196" -extensions .. - Extension section (override value in config file)\n",
197" -extfile file - Configuration file with X509v3 extentions to add\n",
198" -crlexts .. - CRL extension section (override value in config file)\n",
199#ifndef OPENSSL_NO_ENGINE
199" -engine e - use engine e, possibly a hardware device.\n",
200" -engine e - use engine e, possibly a hardware device.\n",
201#endif
200" -status serial - Shows certificate status given the serial number\n",
201" -updatedb - Updates db for expired certificates\n",
202NULL
203};
204
205#ifdef EFENCE
206extern int EF_PROTECT_FREE;
207extern int EF_PROTECT_BELOW;
208extern int EF_ALIGNMENT;
209#endif
210
211static void lookup_fail(char *name,char *tag);
212static unsigned long index_serial_hash(const char **a);
213static int index_serial_cmp(const char **a, const char **b);
214static unsigned long index_name_hash(const char **a);
215static int index_name_qual(char **a);
216static int index_name_cmp(const char **a,const char **b);
217static BIGNUM *load_serial(char *serialfile);
218static int save_serial(char *serialfile, BIGNUM *serial);
219static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
220 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
221 BIGNUM *serial, char *subj, int email_dn, char *startdate,
222 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
223 int verbose, unsigned long certopt, unsigned long nameopt,
224 int default_op, int ext_copy);
225static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
226 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
227 TXT_DB *db, BIGNUM *serial, char *subj, int email_dn,
228 char *startdate, char *enddate, long days, int batch,
229 char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
230 unsigned long nameopt, int default_op, int ext_copy,
231 ENGINE *e);
232static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
233 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
234 TXT_DB *db, BIGNUM *serial,char *subj, int email_dn,
235 char *startdate, char *enddate, long days, char *ext_sect,
236 CONF *conf, int verbose, unsigned long certopt,
237 unsigned long nameopt, int default_op, int ext_copy);
238static int fix_data(int nid, int *type);
239static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
240static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
241 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
242 int email_dn, char *startdate, char *enddate, long days, int batch,
243 int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
244 unsigned long certopt, unsigned long nameopt, int default_op,
245 int ext_copy);
246static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
247static int get_certificate_status(const char *ser_status, TXT_DB *db);
248static int do_updatedb(TXT_DB *db);
249static int check_time_format(char *str);
250char *make_revocation_str(int rev_type, char *rev_arg);
251int make_revoked(X509_REVOKED *rev, char *str);
252int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
253static CONF *conf=NULL;
254static CONF *extconf=NULL;
255static char *section=NULL;
256
257static int preserve=0;
258static int msie_hack=0;
259
260static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
261static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
262static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
263static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
264
265
266int MAIN(int, char **);
267
268int MAIN(int argc, char **argv)
269 {
270 ENGINE *e = NULL;
271 char *key=NULL,*passargin=NULL;
272 int free_key = 0;
273 int total=0;
274 int total_done=0;
275 int badops=0;
276 int ret=1;
277 int email_dn=1;
278 int req=0;
279 int verbose=0;
280 int gencrl=0;
281 int dorevoke=0;
282 int doupdatedb=0;
283 long crldays=0;
284 long crlhours=0;
285 long errorline= -1;
286 char *configfile=NULL;
287 char *md=NULL;
288 char *policy=NULL;
289 char *keyfile=NULL;
290 char *certfile=NULL;
291 int keyform=FORMAT_PEM;
292 char *infile=NULL;
293 char *spkac_file=NULL;
294 char *ss_cert_file=NULL;
295 char *ser_status=NULL;
296 EVP_PKEY *pkey=NULL;
297 int output_der = 0;
298 char *outfile=NULL;
299 char *outdir=NULL;
300 char *serialfile=NULL;
301 char *extensions=NULL;
302 char *extfile=NULL;
303 char *subj=NULL;
304 char *tmp_email_dn=NULL;
305 char *crl_ext=NULL;
306 int rev_type = REV_NONE;
307 char *rev_arg = NULL;
308 BIGNUM *serial=NULL;
309 char *startdate=NULL;
310 char *enddate=NULL;
311 long days=0;
312 int batch=0;
313 int notext=0;
314 unsigned long nameopt = 0, certopt = 0;
315 int default_op = 1;
316 int ext_copy = EXT_COPY_NONE;
317 X509 *x509=NULL;
318 X509 *x=NULL;
319 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
320 char *dbfile=NULL;
321 TXT_DB *db=NULL;
322 X509_CRL *crl=NULL;
323 X509_REVOKED *r=NULL;
324 ASN1_TIME *tmptm;
325 ASN1_INTEGER *tmpser;
326 char **pp,*p,*f;
327 int i,j;
328 long l;
329 const EVP_MD *dgst=NULL;
330 STACK_OF(CONF_VALUE) *attribs=NULL;
331 STACK_OF(X509) *cert_sk=NULL;
332#undef BSIZE
333#define BSIZE 256
334 MS_STATIC char buf[3][BSIZE];
335 char *randfile=NULL;
202" -status serial - Shows certificate status given the serial number\n",
203" -updatedb - Updates db for expired certificates\n",
204NULL
205};
206
207#ifdef EFENCE
208extern int EF_PROTECT_FREE;
209extern int EF_PROTECT_BELOW;
210extern int EF_ALIGNMENT;
211#endif
212
213static void lookup_fail(char *name,char *tag);
214static unsigned long index_serial_hash(const char **a);
215static int index_serial_cmp(const char **a, const char **b);
216static unsigned long index_name_hash(const char **a);
217static int index_name_qual(char **a);
218static int index_name_cmp(const char **a,const char **b);
219static BIGNUM *load_serial(char *serialfile);
220static int save_serial(char *serialfile, BIGNUM *serial);
221static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
222 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db,
223 BIGNUM *serial, char *subj, int email_dn, char *startdate,
224 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
225 int verbose, unsigned long certopt, unsigned long nameopt,
226 int default_op, int ext_copy);
227static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
228 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
229 TXT_DB *db, BIGNUM *serial, char *subj, int email_dn,
230 char *startdate, char *enddate, long days, int batch,
231 char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
232 unsigned long nameopt, int default_op, int ext_copy,
233 ENGINE *e);
234static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
235 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
236 TXT_DB *db, BIGNUM *serial,char *subj, int email_dn,
237 char *startdate, char *enddate, long days, char *ext_sect,
238 CONF *conf, int verbose, unsigned long certopt,
239 unsigned long nameopt, int default_op, int ext_copy);
240static int fix_data(int nid, int *type);
241static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
242static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
243 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj,
244 int email_dn, char *startdate, char *enddate, long days, int batch,
245 int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
246 unsigned long certopt, unsigned long nameopt, int default_op,
247 int ext_copy);
248static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
249static int get_certificate_status(const char *ser_status, TXT_DB *db);
250static int do_updatedb(TXT_DB *db);
251static int check_time_format(char *str);
252char *make_revocation_str(int rev_type, char *rev_arg);
253int make_revoked(X509_REVOKED *rev, char *str);
254int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
255static CONF *conf=NULL;
256static CONF *extconf=NULL;
257static char *section=NULL;
258
259static int preserve=0;
260static int msie_hack=0;
261
262static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
263static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
264static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
265static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
266
267
268int MAIN(int, char **);
269
270int MAIN(int argc, char **argv)
271 {
272 ENGINE *e = NULL;
273 char *key=NULL,*passargin=NULL;
274 int free_key = 0;
275 int total=0;
276 int total_done=0;
277 int badops=0;
278 int ret=1;
279 int email_dn=1;
280 int req=0;
281 int verbose=0;
282 int gencrl=0;
283 int dorevoke=0;
284 int doupdatedb=0;
285 long crldays=0;
286 long crlhours=0;
287 long errorline= -1;
288 char *configfile=NULL;
289 char *md=NULL;
290 char *policy=NULL;
291 char *keyfile=NULL;
292 char *certfile=NULL;
293 int keyform=FORMAT_PEM;
294 char *infile=NULL;
295 char *spkac_file=NULL;
296 char *ss_cert_file=NULL;
297 char *ser_status=NULL;
298 EVP_PKEY *pkey=NULL;
299 int output_der = 0;
300 char *outfile=NULL;
301 char *outdir=NULL;
302 char *serialfile=NULL;
303 char *extensions=NULL;
304 char *extfile=NULL;
305 char *subj=NULL;
306 char *tmp_email_dn=NULL;
307 char *crl_ext=NULL;
308 int rev_type = REV_NONE;
309 char *rev_arg = NULL;
310 BIGNUM *serial=NULL;
311 char *startdate=NULL;
312 char *enddate=NULL;
313 long days=0;
314 int batch=0;
315 int notext=0;
316 unsigned long nameopt = 0, certopt = 0;
317 int default_op = 1;
318 int ext_copy = EXT_COPY_NONE;
319 X509 *x509=NULL;
320 X509 *x=NULL;
321 BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
322 char *dbfile=NULL;
323 TXT_DB *db=NULL;
324 X509_CRL *crl=NULL;
325 X509_REVOKED *r=NULL;
326 ASN1_TIME *tmptm;
327 ASN1_INTEGER *tmpser;
328 char **pp,*p,*f;
329 int i,j;
330 long l;
331 const EVP_MD *dgst=NULL;
332 STACK_OF(CONF_VALUE) *attribs=NULL;
333 STACK_OF(X509) *cert_sk=NULL;
334#undef BSIZE
335#define BSIZE 256
336 MS_STATIC char buf[3][BSIZE];
337 char *randfile=NULL;
338#ifndef OPENSSL_NO_ENGINE
336 char *engine = NULL;
339 char *engine = NULL;
340#endif
337 char *tofree=NULL;
338
339#ifdef EFENCE
340EF_PROTECT_FREE=1;
341EF_PROTECT_BELOW=1;
342EF_ALIGNMENT=0;
343#endif
344
345 apps_startup();
346
347 conf = NULL;
348 key = NULL;
349 section = NULL;
350
351 preserve=0;
352 msie_hack=0;
353 if (bio_err == NULL)
354 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
355 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
356
357 argc--;
358 argv++;
359 while (argc >= 1)
360 {
361 if (strcmp(*argv,"-verbose") == 0)
362 verbose=1;
363 else if (strcmp(*argv,"-config") == 0)
364 {
365 if (--argc < 1) goto bad;
366 configfile= *(++argv);
367 }
368 else if (strcmp(*argv,"-name") == 0)
369 {
370 if (--argc < 1) goto bad;
371 section= *(++argv);
372 }
373 else if (strcmp(*argv,"-subj") == 0)
374 {
375 if (--argc < 1) goto bad;
376 subj= *(++argv);
377 /* preserve=1; */
378 }
379 else if (strcmp(*argv,"-startdate") == 0)
380 {
381 if (--argc < 1) goto bad;
382 startdate= *(++argv);
383 }
384 else if (strcmp(*argv,"-enddate") == 0)
385 {
386 if (--argc < 1) goto bad;
387 enddate= *(++argv);
388 }
389 else if (strcmp(*argv,"-days") == 0)
390 {
391 if (--argc < 1) goto bad;
392 days=atoi(*(++argv));
393 }
394 else if (strcmp(*argv,"-md") == 0)
395 {
396 if (--argc < 1) goto bad;
397 md= *(++argv);
398 }
399 else if (strcmp(*argv,"-policy") == 0)
400 {
401 if (--argc < 1) goto bad;
402 policy= *(++argv);
403 }
404 else if (strcmp(*argv,"-keyfile") == 0)
405 {
406 if (--argc < 1) goto bad;
407 keyfile= *(++argv);
408 }
409 else if (strcmp(*argv,"-keyform") == 0)
410 {
411 if (--argc < 1) goto bad;
412 keyform=str2fmt(*(++argv));
413 }
414 else if (strcmp(*argv,"-passin") == 0)
415 {
416 if (--argc < 1) goto bad;
417 passargin= *(++argv);
418 }
419 else if (strcmp(*argv,"-key") == 0)
420 {
421 if (--argc < 1) goto bad;
422 key= *(++argv);
423 }
424 else if (strcmp(*argv,"-cert") == 0)
425 {
426 if (--argc < 1) goto bad;
427 certfile= *(++argv);
428 }
429 else if (strcmp(*argv,"-in") == 0)
430 {
431 if (--argc < 1) goto bad;
432 infile= *(++argv);
433 req=1;
434 }
435 else if (strcmp(*argv,"-out") == 0)
436 {
437 if (--argc < 1) goto bad;
438 outfile= *(++argv);
439 }
440 else if (strcmp(*argv,"-outdir") == 0)
441 {
442 if (--argc < 1) goto bad;
443 outdir= *(++argv);
444 }
445 else if (strcmp(*argv,"-notext") == 0)
446 notext=1;
447 else if (strcmp(*argv,"-batch") == 0)
448 batch=1;
449 else if (strcmp(*argv,"-preserveDN") == 0)
450 preserve=1;
451 else if (strcmp(*argv,"-noemailDN") == 0)
452 email_dn=0;
453 else if (strcmp(*argv,"-gencrl") == 0)
454 gencrl=1;
455 else if (strcmp(*argv,"-msie_hack") == 0)
456 msie_hack=1;
457 else if (strcmp(*argv,"-crldays") == 0)
458 {
459 if (--argc < 1) goto bad;
460 crldays= atol(*(++argv));
461 }
462 else if (strcmp(*argv,"-crlhours") == 0)
463 {
464 if (--argc < 1) goto bad;
465 crlhours= atol(*(++argv));
466 }
467 else if (strcmp(*argv,"-infiles") == 0)
468 {
469 argc--;
470 argv++;
471 req=1;
472 break;
473 }
474 else if (strcmp(*argv, "-ss_cert") == 0)
475 {
476 if (--argc < 1) goto bad;
477 ss_cert_file = *(++argv);
478 req=1;
479 }
480 else if (strcmp(*argv, "-spkac") == 0)
481 {
482 if (--argc < 1) goto bad;
483 spkac_file = *(++argv);
484 req=1;
485 }
486 else if (strcmp(*argv,"-revoke") == 0)
487 {
488 if (--argc < 1) goto bad;
489 infile= *(++argv);
490 dorevoke=1;
491 }
492 else if (strcmp(*argv,"-extensions") == 0)
493 {
494 if (--argc < 1) goto bad;
495 extensions= *(++argv);
496 }
497 else if (strcmp(*argv,"-extfile") == 0)
498 {
499 if (--argc < 1) goto bad;
500 extfile= *(++argv);
501 }
502 else if (strcmp(*argv,"-status") == 0)
503 {
504 if (--argc < 1) goto bad;
505 ser_status= *(++argv);
506 }
507 else if (strcmp(*argv,"-updatedb") == 0)
508 {
509 doupdatedb=1;
510 }
511 else if (strcmp(*argv,"-crlexts") == 0)
512 {
513 if (--argc < 1) goto bad;
514 crl_ext= *(++argv);
515 }
516 else if (strcmp(*argv,"-crl_reason") == 0)
517 {
518 if (--argc < 1) goto bad;
519 rev_arg = *(++argv);
520 rev_type = REV_CRL_REASON;
521 }
522 else if (strcmp(*argv,"-crl_hold") == 0)
523 {
524 if (--argc < 1) goto bad;
525 rev_arg = *(++argv);
526 rev_type = REV_HOLD;
527 }
528 else if (strcmp(*argv,"-crl_compromise") == 0)
529 {
530 if (--argc < 1) goto bad;
531 rev_arg = *(++argv);
532 rev_type = REV_KEY_COMPROMISE;
533 }
534 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
535 {
536 if (--argc < 1) goto bad;
537 rev_arg = *(++argv);
538 rev_type = REV_CA_COMPROMISE;
539 }
341 char *tofree=NULL;
342
343#ifdef EFENCE
344EF_PROTECT_FREE=1;
345EF_PROTECT_BELOW=1;
346EF_ALIGNMENT=0;
347#endif
348
349 apps_startup();
350
351 conf = NULL;
352 key = NULL;
353 section = NULL;
354
355 preserve=0;
356 msie_hack=0;
357 if (bio_err == NULL)
358 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
359 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
360
361 argc--;
362 argv++;
363 while (argc >= 1)
364 {
365 if (strcmp(*argv,"-verbose") == 0)
366 verbose=1;
367 else if (strcmp(*argv,"-config") == 0)
368 {
369 if (--argc < 1) goto bad;
370 configfile= *(++argv);
371 }
372 else if (strcmp(*argv,"-name") == 0)
373 {
374 if (--argc < 1) goto bad;
375 section= *(++argv);
376 }
377 else if (strcmp(*argv,"-subj") == 0)
378 {
379 if (--argc < 1) goto bad;
380 subj= *(++argv);
381 /* preserve=1; */
382 }
383 else if (strcmp(*argv,"-startdate") == 0)
384 {
385 if (--argc < 1) goto bad;
386 startdate= *(++argv);
387 }
388 else if (strcmp(*argv,"-enddate") == 0)
389 {
390 if (--argc < 1) goto bad;
391 enddate= *(++argv);
392 }
393 else if (strcmp(*argv,"-days") == 0)
394 {
395 if (--argc < 1) goto bad;
396 days=atoi(*(++argv));
397 }
398 else if (strcmp(*argv,"-md") == 0)
399 {
400 if (--argc < 1) goto bad;
401 md= *(++argv);
402 }
403 else if (strcmp(*argv,"-policy") == 0)
404 {
405 if (--argc < 1) goto bad;
406 policy= *(++argv);
407 }
408 else if (strcmp(*argv,"-keyfile") == 0)
409 {
410 if (--argc < 1) goto bad;
411 keyfile= *(++argv);
412 }
413 else if (strcmp(*argv,"-keyform") == 0)
414 {
415 if (--argc < 1) goto bad;
416 keyform=str2fmt(*(++argv));
417 }
418 else if (strcmp(*argv,"-passin") == 0)
419 {
420 if (--argc < 1) goto bad;
421 passargin= *(++argv);
422 }
423 else if (strcmp(*argv,"-key") == 0)
424 {
425 if (--argc < 1) goto bad;
426 key= *(++argv);
427 }
428 else if (strcmp(*argv,"-cert") == 0)
429 {
430 if (--argc < 1) goto bad;
431 certfile= *(++argv);
432 }
433 else if (strcmp(*argv,"-in") == 0)
434 {
435 if (--argc < 1) goto bad;
436 infile= *(++argv);
437 req=1;
438 }
439 else if (strcmp(*argv,"-out") == 0)
440 {
441 if (--argc < 1) goto bad;
442 outfile= *(++argv);
443 }
444 else if (strcmp(*argv,"-outdir") == 0)
445 {
446 if (--argc < 1) goto bad;
447 outdir= *(++argv);
448 }
449 else if (strcmp(*argv,"-notext") == 0)
450 notext=1;
451 else if (strcmp(*argv,"-batch") == 0)
452 batch=1;
453 else if (strcmp(*argv,"-preserveDN") == 0)
454 preserve=1;
455 else if (strcmp(*argv,"-noemailDN") == 0)
456 email_dn=0;
457 else if (strcmp(*argv,"-gencrl") == 0)
458 gencrl=1;
459 else if (strcmp(*argv,"-msie_hack") == 0)
460 msie_hack=1;
461 else if (strcmp(*argv,"-crldays") == 0)
462 {
463 if (--argc < 1) goto bad;
464 crldays= atol(*(++argv));
465 }
466 else if (strcmp(*argv,"-crlhours") == 0)
467 {
468 if (--argc < 1) goto bad;
469 crlhours= atol(*(++argv));
470 }
471 else if (strcmp(*argv,"-infiles") == 0)
472 {
473 argc--;
474 argv++;
475 req=1;
476 break;
477 }
478 else if (strcmp(*argv, "-ss_cert") == 0)
479 {
480 if (--argc < 1) goto bad;
481 ss_cert_file = *(++argv);
482 req=1;
483 }
484 else if (strcmp(*argv, "-spkac") == 0)
485 {
486 if (--argc < 1) goto bad;
487 spkac_file = *(++argv);
488 req=1;
489 }
490 else if (strcmp(*argv,"-revoke") == 0)
491 {
492 if (--argc < 1) goto bad;
493 infile= *(++argv);
494 dorevoke=1;
495 }
496 else if (strcmp(*argv,"-extensions") == 0)
497 {
498 if (--argc < 1) goto bad;
499 extensions= *(++argv);
500 }
501 else if (strcmp(*argv,"-extfile") == 0)
502 {
503 if (--argc < 1) goto bad;
504 extfile= *(++argv);
505 }
506 else if (strcmp(*argv,"-status") == 0)
507 {
508 if (--argc < 1) goto bad;
509 ser_status= *(++argv);
510 }
511 else if (strcmp(*argv,"-updatedb") == 0)
512 {
513 doupdatedb=1;
514 }
515 else if (strcmp(*argv,"-crlexts") == 0)
516 {
517 if (--argc < 1) goto bad;
518 crl_ext= *(++argv);
519 }
520 else if (strcmp(*argv,"-crl_reason") == 0)
521 {
522 if (--argc < 1) goto bad;
523 rev_arg = *(++argv);
524 rev_type = REV_CRL_REASON;
525 }
526 else if (strcmp(*argv,"-crl_hold") == 0)
527 {
528 if (--argc < 1) goto bad;
529 rev_arg = *(++argv);
530 rev_type = REV_HOLD;
531 }
532 else if (strcmp(*argv,"-crl_compromise") == 0)
533 {
534 if (--argc < 1) goto bad;
535 rev_arg = *(++argv);
536 rev_type = REV_KEY_COMPROMISE;
537 }
538 else if (strcmp(*argv,"-crl_CA_compromise") == 0)
539 {
540 if (--argc < 1) goto bad;
541 rev_arg = *(++argv);
542 rev_type = REV_CA_COMPROMISE;
543 }
544#ifndef OPENSSL_NO_ENGINE
540 else if (strcmp(*argv,"-engine") == 0)
541 {
542 if (--argc < 1) goto bad;
543 engine= *(++argv);
544 }
545 else if (strcmp(*argv,"-engine") == 0)
546 {
547 if (--argc < 1) goto bad;
548 engine= *(++argv);
549 }
550#endif
545 else
546 {
547bad:
548 BIO_printf(bio_err,"unknown option %s\n",*argv);
549 badops=1;
550 break;
551 }
552 argc--;
553 argv++;
554 }
555
556 if (badops)
557 {
558 for (pp=ca_usage; (*pp != NULL); pp++)
559 BIO_printf(bio_err,"%s",*pp);
560 goto err;
561 }
562
563 ERR_load_crypto_strings();
564
551 else
552 {
553bad:
554 BIO_printf(bio_err,"unknown option %s\n",*argv);
555 badops=1;
556 break;
557 }
558 argc--;
559 argv++;
560 }
561
562 if (badops)
563 {
564 for (pp=ca_usage; (*pp != NULL); pp++)
565 BIO_printf(bio_err,"%s",*pp);
566 goto err;
567 }
568
569 ERR_load_crypto_strings();
570
571#ifndef OPENSSL_NO_ENGINE
565 e = setup_engine(bio_err, engine, 0);
572 e = setup_engine(bio_err, engine, 0);
573#endif
566
567 /*****************************************************************/
568 tofree=NULL;
569 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
570 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
571 if (configfile == NULL)
572 {
573 const char *s=X509_get_default_cert_area();
574
575#ifdef OPENSSL_SYS_VMS
576 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE));
577 strcpy(tofree,s);
578#else
579 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1);
580 strcpy(tofree,s);
581 strcat(tofree,"/");
582#endif
583 strcat(tofree,CONFIG_FILE);
584 configfile=tofree;
585 }
586
587 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
588 conf = NCONF_new(NULL);
589 if (NCONF_load(conf,configfile,&errorline) <= 0)
590 {
591 if (errorline <= 0)
592 BIO_printf(bio_err,"error loading the config file '%s'\n",
593 configfile);
594 else
595 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
596 ,errorline,configfile);
597 goto err;
598 }
599 if(tofree)
574
575 /*****************************************************************/
576 tofree=NULL;
577 if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
578 if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
579 if (configfile == NULL)
580 {
581 const char *s=X509_get_default_cert_area();
582
583#ifdef OPENSSL_SYS_VMS
584 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE));
585 strcpy(tofree,s);
586#else
587 tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1);
588 strcpy(tofree,s);
589 strcat(tofree,"/");
590#endif
591 strcat(tofree,CONFIG_FILE);
592 configfile=tofree;
593 }
594
595 BIO_printf(bio_err,"Using configuration from %s\n",configfile);
596 conf = NCONF_new(NULL);
597 if (NCONF_load(conf,configfile,&errorline) <= 0)
598 {
599 if (errorline <= 0)
600 BIO_printf(bio_err,"error loading the config file '%s'\n",
601 configfile);
602 else
603 BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
604 ,errorline,configfile);
605 goto err;
606 }
607 if(tofree)
608 {
600 OPENSSL_free(tofree);
609 OPENSSL_free(tofree);
610 tofree = NULL;
611 }
601
602 if (!load_config(bio_err, conf))
603 goto err;
604
605 /* Lets get the config section we are using */
606 if (section == NULL)
607 {
608 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
609 if (section == NULL)
610 {
611 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
612 goto err;
613 }
614 }
615
616 if (conf != NULL)
617 {
618 p=NCONF_get_string(conf,NULL,"oid_file");
619 if (p == NULL)
620 ERR_clear_error();
621 if (p != NULL)
622 {
623 BIO *oid_bio;
624
625 oid_bio=BIO_new_file(p,"r");
626 if (oid_bio == NULL)
627 {
628 /*
629 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
630 ERR_print_errors(bio_err);
631 */
632 ERR_clear_error();
633 }
634 else
635 {
636 OBJ_create_objects(oid_bio);
637 BIO_free(oid_bio);
638 }
639 }
640 if (!add_oid_section(bio_err,conf))
641 {
642 ERR_print_errors(bio_err);
643 goto err;
644 }
645 }
646
647 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
648 if (randfile == NULL)
649 ERR_clear_error();
650 app_RAND_load_file(randfile, bio_err, 0);
651
652 in=BIO_new(BIO_s_file());
653 out=BIO_new(BIO_s_file());
654 Sout=BIO_new(BIO_s_file());
655 Cout=BIO_new(BIO_s_file());
656 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
657 {
658 ERR_print_errors(bio_err);
659 goto err;
660 }
661
662 /*****************************************************************/
663 /* report status of cert with serial number given on command line */
664 if (ser_status)
665 {
666 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
667 {
668 lookup_fail(section,ENV_DATABASE);
669 goto err;
670 }
671 if (BIO_read_filename(in,dbfile) <= 0)
672 {
673 perror(dbfile);
674 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
675 goto err;
676 }
677 db=TXT_DB_read(in,DB_NUMBER);
678 if (db == NULL) goto err;
679
680 if (!make_serial_index(db))
681 goto err;
682
683 if (get_certificate_status(ser_status,db) != 1)
684 BIO_printf(bio_err,"Error verifying serial %s!\n",
685 ser_status);
686 goto err;
687 }
688
689 /*****************************************************************/
690 /* we definitely need a public key, so let's get it */
691
692 if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
693 section,ENV_PRIVATE_KEY)) == NULL))
694 {
695 lookup_fail(section,ENV_PRIVATE_KEY);
696 goto err;
697 }
698 if (!key)
699 {
700 free_key = 1;
701 if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
702 {
703 BIO_printf(bio_err,"Error getting password\n");
704 goto err;
705 }
706 }
707 pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
708 "CA private key");
709 if (key) OPENSSL_cleanse(key,strlen(key));
710 if (pkey == NULL)
711 {
712 /* load_key() has already printed an appropriate message */
713 goto err;
714 }
715
716 /*****************************************************************/
717 /* we need a certificate */
718 if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
719 section,ENV_CERTIFICATE)) == NULL))
720 {
721 lookup_fail(section,ENV_CERTIFICATE);
722 goto err;
723 }
724 x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
725 "CA certificate");
726 if (x509 == NULL)
727 goto err;
728
729 if (!X509_check_private_key(x509,pkey))
730 {
731 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
732 goto err;
733 }
734
735 f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
736 if (f == NULL)
737 ERR_clear_error();
738 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
739 preserve=1;
740 f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
741 if (f == NULL)
742 ERR_clear_error();
743 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
744 msie_hack=1;
745
746 f=NCONF_get_string(conf,section,ENV_NAMEOPT);
747
748 if (f)
749 {
750 if (!set_name_ex(&nameopt, f))
751 {
752 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
753 goto err;
754 }
755 default_op = 0;
756 }
757 else
758 ERR_clear_error();
759
760 f=NCONF_get_string(conf,section,ENV_CERTOPT);
761
762 if (f)
763 {
764 if (!set_cert_ex(&certopt, f))
765 {
766 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
767 goto err;
768 }
769 default_op = 0;
770 }
771 else
772 ERR_clear_error();
773
774 f=NCONF_get_string(conf,section,ENV_EXTCOPY);
775
776 if (f)
777 {
778 if (!set_ext_copy(&ext_copy, f))
779 {
780 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
781 goto err;
782 }
783 }
784 else
785 ERR_clear_error();
786
787 /*****************************************************************/
788 /* lookup where to write new certificates */
789 if ((outdir == NULL) && (req))
790 {
791 struct stat sb;
792
793 if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
794 == NULL)
795 {
796 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
797 goto err;
798 }
799#ifndef OPENSSL_SYS_VMS
800 /* outdir is a directory spec, but access() for VMS demands a
801 filename. In any case, stat(), below, will catch the problem
802 if outdir is not a directory spec, and the fopen() or open()
803 will catch an error if there is no write access.
804
805 Presumably, this problem could also be solved by using the DEC
806 C routines to convert the directory syntax to Unixly, and give
807 that to access(). However, time's too short to do that just
808 now.
809 */
810 if (access(outdir,R_OK|W_OK|X_OK) != 0)
811 {
812 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
813 perror(outdir);
814 goto err;
815 }
816
817 if (stat(outdir,&sb) != 0)
818 {
819 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
820 perror(outdir);
821 goto err;
822 }
823#ifdef S_IFDIR
824 if (!(sb.st_mode & S_IFDIR))
825 {
826 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
827 perror(outdir);
828 goto err;
829 }
830#endif
831#endif
832 }
833
834 /*****************************************************************/
835 /* we need to load the database file */
836 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
837 {
838 lookup_fail(section,ENV_DATABASE);
839 goto err;
840 }
841 if (BIO_read_filename(in,dbfile) <= 0)
842 {
843 perror(dbfile);
844 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
845 goto err;
846 }
847 db=TXT_DB_read(in,DB_NUMBER);
848 if (db == NULL) goto err;
849
850 /* Lets check some fields */
851 for (i=0; i<sk_num(db->data); i++)
852 {
853 pp=(char **)sk_value(db->data,i);
854 if ((pp[DB_type][0] != DB_TYPE_REV) &&
855 (pp[DB_rev_date][0] != '\0'))
856 {
857 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
858 goto err;
859 }
860 if ((pp[DB_type][0] == DB_TYPE_REV) &&
861 !make_revoked(NULL, pp[DB_rev_date]))
862 {
863 BIO_printf(bio_err," in entry %d\n", i+1);
864 goto err;
865 }
866 if (!check_time_format(pp[DB_exp_date]))
867 {
868 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
869 goto err;
870 }
871 p=pp[DB_serial];
872 j=strlen(p);
873 if (*p == '-')
874 {
875 p++;
876 j--;
877 }
878 if ((j&1) || (j < 2))
879 {
880 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
881 goto err;
882 }
883 while (*p)
884 {
885 if (!( ((*p >= '0') && (*p <= '9')) ||
886 ((*p >= 'A') && (*p <= 'F')) ||
887 ((*p >= 'a') && (*p <= 'f'))) )
888 {
889 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);
890 goto err;
891 }
892 p++;
893 }
894 }
895 if (verbose)
896 {
897 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
898#ifdef OPENSSL_SYS_VMS
899 {
900 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
901 out = BIO_push(tmpbio, out);
902 }
903#endif
904 TXT_DB_write(out,db);
905 BIO_printf(bio_err,"%d entries loaded from the database\n",
906 db->data->num);
907 BIO_printf(bio_err,"generating index\n");
908 }
909
910 if (!make_serial_index(db))
911 goto err;
912
913 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
914 LHASH_HASH_FN(index_name_hash),
915 LHASH_COMP_FN(index_name_cmp)))
916 {
917 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
918 db->error,db->arg1,db->arg2);
919 goto err;
920 }
921
922 /*****************************************************************/
923 /* Update the db file for expired certificates */
924 if (doupdatedb)
925 {
926 if (verbose)
927 BIO_printf(bio_err, "Updating %s ...\n",
928 dbfile);
929
930 i = do_updatedb(db);
931 if (i == -1)
932 {
933 BIO_printf(bio_err,"Malloc failure\n");
934 goto err;
935 }
936 else if (i == 0)
937 {
938 if (verbose) BIO_printf(bio_err,
939 "No entries found to mark expired\n");
940 }
941 else
942 {
943 out = BIO_new(BIO_s_file());
944 if (out == NULL)
945 {
946 ERR_print_errors(bio_err);
947 goto err;
948 }
949
950#ifndef OPENSSL_SYS_VMS
951 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
952#else
953 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-new", dbfile);
954#endif
955 if (j < 0 || j >= sizeof buf[0])
956 {
957 BIO_printf(bio_err, "file name too long\n");
958 goto err;
959 }
960 if (BIO_write_filename(out,buf[0]) <= 0)
961 {
962 perror(dbfile);
963 BIO_printf(bio_err,"unable to open '%s'\n",
964 dbfile);
965 goto err;
966 }
967 j=TXT_DB_write(out,db);
968 if (j <= 0) goto err;
969
970 BIO_free(out);
971 out = NULL;
972#ifndef OPENSSL_SYS_VMS
973 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
974#else
975 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-old", dbfile);
976#endif
977 if (j < 0 || j >= sizeof buf[1])
978 {
979 BIO_printf(bio_err, "file name too long\n");
980 goto err;
981 }
982 if (rename(dbfile,buf[1]) < 0)
983 {
984 BIO_printf(bio_err,
985 "unable to rename %s to %s\n",
986 dbfile, buf[1]);
987 perror("reason");
988 goto err;
989 }
990 if (rename(buf[0],dbfile) < 0)
991 {
992 BIO_printf(bio_err,
993 "unable to rename %s to %s\n",
994 buf[0],dbfile);
995 perror("reason");
996 rename(buf[1],dbfile);
997 goto err;
998 }
999
1000 if (verbose) BIO_printf(bio_err,
1001 "Done. %d entries marked as expired\n",i);
1002 }
1003 goto err;
1004 }
1005
1006 /*****************************************************************/
1007 /* Read extentions config file */
1008 if (extfile)
1009 {
1010 extconf = NCONF_new(NULL);
1011 if (NCONF_load(extconf,extfile,&errorline) <= 0)
1012 {
1013 if (errorline <= 0)
1014 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
1015 extfile);
1016 else
1017 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
1018 errorline,extfile);
1019 ret = 1;
1020 goto err;
1021 }
1022
1023 if (verbose)
1024 BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
1025
1026 /* We can have sections in the ext file */
1027 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
1028 extensions = "default";
1029 }
1030
1031 /*****************************************************************/
1032 if (req || gencrl)
1033 {
1034 if (outfile != NULL)
1035 {
1036 if (BIO_write_filename(Sout,outfile) <= 0)
1037 {
1038 perror(outfile);
1039 goto err;
1040 }
1041 }
1042 else
1043 {
1044 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1045#ifdef OPENSSL_SYS_VMS
1046 {
1047 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1048 Sout = BIO_push(tmpbio, Sout);
1049 }
1050#endif
1051 }
1052 }
1053
1054 if (req)
1055 {
1056 if ((md == NULL) && ((md=NCONF_get_string(conf,
1057 section,ENV_DEFAULT_MD)) == NULL))
1058 {
1059 lookup_fail(section,ENV_DEFAULT_MD);
1060 goto err;
1061 }
1062 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1063 section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1064 {
1065 if(strcmp(tmp_email_dn,"no") == 0)
1066 email_dn=0;
1067 }
1068 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1069 {
1070 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1071 goto err;
1072 }
1073 if (verbose)
1074 BIO_printf(bio_err,"message digest is %s\n",
1075 OBJ_nid2ln(dgst->type));
1076 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1077 section,ENV_POLICY)) == NULL))
1078 {
1079 lookup_fail(section,ENV_POLICY);
1080 goto err;
1081 }
1082 if (verbose)
1083 BIO_printf(bio_err,"policy is %s\n",policy);
1084
1085 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1086 == NULL)
1087 {
1088 lookup_fail(section,ENV_SERIAL);
1089 goto err;
1090 }
1091
1092 if (!extconf)
1093 {
1094 /* no '-extfile' option, so we look for extensions
1095 * in the main configuration file */
1096 if (!extensions)
1097 {
1098 extensions=NCONF_get_string(conf,section,
1099 ENV_EXTENSIONS);
1100 if (!extensions)
1101 ERR_clear_error();
1102 }
1103 if (extensions)
1104 {
1105 /* Check syntax of file */
1106 X509V3_CTX ctx;
1107 X509V3_set_ctx_test(&ctx);
1108 X509V3_set_nconf(&ctx, conf);
1109 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1110 NULL))
1111 {
1112 BIO_printf(bio_err,
1113 "Error Loading extension section %s\n",
1114 extensions);
1115 ret = 1;
1116 goto err;
1117 }
1118 }
1119 }
1120
1121 if (startdate == NULL)
1122 {
1123 startdate=NCONF_get_string(conf,section,
1124 ENV_DEFAULT_STARTDATE);
1125 if (startdate == NULL)
1126 ERR_clear_error();
1127 }
1128 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1129 {
1130 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1131 goto err;
1132 }
1133 if (startdate == NULL) startdate="today";
1134
1135 if (enddate == NULL)
1136 {
1137 enddate=NCONF_get_string(conf,section,
1138 ENV_DEFAULT_ENDDATE);
1139 if (enddate == NULL)
1140 ERR_clear_error();
1141 }
1142 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1143 {
1144 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1145 goto err;
1146 }
1147
1148 if (days == 0)
1149 {
1150 if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1151 days = 0;
1152 }
1153 if (!enddate && (days == 0))
1154 {
1155 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1156 goto err;
1157 }
1158
1159 if ((serial=load_serial(serialfile)) == NULL)
1160 {
1161 BIO_printf(bio_err,"error while loading serial number\n");
1162 goto err;
1163 }
1164 if (verbose)
1165 {
1166 if (BN_is_zero(serial))
1167 BIO_printf(bio_err,"next serial number is 00\n");
1168 else
1169 {
1170 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1171 BIO_printf(bio_err,"next serial number is %s\n",f);
1172 OPENSSL_free(f);
1173 }
1174 }
1175
1176 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1177 {
1178 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1179 goto err;
1180 }
1181
1182 if ((cert_sk=sk_X509_new_null()) == NULL)
1183 {
1184 BIO_printf(bio_err,"Memory allocation failure\n");
1185 goto err;
1186 }
1187 if (spkac_file != NULL)
1188 {
1189 total++;
1190 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1191 serial,subj,email_dn,startdate,enddate,days,extensions,
1192 conf,verbose,certopt,nameopt,default_op,ext_copy);
1193 if (j < 0) goto err;
1194 if (j > 0)
1195 {
1196 total_done++;
1197 BIO_printf(bio_err,"\n");
1198 if (!BN_add_word(serial,1)) goto err;
1199 if (!sk_X509_push(cert_sk,x))
1200 {
1201 BIO_printf(bio_err,"Memory allocation failure\n");
1202 goto err;
1203 }
1204 if (outfile)
1205 {
1206 output_der = 1;
1207 batch = 1;
1208 }
1209 }
1210 }
1211 if (ss_cert_file != NULL)
1212 {
1213 total++;
1214 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1215 db,serial,subj,email_dn,startdate,enddate,days,batch,
1216 extensions,conf,verbose, certopt, nameopt,
1217 default_op, ext_copy, e);
1218 if (j < 0) goto err;
1219 if (j > 0)
1220 {
1221 total_done++;
1222 BIO_printf(bio_err,"\n");
1223 if (!BN_add_word(serial,1)) goto err;
1224 if (!sk_X509_push(cert_sk,x))
1225 {
1226 BIO_printf(bio_err,"Memory allocation failure\n");
1227 goto err;
1228 }
1229 }
1230 }
1231 if (infile != NULL)
1232 {
1233 total++;
1234 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1235 serial,subj,email_dn,startdate,enddate,days,batch,
1236 extensions,conf,verbose, certopt, nameopt,
1237 default_op, ext_copy);
1238 if (j < 0) goto err;
1239 if (j > 0)
1240 {
1241 total_done++;
1242 BIO_printf(bio_err,"\n");
1243 if (!BN_add_word(serial,1)) goto err;
1244 if (!sk_X509_push(cert_sk,x))
1245 {
1246 BIO_printf(bio_err,"Memory allocation failure\n");
1247 goto err;
1248 }
1249 }
1250 }
1251 for (i=0; i<argc; i++)
1252 {
1253 total++;
1254 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1255 serial,subj,email_dn,startdate,enddate,days,batch,
1256 extensions,conf,verbose, certopt, nameopt,
1257 default_op, ext_copy);
1258 if (j < 0) goto err;
1259 if (j > 0)
1260 {
1261 total_done++;
1262 BIO_printf(bio_err,"\n");
1263 if (!BN_add_word(serial,1)) goto err;
1264 if (!sk_X509_push(cert_sk,x))
1265 {
1266 BIO_printf(bio_err,"Memory allocation failure\n");
1267 goto err;
1268 }
1269 }
1270 }
1271 /* we have a stack of newly certified certificates
1272 * and a data base and serial number that need
1273 * updating */
1274
1275 if (sk_X509_num(cert_sk) > 0)
1276 {
1277 if (!batch)
1278 {
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);
1281 buf[0][0]='\0';
1282 fgets(buf[0],10,stdin);
1283 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1284 {
1285 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1286 ret=0;
1287 goto err;
1288 }
1289 }
1290
1291 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1292
1293 if(strlen(serialfile) > BSIZE-5 || strlen(dbfile) > BSIZE-5)
1294 {
1295 BIO_printf(bio_err,"file name too long\n");
1296 goto err;
1297 }
1298
1299 strcpy(buf[0],serialfile);
1300
1301#ifdef OPENSSL_SYS_VMS
1302 strcat(buf[0],"-new");
1303#else
1304 strcat(buf[0],".new");
1305#endif
1306
1307 if (!save_serial(buf[0],serial)) goto err;
1308
1309 strcpy(buf[1],dbfile);
1310
1311#ifdef OPENSSL_SYS_VMS
1312 strcat(buf[1],"-new");
1313#else
1314 strcat(buf[1],".new");
1315#endif
1316
1317 if (BIO_write_filename(out,buf[1]) <= 0)
1318 {
1319 perror(dbfile);
1320 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1321 goto err;
1322 }
1323 l=TXT_DB_write(out,db);
1324 if (l <= 0) goto err;
1325 }
1326
1327 if (verbose)
1328 BIO_printf(bio_err,"writing new certificates\n");
1329 for (i=0; i<sk_X509_num(cert_sk); i++)
1330 {
1331 int k;
1332 unsigned char *n;
1333
1334 x=sk_X509_value(cert_sk,i);
1335
1336 j=x->cert_info->serialNumber->length;
1337 p=(char *)x->cert_info->serialNumber->data;
1338
1339 if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1340 {
1341 BIO_printf(bio_err,"certificate file name too long\n");
1342 goto err;
1343 }
1344
1345 strcpy(buf[2],outdir);
1346
1347#ifndef OPENSSL_SYS_VMS
1348 strcat(buf[2],"/");
1349#endif
1350
1351 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1352 if (j > 0)
1353 {
1354 for (k=0; k<j; k++)
1355 {
1356 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1357 n+=2;
1358 }
1359 }
1360 else
1361 {
1362 *(n++)='0';
1363 *(n++)='0';
1364 }
1365 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1366 *n='\0';
1367 if (verbose)
1368 BIO_printf(bio_err,"writing %s\n",buf[2]);
1369
1370 if (BIO_write_filename(Cout,buf[2]) <= 0)
1371 {
1372 perror(buf[2]);
1373 goto err;
1374 }
1375 write_new_certificate(Cout,x, 0, notext);
1376 write_new_certificate(Sout,x, output_der, notext);
1377 }
1378
1379 if (sk_X509_num(cert_sk))
1380 {
1381 /* Rename the database and the serial file */
1382 strncpy(buf[2],serialfile,BSIZE-4);
1383 buf[2][BSIZE-4]='\0';
1384
1385#ifdef OPENSSL_SYS_VMS
1386 strcat(buf[2],"-old");
1387#else
1388 strcat(buf[2],".old");
1389#endif
1390
1391 BIO_free(in);
1392 BIO_free_all(out);
1393 in=NULL;
1394 out=NULL;
1395 if (rename(serialfile,buf[2]) < 0)
1396 {
1397 BIO_printf(bio_err,"unable to rename %s to %s\n",
1398 serialfile,buf[2]);
1399 perror("reason");
1400 goto err;
1401 }
1402 if (rename(buf[0],serialfile) < 0)
1403 {
1404 BIO_printf(bio_err,"unable to rename %s to %s\n",
1405 buf[0],serialfile);
1406 perror("reason");
1407 rename(buf[2],serialfile);
1408 goto err;
1409 }
1410
1411 strncpy(buf[2],dbfile,BSIZE-4);
1412 buf[2][BSIZE-4]='\0';
1413
1414#ifdef OPENSSL_SYS_VMS
1415 strcat(buf[2],"-old");
1416#else
1417 strcat(buf[2],".old");
1418#endif
1419
1420 if (rename(dbfile,buf[2]) < 0)
1421 {
1422 BIO_printf(bio_err,"unable to rename %s to %s\n",
1423 dbfile,buf[2]);
1424 perror("reason");
1425 goto err;
1426 }
1427 if (rename(buf[1],dbfile) < 0)
1428 {
1429 BIO_printf(bio_err,"unable to rename %s to %s\n",
1430 buf[1],dbfile);
1431 perror("reason");
1432 rename(buf[2],dbfile);
1433 goto err;
1434 }
1435 BIO_printf(bio_err,"Data Base Updated\n");
1436 }
1437 }
1438
1439 /*****************************************************************/
1440 if (gencrl)
1441 {
1442 int crl_v2 = 0;
1443 if (!crl_ext)
1444 {
1445 crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1446 if (!crl_ext)
1447 ERR_clear_error();
1448 }
1449 if (crl_ext)
1450 {
1451 /* Check syntax of file */
1452 X509V3_CTX ctx;
1453 X509V3_set_ctx_test(&ctx);
1454 X509V3_set_nconf(&ctx, conf);
1455 if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1456 {
1457 BIO_printf(bio_err,
1458 "Error Loading CRL extension section %s\n",
1459 crl_ext);
1460 ret = 1;
1461 goto err;
1462 }
1463 }
1464
1465 if (!crldays && !crlhours)
1466 {
1467 if (!NCONF_get_number(conf,section,
1468 ENV_DEFAULT_CRL_DAYS, &crldays))
1469 crldays = 0;
1470 if (!NCONF_get_number(conf,section,
1471 ENV_DEFAULT_CRL_HOURS, &crlhours))
1472 crlhours = 0;
1473 }
1474 if ((crldays == 0) && (crlhours == 0))
1475 {
1476 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1477 goto err;
1478 }
1479
1480 if (verbose) BIO_printf(bio_err,"making CRL\n");
1481 if ((crl=X509_CRL_new()) == NULL) goto err;
1482 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1483
1484 tmptm = ASN1_TIME_new();
1485 if (!tmptm) goto err;
1486 X509_gmtime_adj(tmptm,0);
1487 X509_CRL_set_lastUpdate(crl, tmptm);
1488 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1489 X509_CRL_set_nextUpdate(crl, tmptm);
1490
1491 ASN1_TIME_free(tmptm);
1492
1493 for (i=0; i<sk_num(db->data); i++)
1494 {
1495 pp=(char **)sk_value(db->data,i);
1496 if (pp[DB_type][0] == DB_TYPE_REV)
1497 {
1498 if ((r=X509_REVOKED_new()) == NULL) goto err;
1499 j = make_revoked(r, pp[DB_rev_date]);
1500 if (!j) goto err;
1501 if (j == 2) crl_v2 = 1;
1502 if (!BN_hex2bn(&serial, pp[DB_serial]))
1503 goto err;
1504 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1505 BN_free(serial);
1506 serial = NULL;
1507 if (!tmpser)
1508 goto err;
1509 X509_REVOKED_set_serialNumber(r, tmpser);
1510 ASN1_INTEGER_free(tmpser);
1511 X509_CRL_add0_revoked(crl,r);
1512 }
1513 }
1514
1515 /* sort the data so it will be written in serial
1516 * number order */
1517 X509_CRL_sort(crl);
1518
1519 /* we now have a CRL */
1520 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1521 if (md != NULL)
1522 {
1523 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1524 {
1525 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1526 goto err;
1527 }
1528 }
1529 else
1530 {
1531#ifndef OPENSSL_NO_DSA
1532 if (pkey->type == EVP_PKEY_DSA)
1533 dgst=EVP_dss1();
1534 else
1535#endif
1536 dgst=EVP_md5();
1537 }
1538
1539 /* Add any extensions asked for */
1540
1541 if (crl_ext)
1542 {
1543 X509V3_CTX crlctx;
1544 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1545 X509V3_set_nconf(&crlctx, conf);
1546
1547 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1548 crl_ext, crl)) goto err;
1549 }
1550 if (crl_ext || crl_v2)
1551 {
1552 if (!X509_CRL_set_version(crl, 1))
1553 goto err; /* version 2 CRL */
1554 }
1555
1556 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1557
1558 PEM_write_bio_X509_CRL(Sout,crl);
1559 }
1560 /*****************************************************************/
1561 if (dorevoke)
1562 {
1563 if (infile == NULL)
1564 {
1565 BIO_printf(bio_err,"no input files\n");
1566 goto err;
1567 }
1568 else
1569 {
1570 X509 *revcert;
1571 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1572 NULL, e, infile);
1573 if (revcert == NULL)
1574 goto err;
1575 j=do_revoke(revcert,db, rev_type, rev_arg);
1576 if (j <= 0) goto err;
1577 X509_free(revcert);
1578
1579 if(strlen(dbfile) > BSIZE-5)
1580 {
1581 BIO_printf(bio_err,"filename too long\n");
1582 goto err;
1583 }
1584
1585 strcpy(buf[0],dbfile);
1586#ifndef OPENSSL_SYS_VMS
1587 strcat(buf[0],".new");
1588#else
1589 strcat(buf[0],"-new");
1590#endif
1591 if (BIO_write_filename(out,buf[0]) <= 0)
1592 {
1593 perror(dbfile);
1594 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1595 goto err;
1596 }
1597 j=TXT_DB_write(out,db);
1598 if (j <= 0) goto err;
1599 BIO_free_all(out);
1600 out = NULL;
1601 BIO_free_all(in);
1602 in = NULL;
1603 strncpy(buf[1],dbfile,BSIZE-4);
1604 buf[1][BSIZE-4]='\0';
1605#ifndef OPENSSL_SYS_VMS
1606 strcat(buf[1],".old");
1607#else
1608 strcat(buf[1],"-old");
1609#endif
1610 if (rename(dbfile,buf[1]) < 0)
1611 {
1612 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1613 perror("reason");
1614 goto err;
1615 }
1616 if (rename(buf[0],dbfile) < 0)
1617 {
1618 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1619 perror("reason");
1620 rename(buf[1],dbfile);
1621 goto err;
1622 }
1623 BIO_printf(bio_err,"Data Base Updated\n");
1624 }
1625 }
1626 /*****************************************************************/
1627 ret=0;
1628err:
1629 if(tofree)
1630 OPENSSL_free(tofree);
1631 BIO_free_all(Cout);
1632 BIO_free_all(Sout);
1633 BIO_free_all(out);
1634 BIO_free_all(in);
1635
612
613 if (!load_config(bio_err, conf))
614 goto err;
615
616 /* Lets get the config section we are using */
617 if (section == NULL)
618 {
619 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
620 if (section == NULL)
621 {
622 lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
623 goto err;
624 }
625 }
626
627 if (conf != NULL)
628 {
629 p=NCONF_get_string(conf,NULL,"oid_file");
630 if (p == NULL)
631 ERR_clear_error();
632 if (p != NULL)
633 {
634 BIO *oid_bio;
635
636 oid_bio=BIO_new_file(p,"r");
637 if (oid_bio == NULL)
638 {
639 /*
640 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
641 ERR_print_errors(bio_err);
642 */
643 ERR_clear_error();
644 }
645 else
646 {
647 OBJ_create_objects(oid_bio);
648 BIO_free(oid_bio);
649 }
650 }
651 if (!add_oid_section(bio_err,conf))
652 {
653 ERR_print_errors(bio_err);
654 goto err;
655 }
656 }
657
658 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
659 if (randfile == NULL)
660 ERR_clear_error();
661 app_RAND_load_file(randfile, bio_err, 0);
662
663 in=BIO_new(BIO_s_file());
664 out=BIO_new(BIO_s_file());
665 Sout=BIO_new(BIO_s_file());
666 Cout=BIO_new(BIO_s_file());
667 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
668 {
669 ERR_print_errors(bio_err);
670 goto err;
671 }
672
673 /*****************************************************************/
674 /* report status of cert with serial number given on command line */
675 if (ser_status)
676 {
677 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
678 {
679 lookup_fail(section,ENV_DATABASE);
680 goto err;
681 }
682 if (BIO_read_filename(in,dbfile) <= 0)
683 {
684 perror(dbfile);
685 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
686 goto err;
687 }
688 db=TXT_DB_read(in,DB_NUMBER);
689 if (db == NULL) goto err;
690
691 if (!make_serial_index(db))
692 goto err;
693
694 if (get_certificate_status(ser_status,db) != 1)
695 BIO_printf(bio_err,"Error verifying serial %s!\n",
696 ser_status);
697 goto err;
698 }
699
700 /*****************************************************************/
701 /* we definitely need a public key, so let's get it */
702
703 if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
704 section,ENV_PRIVATE_KEY)) == NULL))
705 {
706 lookup_fail(section,ENV_PRIVATE_KEY);
707 goto err;
708 }
709 if (!key)
710 {
711 free_key = 1;
712 if (!app_passwd(bio_err, passargin, NULL, &key, NULL))
713 {
714 BIO_printf(bio_err,"Error getting password\n");
715 goto err;
716 }
717 }
718 pkey = load_key(bio_err, keyfile, keyform, 0, key, e,
719 "CA private key");
720 if (key) OPENSSL_cleanse(key,strlen(key));
721 if (pkey == NULL)
722 {
723 /* load_key() has already printed an appropriate message */
724 goto err;
725 }
726
727 /*****************************************************************/
728 /* we need a certificate */
729 if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
730 section,ENV_CERTIFICATE)) == NULL))
731 {
732 lookup_fail(section,ENV_CERTIFICATE);
733 goto err;
734 }
735 x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
736 "CA certificate");
737 if (x509 == NULL)
738 goto err;
739
740 if (!X509_check_private_key(x509,pkey))
741 {
742 BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
743 goto err;
744 }
745
746 f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
747 if (f == NULL)
748 ERR_clear_error();
749 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
750 preserve=1;
751 f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
752 if (f == NULL)
753 ERR_clear_error();
754 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
755 msie_hack=1;
756
757 f=NCONF_get_string(conf,section,ENV_NAMEOPT);
758
759 if (f)
760 {
761 if (!set_name_ex(&nameopt, f))
762 {
763 BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
764 goto err;
765 }
766 default_op = 0;
767 }
768 else
769 ERR_clear_error();
770
771 f=NCONF_get_string(conf,section,ENV_CERTOPT);
772
773 if (f)
774 {
775 if (!set_cert_ex(&certopt, f))
776 {
777 BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
778 goto err;
779 }
780 default_op = 0;
781 }
782 else
783 ERR_clear_error();
784
785 f=NCONF_get_string(conf,section,ENV_EXTCOPY);
786
787 if (f)
788 {
789 if (!set_ext_copy(&ext_copy, f))
790 {
791 BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
792 goto err;
793 }
794 }
795 else
796 ERR_clear_error();
797
798 /*****************************************************************/
799 /* lookup where to write new certificates */
800 if ((outdir == NULL) && (req))
801 {
802 struct stat sb;
803
804 if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
805 == NULL)
806 {
807 BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
808 goto err;
809 }
810#ifndef OPENSSL_SYS_VMS
811 /* outdir is a directory spec, but access() for VMS demands a
812 filename. In any case, stat(), below, will catch the problem
813 if outdir is not a directory spec, and the fopen() or open()
814 will catch an error if there is no write access.
815
816 Presumably, this problem could also be solved by using the DEC
817 C routines to convert the directory syntax to Unixly, and give
818 that to access(). However, time's too short to do that just
819 now.
820 */
821 if (access(outdir,R_OK|W_OK|X_OK) != 0)
822 {
823 BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
824 perror(outdir);
825 goto err;
826 }
827
828 if (stat(outdir,&sb) != 0)
829 {
830 BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
831 perror(outdir);
832 goto err;
833 }
834#ifdef S_IFDIR
835 if (!(sb.st_mode & S_IFDIR))
836 {
837 BIO_printf(bio_err,"%s need to be a directory\n",outdir);
838 perror(outdir);
839 goto err;
840 }
841#endif
842#endif
843 }
844
845 /*****************************************************************/
846 /* we need to load the database file */
847 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
848 {
849 lookup_fail(section,ENV_DATABASE);
850 goto err;
851 }
852 if (BIO_read_filename(in,dbfile) <= 0)
853 {
854 perror(dbfile);
855 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
856 goto err;
857 }
858 db=TXT_DB_read(in,DB_NUMBER);
859 if (db == NULL) goto err;
860
861 /* Lets check some fields */
862 for (i=0; i<sk_num(db->data); i++)
863 {
864 pp=(char **)sk_value(db->data,i);
865 if ((pp[DB_type][0] != DB_TYPE_REV) &&
866 (pp[DB_rev_date][0] != '\0'))
867 {
868 BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
869 goto err;
870 }
871 if ((pp[DB_type][0] == DB_TYPE_REV) &&
872 !make_revoked(NULL, pp[DB_rev_date]))
873 {
874 BIO_printf(bio_err," in entry %d\n", i+1);
875 goto err;
876 }
877 if (!check_time_format(pp[DB_exp_date]))
878 {
879 BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
880 goto err;
881 }
882 p=pp[DB_serial];
883 j=strlen(p);
884 if (*p == '-')
885 {
886 p++;
887 j--;
888 }
889 if ((j&1) || (j < 2))
890 {
891 BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
892 goto err;
893 }
894 while (*p)
895 {
896 if (!( ((*p >= '0') && (*p <= '9')) ||
897 ((*p >= 'A') && (*p <= 'F')) ||
898 ((*p >= 'a') && (*p <= 'f'))) )
899 {
900 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);
901 goto err;
902 }
903 p++;
904 }
905 }
906 if (verbose)
907 {
908 BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
909#ifdef OPENSSL_SYS_VMS
910 {
911 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
912 out = BIO_push(tmpbio, out);
913 }
914#endif
915 TXT_DB_write(out,db);
916 BIO_printf(bio_err,"%d entries loaded from the database\n",
917 db->data->num);
918 BIO_printf(bio_err,"generating index\n");
919 }
920
921 if (!make_serial_index(db))
922 goto err;
923
924 if (!TXT_DB_create_index(db, DB_name, index_name_qual,
925 LHASH_HASH_FN(index_name_hash),
926 LHASH_COMP_FN(index_name_cmp)))
927 {
928 BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
929 db->error,db->arg1,db->arg2);
930 goto err;
931 }
932
933 /*****************************************************************/
934 /* Update the db file for expired certificates */
935 if (doupdatedb)
936 {
937 if (verbose)
938 BIO_printf(bio_err, "Updating %s ...\n",
939 dbfile);
940
941 i = do_updatedb(db);
942 if (i == -1)
943 {
944 BIO_printf(bio_err,"Malloc failure\n");
945 goto err;
946 }
947 else if (i == 0)
948 {
949 if (verbose) BIO_printf(bio_err,
950 "No entries found to mark expired\n");
951 }
952 else
953 {
954 out = BIO_new(BIO_s_file());
955 if (out == NULL)
956 {
957 ERR_print_errors(bio_err);
958 goto err;
959 }
960
961#ifndef OPENSSL_SYS_VMS
962 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile);
963#else
964 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-new", dbfile);
965#endif
966 if (j < 0 || j >= sizeof buf[0])
967 {
968 BIO_printf(bio_err, "file name too long\n");
969 goto err;
970 }
971 if (BIO_write_filename(out,buf[0]) <= 0)
972 {
973 perror(dbfile);
974 BIO_printf(bio_err,"unable to open '%s'\n",
975 dbfile);
976 goto err;
977 }
978 j=TXT_DB_write(out,db);
979 if (j <= 0) goto err;
980
981 BIO_free(out);
982 out = NULL;
983#ifndef OPENSSL_SYS_VMS
984 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile);
985#else
986 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-old", dbfile);
987#endif
988 if (j < 0 || j >= sizeof buf[1])
989 {
990 BIO_printf(bio_err, "file name too long\n");
991 goto err;
992 }
993 if (rename(dbfile,buf[1]) < 0)
994 {
995 BIO_printf(bio_err,
996 "unable to rename %s to %s\n",
997 dbfile, buf[1]);
998 perror("reason");
999 goto err;
1000 }
1001 if (rename(buf[0],dbfile) < 0)
1002 {
1003 BIO_printf(bio_err,
1004 "unable to rename %s to %s\n",
1005 buf[0],dbfile);
1006 perror("reason");
1007 rename(buf[1],dbfile);
1008 goto err;
1009 }
1010
1011 if (verbose) BIO_printf(bio_err,
1012 "Done. %d entries marked as expired\n",i);
1013 }
1014 goto err;
1015 }
1016
1017 /*****************************************************************/
1018 /* Read extentions config file */
1019 if (extfile)
1020 {
1021 extconf = NCONF_new(NULL);
1022 if (NCONF_load(extconf,extfile,&errorline) <= 0)
1023 {
1024 if (errorline <= 0)
1025 BIO_printf(bio_err, "ERROR: loading the config file '%s'\n",
1026 extfile);
1027 else
1028 BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n",
1029 errorline,extfile);
1030 ret = 1;
1031 goto err;
1032 }
1033
1034 if (verbose)
1035 BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
1036
1037 /* We can have sections in the ext file */
1038 if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
1039 extensions = "default";
1040 }
1041
1042 /*****************************************************************/
1043 if (req || gencrl)
1044 {
1045 if (outfile != NULL)
1046 {
1047 if (BIO_write_filename(Sout,outfile) <= 0)
1048 {
1049 perror(outfile);
1050 goto err;
1051 }
1052 }
1053 else
1054 {
1055 BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
1056#ifdef OPENSSL_SYS_VMS
1057 {
1058 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1059 Sout = BIO_push(tmpbio, Sout);
1060 }
1061#endif
1062 }
1063 }
1064
1065 if (req)
1066 {
1067 if ((md == NULL) && ((md=NCONF_get_string(conf,
1068 section,ENV_DEFAULT_MD)) == NULL))
1069 {
1070 lookup_fail(section,ENV_DEFAULT_MD);
1071 goto err;
1072 }
1073 if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1074 section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1075 {
1076 if(strcmp(tmp_email_dn,"no") == 0)
1077 email_dn=0;
1078 }
1079 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1080 {
1081 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1082 goto err;
1083 }
1084 if (verbose)
1085 BIO_printf(bio_err,"message digest is %s\n",
1086 OBJ_nid2ln(dgst->type));
1087 if ((policy == NULL) && ((policy=NCONF_get_string(conf,
1088 section,ENV_POLICY)) == NULL))
1089 {
1090 lookup_fail(section,ENV_POLICY);
1091 goto err;
1092 }
1093 if (verbose)
1094 BIO_printf(bio_err,"policy is %s\n",policy);
1095
1096 if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL))
1097 == NULL)
1098 {
1099 lookup_fail(section,ENV_SERIAL);
1100 goto err;
1101 }
1102
1103 if (!extconf)
1104 {
1105 /* no '-extfile' option, so we look for extensions
1106 * in the main configuration file */
1107 if (!extensions)
1108 {
1109 extensions=NCONF_get_string(conf,section,
1110 ENV_EXTENSIONS);
1111 if (!extensions)
1112 ERR_clear_error();
1113 }
1114 if (extensions)
1115 {
1116 /* Check syntax of file */
1117 X509V3_CTX ctx;
1118 X509V3_set_ctx_test(&ctx);
1119 X509V3_set_nconf(&ctx, conf);
1120 if (!X509V3_EXT_add_nconf(conf, &ctx, extensions,
1121 NULL))
1122 {
1123 BIO_printf(bio_err,
1124 "Error Loading extension section %s\n",
1125 extensions);
1126 ret = 1;
1127 goto err;
1128 }
1129 }
1130 }
1131
1132 if (startdate == NULL)
1133 {
1134 startdate=NCONF_get_string(conf,section,
1135 ENV_DEFAULT_STARTDATE);
1136 if (startdate == NULL)
1137 ERR_clear_error();
1138 }
1139 if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
1140 {
1141 BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
1142 goto err;
1143 }
1144 if (startdate == NULL) startdate="today";
1145
1146 if (enddate == NULL)
1147 {
1148 enddate=NCONF_get_string(conf,section,
1149 ENV_DEFAULT_ENDDATE);
1150 if (enddate == NULL)
1151 ERR_clear_error();
1152 }
1153 if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
1154 {
1155 BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
1156 goto err;
1157 }
1158
1159 if (days == 0)
1160 {
1161 if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days))
1162 days = 0;
1163 }
1164 if (!enddate && (days == 0))
1165 {
1166 BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
1167 goto err;
1168 }
1169
1170 if ((serial=load_serial(serialfile)) == NULL)
1171 {
1172 BIO_printf(bio_err,"error while loading serial number\n");
1173 goto err;
1174 }
1175 if (verbose)
1176 {
1177 if (BN_is_zero(serial))
1178 BIO_printf(bio_err,"next serial number is 00\n");
1179 else
1180 {
1181 if ((f=BN_bn2hex(serial)) == NULL) goto err;
1182 BIO_printf(bio_err,"next serial number is %s\n",f);
1183 OPENSSL_free(f);
1184 }
1185 }
1186
1187 if ((attribs=NCONF_get_section(conf,policy)) == NULL)
1188 {
1189 BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
1190 goto err;
1191 }
1192
1193 if ((cert_sk=sk_X509_new_null()) == NULL)
1194 {
1195 BIO_printf(bio_err,"Memory allocation failure\n");
1196 goto err;
1197 }
1198 if (spkac_file != NULL)
1199 {
1200 total++;
1201 j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1202 serial,subj,email_dn,startdate,enddate,days,extensions,
1203 conf,verbose,certopt,nameopt,default_op,ext_copy);
1204 if (j < 0) goto err;
1205 if (j > 0)
1206 {
1207 total_done++;
1208 BIO_printf(bio_err,"\n");
1209 if (!BN_add_word(serial,1)) goto err;
1210 if (!sk_X509_push(cert_sk,x))
1211 {
1212 BIO_printf(bio_err,"Memory allocation failure\n");
1213 goto err;
1214 }
1215 if (outfile)
1216 {
1217 output_der = 1;
1218 batch = 1;
1219 }
1220 }
1221 }
1222 if (ss_cert_file != NULL)
1223 {
1224 total++;
1225 j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1226 db,serial,subj,email_dn,startdate,enddate,days,batch,
1227 extensions,conf,verbose, certopt, nameopt,
1228 default_op, ext_copy, e);
1229 if (j < 0) goto err;
1230 if (j > 0)
1231 {
1232 total_done++;
1233 BIO_printf(bio_err,"\n");
1234 if (!BN_add_word(serial,1)) goto err;
1235 if (!sk_X509_push(cert_sk,x))
1236 {
1237 BIO_printf(bio_err,"Memory allocation failure\n");
1238 goto err;
1239 }
1240 }
1241 }
1242 if (infile != NULL)
1243 {
1244 total++;
1245 j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1246 serial,subj,email_dn,startdate,enddate,days,batch,
1247 extensions,conf,verbose, certopt, nameopt,
1248 default_op, ext_copy);
1249 if (j < 0) goto err;
1250 if (j > 0)
1251 {
1252 total_done++;
1253 BIO_printf(bio_err,"\n");
1254 if (!BN_add_word(serial,1)) goto err;
1255 if (!sk_X509_push(cert_sk,x))
1256 {
1257 BIO_printf(bio_err,"Memory allocation failure\n");
1258 goto err;
1259 }
1260 }
1261 }
1262 for (i=0; i<argc; i++)
1263 {
1264 total++;
1265 j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1266 serial,subj,email_dn,startdate,enddate,days,batch,
1267 extensions,conf,verbose, certopt, nameopt,
1268 default_op, ext_copy);
1269 if (j < 0) goto err;
1270 if (j > 0)
1271 {
1272 total_done++;
1273 BIO_printf(bio_err,"\n");
1274 if (!BN_add_word(serial,1)) goto err;
1275 if (!sk_X509_push(cert_sk,x))
1276 {
1277 BIO_printf(bio_err,"Memory allocation failure\n");
1278 goto err;
1279 }
1280 }
1281 }
1282 /* we have a stack of newly certified certificates
1283 * and a data base and serial number that need
1284 * updating */
1285
1286 if (sk_X509_num(cert_sk) > 0)
1287 {
1288 if (!batch)
1289 {
1290 BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
1291 (void)BIO_flush(bio_err);
1292 buf[0][0]='\0';
1293 fgets(buf[0],10,stdin);
1294 if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
1295 {
1296 BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
1297 ret=0;
1298 goto err;
1299 }
1300 }
1301
1302 BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk));
1303
1304 if(strlen(serialfile) > BSIZE-5 || strlen(dbfile) > BSIZE-5)
1305 {
1306 BIO_printf(bio_err,"file name too long\n");
1307 goto err;
1308 }
1309
1310 strcpy(buf[0],serialfile);
1311
1312#ifdef OPENSSL_SYS_VMS
1313 strcat(buf[0],"-new");
1314#else
1315 strcat(buf[0],".new");
1316#endif
1317
1318 if (!save_serial(buf[0],serial)) goto err;
1319
1320 strcpy(buf[1],dbfile);
1321
1322#ifdef OPENSSL_SYS_VMS
1323 strcat(buf[1],"-new");
1324#else
1325 strcat(buf[1],".new");
1326#endif
1327
1328 if (BIO_write_filename(out,buf[1]) <= 0)
1329 {
1330 perror(dbfile);
1331 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1332 goto err;
1333 }
1334 l=TXT_DB_write(out,db);
1335 if (l <= 0) goto err;
1336 }
1337
1338 if (verbose)
1339 BIO_printf(bio_err,"writing new certificates\n");
1340 for (i=0; i<sk_X509_num(cert_sk); i++)
1341 {
1342 int k;
1343 unsigned char *n;
1344
1345 x=sk_X509_value(cert_sk,i);
1346
1347 j=x->cert_info->serialNumber->length;
1348 p=(char *)x->cert_info->serialNumber->data;
1349
1350 if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1351 {
1352 BIO_printf(bio_err,"certificate file name too long\n");
1353 goto err;
1354 }
1355
1356 strcpy(buf[2],outdir);
1357
1358#ifndef OPENSSL_SYS_VMS
1359 strcat(buf[2],"/");
1360#endif
1361
1362 n=(unsigned char *)&(buf[2][strlen(buf[2])]);
1363 if (j > 0)
1364 {
1365 for (k=0; k<j; k++)
1366 {
1367 sprintf((char *)n,"%02X",(unsigned char)*(p++));
1368 n+=2;
1369 }
1370 }
1371 else
1372 {
1373 *(n++)='0';
1374 *(n++)='0';
1375 }
1376 *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
1377 *n='\0';
1378 if (verbose)
1379 BIO_printf(bio_err,"writing %s\n",buf[2]);
1380
1381 if (BIO_write_filename(Cout,buf[2]) <= 0)
1382 {
1383 perror(buf[2]);
1384 goto err;
1385 }
1386 write_new_certificate(Cout,x, 0, notext);
1387 write_new_certificate(Sout,x, output_der, notext);
1388 }
1389
1390 if (sk_X509_num(cert_sk))
1391 {
1392 /* Rename the database and the serial file */
1393 strncpy(buf[2],serialfile,BSIZE-4);
1394 buf[2][BSIZE-4]='\0';
1395
1396#ifdef OPENSSL_SYS_VMS
1397 strcat(buf[2],"-old");
1398#else
1399 strcat(buf[2],".old");
1400#endif
1401
1402 BIO_free(in);
1403 BIO_free_all(out);
1404 in=NULL;
1405 out=NULL;
1406 if (rename(serialfile,buf[2]) < 0)
1407 {
1408 BIO_printf(bio_err,"unable to rename %s to %s\n",
1409 serialfile,buf[2]);
1410 perror("reason");
1411 goto err;
1412 }
1413 if (rename(buf[0],serialfile) < 0)
1414 {
1415 BIO_printf(bio_err,"unable to rename %s to %s\n",
1416 buf[0],serialfile);
1417 perror("reason");
1418 rename(buf[2],serialfile);
1419 goto err;
1420 }
1421
1422 strncpy(buf[2],dbfile,BSIZE-4);
1423 buf[2][BSIZE-4]='\0';
1424
1425#ifdef OPENSSL_SYS_VMS
1426 strcat(buf[2],"-old");
1427#else
1428 strcat(buf[2],".old");
1429#endif
1430
1431 if (rename(dbfile,buf[2]) < 0)
1432 {
1433 BIO_printf(bio_err,"unable to rename %s to %s\n",
1434 dbfile,buf[2]);
1435 perror("reason");
1436 goto err;
1437 }
1438 if (rename(buf[1],dbfile) < 0)
1439 {
1440 BIO_printf(bio_err,"unable to rename %s to %s\n",
1441 buf[1],dbfile);
1442 perror("reason");
1443 rename(buf[2],dbfile);
1444 goto err;
1445 }
1446 BIO_printf(bio_err,"Data Base Updated\n");
1447 }
1448 }
1449
1450 /*****************************************************************/
1451 if (gencrl)
1452 {
1453 int crl_v2 = 0;
1454 if (!crl_ext)
1455 {
1456 crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT);
1457 if (!crl_ext)
1458 ERR_clear_error();
1459 }
1460 if (crl_ext)
1461 {
1462 /* Check syntax of file */
1463 X509V3_CTX ctx;
1464 X509V3_set_ctx_test(&ctx);
1465 X509V3_set_nconf(&ctx, conf);
1466 if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL))
1467 {
1468 BIO_printf(bio_err,
1469 "Error Loading CRL extension section %s\n",
1470 crl_ext);
1471 ret = 1;
1472 goto err;
1473 }
1474 }
1475
1476 if (!crldays && !crlhours)
1477 {
1478 if (!NCONF_get_number(conf,section,
1479 ENV_DEFAULT_CRL_DAYS, &crldays))
1480 crldays = 0;
1481 if (!NCONF_get_number(conf,section,
1482 ENV_DEFAULT_CRL_HOURS, &crlhours))
1483 crlhours = 0;
1484 }
1485 if ((crldays == 0) && (crlhours == 0))
1486 {
1487 BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
1488 goto err;
1489 }
1490
1491 if (verbose) BIO_printf(bio_err,"making CRL\n");
1492 if ((crl=X509_CRL_new()) == NULL) goto err;
1493 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
1494
1495 tmptm = ASN1_TIME_new();
1496 if (!tmptm) goto err;
1497 X509_gmtime_adj(tmptm,0);
1498 X509_CRL_set_lastUpdate(crl, tmptm);
1499 X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
1500 X509_CRL_set_nextUpdate(crl, tmptm);
1501
1502 ASN1_TIME_free(tmptm);
1503
1504 for (i=0; i<sk_num(db->data); i++)
1505 {
1506 pp=(char **)sk_value(db->data,i);
1507 if (pp[DB_type][0] == DB_TYPE_REV)
1508 {
1509 if ((r=X509_REVOKED_new()) == NULL) goto err;
1510 j = make_revoked(r, pp[DB_rev_date]);
1511 if (!j) goto err;
1512 if (j == 2) crl_v2 = 1;
1513 if (!BN_hex2bn(&serial, pp[DB_serial]))
1514 goto err;
1515 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1516 BN_free(serial);
1517 serial = NULL;
1518 if (!tmpser)
1519 goto err;
1520 X509_REVOKED_set_serialNumber(r, tmpser);
1521 ASN1_INTEGER_free(tmpser);
1522 X509_CRL_add0_revoked(crl,r);
1523 }
1524 }
1525
1526 /* sort the data so it will be written in serial
1527 * number order */
1528 X509_CRL_sort(crl);
1529
1530 /* we now have a CRL */
1531 if (verbose) BIO_printf(bio_err,"signing CRL\n");
1532 if (md != NULL)
1533 {
1534 if ((dgst=EVP_get_digestbyname(md)) == NULL)
1535 {
1536 BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1537 goto err;
1538 }
1539 }
1540 else
1541 {
1542#ifndef OPENSSL_NO_DSA
1543 if (pkey->type == EVP_PKEY_DSA)
1544 dgst=EVP_dss1();
1545 else
1546#endif
1547 dgst=EVP_md5();
1548 }
1549
1550 /* Add any extensions asked for */
1551
1552 if (crl_ext)
1553 {
1554 X509V3_CTX crlctx;
1555 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1556 X509V3_set_nconf(&crlctx, conf);
1557
1558 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1559 crl_ext, crl)) goto err;
1560 }
1561 if (crl_ext || crl_v2)
1562 {
1563 if (!X509_CRL_set_version(crl, 1))
1564 goto err; /* version 2 CRL */
1565 }
1566
1567 if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
1568
1569 PEM_write_bio_X509_CRL(Sout,crl);
1570 }
1571 /*****************************************************************/
1572 if (dorevoke)
1573 {
1574 if (infile == NULL)
1575 {
1576 BIO_printf(bio_err,"no input files\n");
1577 goto err;
1578 }
1579 else
1580 {
1581 X509 *revcert;
1582 revcert=load_cert(bio_err, infile, FORMAT_PEM,
1583 NULL, e, infile);
1584 if (revcert == NULL)
1585 goto err;
1586 j=do_revoke(revcert,db, rev_type, rev_arg);
1587 if (j <= 0) goto err;
1588 X509_free(revcert);
1589
1590 if(strlen(dbfile) > BSIZE-5)
1591 {
1592 BIO_printf(bio_err,"filename too long\n");
1593 goto err;
1594 }
1595
1596 strcpy(buf[0],dbfile);
1597#ifndef OPENSSL_SYS_VMS
1598 strcat(buf[0],".new");
1599#else
1600 strcat(buf[0],"-new");
1601#endif
1602 if (BIO_write_filename(out,buf[0]) <= 0)
1603 {
1604 perror(dbfile);
1605 BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
1606 goto err;
1607 }
1608 j=TXT_DB_write(out,db);
1609 if (j <= 0) goto err;
1610 BIO_free_all(out);
1611 out = NULL;
1612 BIO_free_all(in);
1613 in = NULL;
1614 strncpy(buf[1],dbfile,BSIZE-4);
1615 buf[1][BSIZE-4]='\0';
1616#ifndef OPENSSL_SYS_VMS
1617 strcat(buf[1],".old");
1618#else
1619 strcat(buf[1],"-old");
1620#endif
1621 if (rename(dbfile,buf[1]) < 0)
1622 {
1623 BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
1624 perror("reason");
1625 goto err;
1626 }
1627 if (rename(buf[0],dbfile) < 0)
1628 {
1629 BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile);
1630 perror("reason");
1631 rename(buf[1],dbfile);
1632 goto err;
1633 }
1634 BIO_printf(bio_err,"Data Base Updated\n");
1635 }
1636 }
1637 /*****************************************************************/
1638 ret=0;
1639err:
1640 if(tofree)
1641 OPENSSL_free(tofree);
1642 BIO_free_all(Cout);
1643 BIO_free_all(Sout);
1644 BIO_free_all(out);
1645 BIO_free_all(in);
1646
1636 sk_X509_pop_free(cert_sk,X509_free);
1647 if (cert_sk)
1648 sk_X509_pop_free(cert_sk,X509_free);
1637
1638 if (ret) ERR_print_errors(bio_err);
1639 app_RAND_write_file(randfile, bio_err);
1649
1650 if (ret) ERR_print_errors(bio_err);
1651 app_RAND_write_file(randfile, bio_err);
1640 if (free_key)
1652 if (free_key && key)
1641 OPENSSL_free(key);
1642 BN_free(serial);
1643 TXT_DB_free(db);
1644 EVP_PKEY_free(pkey);
1645 X509_free(x509);
1646 X509_CRL_free(crl);
1647 NCONF_free(conf);
1648 OBJ_cleanup();
1649 apps_shutdown();
1650 OPENSSL_EXIT(ret);
1651 }
1652
1653static void lookup_fail(char *name, char *tag)
1654 {
1655 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1656 }
1657
1658static unsigned long index_serial_hash(const char **a)
1659 {
1660 const char *n;
1661
1662 n=a[DB_serial];
1663 while (*n == '0') n++;
1664 return(lh_strhash(n));
1665 }
1666
1667static int index_serial_cmp(const char **a, const char **b)
1668 {
1669 const char *aa,*bb;
1670
1671 for (aa=a[DB_serial]; *aa == '0'; aa++);
1672 for (bb=b[DB_serial]; *bb == '0'; bb++);
1673 return(strcmp(aa,bb));
1674 }
1675
1676static unsigned long index_name_hash(const char **a)
1677 { return(lh_strhash(a[DB_name])); }
1678
1679static int index_name_qual(char **a)
1680 { return(a[0][0] == 'V'); }
1681
1682static int index_name_cmp(const char **a, const char **b)
1683 { return(strcmp(a[DB_name],
1684 b[DB_name])); }
1685
1686static BIGNUM *load_serial(char *serialfile)
1687 {
1688 BIO *in=NULL;
1689 BIGNUM *ret=NULL;
1690 MS_STATIC char buf[1024];
1691 ASN1_INTEGER *ai=NULL;
1692
1693 if ((in=BIO_new(BIO_s_file())) == NULL)
1694 {
1695 ERR_print_errors(bio_err);
1696 goto err;
1697 }
1698
1699 if (BIO_read_filename(in,serialfile) <= 0)
1700 {
1701 perror(serialfile);
1702 goto err;
1703 }
1704 ai=ASN1_INTEGER_new();
1705 if (ai == NULL) goto err;
1706 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1707 {
1708 BIO_printf(bio_err,"unable to load number from %s\n",
1709 serialfile);
1710 goto err;
1711 }
1712 ret=ASN1_INTEGER_to_BN(ai,NULL);
1713 if (ret == NULL)
1714 {
1715 BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
1716 goto err;
1717 }
1718err:
1719 if (in != NULL) BIO_free(in);
1720 if (ai != NULL) ASN1_INTEGER_free(ai);
1721 return(ret);
1722 }
1723
1724static int save_serial(char *serialfile, BIGNUM *serial)
1725 {
1726 BIO *out;
1727 int ret=0;
1728 ASN1_INTEGER *ai=NULL;
1729
1730 out=BIO_new(BIO_s_file());
1731 if (out == NULL)
1732 {
1733 ERR_print_errors(bio_err);
1734 goto err;
1735 }
1736 if (BIO_write_filename(out,serialfile) <= 0)
1737 {
1738 perror(serialfile);
1739 goto err;
1740 }
1741
1742 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1743 {
1744 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1745 goto err;
1746 }
1747 i2a_ASN1_INTEGER(out,ai);
1748 BIO_puts(out,"\n");
1749 ret=1;
1750err:
1751 if (out != NULL) BIO_free_all(out);
1752 if (ai != NULL) ASN1_INTEGER_free(ai);
1753 return(ret);
1754 }
1755
1756static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1757 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1758 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1759 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1760 unsigned long certopt, unsigned long nameopt, int default_op,
1761 int ext_copy)
1762 {
1763 X509_REQ *req=NULL;
1764 BIO *in=NULL;
1765 EVP_PKEY *pktmp=NULL;
1766 int ok= -1,i;
1767
1768 in=BIO_new(BIO_s_file());
1769
1770 if (BIO_read_filename(in,infile) <= 0)
1771 {
1772 perror(infile);
1773 goto err;
1774 }
1775 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1776 {
1777 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1778 infile);
1779 goto err;
1780 }
1781 if (verbose)
1782 X509_REQ_print(bio_err,req);
1783
1784 BIO_printf(bio_err,"Check that the request matches the signature\n");
1785
1786 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1787 {
1788 BIO_printf(bio_err,"error unpacking public key\n");
1789 goto err;
1790 }
1791 i=X509_REQ_verify(req,pktmp);
1792 EVP_PKEY_free(pktmp);
1793 if (i < 0)
1794 {
1795 ok=0;
1796 BIO_printf(bio_err,"Signature verification problems....\n");
1797 goto err;
1798 }
1799 if (i == 0)
1800 {
1801 ok=0;
1802 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1803 goto err;
1804 }
1805 else
1806 BIO_printf(bio_err,"Signature ok\n");
1807
1808 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1809 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1810 certopt, nameopt, default_op, ext_copy);
1811
1812err:
1813 if (req != NULL) X509_REQ_free(req);
1814 if (in != NULL) BIO_free(in);
1815 return(ok);
1816 }
1817
1818static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1819 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1820 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1821 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1822 unsigned long certopt, unsigned long nameopt, int default_op,
1823 int ext_copy, ENGINE *e)
1824 {
1825 X509 *req=NULL;
1826 X509_REQ *rreq=NULL;
1827 EVP_PKEY *pktmp=NULL;
1828 int ok= -1,i;
1829
1830 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1831 goto err;
1832 if (verbose)
1833 X509_print(bio_err,req);
1834
1835 BIO_printf(bio_err,"Check that the request matches the signature\n");
1836
1837 if ((pktmp=X509_get_pubkey(req)) == NULL)
1838 {
1839 BIO_printf(bio_err,"error unpacking public key\n");
1840 goto err;
1841 }
1842 i=X509_verify(req,pktmp);
1843 EVP_PKEY_free(pktmp);
1844 if (i < 0)
1845 {
1846 ok=0;
1847 BIO_printf(bio_err,"Signature verification problems....\n");
1848 goto err;
1849 }
1850 if (i == 0)
1851 {
1852 ok=0;
1853 BIO_printf(bio_err,"Signature did not match the certificate\n");
1854 goto err;
1855 }
1856 else
1857 BIO_printf(bio_err,"Signature ok\n");
1858
1859 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1860 goto err;
1861
1862 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1863 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1864 ext_copy);
1865
1866err:
1867 if (rreq != NULL) X509_REQ_free(rreq);
1868 if (req != NULL) X509_free(req);
1869 return(ok);
1870 }
1871
1872static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1873 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1874 int email_dn, char *startdate, char *enddate, long days, int batch,
1875 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1876 unsigned long certopt, unsigned long nameopt, int default_op,
1877 int ext_copy)
1878 {
1879 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1880 ASN1_UTCTIME *tm,*tmptm;
1881 ASN1_STRING *str,*str2;
1882 ASN1_OBJECT *obj;
1883 X509 *ret=NULL;
1884 X509_CINF *ci;
1885 X509_NAME_ENTRY *ne;
1886 X509_NAME_ENTRY *tne,*push;
1887 EVP_PKEY *pktmp;
1888 int ok= -1,i,j,last,nid;
1889 char *p;
1890 CONF_VALUE *cv;
1891 char *row[DB_NUMBER],**rrow,**irow=NULL;
1892 char buf[25];
1893
1894 tmptm=ASN1_UTCTIME_new();
1895 if (tmptm == NULL)
1896 {
1897 BIO_printf(bio_err,"malloc error\n");
1898 return(0);
1899 }
1900
1901 for (i=0; i<DB_NUMBER; i++)
1902 row[i]=NULL;
1903
1904 if (subj)
1905 {
1906 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1907
1908 if (!n)
1909 {
1910 ERR_print_errors(bio_err);
1911 goto err;
1912 }
1913 X509_REQ_set_subject_name(req,n);
1914 req->req_info->enc.modified = 1;
1915 X509_NAME_free(n);
1916 }
1917
1918 if (default_op)
1919 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1920
1921 name=X509_REQ_get_subject_name(req);
1922 for (i=0; i<X509_NAME_entry_count(name); i++)
1923 {
1924 ne= X509_NAME_get_entry(name,i);
1925 str=X509_NAME_ENTRY_get_data(ne);
1926 obj=X509_NAME_ENTRY_get_object(ne);
1927
1928 if (msie_hack)
1929 {
1930 /* assume all type should be strings */
1931 nid=OBJ_obj2nid(ne->object);
1932
1933 if (str->type == V_ASN1_UNIVERSALSTRING)
1934 ASN1_UNIVERSALSTRING_to_string(str);
1935
1936 if ((str->type == V_ASN1_IA5STRING) &&
1937 (nid != NID_pkcs9_emailAddress))
1938 str->type=V_ASN1_T61STRING;
1939
1940 if ((nid == NID_pkcs9_emailAddress) &&
1941 (str->type == V_ASN1_PRINTABLESTRING))
1942 str->type=V_ASN1_IA5STRING;
1943 }
1944
1945 /* If no EMAIL is wanted in the subject */
1946 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1947 continue;
1948
1949 /* check some things */
1950 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1951 (str->type != V_ASN1_IA5STRING))
1952 {
1953 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1954 goto err;
1955 }
1956 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1957 {
1958 j=ASN1_PRINTABLE_type(str->data,str->length);
1959 if ( ((j == V_ASN1_T61STRING) &&
1960 (str->type != V_ASN1_T61STRING)) ||
1961 ((j == V_ASN1_IA5STRING) &&
1962 (str->type == V_ASN1_PRINTABLESTRING)))
1963 {
1964 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1965 goto err;
1966 }
1967 }
1968
1969 if (default_op)
1970 old_entry_print(bio_err, obj, str);
1971 }
1972
1973 /* Ok, now we check the 'policy' stuff. */
1974 if ((subject=X509_NAME_new()) == NULL)
1975 {
1976 BIO_printf(bio_err,"Memory allocation failure\n");
1977 goto err;
1978 }
1979
1980 /* take a copy of the issuer name before we mess with it. */
1981 CAname=X509_NAME_dup(x509->cert_info->subject);
1982 if (CAname == NULL) goto err;
1983 str=str2=NULL;
1984
1985 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1986 {
1987 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
1988 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
1989 {
1990 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
1991 goto err;
1992 }
1993 obj=OBJ_nid2obj(j);
1994
1995 last= -1;
1996 for (;;)
1997 {
1998 /* lookup the object in the supplied name list */
1999 j=X509_NAME_get_index_by_OBJ(name,obj,last);
2000 if (j < 0)
2001 {
2002 if (last != -1) break;
2003 tne=NULL;
2004 }
2005 else
2006 {
2007 tne=X509_NAME_get_entry(name,j);
2008 }
2009 last=j;
2010
2011 /* depending on the 'policy', decide what to do. */
2012 push=NULL;
2013 if (strcmp(cv->value,"optional") == 0)
2014 {
2015 if (tne != NULL)
2016 push=tne;
2017 }
2018 else if (strcmp(cv->value,"supplied") == 0)
2019 {
2020 if (tne == NULL)
2021 {
2022 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2023 goto err;
2024 }
2025 else
2026 push=tne;
2027 }
2028 else if (strcmp(cv->value,"match") == 0)
2029 {
2030 int last2;
2031
2032 if (tne == NULL)
2033 {
2034 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2035 goto err;
2036 }
2037
2038 last2= -1;
2039
2040again2:
2041 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2042 if ((j < 0) && (last2 == -1))
2043 {
2044 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2045 goto err;
2046 }
2047 if (j >= 0)
2048 {
2049 push=X509_NAME_get_entry(CAname,j);
2050 str=X509_NAME_ENTRY_get_data(tne);
2051 str2=X509_NAME_ENTRY_get_data(push);
2052 last2=j;
2053 if (ASN1_STRING_cmp(str,str2) != 0)
2054 goto again2;
2055 }
2056 if (j < 0)
2057 {
2058 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));
2059 goto err;
2060 }
2061 }
2062 else
2063 {
2064 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2065 goto err;
2066 }
2067
2068 if (push != NULL)
2069 {
2070 if (!X509_NAME_add_entry(subject,push, -1, 0))
2071 {
2072 if (push != NULL)
2073 X509_NAME_ENTRY_free(push);
2074 BIO_printf(bio_err,"Memory allocation failure\n");
2075 goto err;
2076 }
2077 }
2078 if (j < 0) break;
2079 }
2080 }
2081
2082 if (preserve)
2083 {
2084 X509_NAME_free(subject);
2085 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
2086 subject=X509_NAME_dup(name);
2087 if (subject == NULL) goto err;
2088 }
2089
2090 if (verbose)
2091 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2092
2093 /* Build the correct Subject if no e-mail is wanted in the subject */
2094 /* and add it later on because of the method extensions are added (altName) */
2095
2096 if (email_dn)
2097 dn_subject = subject;
2098 else
2099 {
2100 X509_NAME_ENTRY *tmpne;
2101 /* Its best to dup the subject DN and then delete any email
2102 * addresses because this retains its structure.
2103 */
2104 if (!(dn_subject = X509_NAME_dup(subject)))
2105 {
2106 BIO_printf(bio_err,"Memory allocation failure\n");
2107 goto err;
2108 }
2109 while((i = X509_NAME_get_index_by_NID(dn_subject,
2110 NID_pkcs9_emailAddress, -1)) >= 0)
2111 {
2112 tmpne = X509_NAME_get_entry(dn_subject, i);
2113 X509_NAME_delete_entry(dn_subject, i);
2114 X509_NAME_ENTRY_free(tmpne);
2115 }
2116 }
2117
2118 if (BN_is_zero(serial))
2119 row[DB_serial]=BUF_strdup("00");
2120 else
2121 row[DB_serial]=BN_bn2hex(serial);
2122 if (row[DB_serial] == NULL)
2123 {
2124 BIO_printf(bio_err,"Memory allocation failure\n");
2125 goto err;
2126 }
2127
2128 rrow=TXT_DB_get_by_index(db,DB_name,row);
2129 if (rrow != NULL)
2130 {
2131 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2132 row[DB_name]);
2133 }
2134 else
2135 {
2136 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2137 if (rrow != NULL)
2138 {
2139 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2140 row[DB_serial]);
2141 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2142 }
2143 }
2144
2145 if (rrow != NULL)
2146 {
2147 BIO_printf(bio_err,
2148 "The matching entry has the following details\n");
2149 if (rrow[DB_type][0] == 'E')
2150 p="Expired";
2151 else if (rrow[DB_type][0] == 'R')
2152 p="Revoked";
2153 else if (rrow[DB_type][0] == 'V')
2154 p="Valid";
2155 else
2156 p="\ninvalid type, Data base error\n";
2157 BIO_printf(bio_err,"Type :%s\n",p);;
2158 if (rrow[DB_type][0] == 'R')
2159 {
2160 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2161 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2162 }
2163 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2164 BIO_printf(bio_err,"Expires on :%s\n",p);
2165 p=rrow[DB_serial]; if (p == NULL) p="undef";
2166 BIO_printf(bio_err,"Serial Number :%s\n",p);
2167 p=rrow[DB_file]; if (p == NULL) p="undef";
2168 BIO_printf(bio_err,"File name :%s\n",p);
2169 p=rrow[DB_name]; if (p == NULL) p="undef";
2170 BIO_printf(bio_err,"Subject Name :%s\n",p);
2171 ok= -1; /* This is now a 'bad' error. */
2172 goto err;
2173 }
2174
2175 /* We are now totally happy, lets make and sign the certificate */
2176 if (verbose)
2177 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2178
2179 if ((ret=X509_new()) == NULL) goto err;
2180 ci=ret->cert_info;
2181
2182#ifdef X509_V3
2183 /* Make it an X509 v3 certificate. */
2184 if (!X509_set_version(x509,2)) goto err;
2185#endif
2186
2187 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2188 goto err;
2189 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2190 goto err;
2191
2192 if (strcmp(startdate,"today") == 0)
2193 X509_gmtime_adj(X509_get_notBefore(ret),0);
2194 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2195
2196 if (enddate == NULL)
2197 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2198 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2199
2200 if (!X509_set_subject_name(ret,subject)) goto err;
2201
2202 pktmp=X509_REQ_get_pubkey(req);
2203 i = X509_set_pubkey(ret,pktmp);
2204 EVP_PKEY_free(pktmp);
2205 if (!i) goto err;
2206
2207 /* Lets add the extensions, if there are any */
2208 if (ext_sect)
2209 {
2210 X509V3_CTX ctx;
2211 if (ci->version == NULL)
2212 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2213 goto err;
2214 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2215
2216 /* Free the current entries if any, there should not
2217 * be any I believe */
2218 if (ci->extensions != NULL)
2219 sk_X509_EXTENSION_pop_free(ci->extensions,
2220 X509_EXTENSION_free);
2221
2222 ci->extensions = NULL;
2223
2224 /* Initialize the context structure */
2225 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2226
2227 if (extconf)
2228 {
2229 if (verbose)
2230 BIO_printf(bio_err, "Extra configuration file found\n");
2231
2232 /* Use the extconf configuration db LHASH */
2233 X509V3_set_nconf(&ctx, extconf);
2234
2235 /* Test the structure (needed?) */
2236 /* X509V3_set_ctx_test(&ctx); */
2237
2238 /* Adds exts contained in the configuration file */
2239 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2240 {
2241 BIO_printf(bio_err,
2242 "ERROR: adding extensions in section %s\n",
2243 ext_sect);
2244 ERR_print_errors(bio_err);
2245 goto err;
2246 }
2247 if (verbose)
2248 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2249 }
2250 else if (ext_sect)
2251 {
2252 /* We found extensions to be set from config file */
2253 X509V3_set_nconf(&ctx, lconf);
2254
2255 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2256 {
2257 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2258 ERR_print_errors(bio_err);
2259 goto err;
2260 }
2261
2262 if (verbose)
2263 BIO_printf(bio_err, "Successfully added extensions from config\n");
2264 }
2265 }
2266
2267 /* Copy extensions from request (if any) */
2268
2269 if (!copy_extensions(ret, req, ext_copy))
2270 {
2271 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2272 ERR_print_errors(bio_err);
2273 goto err;
2274 }
2275
2276 /* Set the right value for the noemailDN option */
2277 if( email_dn == 0 )
2278 {
2279 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2280 }
2281
2282 if (!default_op)
2283 {
2284 BIO_printf(bio_err, "Certificate Details:\n");
2285 /* Never print signature details because signature not present */
2286 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2287 X509_print_ex(bio_err, ret, nameopt, certopt);
2288 }
2289
2290 BIO_printf(bio_err,"Certificate is to be certified until ");
2291 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2292 if (days) BIO_printf(bio_err," (%d days)",days);
2293 BIO_printf(bio_err, "\n");
2294
2295 if (!batch)
2296 {
2297
2298 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2299 (void)BIO_flush(bio_err);
2300 buf[0]='\0';
2301 fgets(buf,sizeof(buf)-1,stdin);
2302 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2303 {
2304 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2305 ok=0;
2306 goto err;
2307 }
2308 }
2309
2310
2311#ifndef OPENSSL_NO_DSA
2312 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2313 pktmp=X509_get_pubkey(ret);
2314 if (EVP_PKEY_missing_parameters(pktmp) &&
2315 !EVP_PKEY_missing_parameters(pkey))
2316 EVP_PKEY_copy_parameters(pktmp,pkey);
2317 EVP_PKEY_free(pktmp);
2318#endif
2319
2320 if (!X509_sign(ret,pkey,dgst))
2321 goto err;
2322
2323 /* We now just add it to the database */
2324 row[DB_type]=(char *)OPENSSL_malloc(2);
2325
2326 tm=X509_get_notAfter(ret);
2327 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2328 memcpy(row[DB_exp_date],tm->data,tm->length);
2329 row[DB_exp_date][tm->length]='\0';
2330
2331 row[DB_rev_date]=NULL;
2332
2333 /* row[DB_serial] done already */
2334 row[DB_file]=(char *)OPENSSL_malloc(8);
2335 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2336
2337 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2338 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2339 {
2340 BIO_printf(bio_err,"Memory allocation failure\n");
2341 goto err;
2342 }
2343 strcpy(row[DB_file],"unknown");
2344 row[DB_type][0]='V';
2345 row[DB_type][1]='\0';
2346
2347 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2348 {
2349 BIO_printf(bio_err,"Memory allocation failure\n");
2350 goto err;
2351 }
2352
2353 for (i=0; i<DB_NUMBER; i++)
2354 {
2355 irow[i]=row[i];
2356 row[i]=NULL;
2357 }
2358 irow[DB_NUMBER]=NULL;
2359
2360 if (!TXT_DB_insert(db,irow))
2361 {
2362 BIO_printf(bio_err,"failed to update database\n");
2363 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2364 goto err;
2365 }
2366 ok=1;
2367err:
2368 for (i=0; i<DB_NUMBER; i++)
2369 if (row[i] != NULL) OPENSSL_free(row[i]);
2370
2371 if (CAname != NULL)
2372 X509_NAME_free(CAname);
2373 if (subject != NULL)
2374 X509_NAME_free(subject);
2375 if ((dn_subject != NULL) && !email_dn)
2376 X509_NAME_free(dn_subject);
2377 if (tmptm != NULL)
2378 ASN1_UTCTIME_free(tmptm);
2379 if (ok <= 0)
2380 {
2381 if (ret != NULL) X509_free(ret);
2382 ret=NULL;
2383 }
2384 else
2385 *xret=ret;
2386 return(ok);
2387 }
2388
2389static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2390 {
2391
2392 if (output_der)
2393 {
2394 (void)i2d_X509_bio(bp,x);
2395 return;
2396 }
2397#if 0
2398 /* ??? Not needed since X509_print prints all this stuff anyway */
2399 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2400 BIO_printf(bp,"issuer :%s\n",f);
2401
2402 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2403 BIO_printf(bp,"subject:%s\n",f);
2404
2405 BIO_puts(bp,"serial :");
2406 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2407 BIO_puts(bp,"\n\n");
2408#endif
2409 if (!notext)X509_print(bp,x);
2410 PEM_write_bio_X509(bp,x);
2411 }
2412
2413static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2414 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2415 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2416 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2417 unsigned long nameopt, int default_op, int ext_copy)
2418 {
2419 STACK_OF(CONF_VALUE) *sk=NULL;
2420 LHASH *parms=NULL;
2421 X509_REQ *req=NULL;
2422 CONF_VALUE *cv=NULL;
2423 NETSCAPE_SPKI *spki = NULL;
2424 X509_REQ_INFO *ri;
2425 char *type,*buf;
2426 EVP_PKEY *pktmp=NULL;
2427 X509_NAME *n=NULL;
2428 X509_NAME_ENTRY *ne=NULL;
2429 int ok= -1,i,j;
2430 long errline;
2431 int nid;
2432
2433 /*
2434 * Load input file into a hash table. (This is just an easy
2435 * way to read and parse the file, then put it into a convenient
2436 * STACK format).
2437 */
2438 parms=CONF_load(NULL,infile,&errline);
2439 if (parms == NULL)
2440 {
2441 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2442 ERR_print_errors(bio_err);
2443 goto err;
2444 }
2445
2446 sk=CONF_get_section(parms, "default");
2447 if (sk_CONF_VALUE_num(sk) == 0)
2448 {
2449 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2450 CONF_free(parms);
2451 goto err;
2452 }
2453
2454 /*
2455 * Now create a dummy X509 request structure. We don't actually
2456 * have an X509 request, but we have many of the components
2457 * (a public key, various DN components). The idea is that we
2458 * put these components into the right X509 request structure
2459 * and we can use the same code as if you had a real X509 request.
2460 */
2461 req=X509_REQ_new();
2462 if (req == NULL)
2463 {
2464 ERR_print_errors(bio_err);
2465 goto err;
2466 }
2467
2468 /*
2469 * Build up the subject name set.
2470 */
2471 ri=req->req_info;
2472 n = ri->subject;
2473
2474 for (i = 0; ; i++)
2475 {
2476 if (sk_CONF_VALUE_num(sk) <= i) break;
2477
2478 cv=sk_CONF_VALUE_value(sk,i);
2479 type=cv->name;
2480 /* Skip past any leading X. X: X, etc to allow for
2481 * multiple instances
2482 */
2483 for (buf = cv->name; *buf ; buf++)
2484 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2485 {
2486 buf++;
2487 if (*buf) type = buf;
2488 break;
2489 }
2490
2491 buf=cv->value;
2492 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2493 {
2494 if (strcmp(type, "SPKAC") == 0)
2495 {
2496 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2497 if (spki == NULL)
2498 {
2499 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2500 ERR_print_errors(bio_err);
2501 goto err;
2502 }
2503 }
2504 continue;
2505 }
2506
2507 /*
2508 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2509 continue;
2510 */
2511
2512 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2513 if (fix_data(nid, &j) == 0)
2514 {
2515 BIO_printf(bio_err,
2516 "invalid characters in string %s\n",buf);
2517 goto err;
2518 }
2519
2520 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2521 (unsigned char *)buf,
2522 strlen(buf))) == NULL)
2523 goto err;
2524
2525 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2526 }
2527 if (spki == NULL)
2528 {
2529 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2530 infile);
2531 goto err;
2532 }
2533
2534 /*
2535 * Now extract the key from the SPKI structure.
2536 */
2537
2538 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2539
2540 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2541 {
2542 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2543 goto err;
2544 }
2545
2546 j = NETSCAPE_SPKI_verify(spki, pktmp);
2547 if (j <= 0)
2548 {
2549 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2550 goto err;
2551 }
2552 BIO_printf(bio_err,"Signature ok\n");
2553
2554 X509_REQ_set_pubkey(req,pktmp);
2555 EVP_PKEY_free(pktmp);
2556 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2557 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2558 ext_copy);
2559err:
2560 if (req != NULL) X509_REQ_free(req);
2561 if (parms != NULL) CONF_free(parms);
2562 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2563 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2564
2565 return(ok);
2566 }
2567
2568static int fix_data(int nid, int *type)
2569 {
2570 if (nid == NID_pkcs9_emailAddress)
2571 *type=V_ASN1_IA5STRING;
2572 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2573 *type=V_ASN1_T61STRING;
2574 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2575 *type=V_ASN1_T61STRING;
2576 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2577 return(0);
2578 if (nid == NID_pkcs9_unstructuredName)
2579 *type=V_ASN1_IA5STRING;
2580 return(1);
2581 }
2582
2583static int check_time_format(char *str)
2584 {
2585 ASN1_UTCTIME tm;
2586
2587 tm.data=(unsigned char *)str;
2588 tm.length=strlen(str);
2589 tm.type=V_ASN1_UTCTIME;
2590 return(ASN1_UTCTIME_check(&tm));
2591 }
2592
2593static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2594 {
2595 ASN1_UTCTIME *tm=NULL;
2596 char *row[DB_NUMBER],**rrow,**irow;
2597 char *rev_str = NULL;
2598 BIGNUM *bn = NULL;
2599 int ok=-1,i;
2600
2601 for (i=0; i<DB_NUMBER; i++)
2602 row[i]=NULL;
2603 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2604 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2605 if (BN_is_zero(bn))
2606 row[DB_serial]=BUF_strdup("00");
2607 else
2608 row[DB_serial]=BN_bn2hex(bn);
2609 BN_free(bn);
2610 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2611 {
2612 BIO_printf(bio_err,"Memory allocation failure\n");
2613 goto err;
2614 }
2615 /* We have to lookup by serial number because name lookup
2616 * skips revoked certs
2617 */
2618 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2619 if (rrow == NULL)
2620 {
2621 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2622
2623 /* We now just add it to the database */
2624 row[DB_type]=(char *)OPENSSL_malloc(2);
2625
2626 tm=X509_get_notAfter(x509);
2627 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2628 memcpy(row[DB_exp_date],tm->data,tm->length);
2629 row[DB_exp_date][tm->length]='\0';
2630
2631 row[DB_rev_date]=NULL;
2632
2633 /* row[DB_serial] done already */
2634 row[DB_file]=(char *)OPENSSL_malloc(8);
2635
2636 /* row[DB_name] done already */
2637
2638 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2639 (row[DB_file] == NULL))
2640 {
2641 BIO_printf(bio_err,"Memory allocation failure\n");
2642 goto err;
2643 }
2644 strcpy(row[DB_file],"unknown");
2645 row[DB_type][0]='V';
2646 row[DB_type][1]='\0';
2647
2648 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2649 {
2650 BIO_printf(bio_err,"Memory allocation failure\n");
2651 goto err;
2652 }
2653
2654 for (i=0; i<DB_NUMBER; i++)
2655 {
2656 irow[i]=row[i];
2657 row[i]=NULL;
2658 }
2659 irow[DB_NUMBER]=NULL;
2660
2661 if (!TXT_DB_insert(db,irow))
2662 {
2663 BIO_printf(bio_err,"failed to update database\n");
2664 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2665 goto err;
2666 }
2667
2668 /* Revoke Certificate */
2669 ok = do_revoke(x509,db, type, value);
2670
2671 goto err;
2672
2673 }
2674 else if (index_name_cmp((const char **)row,(const char **)rrow))
2675 {
2676 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2677 row[DB_name]);
2678 goto err;
2679 }
2680 else if (rrow[DB_type][0]=='R')
2681 {
2682 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2683 row[DB_serial]);
2684 goto err;
2685 }
2686 else
2687 {
2688 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2689 rev_str = make_revocation_str(type, value);
2690 if (!rev_str)
2691 {
2692 BIO_printf(bio_err, "Error in revocation arguments\n");
2693 goto err;
2694 }
2695 rrow[DB_type][0]='R';
2696 rrow[DB_type][1]='\0';
2697 rrow[DB_rev_date] = rev_str;
2698 }
2699 ok=1;
2700err:
2701 for (i=0; i<DB_NUMBER; i++)
2702 {
2703 if (row[i] != NULL)
2704 OPENSSL_free(row[i]);
2705 }
2706 return(ok);
2707 }
2708
2709static int get_certificate_status(const char *serial, TXT_DB *db)
2710 {
2711 char *row[DB_NUMBER],**rrow;
2712 int ok=-1,i;
2713
2714 /* Free Resources */
2715 for (i=0; i<DB_NUMBER; i++)
2716 row[i]=NULL;
2717
2718 /* Malloc needed char spaces */
2719 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2720 if (row[DB_serial] == NULL)
2721 {
2722 BIO_printf(bio_err,"Malloc failure\n");
2723 goto err;
2724 }
2725
2726 if (strlen(serial) % 2)
2727 {
2728 /* Set the first char to 0 */;
2729 row[DB_serial][0]='0';
2730
2731 /* Copy String from serial to row[DB_serial] */
2732 memcpy(row[DB_serial]+1, serial, strlen(serial));
2733 row[DB_serial][strlen(serial)+1]='\0';
2734 }
2735 else
2736 {
2737 /* Copy String from serial to row[DB_serial] */
2738 memcpy(row[DB_serial], serial, strlen(serial));
2739 row[DB_serial][strlen(serial)]='\0';
2740 }
2741
2742 /* Make it Upper Case */
2743 for (i=0; row[DB_serial][i] != '\0'; i++)
2744 row[DB_serial][i] = toupper(row[DB_serial][i]);
2745
2746
2747 ok=1;
2748
2749 /* Search for the certificate */
2750 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2751 if (rrow == NULL)
2752 {
2753 BIO_printf(bio_err,"Serial %s not present in db.\n",
2754 row[DB_serial]);
2755 ok=-1;
2756 goto err;
2757 }
2758 else if (rrow[DB_type][0]=='V')
2759 {
2760 BIO_printf(bio_err,"%s=Valid (%c)\n",
2761 row[DB_serial], rrow[DB_type][0]);
2762 goto err;
2763 }
2764 else if (rrow[DB_type][0]=='R')
2765 {
2766 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2767 row[DB_serial], rrow[DB_type][0]);
2768 goto err;
2769 }
2770 else if (rrow[DB_type][0]=='E')
2771 {
2772 BIO_printf(bio_err,"%s=Expired (%c)\n",
2773 row[DB_serial], rrow[DB_type][0]);
2774 goto err;
2775 }
2776 else if (rrow[DB_type][0]=='S')
2777 {
2778 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2779 row[DB_serial], rrow[DB_type][0]);
2780 goto err;
2781 }
2782 else
2783 {
2784 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2785 row[DB_serial], rrow[DB_type][0]);
2786 ok=-1;
2787 }
2788err:
2789 for (i=0; i<DB_NUMBER; i++)
2790 {
2791 if (row[i] != NULL)
2792 OPENSSL_free(row[i]);
2793 }
2794 return(ok);
2795 }
2796
2797static int do_updatedb (TXT_DB *db)
2798 {
2799 ASN1_UTCTIME *a_tm = NULL;
2800 int i, cnt = 0;
2801 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2802 char **rrow, *a_tm_s;
2803
2804 a_tm = ASN1_UTCTIME_new();
2805
2806 /* get actual time and make a string */
2807 a_tm = X509_gmtime_adj(a_tm, 0);
2808 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2809 if (a_tm_s == NULL)
2810 {
2811 cnt = -1;
2812 goto err;
2813 }
2814
2815 memcpy(a_tm_s, a_tm->data, a_tm->length);
2816 a_tm_s[a_tm->length] = '\0';
2817
2818 if (strncmp(a_tm_s, "49", 2) <= 0)
2819 a_y2k = 1;
2820 else
2821 a_y2k = 0;
2822
2823 for (i = 0; i < sk_num(db->data); i++)
2824 {
2825 rrow = (char **) sk_value(db->data, i);
2826
2827 if (rrow[DB_type][0] == 'V')
2828 {
2829 /* ignore entries that are not valid */
2830 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2831 db_y2k = 1;
2832 else
2833 db_y2k = 0;
2834
2835 if (db_y2k == a_y2k)
2836 {
2837 /* all on the same y2k side */
2838 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2839 {
2840 rrow[DB_type][0] = 'E';
2841 rrow[DB_type][1] = '\0';
2842 cnt++;
2843
2844 BIO_printf(bio_err, "%s=Expired\n",
2845 rrow[DB_serial]);
2846 }
2847 }
2848 else if (db_y2k < a_y2k)
2849 {
2850 rrow[DB_type][0] = 'E';
2851 rrow[DB_type][1] = '\0';
2852 cnt++;
2853
2854 BIO_printf(bio_err, "%s=Expired\n",
2855 rrow[DB_serial]);
2856 }
2857
2858 }
2859 }
2860
2861err:
2862
2863 ASN1_UTCTIME_free(a_tm);
2864 OPENSSL_free(a_tm_s);
2865
2866 return (cnt);
2867 }
2868
2869static char *crl_reasons[] = {
2870 /* CRL reason strings */
2871 "unspecified",
2872 "keyCompromise",
2873 "CACompromise",
2874 "affiliationChanged",
2875 "superseded",
2876 "cessationOfOperation",
2877 "certificateHold",
2878 "removeFromCRL",
2879 /* Additional pseudo reasons */
2880 "holdInstruction",
2881 "keyTime",
2882 "CAkeyTime"
2883};
2884
2885#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2886
2887/* Given revocation information convert to a DB string.
2888 * The format of the string is:
2889 * revtime[,reason,extra]. Where 'revtime' is the
2890 * revocation time (the current time). 'reason' is the
2891 * optional CRL reason and 'extra' is any additional
2892 * argument
2893 */
2894
2895char *make_revocation_str(int rev_type, char *rev_arg)
2896 {
2897 char *reason = NULL, *other = NULL, *str;
2898 ASN1_OBJECT *otmp;
2899 ASN1_UTCTIME *revtm = NULL;
2900 int i;
2901 switch (rev_type)
2902 {
2903 case REV_NONE:
2904 break;
2905
2906 case REV_CRL_REASON:
2907 for (i = 0; i < 8; i++)
2908 {
2909 if (!strcasecmp(rev_arg, crl_reasons[i]))
2910 {
2911 reason = crl_reasons[i];
2912 break;
2913 }
2914 }
2915 if (reason == NULL)
2916 {
2917 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2918 return NULL;
2919 }
2920 break;
2921
2922 case REV_HOLD:
2923 /* Argument is an OID */
2924
2925 otmp = OBJ_txt2obj(rev_arg, 0);
2926 ASN1_OBJECT_free(otmp);
2927
2928 if (otmp == NULL)
2929 {
2930 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2931 return NULL;
2932 }
2933
2934 reason = "holdInstruction";
2935 other = rev_arg;
2936 break;
2937
2938 case REV_KEY_COMPROMISE:
2939 case REV_CA_COMPROMISE:
2940
2941 /* Argument is the key compromise time */
2942 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2943 {
2944 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2945 return NULL;
2946 }
2947 other = rev_arg;
2948 if (rev_type == REV_KEY_COMPROMISE)
2949 reason = "keyTime";
2950 else
2951 reason = "CAkeyTime";
2952
2953 break;
2954
2955 }
2956
2957 revtm = X509_gmtime_adj(NULL, 0);
2958
2959 i = revtm->length + 1;
2960
2961 if (reason) i += strlen(reason) + 1;
2962 if (other) i += strlen(other) + 1;
2963
2964 str = OPENSSL_malloc(i);
2965
2966 if (!str) return NULL;
2967
2968 strcpy(str, (char *)revtm->data);
2969 if (reason)
2970 {
2971 strcat(str, ",");
2972 strcat(str, reason);
2973 }
2974 if (other)
2975 {
2976 strcat(str, ",");
2977 strcat(str, other);
2978 }
2979 ASN1_UTCTIME_free(revtm);
2980 return str;
2981 }
2982
2983/* Convert revocation field to X509_REVOKED entry
2984 * return code:
2985 * 0 error
2986 * 1 OK
2987 * 2 OK and some extensions added (i.e. V2 CRL)
2988 */
2989
2990
2991int make_revoked(X509_REVOKED *rev, char *str)
2992 {
2993 char *tmp = NULL;
2994 int reason_code = -1;
2995 int i, ret = 0;
2996 ASN1_OBJECT *hold = NULL;
2997 ASN1_GENERALIZEDTIME *comp_time = NULL;
2998 ASN1_ENUMERATED *rtmp = NULL;
2999
3000 ASN1_TIME *revDate = NULL;
3001
3002 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
3003
3004 if (i == 0)
3005 goto err;
3006
3007 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
3008 goto err;
3009
3010 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3011 {
3012 rtmp = ASN1_ENUMERATED_new();
3013 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3014 goto err;
3015 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3016 goto err;
3017 }
3018
3019 if (rev && comp_time)
3020 {
3021 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3022 goto err;
3023 }
3024 if (rev && hold)
3025 {
3026 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3027 goto err;
3028 }
3029
3030 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3031 ret = 2;
3032 else ret = 1;
3033
3034 err:
3035
3036 if (tmp) OPENSSL_free(tmp);
3037 ASN1_OBJECT_free(hold);
3038 ASN1_GENERALIZEDTIME_free(comp_time);
3039 ASN1_ENUMERATED_free(rtmp);
3040 ASN1_TIME_free(revDate);
3041
3042 return ret;
3043 }
3044
3045/*
3046 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
3047 * where characters may be escaped by \
3048 */
3049X509_NAME *do_subject(char *subject, long chtype)
3050 {
3051 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
3052 char *buf = OPENSSL_malloc(buflen);
3053 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
3054 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
3055 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
3056
3057 char *sp = subject, *bp = buf;
3058 int i, ne_num = 0;
3059
3060 X509_NAME *n = NULL;
3061 int nid;
3062
3063 if (!buf || !ne_types || !ne_values)
3064 {
3065 BIO_printf(bio_err, "malloc error\n");
3066 goto error;
3067 }
3068
3069 if (*subject != '/')
3070 {
3071 BIO_printf(bio_err, "Subject does not start with '/'.\n");
3072 goto error;
3073 }
3074 sp++; /* skip leading / */
3075
3076 while (*sp)
3077 {
3078 /* collect type */
3079 ne_types[ne_num] = bp;
3080 while (*sp)
3081 {
3082 if (*sp == '\\') /* is there anything to escape in the type...? */
3083 {
3084 if (*++sp)
3085 *bp++ = *sp++;
3086 else
3087 {
3088 BIO_printf(bio_err, "escape character at end of string\n");
3089 goto error;
3090 }
3091 }
3092 else if (*sp == '=')
3093 {
3094 sp++;
3095 *bp++ = '\0';
3096 break;
3097 }
3098 else
3099 *bp++ = *sp++;
3100 }
3101 if (!*sp)
3102 {
3103 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
3104 goto error;
3105 }
3106 ne_values[ne_num] = bp;
3107 while (*sp)
3108 {
3109 if (*sp == '\\')
3110 {
3111 if (*++sp)
3112 *bp++ = *sp++;
3113 else
3114 {
3115 BIO_printf(bio_err, "escape character at end of string\n");
3116 goto error;
3117 }
3118 }
3119 else if (*sp == '/')
3120 {
3121 sp++;
3122 break;
3123 }
3124 else
3125 *bp++ = *sp++;
3126 }
3127 *bp++ = '\0';
3128 ne_num++;
3129 }
3130
3131 if (!(n = X509_NAME_new()))
3132 goto error;
3133
3134 for (i = 0; i < ne_num; i++)
3135 {
3136 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
3137 {
3138 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
3139 continue;
3140 }
3141
3142 if (!*ne_values[i])
3143 {
3144 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
3145 continue;
3146 }
3147
3148 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
3149 goto error;
3150 }
3151
3152 OPENSSL_free(ne_values);
3153 OPENSSL_free(ne_types);
3154 OPENSSL_free(buf);
3155 return n;
3156
3157error:
3158 X509_NAME_free(n);
3159 if (ne_values)
3160 OPENSSL_free(ne_values);
3161 if (ne_types)
3162 OPENSSL_free(ne_types);
3163 if (buf)
3164 OPENSSL_free(buf);
3165 return NULL;
3166}
3167
3168int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3169 {
3170 char buf[25],*pbuf, *p;
3171 int j;
3172 j=i2a_ASN1_OBJECT(bp,obj);
3173 pbuf=buf;
3174 for (j=22-j; j>0; j--)
3175 *(pbuf++)=' ';
3176 *(pbuf++)=':';
3177 *(pbuf++)='\0';
3178 BIO_puts(bp,buf);
3179
3180 if (str->type == V_ASN1_PRINTABLESTRING)
3181 BIO_printf(bp,"PRINTABLE:'");
3182 else if (str->type == V_ASN1_T61STRING)
3183 BIO_printf(bp,"T61STRING:'");
3184 else if (str->type == V_ASN1_IA5STRING)
3185 BIO_printf(bp,"IA5STRING:'");
3186 else if (str->type == V_ASN1_UNIVERSALSTRING)
3187 BIO_printf(bp,"UNIVERSALSTRING:'");
3188 else
3189 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3190
3191 p=(char *)str->data;
3192 for (j=str->length; j>0; j--)
3193 {
3194 if ((*p >= ' ') && (*p <= '~'))
3195 BIO_printf(bp,"%c",*p);
3196 else if (*p & 0x80)
3197 BIO_printf(bp,"\\0x%02X",*p);
3198 else if ((unsigned char)*p == 0xf7)
3199 BIO_printf(bp,"^?");
3200 else BIO_printf(bp,"^%c",*p+'@');
3201 p++;
3202 }
3203 BIO_printf(bp,"'\n");
3204 return 1;
3205 }
3206
3207int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3208 {
3209 char *tmp = NULL;
3210 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3211 int reason_code = -1;
3212 int i, ret = 0;
3213 ASN1_OBJECT *hold = NULL;
3214 ASN1_GENERALIZEDTIME *comp_time = NULL;
3215 tmp = BUF_strdup(str);
3216
3217 p = strchr(tmp, ',');
3218
3219 rtime_str = tmp;
3220
3221 if (p)
3222 {
3223 *p = '\0';
3224 p++;
3225 reason_str = p;
3226 p = strchr(p, ',');
3227 if (p)
3228 {
3229 *p = '\0';
3230 arg_str = p + 1;
3231 }
3232 }
3233
3234 if (prevtm)
3235 {
3236 *prevtm = ASN1_UTCTIME_new();
3237 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3238 {
3239 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3240 goto err;
3241 }
3242 }
3243 if (reason_str)
3244 {
3245 for (i = 0; i < NUM_REASONS; i++)
3246 {
3247 if(!strcasecmp(reason_str, crl_reasons[i]))
3248 {
3249 reason_code = i;
3250 break;
3251 }
3252 }
3253 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3254 {
3255 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3256 goto err;
3257 }
3258
3259 if (reason_code == 7)
3260 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3261 else if (reason_code == 8) /* Hold instruction */
3262 {
3263 if (!arg_str)
3264 {
3265 BIO_printf(bio_err, "missing hold instruction\n");
3266 goto err;
3267 }
3268 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3269 hold = OBJ_txt2obj(arg_str, 0);
3270
3271 if (!hold)
3272 {
3273 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3274 goto err;
3275 }
3276 if (phold) *phold = hold;
3277 }
3278 else if ((reason_code == 9) || (reason_code == 10))
3279 {
3280 if (!arg_str)
3281 {
3282 BIO_printf(bio_err, "missing compromised time\n");
3283 goto err;
3284 }
3285 comp_time = ASN1_GENERALIZEDTIME_new();
3286 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3287 {
3288 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3289 goto err;
3290 }
3291 if (reason_code == 9)
3292 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3293 else
3294 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3295 }
3296 }
3297
3298 if (preason) *preason = reason_code;
3299 if (pinvtm) *pinvtm = comp_time;
3300 else ASN1_GENERALIZEDTIME_free(comp_time);
3301
3302 ret = 1;
3303
3304 err:
3305
3306 if (tmp) OPENSSL_free(tmp);
3307 if (!phold) ASN1_OBJECT_free(hold);
3308 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3309
3310 return ret;
3311 }
3312
3313int make_serial_index(TXT_DB *db)
3314 {
3315 if (!TXT_DB_create_index(db, DB_serial, NULL,
3316 LHASH_HASH_FN(index_serial_hash),
3317 LHASH_COMP_FN(index_serial_cmp)))
3318 {
3319 BIO_printf(bio_err,
3320 "error creating serial number index:(%ld,%ld,%ld)\n",
3321 db->error,db->arg1,db->arg2);
3322 return 0;
3323 }
3324 return 1;
3325 }
1653 OPENSSL_free(key);
1654 BN_free(serial);
1655 TXT_DB_free(db);
1656 EVP_PKEY_free(pkey);
1657 X509_free(x509);
1658 X509_CRL_free(crl);
1659 NCONF_free(conf);
1660 OBJ_cleanup();
1661 apps_shutdown();
1662 OPENSSL_EXIT(ret);
1663 }
1664
1665static void lookup_fail(char *name, char *tag)
1666 {
1667 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1668 }
1669
1670static unsigned long index_serial_hash(const char **a)
1671 {
1672 const char *n;
1673
1674 n=a[DB_serial];
1675 while (*n == '0') n++;
1676 return(lh_strhash(n));
1677 }
1678
1679static int index_serial_cmp(const char **a, const char **b)
1680 {
1681 const char *aa,*bb;
1682
1683 for (aa=a[DB_serial]; *aa == '0'; aa++);
1684 for (bb=b[DB_serial]; *bb == '0'; bb++);
1685 return(strcmp(aa,bb));
1686 }
1687
1688static unsigned long index_name_hash(const char **a)
1689 { return(lh_strhash(a[DB_name])); }
1690
1691static int index_name_qual(char **a)
1692 { return(a[0][0] == 'V'); }
1693
1694static int index_name_cmp(const char **a, const char **b)
1695 { return(strcmp(a[DB_name],
1696 b[DB_name])); }
1697
1698static BIGNUM *load_serial(char *serialfile)
1699 {
1700 BIO *in=NULL;
1701 BIGNUM *ret=NULL;
1702 MS_STATIC char buf[1024];
1703 ASN1_INTEGER *ai=NULL;
1704
1705 if ((in=BIO_new(BIO_s_file())) == NULL)
1706 {
1707 ERR_print_errors(bio_err);
1708 goto err;
1709 }
1710
1711 if (BIO_read_filename(in,serialfile) <= 0)
1712 {
1713 perror(serialfile);
1714 goto err;
1715 }
1716 ai=ASN1_INTEGER_new();
1717 if (ai == NULL) goto err;
1718 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
1719 {
1720 BIO_printf(bio_err,"unable to load number from %s\n",
1721 serialfile);
1722 goto err;
1723 }
1724 ret=ASN1_INTEGER_to_BN(ai,NULL);
1725 if (ret == NULL)
1726 {
1727 BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
1728 goto err;
1729 }
1730err:
1731 if (in != NULL) BIO_free(in);
1732 if (ai != NULL) ASN1_INTEGER_free(ai);
1733 return(ret);
1734 }
1735
1736static int save_serial(char *serialfile, BIGNUM *serial)
1737 {
1738 BIO *out;
1739 int ret=0;
1740 ASN1_INTEGER *ai=NULL;
1741
1742 out=BIO_new(BIO_s_file());
1743 if (out == NULL)
1744 {
1745 ERR_print_errors(bio_err);
1746 goto err;
1747 }
1748 if (BIO_write_filename(out,serialfile) <= 0)
1749 {
1750 perror(serialfile);
1751 goto err;
1752 }
1753
1754 if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
1755 {
1756 BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
1757 goto err;
1758 }
1759 i2a_ASN1_INTEGER(out,ai);
1760 BIO_puts(out,"\n");
1761 ret=1;
1762err:
1763 if (out != NULL) BIO_free_all(out);
1764 if (ai != NULL) ASN1_INTEGER_free(ai);
1765 return(ret);
1766 }
1767
1768static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1769 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1770 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1771 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1772 unsigned long certopt, unsigned long nameopt, int default_op,
1773 int ext_copy)
1774 {
1775 X509_REQ *req=NULL;
1776 BIO *in=NULL;
1777 EVP_PKEY *pktmp=NULL;
1778 int ok= -1,i;
1779
1780 in=BIO_new(BIO_s_file());
1781
1782 if (BIO_read_filename(in,infile) <= 0)
1783 {
1784 perror(infile);
1785 goto err;
1786 }
1787 if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
1788 {
1789 BIO_printf(bio_err,"Error reading certificate request in %s\n",
1790 infile);
1791 goto err;
1792 }
1793 if (verbose)
1794 X509_REQ_print(bio_err,req);
1795
1796 BIO_printf(bio_err,"Check that the request matches the signature\n");
1797
1798 if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1799 {
1800 BIO_printf(bio_err,"error unpacking public key\n");
1801 goto err;
1802 }
1803 i=X509_REQ_verify(req,pktmp);
1804 EVP_PKEY_free(pktmp);
1805 if (i < 0)
1806 {
1807 ok=0;
1808 BIO_printf(bio_err,"Signature verification problems....\n");
1809 goto err;
1810 }
1811 if (i == 0)
1812 {
1813 ok=0;
1814 BIO_printf(bio_err,"Signature did not match the certificate request\n");
1815 goto err;
1816 }
1817 else
1818 BIO_printf(bio_err,"Signature ok\n");
1819
1820 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
1821 startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1822 certopt, nameopt, default_op, ext_copy);
1823
1824err:
1825 if (req != NULL) X509_REQ_free(req);
1826 if (in != NULL) BIO_free(in);
1827 return(ok);
1828 }
1829
1830static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1831 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
1832 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
1833 long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1834 unsigned long certopt, unsigned long nameopt, int default_op,
1835 int ext_copy, ENGINE *e)
1836 {
1837 X509 *req=NULL;
1838 X509_REQ *rreq=NULL;
1839 EVP_PKEY *pktmp=NULL;
1840 int ok= -1,i;
1841
1842 if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
1843 goto err;
1844 if (verbose)
1845 X509_print(bio_err,req);
1846
1847 BIO_printf(bio_err,"Check that the request matches the signature\n");
1848
1849 if ((pktmp=X509_get_pubkey(req)) == NULL)
1850 {
1851 BIO_printf(bio_err,"error unpacking public key\n");
1852 goto err;
1853 }
1854 i=X509_verify(req,pktmp);
1855 EVP_PKEY_free(pktmp);
1856 if (i < 0)
1857 {
1858 ok=0;
1859 BIO_printf(bio_err,"Signature verification problems....\n");
1860 goto err;
1861 }
1862 if (i == 0)
1863 {
1864 ok=0;
1865 BIO_printf(bio_err,"Signature did not match the certificate\n");
1866 goto err;
1867 }
1868 else
1869 BIO_printf(bio_err,"Signature ok\n");
1870
1871 if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1872 goto err;
1873
1874 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
1875 days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1876 ext_copy);
1877
1878err:
1879 if (rreq != NULL) X509_REQ_free(rreq);
1880 if (req != NULL) X509_free(req);
1881 return(ok);
1882 }
1883
1884static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1885 STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj,
1886 int email_dn, char *startdate, char *enddate, long days, int batch,
1887 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1888 unsigned long certopt, unsigned long nameopt, int default_op,
1889 int ext_copy)
1890 {
1891 X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1892 ASN1_UTCTIME *tm,*tmptm;
1893 ASN1_STRING *str,*str2;
1894 ASN1_OBJECT *obj;
1895 X509 *ret=NULL;
1896 X509_CINF *ci;
1897 X509_NAME_ENTRY *ne;
1898 X509_NAME_ENTRY *tne,*push;
1899 EVP_PKEY *pktmp;
1900 int ok= -1,i,j,last,nid;
1901 char *p;
1902 CONF_VALUE *cv;
1903 char *row[DB_NUMBER],**rrow,**irow=NULL;
1904 char buf[25];
1905
1906 tmptm=ASN1_UTCTIME_new();
1907 if (tmptm == NULL)
1908 {
1909 BIO_printf(bio_err,"malloc error\n");
1910 return(0);
1911 }
1912
1913 for (i=0; i<DB_NUMBER; i++)
1914 row[i]=NULL;
1915
1916 if (subj)
1917 {
1918 X509_NAME *n = do_subject(subj, MBSTRING_ASC);
1919
1920 if (!n)
1921 {
1922 ERR_print_errors(bio_err);
1923 goto err;
1924 }
1925 X509_REQ_set_subject_name(req,n);
1926 req->req_info->enc.modified = 1;
1927 X509_NAME_free(n);
1928 }
1929
1930 if (default_op)
1931 BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
1932
1933 name=X509_REQ_get_subject_name(req);
1934 for (i=0; i<X509_NAME_entry_count(name); i++)
1935 {
1936 ne= X509_NAME_get_entry(name,i);
1937 str=X509_NAME_ENTRY_get_data(ne);
1938 obj=X509_NAME_ENTRY_get_object(ne);
1939
1940 if (msie_hack)
1941 {
1942 /* assume all type should be strings */
1943 nid=OBJ_obj2nid(ne->object);
1944
1945 if (str->type == V_ASN1_UNIVERSALSTRING)
1946 ASN1_UNIVERSALSTRING_to_string(str);
1947
1948 if ((str->type == V_ASN1_IA5STRING) &&
1949 (nid != NID_pkcs9_emailAddress))
1950 str->type=V_ASN1_T61STRING;
1951
1952 if ((nid == NID_pkcs9_emailAddress) &&
1953 (str->type == V_ASN1_PRINTABLESTRING))
1954 str->type=V_ASN1_IA5STRING;
1955 }
1956
1957 /* If no EMAIL is wanted in the subject */
1958 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1959 continue;
1960
1961 /* check some things */
1962 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1963 (str->type != V_ASN1_IA5STRING))
1964 {
1965 BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
1966 goto err;
1967 }
1968 if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
1969 {
1970 j=ASN1_PRINTABLE_type(str->data,str->length);
1971 if ( ((j == V_ASN1_T61STRING) &&
1972 (str->type != V_ASN1_T61STRING)) ||
1973 ((j == V_ASN1_IA5STRING) &&
1974 (str->type == V_ASN1_PRINTABLESTRING)))
1975 {
1976 BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
1977 goto err;
1978 }
1979 }
1980
1981 if (default_op)
1982 old_entry_print(bio_err, obj, str);
1983 }
1984
1985 /* Ok, now we check the 'policy' stuff. */
1986 if ((subject=X509_NAME_new()) == NULL)
1987 {
1988 BIO_printf(bio_err,"Memory allocation failure\n");
1989 goto err;
1990 }
1991
1992 /* take a copy of the issuer name before we mess with it. */
1993 CAname=X509_NAME_dup(x509->cert_info->subject);
1994 if (CAname == NULL) goto err;
1995 str=str2=NULL;
1996
1997 for (i=0; i<sk_CONF_VALUE_num(policy); i++)
1998 {
1999 cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
2000 if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
2001 {
2002 BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
2003 goto err;
2004 }
2005 obj=OBJ_nid2obj(j);
2006
2007 last= -1;
2008 for (;;)
2009 {
2010 /* lookup the object in the supplied name list */
2011 j=X509_NAME_get_index_by_OBJ(name,obj,last);
2012 if (j < 0)
2013 {
2014 if (last != -1) break;
2015 tne=NULL;
2016 }
2017 else
2018 {
2019 tne=X509_NAME_get_entry(name,j);
2020 }
2021 last=j;
2022
2023 /* depending on the 'policy', decide what to do. */
2024 push=NULL;
2025 if (strcmp(cv->value,"optional") == 0)
2026 {
2027 if (tne != NULL)
2028 push=tne;
2029 }
2030 else if (strcmp(cv->value,"supplied") == 0)
2031 {
2032 if (tne == NULL)
2033 {
2034 BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
2035 goto err;
2036 }
2037 else
2038 push=tne;
2039 }
2040 else if (strcmp(cv->value,"match") == 0)
2041 {
2042 int last2;
2043
2044 if (tne == NULL)
2045 {
2046 BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
2047 goto err;
2048 }
2049
2050 last2= -1;
2051
2052again2:
2053 j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
2054 if ((j < 0) && (last2 == -1))
2055 {
2056 BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
2057 goto err;
2058 }
2059 if (j >= 0)
2060 {
2061 push=X509_NAME_get_entry(CAname,j);
2062 str=X509_NAME_ENTRY_get_data(tne);
2063 str2=X509_NAME_ENTRY_get_data(push);
2064 last2=j;
2065 if (ASN1_STRING_cmp(str,str2) != 0)
2066 goto again2;
2067 }
2068 if (j < 0)
2069 {
2070 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));
2071 goto err;
2072 }
2073 }
2074 else
2075 {
2076 BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
2077 goto err;
2078 }
2079
2080 if (push != NULL)
2081 {
2082 if (!X509_NAME_add_entry(subject,push, -1, 0))
2083 {
2084 if (push != NULL)
2085 X509_NAME_ENTRY_free(push);
2086 BIO_printf(bio_err,"Memory allocation failure\n");
2087 goto err;
2088 }
2089 }
2090 if (j < 0) break;
2091 }
2092 }
2093
2094 if (preserve)
2095 {
2096 X509_NAME_free(subject);
2097 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
2098 subject=X509_NAME_dup(name);
2099 if (subject == NULL) goto err;
2100 }
2101
2102 if (verbose)
2103 BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
2104
2105 /* Build the correct Subject if no e-mail is wanted in the subject */
2106 /* and add it later on because of the method extensions are added (altName) */
2107
2108 if (email_dn)
2109 dn_subject = subject;
2110 else
2111 {
2112 X509_NAME_ENTRY *tmpne;
2113 /* Its best to dup the subject DN and then delete any email
2114 * addresses because this retains its structure.
2115 */
2116 if (!(dn_subject = X509_NAME_dup(subject)))
2117 {
2118 BIO_printf(bio_err,"Memory allocation failure\n");
2119 goto err;
2120 }
2121 while((i = X509_NAME_get_index_by_NID(dn_subject,
2122 NID_pkcs9_emailAddress, -1)) >= 0)
2123 {
2124 tmpne = X509_NAME_get_entry(dn_subject, i);
2125 X509_NAME_delete_entry(dn_subject, i);
2126 X509_NAME_ENTRY_free(tmpne);
2127 }
2128 }
2129
2130 if (BN_is_zero(serial))
2131 row[DB_serial]=BUF_strdup("00");
2132 else
2133 row[DB_serial]=BN_bn2hex(serial);
2134 if (row[DB_serial] == NULL)
2135 {
2136 BIO_printf(bio_err,"Memory allocation failure\n");
2137 goto err;
2138 }
2139
2140 rrow=TXT_DB_get_by_index(db,DB_name,row);
2141 if (rrow != NULL)
2142 {
2143 BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n",
2144 row[DB_name]);
2145 }
2146 else
2147 {
2148 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2149 if (rrow != NULL)
2150 {
2151 BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
2152 row[DB_serial]);
2153 BIO_printf(bio_err," check the database/serial_file for corruption\n");
2154 }
2155 }
2156
2157 if (rrow != NULL)
2158 {
2159 BIO_printf(bio_err,
2160 "The matching entry has the following details\n");
2161 if (rrow[DB_type][0] == 'E')
2162 p="Expired";
2163 else if (rrow[DB_type][0] == 'R')
2164 p="Revoked";
2165 else if (rrow[DB_type][0] == 'V')
2166 p="Valid";
2167 else
2168 p="\ninvalid type, Data base error\n";
2169 BIO_printf(bio_err,"Type :%s\n",p);;
2170 if (rrow[DB_type][0] == 'R')
2171 {
2172 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2173 BIO_printf(bio_err,"Was revoked on:%s\n",p);
2174 }
2175 p=rrow[DB_exp_date]; if (p == NULL) p="undef";
2176 BIO_printf(bio_err,"Expires on :%s\n",p);
2177 p=rrow[DB_serial]; if (p == NULL) p="undef";
2178 BIO_printf(bio_err,"Serial Number :%s\n",p);
2179 p=rrow[DB_file]; if (p == NULL) p="undef";
2180 BIO_printf(bio_err,"File name :%s\n",p);
2181 p=rrow[DB_name]; if (p == NULL) p="undef";
2182 BIO_printf(bio_err,"Subject Name :%s\n",p);
2183 ok= -1; /* This is now a 'bad' error. */
2184 goto err;
2185 }
2186
2187 /* We are now totally happy, lets make and sign the certificate */
2188 if (verbose)
2189 BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
2190
2191 if ((ret=X509_new()) == NULL) goto err;
2192 ci=ret->cert_info;
2193
2194#ifdef X509_V3
2195 /* Make it an X509 v3 certificate. */
2196 if (!X509_set_version(x509,2)) goto err;
2197#endif
2198
2199 if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
2200 goto err;
2201 if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
2202 goto err;
2203
2204 if (strcmp(startdate,"today") == 0)
2205 X509_gmtime_adj(X509_get_notBefore(ret),0);
2206 else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
2207
2208 if (enddate == NULL)
2209 X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
2210 else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
2211
2212 if (!X509_set_subject_name(ret,subject)) goto err;
2213
2214 pktmp=X509_REQ_get_pubkey(req);
2215 i = X509_set_pubkey(ret,pktmp);
2216 EVP_PKEY_free(pktmp);
2217 if (!i) goto err;
2218
2219 /* Lets add the extensions, if there are any */
2220 if (ext_sect)
2221 {
2222 X509V3_CTX ctx;
2223 if (ci->version == NULL)
2224 if ((ci->version=ASN1_INTEGER_new()) == NULL)
2225 goto err;
2226 ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */
2227
2228 /* Free the current entries if any, there should not
2229 * be any I believe */
2230 if (ci->extensions != NULL)
2231 sk_X509_EXTENSION_pop_free(ci->extensions,
2232 X509_EXTENSION_free);
2233
2234 ci->extensions = NULL;
2235
2236 /* Initialize the context structure */
2237 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
2238
2239 if (extconf)
2240 {
2241 if (verbose)
2242 BIO_printf(bio_err, "Extra configuration file found\n");
2243
2244 /* Use the extconf configuration db LHASH */
2245 X509V3_set_nconf(&ctx, extconf);
2246
2247 /* Test the structure (needed?) */
2248 /* X509V3_set_ctx_test(&ctx); */
2249
2250 /* Adds exts contained in the configuration file */
2251 if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret))
2252 {
2253 BIO_printf(bio_err,
2254 "ERROR: adding extensions in section %s\n",
2255 ext_sect);
2256 ERR_print_errors(bio_err);
2257 goto err;
2258 }
2259 if (verbose)
2260 BIO_printf(bio_err, "Successfully added extensions from file.\n");
2261 }
2262 else if (ext_sect)
2263 {
2264 /* We found extensions to be set from config file */
2265 X509V3_set_nconf(&ctx, lconf);
2266
2267 if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret))
2268 {
2269 BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect);
2270 ERR_print_errors(bio_err);
2271 goto err;
2272 }
2273
2274 if (verbose)
2275 BIO_printf(bio_err, "Successfully added extensions from config\n");
2276 }
2277 }
2278
2279 /* Copy extensions from request (if any) */
2280
2281 if (!copy_extensions(ret, req, ext_copy))
2282 {
2283 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
2284 ERR_print_errors(bio_err);
2285 goto err;
2286 }
2287
2288 /* Set the right value for the noemailDN option */
2289 if( email_dn == 0 )
2290 {
2291 if (!X509_set_subject_name(ret,dn_subject)) goto err;
2292 }
2293
2294 if (!default_op)
2295 {
2296 BIO_printf(bio_err, "Certificate Details:\n");
2297 /* Never print signature details because signature not present */
2298 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2299 X509_print_ex(bio_err, ret, nameopt, certopt);
2300 }
2301
2302 BIO_printf(bio_err,"Certificate is to be certified until ");
2303 ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2304 if (days) BIO_printf(bio_err," (%d days)",days);
2305 BIO_printf(bio_err, "\n");
2306
2307 if (!batch)
2308 {
2309
2310 BIO_printf(bio_err,"Sign the certificate? [y/n]:");
2311 (void)BIO_flush(bio_err);
2312 buf[0]='\0';
2313 fgets(buf,sizeof(buf)-1,stdin);
2314 if (!((buf[0] == 'y') || (buf[0] == 'Y')))
2315 {
2316 BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n");
2317 ok=0;
2318 goto err;
2319 }
2320 }
2321
2322
2323#ifndef OPENSSL_NO_DSA
2324 if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
2325 pktmp=X509_get_pubkey(ret);
2326 if (EVP_PKEY_missing_parameters(pktmp) &&
2327 !EVP_PKEY_missing_parameters(pkey))
2328 EVP_PKEY_copy_parameters(pktmp,pkey);
2329 EVP_PKEY_free(pktmp);
2330#endif
2331
2332 if (!X509_sign(ret,pkey,dgst))
2333 goto err;
2334
2335 /* We now just add it to the database */
2336 row[DB_type]=(char *)OPENSSL_malloc(2);
2337
2338 tm=X509_get_notAfter(ret);
2339 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2340 memcpy(row[DB_exp_date],tm->data,tm->length);
2341 row[DB_exp_date][tm->length]='\0';
2342
2343 row[DB_rev_date]=NULL;
2344
2345 /* row[DB_serial] done already */
2346 row[DB_file]=(char *)OPENSSL_malloc(8);
2347 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0);
2348
2349 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2350 (row[DB_file] == NULL) || (row[DB_name] == NULL))
2351 {
2352 BIO_printf(bio_err,"Memory allocation failure\n");
2353 goto err;
2354 }
2355 strcpy(row[DB_file],"unknown");
2356 row[DB_type][0]='V';
2357 row[DB_type][1]='\0';
2358
2359 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2360 {
2361 BIO_printf(bio_err,"Memory allocation failure\n");
2362 goto err;
2363 }
2364
2365 for (i=0; i<DB_NUMBER; i++)
2366 {
2367 irow[i]=row[i];
2368 row[i]=NULL;
2369 }
2370 irow[DB_NUMBER]=NULL;
2371
2372 if (!TXT_DB_insert(db,irow))
2373 {
2374 BIO_printf(bio_err,"failed to update database\n");
2375 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2376 goto err;
2377 }
2378 ok=1;
2379err:
2380 for (i=0; i<DB_NUMBER; i++)
2381 if (row[i] != NULL) OPENSSL_free(row[i]);
2382
2383 if (CAname != NULL)
2384 X509_NAME_free(CAname);
2385 if (subject != NULL)
2386 X509_NAME_free(subject);
2387 if ((dn_subject != NULL) && !email_dn)
2388 X509_NAME_free(dn_subject);
2389 if (tmptm != NULL)
2390 ASN1_UTCTIME_free(tmptm);
2391 if (ok <= 0)
2392 {
2393 if (ret != NULL) X509_free(ret);
2394 ret=NULL;
2395 }
2396 else
2397 *xret=ret;
2398 return(ok);
2399 }
2400
2401static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2402 {
2403
2404 if (output_der)
2405 {
2406 (void)i2d_X509_bio(bp,x);
2407 return;
2408 }
2409#if 0
2410 /* ??? Not needed since X509_print prints all this stuff anyway */
2411 f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256);
2412 BIO_printf(bp,"issuer :%s\n",f);
2413
2414 f=X509_NAME_oneline(X509_get_subject_name(x),buf,256);
2415 BIO_printf(bp,"subject:%s\n",f);
2416
2417 BIO_puts(bp,"serial :");
2418 i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber);
2419 BIO_puts(bp,"\n\n");
2420#endif
2421 if (!notext)X509_print(bp,x);
2422 PEM_write_bio_X509(bp,x);
2423 }
2424
2425static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2426 const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db,
2427 BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
2428 long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2429 unsigned long nameopt, int default_op, int ext_copy)
2430 {
2431 STACK_OF(CONF_VALUE) *sk=NULL;
2432 LHASH *parms=NULL;
2433 X509_REQ *req=NULL;
2434 CONF_VALUE *cv=NULL;
2435 NETSCAPE_SPKI *spki = NULL;
2436 X509_REQ_INFO *ri;
2437 char *type,*buf;
2438 EVP_PKEY *pktmp=NULL;
2439 X509_NAME *n=NULL;
2440 X509_NAME_ENTRY *ne=NULL;
2441 int ok= -1,i,j;
2442 long errline;
2443 int nid;
2444
2445 /*
2446 * Load input file into a hash table. (This is just an easy
2447 * way to read and parse the file, then put it into a convenient
2448 * STACK format).
2449 */
2450 parms=CONF_load(NULL,infile,&errline);
2451 if (parms == NULL)
2452 {
2453 BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile);
2454 ERR_print_errors(bio_err);
2455 goto err;
2456 }
2457
2458 sk=CONF_get_section(parms, "default");
2459 if (sk_CONF_VALUE_num(sk) == 0)
2460 {
2461 BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2462 CONF_free(parms);
2463 goto err;
2464 }
2465
2466 /*
2467 * Now create a dummy X509 request structure. We don't actually
2468 * have an X509 request, but we have many of the components
2469 * (a public key, various DN components). The idea is that we
2470 * put these components into the right X509 request structure
2471 * and we can use the same code as if you had a real X509 request.
2472 */
2473 req=X509_REQ_new();
2474 if (req == NULL)
2475 {
2476 ERR_print_errors(bio_err);
2477 goto err;
2478 }
2479
2480 /*
2481 * Build up the subject name set.
2482 */
2483 ri=req->req_info;
2484 n = ri->subject;
2485
2486 for (i = 0; ; i++)
2487 {
2488 if (sk_CONF_VALUE_num(sk) <= i) break;
2489
2490 cv=sk_CONF_VALUE_value(sk,i);
2491 type=cv->name;
2492 /* Skip past any leading X. X: X, etc to allow for
2493 * multiple instances
2494 */
2495 for (buf = cv->name; *buf ; buf++)
2496 if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
2497 {
2498 buf++;
2499 if (*buf) type = buf;
2500 break;
2501 }
2502
2503 buf=cv->value;
2504 if ((nid=OBJ_txt2nid(type)) == NID_undef)
2505 {
2506 if (strcmp(type, "SPKAC") == 0)
2507 {
2508 spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2509 if (spki == NULL)
2510 {
2511 BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n");
2512 ERR_print_errors(bio_err);
2513 goto err;
2514 }
2515 }
2516 continue;
2517 }
2518
2519 /*
2520 if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0))
2521 continue;
2522 */
2523
2524 j=ASN1_PRINTABLE_type((unsigned char *)buf,-1);
2525 if (fix_data(nid, &j) == 0)
2526 {
2527 BIO_printf(bio_err,
2528 "invalid characters in string %s\n",buf);
2529 goto err;
2530 }
2531
2532 if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j,
2533 (unsigned char *)buf,
2534 strlen(buf))) == NULL)
2535 goto err;
2536
2537 if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err;
2538 }
2539 if (spki == NULL)
2540 {
2541 BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n",
2542 infile);
2543 goto err;
2544 }
2545
2546 /*
2547 * Now extract the key from the SPKI structure.
2548 */
2549
2550 BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n");
2551
2552 if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
2553 {
2554 BIO_printf(bio_err,"error unpacking SPKAC public key\n");
2555 goto err;
2556 }
2557
2558 j = NETSCAPE_SPKI_verify(spki, pktmp);
2559 if (j <= 0)
2560 {
2561 BIO_printf(bio_err,"signature verification failed on SPKAC public key\n");
2562 goto err;
2563 }
2564 BIO_printf(bio_err,"Signature ok\n");
2565
2566 X509_REQ_set_pubkey(req,pktmp);
2567 EVP_PKEY_free(pktmp);
2568 ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
2569 days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2570 ext_copy);
2571err:
2572 if (req != NULL) X509_REQ_free(req);
2573 if (parms != NULL) CONF_free(parms);
2574 if (spki != NULL) NETSCAPE_SPKI_free(spki);
2575 if (ne != NULL) X509_NAME_ENTRY_free(ne);
2576
2577 return(ok);
2578 }
2579
2580static int fix_data(int nid, int *type)
2581 {
2582 if (nid == NID_pkcs9_emailAddress)
2583 *type=V_ASN1_IA5STRING;
2584 if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING))
2585 *type=V_ASN1_T61STRING;
2586 if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING))
2587 *type=V_ASN1_T61STRING;
2588 if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING))
2589 return(0);
2590 if (nid == NID_pkcs9_unstructuredName)
2591 *type=V_ASN1_IA5STRING;
2592 return(1);
2593 }
2594
2595static int check_time_format(char *str)
2596 {
2597 ASN1_UTCTIME tm;
2598
2599 tm.data=(unsigned char *)str;
2600 tm.length=strlen(str);
2601 tm.type=V_ASN1_UTCTIME;
2602 return(ASN1_UTCTIME_check(&tm));
2603 }
2604
2605static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
2606 {
2607 ASN1_UTCTIME *tm=NULL;
2608 char *row[DB_NUMBER],**rrow,**irow;
2609 char *rev_str = NULL;
2610 BIGNUM *bn = NULL;
2611 int ok=-1,i;
2612
2613 for (i=0; i<DB_NUMBER; i++)
2614 row[i]=NULL;
2615 row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
2616 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
2617 if (BN_is_zero(bn))
2618 row[DB_serial]=BUF_strdup("00");
2619 else
2620 row[DB_serial]=BN_bn2hex(bn);
2621 BN_free(bn);
2622 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
2623 {
2624 BIO_printf(bio_err,"Memory allocation failure\n");
2625 goto err;
2626 }
2627 /* We have to lookup by serial number because name lookup
2628 * skips revoked certs
2629 */
2630 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2631 if (rrow == NULL)
2632 {
2633 BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]);
2634
2635 /* We now just add it to the database */
2636 row[DB_type]=(char *)OPENSSL_malloc(2);
2637
2638 tm=X509_get_notAfter(x509);
2639 row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1);
2640 memcpy(row[DB_exp_date],tm->data,tm->length);
2641 row[DB_exp_date][tm->length]='\0';
2642
2643 row[DB_rev_date]=NULL;
2644
2645 /* row[DB_serial] done already */
2646 row[DB_file]=(char *)OPENSSL_malloc(8);
2647
2648 /* row[DB_name] done already */
2649
2650 if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
2651 (row[DB_file] == NULL))
2652 {
2653 BIO_printf(bio_err,"Memory allocation failure\n");
2654 goto err;
2655 }
2656 strcpy(row[DB_file],"unknown");
2657 row[DB_type][0]='V';
2658 row[DB_type][1]='\0';
2659
2660 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
2661 {
2662 BIO_printf(bio_err,"Memory allocation failure\n");
2663 goto err;
2664 }
2665
2666 for (i=0; i<DB_NUMBER; i++)
2667 {
2668 irow[i]=row[i];
2669 row[i]=NULL;
2670 }
2671 irow[DB_NUMBER]=NULL;
2672
2673 if (!TXT_DB_insert(db,irow))
2674 {
2675 BIO_printf(bio_err,"failed to update database\n");
2676 BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error);
2677 goto err;
2678 }
2679
2680 /* Revoke Certificate */
2681 ok = do_revoke(x509,db, type, value);
2682
2683 goto err;
2684
2685 }
2686 else if (index_name_cmp((const char **)row,(const char **)rrow))
2687 {
2688 BIO_printf(bio_err,"ERROR:name does not match %s\n",
2689 row[DB_name]);
2690 goto err;
2691 }
2692 else if (rrow[DB_type][0]=='R')
2693 {
2694 BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n",
2695 row[DB_serial]);
2696 goto err;
2697 }
2698 else
2699 {
2700 BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]);
2701 rev_str = make_revocation_str(type, value);
2702 if (!rev_str)
2703 {
2704 BIO_printf(bio_err, "Error in revocation arguments\n");
2705 goto err;
2706 }
2707 rrow[DB_type][0]='R';
2708 rrow[DB_type][1]='\0';
2709 rrow[DB_rev_date] = rev_str;
2710 }
2711 ok=1;
2712err:
2713 for (i=0; i<DB_NUMBER; i++)
2714 {
2715 if (row[i] != NULL)
2716 OPENSSL_free(row[i]);
2717 }
2718 return(ok);
2719 }
2720
2721static int get_certificate_status(const char *serial, TXT_DB *db)
2722 {
2723 char *row[DB_NUMBER],**rrow;
2724 int ok=-1,i;
2725
2726 /* Free Resources */
2727 for (i=0; i<DB_NUMBER; i++)
2728 row[i]=NULL;
2729
2730 /* Malloc needed char spaces */
2731 row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2);
2732 if (row[DB_serial] == NULL)
2733 {
2734 BIO_printf(bio_err,"Malloc failure\n");
2735 goto err;
2736 }
2737
2738 if (strlen(serial) % 2)
2739 {
2740 /* Set the first char to 0 */;
2741 row[DB_serial][0]='0';
2742
2743 /* Copy String from serial to row[DB_serial] */
2744 memcpy(row[DB_serial]+1, serial, strlen(serial));
2745 row[DB_serial][strlen(serial)+1]='\0';
2746 }
2747 else
2748 {
2749 /* Copy String from serial to row[DB_serial] */
2750 memcpy(row[DB_serial], serial, strlen(serial));
2751 row[DB_serial][strlen(serial)]='\0';
2752 }
2753
2754 /* Make it Upper Case */
2755 for (i=0; row[DB_serial][i] != '\0'; i++)
2756 row[DB_serial][i] = toupper(row[DB_serial][i]);
2757
2758
2759 ok=1;
2760
2761 /* Search for the certificate */
2762 rrow=TXT_DB_get_by_index(db,DB_serial,row);
2763 if (rrow == NULL)
2764 {
2765 BIO_printf(bio_err,"Serial %s not present in db.\n",
2766 row[DB_serial]);
2767 ok=-1;
2768 goto err;
2769 }
2770 else if (rrow[DB_type][0]=='V')
2771 {
2772 BIO_printf(bio_err,"%s=Valid (%c)\n",
2773 row[DB_serial], rrow[DB_type][0]);
2774 goto err;
2775 }
2776 else if (rrow[DB_type][0]=='R')
2777 {
2778 BIO_printf(bio_err,"%s=Revoked (%c)\n",
2779 row[DB_serial], rrow[DB_type][0]);
2780 goto err;
2781 }
2782 else if (rrow[DB_type][0]=='E')
2783 {
2784 BIO_printf(bio_err,"%s=Expired (%c)\n",
2785 row[DB_serial], rrow[DB_type][0]);
2786 goto err;
2787 }
2788 else if (rrow[DB_type][0]=='S')
2789 {
2790 BIO_printf(bio_err,"%s=Suspended (%c)\n",
2791 row[DB_serial], rrow[DB_type][0]);
2792 goto err;
2793 }
2794 else
2795 {
2796 BIO_printf(bio_err,"%s=Unknown (%c).\n",
2797 row[DB_serial], rrow[DB_type][0]);
2798 ok=-1;
2799 }
2800err:
2801 for (i=0; i<DB_NUMBER; i++)
2802 {
2803 if (row[i] != NULL)
2804 OPENSSL_free(row[i]);
2805 }
2806 return(ok);
2807 }
2808
2809static int do_updatedb (TXT_DB *db)
2810 {
2811 ASN1_UTCTIME *a_tm = NULL;
2812 int i, cnt = 0;
2813 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2814 char **rrow, *a_tm_s;
2815
2816 a_tm = ASN1_UTCTIME_new();
2817
2818 /* get actual time and make a string */
2819 a_tm = X509_gmtime_adj(a_tm, 0);
2820 a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1);
2821 if (a_tm_s == NULL)
2822 {
2823 cnt = -1;
2824 goto err;
2825 }
2826
2827 memcpy(a_tm_s, a_tm->data, a_tm->length);
2828 a_tm_s[a_tm->length] = '\0';
2829
2830 if (strncmp(a_tm_s, "49", 2) <= 0)
2831 a_y2k = 1;
2832 else
2833 a_y2k = 0;
2834
2835 for (i = 0; i < sk_num(db->data); i++)
2836 {
2837 rrow = (char **) sk_value(db->data, i);
2838
2839 if (rrow[DB_type][0] == 'V')
2840 {
2841 /* ignore entries that are not valid */
2842 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2843 db_y2k = 1;
2844 else
2845 db_y2k = 0;
2846
2847 if (db_y2k == a_y2k)
2848 {
2849 /* all on the same y2k side */
2850 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0)
2851 {
2852 rrow[DB_type][0] = 'E';
2853 rrow[DB_type][1] = '\0';
2854 cnt++;
2855
2856 BIO_printf(bio_err, "%s=Expired\n",
2857 rrow[DB_serial]);
2858 }
2859 }
2860 else if (db_y2k < a_y2k)
2861 {
2862 rrow[DB_type][0] = 'E';
2863 rrow[DB_type][1] = '\0';
2864 cnt++;
2865
2866 BIO_printf(bio_err, "%s=Expired\n",
2867 rrow[DB_serial]);
2868 }
2869
2870 }
2871 }
2872
2873err:
2874
2875 ASN1_UTCTIME_free(a_tm);
2876 OPENSSL_free(a_tm_s);
2877
2878 return (cnt);
2879 }
2880
2881static char *crl_reasons[] = {
2882 /* CRL reason strings */
2883 "unspecified",
2884 "keyCompromise",
2885 "CACompromise",
2886 "affiliationChanged",
2887 "superseded",
2888 "cessationOfOperation",
2889 "certificateHold",
2890 "removeFromCRL",
2891 /* Additional pseudo reasons */
2892 "holdInstruction",
2893 "keyTime",
2894 "CAkeyTime"
2895};
2896
2897#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2898
2899/* Given revocation information convert to a DB string.
2900 * The format of the string is:
2901 * revtime[,reason,extra]. Where 'revtime' is the
2902 * revocation time (the current time). 'reason' is the
2903 * optional CRL reason and 'extra' is any additional
2904 * argument
2905 */
2906
2907char *make_revocation_str(int rev_type, char *rev_arg)
2908 {
2909 char *reason = NULL, *other = NULL, *str;
2910 ASN1_OBJECT *otmp;
2911 ASN1_UTCTIME *revtm = NULL;
2912 int i;
2913 switch (rev_type)
2914 {
2915 case REV_NONE:
2916 break;
2917
2918 case REV_CRL_REASON:
2919 for (i = 0; i < 8; i++)
2920 {
2921 if (!strcasecmp(rev_arg, crl_reasons[i]))
2922 {
2923 reason = crl_reasons[i];
2924 break;
2925 }
2926 }
2927 if (reason == NULL)
2928 {
2929 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2930 return NULL;
2931 }
2932 break;
2933
2934 case REV_HOLD:
2935 /* Argument is an OID */
2936
2937 otmp = OBJ_txt2obj(rev_arg, 0);
2938 ASN1_OBJECT_free(otmp);
2939
2940 if (otmp == NULL)
2941 {
2942 BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2943 return NULL;
2944 }
2945
2946 reason = "holdInstruction";
2947 other = rev_arg;
2948 break;
2949
2950 case REV_KEY_COMPROMISE:
2951 case REV_CA_COMPROMISE:
2952
2953 /* Argument is the key compromise time */
2954 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg))
2955 {
2956 BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg);
2957 return NULL;
2958 }
2959 other = rev_arg;
2960 if (rev_type == REV_KEY_COMPROMISE)
2961 reason = "keyTime";
2962 else
2963 reason = "CAkeyTime";
2964
2965 break;
2966
2967 }
2968
2969 revtm = X509_gmtime_adj(NULL, 0);
2970
2971 i = revtm->length + 1;
2972
2973 if (reason) i += strlen(reason) + 1;
2974 if (other) i += strlen(other) + 1;
2975
2976 str = OPENSSL_malloc(i);
2977
2978 if (!str) return NULL;
2979
2980 strcpy(str, (char *)revtm->data);
2981 if (reason)
2982 {
2983 strcat(str, ",");
2984 strcat(str, reason);
2985 }
2986 if (other)
2987 {
2988 strcat(str, ",");
2989 strcat(str, other);
2990 }
2991 ASN1_UTCTIME_free(revtm);
2992 return str;
2993 }
2994
2995/* Convert revocation field to X509_REVOKED entry
2996 * return code:
2997 * 0 error
2998 * 1 OK
2999 * 2 OK and some extensions added (i.e. V2 CRL)
3000 */
3001
3002
3003int make_revoked(X509_REVOKED *rev, char *str)
3004 {
3005 char *tmp = NULL;
3006 int reason_code = -1;
3007 int i, ret = 0;
3008 ASN1_OBJECT *hold = NULL;
3009 ASN1_GENERALIZEDTIME *comp_time = NULL;
3010 ASN1_ENUMERATED *rtmp = NULL;
3011
3012 ASN1_TIME *revDate = NULL;
3013
3014 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
3015
3016 if (i == 0)
3017 goto err;
3018
3019 if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
3020 goto err;
3021
3022 if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
3023 {
3024 rtmp = ASN1_ENUMERATED_new();
3025 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code))
3026 goto err;
3027 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
3028 goto err;
3029 }
3030
3031 if (rev && comp_time)
3032 {
3033 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0))
3034 goto err;
3035 }
3036 if (rev && hold)
3037 {
3038 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0))
3039 goto err;
3040 }
3041
3042 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
3043 ret = 2;
3044 else ret = 1;
3045
3046 err:
3047
3048 if (tmp) OPENSSL_free(tmp);
3049 ASN1_OBJECT_free(hold);
3050 ASN1_GENERALIZEDTIME_free(comp_time);
3051 ASN1_ENUMERATED_free(rtmp);
3052 ASN1_TIME_free(revDate);
3053
3054 return ret;
3055 }
3056
3057/*
3058 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
3059 * where characters may be escaped by \
3060 */
3061X509_NAME *do_subject(char *subject, long chtype)
3062 {
3063 size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
3064 char *buf = OPENSSL_malloc(buflen);
3065 size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
3066 char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
3067 char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
3068
3069 char *sp = subject, *bp = buf;
3070 int i, ne_num = 0;
3071
3072 X509_NAME *n = NULL;
3073 int nid;
3074
3075 if (!buf || !ne_types || !ne_values)
3076 {
3077 BIO_printf(bio_err, "malloc error\n");
3078 goto error;
3079 }
3080
3081 if (*subject != '/')
3082 {
3083 BIO_printf(bio_err, "Subject does not start with '/'.\n");
3084 goto error;
3085 }
3086 sp++; /* skip leading / */
3087
3088 while (*sp)
3089 {
3090 /* collect type */
3091 ne_types[ne_num] = bp;
3092 while (*sp)
3093 {
3094 if (*sp == '\\') /* is there anything to escape in the type...? */
3095 {
3096 if (*++sp)
3097 *bp++ = *sp++;
3098 else
3099 {
3100 BIO_printf(bio_err, "escape character at end of string\n");
3101 goto error;
3102 }
3103 }
3104 else if (*sp == '=')
3105 {
3106 sp++;
3107 *bp++ = '\0';
3108 break;
3109 }
3110 else
3111 *bp++ = *sp++;
3112 }
3113 if (!*sp)
3114 {
3115 BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
3116 goto error;
3117 }
3118 ne_values[ne_num] = bp;
3119 while (*sp)
3120 {
3121 if (*sp == '\\')
3122 {
3123 if (*++sp)
3124 *bp++ = *sp++;
3125 else
3126 {
3127 BIO_printf(bio_err, "escape character at end of string\n");
3128 goto error;
3129 }
3130 }
3131 else if (*sp == '/')
3132 {
3133 sp++;
3134 break;
3135 }
3136 else
3137 *bp++ = *sp++;
3138 }
3139 *bp++ = '\0';
3140 ne_num++;
3141 }
3142
3143 if (!(n = X509_NAME_new()))
3144 goto error;
3145
3146 for (i = 0; i < ne_num; i++)
3147 {
3148 if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
3149 {
3150 BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
3151 continue;
3152 }
3153
3154 if (!*ne_values[i])
3155 {
3156 BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
3157 continue;
3158 }
3159
3160 if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
3161 goto error;
3162 }
3163
3164 OPENSSL_free(ne_values);
3165 OPENSSL_free(ne_types);
3166 OPENSSL_free(buf);
3167 return n;
3168
3169error:
3170 X509_NAME_free(n);
3171 if (ne_values)
3172 OPENSSL_free(ne_values);
3173 if (ne_types)
3174 OPENSSL_free(ne_types);
3175 if (buf)
3176 OPENSSL_free(buf);
3177 return NULL;
3178}
3179
3180int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
3181 {
3182 char buf[25],*pbuf, *p;
3183 int j;
3184 j=i2a_ASN1_OBJECT(bp,obj);
3185 pbuf=buf;
3186 for (j=22-j; j>0; j--)
3187 *(pbuf++)=' ';
3188 *(pbuf++)=':';
3189 *(pbuf++)='\0';
3190 BIO_puts(bp,buf);
3191
3192 if (str->type == V_ASN1_PRINTABLESTRING)
3193 BIO_printf(bp,"PRINTABLE:'");
3194 else if (str->type == V_ASN1_T61STRING)
3195 BIO_printf(bp,"T61STRING:'");
3196 else if (str->type == V_ASN1_IA5STRING)
3197 BIO_printf(bp,"IA5STRING:'");
3198 else if (str->type == V_ASN1_UNIVERSALSTRING)
3199 BIO_printf(bp,"UNIVERSALSTRING:'");
3200 else
3201 BIO_printf(bp,"ASN.1 %2d:'",str->type);
3202
3203 p=(char *)str->data;
3204 for (j=str->length; j>0; j--)
3205 {
3206 if ((*p >= ' ') && (*p <= '~'))
3207 BIO_printf(bp,"%c",*p);
3208 else if (*p & 0x80)
3209 BIO_printf(bp,"\\0x%02X",*p);
3210 else if ((unsigned char)*p == 0xf7)
3211 BIO_printf(bp,"^?");
3212 else BIO_printf(bp,"^%c",*p+'@');
3213 p++;
3214 }
3215 BIO_printf(bp,"'\n");
3216 return 1;
3217 }
3218
3219int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
3220 {
3221 char *tmp = NULL;
3222 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
3223 int reason_code = -1;
3224 int i, ret = 0;
3225 ASN1_OBJECT *hold = NULL;
3226 ASN1_GENERALIZEDTIME *comp_time = NULL;
3227 tmp = BUF_strdup(str);
3228
3229 p = strchr(tmp, ',');
3230
3231 rtime_str = tmp;
3232
3233 if (p)
3234 {
3235 *p = '\0';
3236 p++;
3237 reason_str = p;
3238 p = strchr(p, ',');
3239 if (p)
3240 {
3241 *p = '\0';
3242 arg_str = p + 1;
3243 }
3244 }
3245
3246 if (prevtm)
3247 {
3248 *prevtm = ASN1_UTCTIME_new();
3249 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str))
3250 {
3251 BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
3252 goto err;
3253 }
3254 }
3255 if (reason_str)
3256 {
3257 for (i = 0; i < NUM_REASONS; i++)
3258 {
3259 if(!strcasecmp(reason_str, crl_reasons[i]))
3260 {
3261 reason_code = i;
3262 break;
3263 }
3264 }
3265 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS)
3266 {
3267 BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
3268 goto err;
3269 }
3270
3271 if (reason_code == 7)
3272 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
3273 else if (reason_code == 8) /* Hold instruction */
3274 {
3275 if (!arg_str)
3276 {
3277 BIO_printf(bio_err, "missing hold instruction\n");
3278 goto err;
3279 }
3280 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
3281 hold = OBJ_txt2obj(arg_str, 0);
3282
3283 if (!hold)
3284 {
3285 BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
3286 goto err;
3287 }
3288 if (phold) *phold = hold;
3289 }
3290 else if ((reason_code == 9) || (reason_code == 10))
3291 {
3292 if (!arg_str)
3293 {
3294 BIO_printf(bio_err, "missing compromised time\n");
3295 goto err;
3296 }
3297 comp_time = ASN1_GENERALIZEDTIME_new();
3298 if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str))
3299 {
3300 BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
3301 goto err;
3302 }
3303 if (reason_code == 9)
3304 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
3305 else
3306 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
3307 }
3308 }
3309
3310 if (preason) *preason = reason_code;
3311 if (pinvtm) *pinvtm = comp_time;
3312 else ASN1_GENERALIZEDTIME_free(comp_time);
3313
3314 ret = 1;
3315
3316 err:
3317
3318 if (tmp) OPENSSL_free(tmp);
3319 if (!phold) ASN1_OBJECT_free(hold);
3320 if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time);
3321
3322 return ret;
3323 }
3324
3325int make_serial_index(TXT_DB *db)
3326 {
3327 if (!TXT_DB_create_index(db, DB_serial, NULL,
3328 LHASH_HASH_FN(index_serial_hash),
3329 LHASH_COMP_FN(index_serial_cmp)))
3330 {
3331 BIO_printf(bio_err,
3332 "error creating serial number index:(%ld,%ld,%ld)\n",
3333 db->error,db->arg1,db->arg2);
3334 return 0;
3335 }
3336 return 1;
3337 }