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