Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/apps/ca.c
105517 views
1
/*
2
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
#include "internal/e_os.h"
10
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <string.h>
14
#include <ctype.h>
15
#include <sys/types.h>
16
#include <openssl/conf.h>
17
#include <openssl/bio.h>
18
#include <openssl/err.h>
19
#include <openssl/bn.h>
20
#include <openssl/txt_db.h>
21
#include <openssl/evp.h>
22
#include <openssl/x509.h>
23
#include <openssl/x509v3.h>
24
#include <openssl/objects.h>
25
#include <openssl/ocsp.h>
26
#include <openssl/pem.h>
27
28
#ifndef W_OK
29
#ifdef OPENSSL_SYS_VMS
30
#include <unistd.h>
31
#elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_TANDEM)
32
#include <sys/file.h>
33
#endif
34
#endif
35
36
#include "apps.h"
37
#include "progs.h"
38
39
#ifndef W_OK
40
#define F_OK 0
41
#define W_OK 2
42
#define R_OK 4
43
#endif
44
45
#ifndef PATH_MAX
46
#define PATH_MAX 4096
47
#endif
48
49
#define BASE_SECTION "ca"
50
51
#define ENV_DEFAULT_CA "default_ca"
52
53
#define STRING_MASK "string_mask"
54
#define UTF8_IN "utf8"
55
56
#define ENV_NEW_CERTS_DIR "new_certs_dir"
57
#define ENV_CERTIFICATE "certificate"
58
#define ENV_SERIAL "serial"
59
#define ENV_RAND_SERIAL "rand_serial"
60
#define ENV_CRLNUMBER "crlnumber"
61
#define ENV_PRIVATE_KEY "private_key"
62
#define ENV_DEFAULT_DAYS "default_days"
63
#define ENV_DEFAULT_STARTDATE "default_startdate"
64
#define ENV_DEFAULT_ENDDATE "default_enddate"
65
#define ENV_DEFAULT_CRL_DAYS "default_crl_days"
66
#define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
67
#define ENV_DEFAULT_MD "default_md"
68
#define ENV_DEFAULT_EMAIL_DN "email_in_dn"
69
#define ENV_PRESERVE "preserve"
70
#define ENV_POLICY "policy"
71
#define ENV_EXTENSIONS "x509_extensions"
72
#define ENV_CRLEXT "crl_extensions"
73
#define ENV_MSIE_HACK "msie_hack"
74
#define ENV_NAMEOPT "name_opt"
75
#define ENV_CERTOPT "cert_opt"
76
#define ENV_EXTCOPY "copy_extensions"
77
#define ENV_UNIQUE_SUBJECT "unique_subject"
78
79
#define ENV_DATABASE "database"
80
81
/* Additional revocation information types */
82
typedef enum {
83
REV_VALID = -1, /* Valid (not-revoked) status */
84
REV_NONE = 0, /* No additional information */
85
REV_CRL_REASON = 1, /* Value is CRL reason code */
86
REV_HOLD = 2, /* Value is hold instruction */
87
REV_KEY_COMPROMISE = 3, /* Value is cert key compromise time */
88
REV_CA_COMPROMISE = 4 /* Value is CA key compromise time */
89
} REVINFO_TYPE;
90
91
static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
92
93
static int certify(X509 **xret, const char *infile, int informat,
94
EVP_PKEY *pkey, X509 *x509,
95
const char *dgst,
96
STACK_OF(OPENSSL_STRING) *sigopts,
97
STACK_OF(OPENSSL_STRING) *vfyopts,
98
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
99
BIGNUM *serial, const char *subj, unsigned long chtype,
100
int multirdn, int email_dn, const char *startdate,
101
const char *enddate,
102
long days, int batch, const char *ext_sect, CONF *conf,
103
int verbose, unsigned long certopt, unsigned long nameopt,
104
int default_op, int ext_copy, int selfsign, unsigned long dateopt);
105
static int certify_cert(X509 **xret, const char *infile, int certformat,
106
const char *passin, EVP_PKEY *pkey, X509 *x509,
107
const char *dgst,
108
STACK_OF(OPENSSL_STRING) *sigopts,
109
STACK_OF(OPENSSL_STRING) *vfyopts,
110
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
111
BIGNUM *serial, const char *subj, unsigned long chtype,
112
int multirdn, int email_dn, const char *startdate,
113
const char *enddate, long days, int batch, const char *ext_sect,
114
CONF *conf, int verbose, unsigned long certopt,
115
unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt);
116
static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
117
X509 *x509, const char *dgst,
118
STACK_OF(OPENSSL_STRING) *sigopts,
119
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
120
BIGNUM *serial, const char *subj, unsigned long chtype,
121
int multirdn, int email_dn, const char *startdate,
122
const char *enddate, long days, const char *ext_sect, CONF *conf,
123
int verbose, unsigned long certopt,
124
unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt);
125
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
126
const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
127
STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
128
const char *subj, unsigned long chtype, int multirdn,
129
int email_dn, const char *startdate, const char *enddate, long days,
130
int batch, int verbose, X509_REQ *req, const char *ext_sect,
131
CONF *conf, unsigned long certopt, unsigned long nameopt,
132
int default_op, int ext_copy, int selfsign, unsigned long dateopt);
133
static int get_certificate_status(const char *ser_status, CA_DB *db);
134
static int check_time_format(const char *str);
135
static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
136
const char *extval);
137
static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg);
138
static int make_revoked(X509_REVOKED *rev, const char *str);
139
static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str);
140
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
141
142
static CONF *extfile_conf = NULL;
143
static int preserve = 0;
144
static int msie_hack = 0;
145
146
typedef enum OPTION_choice {
147
OPT_COMMON,
148
OPT_ENGINE,
149
OPT_VERBOSE,
150
OPT_CONFIG,
151
OPT_NAME,
152
OPT_SUBJ,
153
OPT_UTF8,
154
OPT_CREATE_SERIAL,
155
OPT_MULTIVALUE_RDN,
156
OPT_STARTDATE,
157
OPT_ENDDATE,
158
OPT_DAYS,
159
OPT_MD,
160
OPT_POLICY,
161
OPT_KEYFILE,
162
OPT_KEYFORM,
163
OPT_PASSIN,
164
OPT_KEY,
165
OPT_CERT,
166
OPT_CERTFORM,
167
OPT_SELFSIGN,
168
OPT_IN,
169
OPT_INFORM,
170
OPT_OUT,
171
OPT_DATEOPT,
172
OPT_OUTDIR,
173
OPT_VFYOPT,
174
OPT_SIGOPT,
175
OPT_NOTEXT,
176
OPT_BATCH,
177
OPT_PRESERVEDN,
178
OPT_NOEMAILDN,
179
OPT_GENCRL,
180
OPT_MSIE_HACK,
181
OPT_CRL_LASTUPDATE,
182
OPT_CRL_NEXTUPDATE,
183
OPT_CRLDAYS,
184
OPT_CRLHOURS,
185
OPT_CRLSEC,
186
OPT_NOT_BEFORE,
187
OPT_NOT_AFTER,
188
OPT_INFILES,
189
OPT_SS_CERT,
190
OPT_SPKAC,
191
OPT_REVOKE,
192
OPT_VALID,
193
OPT_EXTENSIONS,
194
OPT_EXTFILE,
195
OPT_STATUS,
196
OPT_UPDATEDB,
197
OPT_CRLEXTS,
198
OPT_RAND_SERIAL,
199
OPT_QUIET,
200
OPT_R_ENUM,
201
OPT_PROV_ENUM,
202
/* Do not change the order here; see related case statements below */
203
OPT_CRL_REASON,
204
OPT_CRL_HOLD,
205
OPT_CRL_COMPROMISE,
206
OPT_CRL_CA_COMPROMISE
207
} OPTION_CHOICE;
208
209
const OPTIONS ca_options[] = {
210
{ OPT_HELP_STR, 1, '-', "Usage: %s [options] [certreq...]\n" },
211
212
OPT_SECTION("General"),
213
{ "help", OPT_HELP, '-', "Display this summary" },
214
{ "verbose", OPT_VERBOSE, '-', "Verbose output during processing" },
215
{ "quiet", OPT_QUIET, '-', "Terse output during processing" },
216
{ "outdir", OPT_OUTDIR, '/', "Where to put output cert" },
217
{ "in", OPT_IN, '<', "The input cert request(s)" },
218
{ "inform", OPT_INFORM, 'F',
219
"CSR input format to use (PEM or DER; by default try PEM first)" },
220
{ "infiles", OPT_INFILES, '-', "The last argument, requests to process" },
221
{ "out", OPT_OUT, '>', "Where to put the output file(s)" },
222
{ "dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822." },
223
{ "notext", OPT_NOTEXT, '-', "Do not print the generated certificate" },
224
{ "batch", OPT_BATCH, '-', "Don't ask questions" },
225
{ "msie_hack", OPT_MSIE_HACK, '-',
226
"msie modifications to handle all Universal Strings" },
227
{ "ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign" },
228
{ "spkac", OPT_SPKAC, '<',
229
"File contains DN and signed public key and challenge" },
230
#ifndef OPENSSL_NO_ENGINE
231
{ "engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device" },
232
#endif
233
234
OPT_SECTION("Configuration"),
235
{ "config", OPT_CONFIG, 's', "A config file" },
236
{ "name", OPT_NAME, 's', "The particular CA definition to use" },
237
{ "section", OPT_NAME, 's', "An alias for -name" },
238
{ "policy", OPT_POLICY, 's', "The CA 'policy' to support" },
239
240
OPT_SECTION("Certificate"),
241
{ "subj", OPT_SUBJ, 's', "Use arg instead of request's subject" },
242
{ "utf8", OPT_UTF8, '-', "Input characters are UTF8; default ASCII" },
243
{ "create_serial", OPT_CREATE_SERIAL, '-',
244
"If reading serial fails, create a new random serial" },
245
{ "rand_serial", OPT_RAND_SERIAL, '-',
246
"Always create a random serial; do not store it" },
247
{ "multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
248
"Deprecated; multi-valued RDNs support is always on." },
249
{ "startdate", OPT_STARTDATE, 's',
250
"[CC]YYMMDDHHMMSSZ value for notBefore certificate field" },
251
{ "not_before", OPT_NOT_BEFORE, 's', "An alias for -startdate" },
252
{ "enddate", OPT_ENDDATE, 's',
253
"[CC]YYMMDDHHMMSSZ value for notAfter certificate field, overrides -days" },
254
{ "not_after", OPT_NOT_AFTER, 's', "An alias for -enddate" },
255
{ "days", OPT_DAYS, 'p', "Number of days from today to certify the cert for" },
256
{ "extensions", OPT_EXTENSIONS, 's',
257
"Extension section (override value in config file)" },
258
{ "extfile", OPT_EXTFILE, '<',
259
"Configuration file with X509v3 extensions to add" },
260
{ "preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN" },
261
{ "noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN" },
262
263
OPT_SECTION("Signing"),
264
{ "md", OPT_MD, 's', "Digest to use, such as sha256" },
265
{ "keyfile", OPT_KEYFILE, 's', "The CA private key" },
266
{ "keyform", OPT_KEYFORM, 'f',
267
"Private key file format (ENGINE, other values ignored)" },
268
{ "passin", OPT_PASSIN, 's', "Key and cert input file pass phrase source" },
269
{ "key", OPT_KEY, 's',
270
"Key to decrypt the private key or cert files if encrypted. Better use -passin" },
271
{ "cert", OPT_CERT, '<', "The CA cert" },
272
{ "certform", OPT_CERTFORM, 'F',
273
"Certificate input format (DER/PEM/P12); has no effect" },
274
{ "selfsign", OPT_SELFSIGN, '-',
275
"Sign a cert with the key associated with it" },
276
{ "sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form" },
277
{ "vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form" },
278
279
OPT_SECTION("Revocation"),
280
{ "gencrl", OPT_GENCRL, '-', "Generate a new CRL" },
281
{ "valid", OPT_VALID, 's',
282
"Add a Valid(not-revoked) DB entry about a cert (given in file)" },
283
{ "status", OPT_STATUS, 's', "Shows cert status given the serial number" },
284
{ "updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert" },
285
{ "crlexts", OPT_CRLEXTS, 's',
286
"CRL extension section (override value in config file)" },
287
{ "crl_reason", OPT_CRL_REASON, 's', "revocation reason" },
288
{ "crl_hold", OPT_CRL_HOLD, 's',
289
"the hold instruction, an OID. Sets revocation reason to certificateHold" },
290
{ "crl_compromise", OPT_CRL_COMPROMISE, 's',
291
"sets compromise time to val and the revocation reason to keyCompromise" },
292
{ "crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
293
"sets compromise time to val and the revocation reason to CACompromise" },
294
{ "crl_lastupdate", OPT_CRL_LASTUPDATE, 's',
295
"Sets the CRL lastUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)" },
296
{ "crl_nextupdate", OPT_CRL_NEXTUPDATE, 's',
297
"Sets the CRL nextUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)" },
298
{ "crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due" },
299
{ "crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due" },
300
{ "crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due" },
301
{ "revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)" },
302
303
OPT_R_OPTIONS,
304
OPT_PROV_OPTIONS,
305
306
OPT_PARAMETERS(),
307
{ "certreq", 0, 0, "Certificate requests to be signed (optional)" },
308
{ NULL }
309
};
310
311
int ca_main(int argc, char **argv)
312
{
313
CONF *conf = NULL;
314
ENGINE *e = NULL;
315
BIGNUM *crlnumber = NULL, *serial = NULL;
316
EVP_PKEY *pkey = NULL;
317
BIO *in = NULL, *out = NULL, *Sout = NULL;
318
ASN1_INTEGER *tmpser;
319
CA_DB *db = NULL;
320
DB_ATTR db_attr;
321
STACK_OF(CONF_VALUE) *attribs = NULL;
322
STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL;
323
STACK_OF(X509) *cert_sk = NULL;
324
X509_CRL *crl = NULL;
325
char *configfile = default_config_file, *section = NULL;
326
char def_dgst[80] = "";
327
char *dgst = NULL, *policy = NULL, *keyfile = NULL;
328
char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL;
329
int certformat = FORMAT_UNDEF, informat = FORMAT_UNDEF;
330
unsigned long dateopt = ASN1_DTFLGS_RFC822;
331
const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL;
332
const char *extensions = NULL, *extfile = NULL, *passinarg = NULL;
333
char *passin = NULL;
334
char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
335
const char *serialfile = NULL, *subj = NULL;
336
char *prog, *startdate = NULL, *enddate = NULL;
337
char *dbfile = NULL, *f;
338
char new_cert[PATH_MAX];
339
char tmp[10 + 1] = "\0";
340
char *const *pp;
341
const char *p;
342
size_t outdirlen = 0;
343
int create_ser = 0, free_passin = 0, total = 0, total_done = 0;
344
int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE;
345
int keyformat = FORMAT_UNDEF, multirdn = 1, notext = 0, output_der = 0;
346
int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0;
347
int rand_ser = 0, i, j, selfsign = 0, def_ret;
348
char *crl_lastupdate = NULL, *crl_nextupdate = NULL;
349
long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
350
unsigned long chtype = MBSTRING_ASC, certopt = 0;
351
X509 *x509 = NULL, *x509p = NULL, *x = NULL;
352
REVINFO_TYPE rev_type = REV_NONE;
353
X509_REVOKED *r = NULL;
354
OPTION_CHOICE o;
355
356
prog = opt_init(argc, argv, ca_options);
357
while ((o = opt_next()) != OPT_EOF) {
358
switch (o) {
359
case OPT_EOF:
360
case OPT_ERR:
361
opthelp:
362
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
363
goto end;
364
case OPT_HELP:
365
opt_help(ca_options);
366
ret = 0;
367
goto end;
368
case OPT_IN:
369
req = 1;
370
infile = opt_arg();
371
break;
372
case OPT_INFORM:
373
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
374
goto opthelp;
375
break;
376
case OPT_OUT:
377
outfile = opt_arg();
378
break;
379
case OPT_DATEOPT:
380
if (!set_dateopt(&dateopt, opt_arg()))
381
goto opthelp;
382
break;
383
case OPT_VERBOSE:
384
verbose = 1;
385
break;
386
case OPT_QUIET:
387
verbose = 0;
388
break;
389
case OPT_CONFIG:
390
configfile = opt_arg();
391
break;
392
case OPT_NAME:
393
section = opt_arg();
394
break;
395
case OPT_SUBJ:
396
subj = opt_arg();
397
/* preserve=1; */
398
break;
399
case OPT_UTF8:
400
chtype = MBSTRING_UTF8;
401
break;
402
case OPT_RAND_SERIAL:
403
rand_ser = 1;
404
break;
405
case OPT_CREATE_SERIAL:
406
create_ser = 1;
407
break;
408
case OPT_MULTIVALUE_RDN:
409
/* obsolete */
410
break;
411
case OPT_STARTDATE:
412
case OPT_NOT_BEFORE:
413
startdate = opt_arg();
414
break;
415
case OPT_ENDDATE:
416
case OPT_NOT_AFTER:
417
enddate = opt_arg();
418
break;
419
case OPT_DAYS:
420
days = atoi(opt_arg());
421
break;
422
case OPT_MD:
423
dgst = opt_arg();
424
break;
425
case OPT_POLICY:
426
policy = opt_arg();
427
break;
428
case OPT_KEYFILE:
429
keyfile = opt_arg();
430
break;
431
case OPT_KEYFORM:
432
if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
433
goto opthelp;
434
break;
435
case OPT_PASSIN:
436
passinarg = opt_arg();
437
break;
438
case OPT_R_CASES:
439
if (!opt_rand(o))
440
goto end;
441
break;
442
case OPT_PROV_CASES:
443
if (!opt_provider(o))
444
goto end;
445
break;
446
case OPT_KEY:
447
passin = opt_arg();
448
break;
449
case OPT_CERT:
450
certfile = opt_arg();
451
break;
452
case OPT_CERTFORM:
453
if (!opt_format(opt_arg(), OPT_FMT_ANY, &certformat))
454
goto opthelp;
455
break;
456
case OPT_SELFSIGN:
457
selfsign = 1;
458
break;
459
case OPT_OUTDIR:
460
outdir = opt_arg();
461
break;
462
case OPT_SIGOPT:
463
if (sigopts == NULL)
464
sigopts = sk_OPENSSL_STRING_new_null();
465
if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
466
goto end;
467
break;
468
case OPT_VFYOPT:
469
if (vfyopts == NULL)
470
vfyopts = sk_OPENSSL_STRING_new_null();
471
if (vfyopts == NULL || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
472
goto end;
473
break;
474
case OPT_NOTEXT:
475
notext = 1;
476
break;
477
case OPT_BATCH:
478
batch = 1;
479
break;
480
case OPT_PRESERVEDN:
481
preserve = 1;
482
break;
483
case OPT_NOEMAILDN:
484
email_dn = 0;
485
break;
486
case OPT_GENCRL:
487
gencrl = 1;
488
break;
489
case OPT_MSIE_HACK:
490
msie_hack = 1;
491
break;
492
case OPT_CRL_LASTUPDATE:
493
crl_lastupdate = opt_arg();
494
break;
495
case OPT_CRL_NEXTUPDATE:
496
crl_nextupdate = opt_arg();
497
break;
498
case OPT_CRLDAYS:
499
crldays = atol(opt_arg());
500
break;
501
case OPT_CRLHOURS:
502
crlhours = atol(opt_arg());
503
break;
504
case OPT_CRLSEC:
505
crlsec = atol(opt_arg());
506
break;
507
case OPT_INFILES:
508
req = 1;
509
goto end_of_options;
510
case OPT_SS_CERT:
511
ss_cert_file = opt_arg();
512
req = 1;
513
break;
514
case OPT_SPKAC:
515
spkac_file = opt_arg();
516
req = 1;
517
break;
518
case OPT_REVOKE:
519
infile = opt_arg();
520
dorevoke = 1;
521
break;
522
case OPT_VALID:
523
infile = opt_arg();
524
dorevoke = 2;
525
break;
526
case OPT_EXTENSIONS:
527
extensions = opt_arg();
528
break;
529
case OPT_EXTFILE:
530
extfile = opt_arg();
531
break;
532
case OPT_STATUS:
533
ser_status = opt_arg();
534
break;
535
case OPT_UPDATEDB:
536
doupdatedb = 1;
537
break;
538
case OPT_CRLEXTS:
539
crl_ext = opt_arg();
540
break;
541
case OPT_CRL_REASON: /* := REV_CRL_REASON */
542
case OPT_CRL_HOLD:
543
case OPT_CRL_COMPROMISE:
544
case OPT_CRL_CA_COMPROMISE:
545
rev_arg = opt_arg();
546
rev_type = (o - OPT_CRL_REASON) + REV_CRL_REASON;
547
break;
548
case OPT_ENGINE:
549
e = setup_engine(opt_arg(), 0);
550
break;
551
}
552
}
553
554
end_of_options:
555
/* Remaining args are files to certify. */
556
argc = opt_num_rest();
557
argv = opt_rest();
558
559
if ((conf = app_load_config_verbose(configfile, 1)) == NULL)
560
goto end;
561
if (configfile != default_config_file && !app_load_modules(conf))
562
goto end;
563
564
/* Lets get the config section we are using */
565
if (section == NULL
566
&& (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL)
567
goto end;
568
569
p = app_conf_try_string(conf, NULL, "oid_file");
570
if (p != NULL) {
571
BIO *oid_bio = BIO_new_file(p, "r");
572
573
if (oid_bio == NULL) {
574
ERR_clear_error();
575
} else {
576
OBJ_create_objects(oid_bio);
577
BIO_free(oid_bio);
578
}
579
}
580
if (!add_oid_section(conf))
581
goto end;
582
583
app_RAND_load_conf(conf, BASE_SECTION);
584
if (!app_RAND_load())
585
goto end;
586
587
f = app_conf_try_string(conf, section, STRING_MASK);
588
if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
589
BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
590
goto end;
591
}
592
593
if (chtype != MBSTRING_UTF8) {
594
f = app_conf_try_string(conf, section, UTF8_IN);
595
if (f != NULL && strcmp(f, "yes") == 0)
596
chtype = MBSTRING_UTF8;
597
}
598
599
db_attr.unique_subject = 1;
600
p = app_conf_try_string(conf, section, ENV_UNIQUE_SUBJECT);
601
if (p != NULL)
602
db_attr.unique_subject = parse_yesno(p, 1);
603
604
/*****************************************************************/
605
/* report status of cert with serial number given on command line */
606
if (ser_status) {
607
dbfile = lookup_conf(conf, section, ENV_DATABASE);
608
if (dbfile == NULL)
609
goto end;
610
611
db = load_index(dbfile, &db_attr);
612
if (db == NULL) {
613
BIO_printf(bio_err, "Problem with index file: %s (could not load/parse file)\n", dbfile);
614
goto end;
615
}
616
617
if (index_index(db) <= 0)
618
goto end;
619
620
if (get_certificate_status(ser_status, db) != 1)
621
BIO_printf(bio_err, "Error verifying serial %s!\n", ser_status);
622
goto end;
623
}
624
625
/*****************************************************************/
626
/* we definitely need a private key, so let's get it */
627
628
if (keyfile == NULL
629
&& (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL)
630
goto end;
631
632
if (passin == NULL) {
633
free_passin = 1;
634
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
635
BIO_printf(bio_err, "Error getting password\n");
636
goto end;
637
}
638
}
639
pkey = load_key(keyfile, keyformat, 0, passin, e, "CA private key");
640
cleanse(passin);
641
if (pkey == NULL)
642
/* load_key() has already printed an appropriate message */
643
goto end;
644
645
/*****************************************************************/
646
/* we need a certificate */
647
if (!selfsign || spkac_file || ss_cert_file || gencrl) {
648
if (certfile == NULL
649
&& (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL)
650
goto end;
651
652
x509 = load_cert_pass(certfile, certformat, 1, passin, "CA certificate");
653
if (x509 == NULL)
654
goto end;
655
656
if (!X509_check_private_key(x509, pkey)) {
657
BIO_printf(bio_err,
658
"CA certificate and CA private key do not match\n");
659
goto end;
660
}
661
}
662
if (!selfsign)
663
x509p = x509;
664
665
f = app_conf_try_string(conf, BASE_SECTION, ENV_PRESERVE);
666
if (f != NULL && (*f == 'y' || *f == 'Y'))
667
preserve = 1;
668
f = app_conf_try_string(conf, BASE_SECTION, ENV_MSIE_HACK);
669
if (f != NULL && (*f == 'y' || *f == 'Y'))
670
msie_hack = 1;
671
672
f = app_conf_try_string(conf, section, ENV_NAMEOPT);
673
if (f != NULL) {
674
if (!set_nameopt(f)) {
675
BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
676
goto end;
677
}
678
default_op = 0;
679
}
680
681
f = app_conf_try_string(conf, section, ENV_CERTOPT);
682
if (f != NULL) {
683
if (!set_cert_ex(&certopt, f)) {
684
BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
685
goto end;
686
}
687
default_op = 0;
688
}
689
690
f = app_conf_try_string(conf, section, ENV_EXTCOPY);
691
if (f != NULL) {
692
if (!set_ext_copy(&ext_copy, f)) {
693
BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
694
goto end;
695
}
696
}
697
698
/*****************************************************************/
699
/* lookup where to write new certificates */
700
if ((outdir == NULL) && (req)) {
701
702
outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR);
703
if (outdir == NULL) {
704
BIO_printf(bio_err,
705
"there needs to be defined a directory for new certificate to be placed in\n");
706
goto end;
707
}
708
#ifndef OPENSSL_SYS_VMS
709
/*
710
* outdir is a directory spec, but access() for VMS demands a
711
* filename. We could use the DEC C routine to convert the
712
* directory syntax to Unix, and give that to app_isdir,
713
* but for now the fopen will catch the error if it's not a
714
* directory
715
*/
716
if (app_isdir(outdir) <= 0) {
717
BIO_printf(bio_err, "%s: %s is not a directory\n", prog, outdir);
718
perror(outdir);
719
goto end;
720
}
721
#endif
722
}
723
724
/*****************************************************************/
725
/* we need to load the database file */
726
dbfile = lookup_conf(conf, section, ENV_DATABASE);
727
if (dbfile == NULL)
728
goto end;
729
730
db = load_index(dbfile, &db_attr);
731
if (db == NULL) {
732
BIO_printf(bio_err, "Problem with index file: %s (could not load/parse file)\n", dbfile);
733
goto end;
734
}
735
736
/* Lets check some fields */
737
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
738
pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
739
if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) {
740
BIO_printf(bio_err,
741
"entry %d: not revoked yet, but has a revocation date\n",
742
i + 1);
743
goto end;
744
}
745
if ((pp[DB_type][0] == DB_TYPE_REV) && !make_revoked(NULL, pp[DB_rev_date])) {
746
BIO_printf(bio_err, " in entry %d\n", i + 1);
747
goto end;
748
}
749
if (!check_time_format((char *)pp[DB_exp_date])) {
750
BIO_printf(bio_err, "entry %d: invalid expiry date\n", i + 1);
751
goto end;
752
}
753
p = pp[DB_serial];
754
j = strlen(p);
755
if (*p == '-') {
756
p++;
757
j--;
758
}
759
if ((j & 1) || (j < 2)) {
760
BIO_printf(bio_err, "entry %d: bad serial number length (%d)\n",
761
i + 1, j);
762
goto end;
763
}
764
for (; *p; p++) {
765
if (!isxdigit(_UC(*p))) {
766
BIO_printf(bio_err,
767
"entry %d: bad char 0%o '%c' in serial number\n",
768
i + 1, *p, *p);
769
goto end;
770
}
771
}
772
}
773
if (verbose) {
774
TXT_DB_write(bio_out, db->db);
775
BIO_printf(bio_err, "%d entries loaded from the database\n",
776
sk_OPENSSL_PSTRING_num(db->db->data));
777
BIO_printf(bio_err, "generating index\n");
778
}
779
780
if (index_index(db) <= 0)
781
goto end;
782
783
/*****************************************************************/
784
/* Update the db file for expired certificates */
785
if (doupdatedb) {
786
if (verbose)
787
BIO_printf(bio_err, "Updating %s ...\n", dbfile);
788
789
i = do_updatedb(db, NULL);
790
if (i == -1) {
791
BIO_printf(bio_err, "Malloc failure\n");
792
goto end;
793
} else if (i == 0) {
794
if (verbose)
795
BIO_printf(bio_err, "No entries found to mark expired\n");
796
} else {
797
if (!save_index(dbfile, "new", db))
798
goto end;
799
800
if (!rotate_index(dbfile, "new", "old"))
801
goto end;
802
803
if (verbose)
804
BIO_printf(bio_err, "Done. %d entries marked as expired\n", i);
805
}
806
}
807
808
/*****************************************************************/
809
/* Read extensions config file */
810
if (extfile) {
811
if ((extfile_conf = app_load_config(extfile)) == NULL) {
812
ret = 1;
813
goto end;
814
}
815
816
if (verbose)
817
BIO_printf(bio_err, "Successfully loaded extensions file %s\n",
818
extfile);
819
820
/* We can have sections in the ext file */
821
if (extensions == NULL) {
822
extensions = app_conf_try_string(extfile_conf, "default", "extensions");
823
if (extensions == NULL)
824
extensions = "default";
825
}
826
}
827
828
/*****************************************************************/
829
if (req || gencrl) {
830
if (spkac_file != NULL && outfile != NULL) {
831
output_der = 1;
832
batch = 1;
833
}
834
}
835
836
def_ret = EVP_PKEY_get_default_digest_name(pkey, def_dgst, sizeof(def_dgst));
837
/*
838
* EVP_PKEY_get_default_digest_name() returns 2 if the digest is
839
* mandatory for this algorithm.
840
*
841
* That call may give back the name "UNDEF", which has these meanings:
842
*
843
* when def_ret == 2: the user MUST leave the digest unspecified
844
* when def_ret == 1: the user MAY leave the digest unspecified
845
*/
846
if (def_ret == 2 && strcmp(def_dgst, "UNDEF") == 0) {
847
dgst = NULL;
848
} else if (dgst == NULL
849
&& (dgst = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL
850
&& strcmp(def_dgst, "UNDEF") != 0) {
851
goto end;
852
} else {
853
if (strcmp(dgst, "default") == 0 || strcmp(def_dgst, "UNDEF") == 0) {
854
if (def_ret <= 0) {
855
BIO_puts(bio_err, "no default digest\n");
856
goto end;
857
}
858
dgst = def_dgst;
859
}
860
}
861
862
if (req) {
863
if (email_dn == 1) {
864
char *tmp_email_dn = NULL;
865
866
tmp_email_dn = app_conf_try_string(conf, section, ENV_DEFAULT_EMAIL_DN);
867
if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
868
email_dn = 0;
869
}
870
if (verbose)
871
BIO_printf(bio_err, "message digest is %s\n", dgst);
872
if (policy == NULL
873
&& (policy = lookup_conf(conf, section, ENV_POLICY)) == NULL)
874
goto end;
875
876
if (verbose)
877
BIO_printf(bio_err, "policy is %s\n", policy);
878
879
if (app_conf_try_string(conf, section, ENV_RAND_SERIAL) != NULL) {
880
rand_ser = 1;
881
} else {
882
serialfile = lookup_conf(conf, section, ENV_SERIAL);
883
if (serialfile == NULL)
884
goto end;
885
}
886
887
if (extfile_conf != NULL) {
888
/* Check syntax of extfile */
889
X509V3_CTX ctx;
890
891
X509V3_set_ctx_test(&ctx);
892
X509V3_set_nconf(&ctx, extfile_conf);
893
if (!X509V3_EXT_add_nconf(extfile_conf, &ctx, extensions, NULL)) {
894
BIO_printf(bio_err,
895
"Error checking certificate extensions from extfile section %s\n",
896
extensions);
897
ret = 1;
898
goto end;
899
}
900
} else {
901
/*
902
* no '-extfile' option, so we look for extensions in the main
903
* configuration file
904
*/
905
if (extensions == NULL)
906
extensions = app_conf_try_string(conf, section, ENV_EXTENSIONS);
907
if (extensions != NULL) {
908
/* Check syntax of config file section */
909
X509V3_CTX ctx;
910
911
X509V3_set_ctx_test(&ctx);
912
X509V3_set_nconf(&ctx, conf);
913
if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) {
914
BIO_printf(bio_err,
915
"Error checking certificate extension config section %s\n",
916
extensions);
917
ret = 1;
918
goto end;
919
}
920
}
921
}
922
923
if (startdate == NULL)
924
startdate = app_conf_try_string(conf, section, ENV_DEFAULT_STARTDATE);
925
if (enddate == NULL)
926
enddate = app_conf_try_string(conf, section, ENV_DEFAULT_ENDDATE);
927
if (days == 0) {
928
if (!app_conf_try_number(conf, section, ENV_DEFAULT_DAYS, &days))
929
days = 0;
930
}
931
if (enddate == NULL && days == 0) {
932
BIO_printf(bio_err, "cannot lookup how many days to certify for\n");
933
goto end;
934
}
935
if (days != 0 && enddate != NULL)
936
BIO_printf(bio_err,
937
"Warning: -enddate or -not_after option overriding -days option\n");
938
939
if (rand_ser) {
940
if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
941
BIO_printf(bio_err, "error generating serial number\n");
942
goto end;
943
}
944
} else {
945
serial = load_serial(serialfile, NULL, create_ser, NULL);
946
if (serial == NULL) {
947
BIO_printf(bio_err, "error while loading serial number\n");
948
goto end;
949
}
950
if (verbose) {
951
if (BN_is_zero(serial)) {
952
BIO_printf(bio_err, "next serial number is 00\n");
953
} else {
954
if ((f = BN_bn2hex(serial)) == NULL)
955
goto end;
956
BIO_printf(bio_err, "next serial number is %s\n", f);
957
OPENSSL_free(f);
958
}
959
}
960
}
961
962
if ((attribs = NCONF_get_section(conf, policy)) == NULL) {
963
BIO_printf(bio_err, "unable to find 'section' for %s\n", policy);
964
goto end;
965
}
966
967
if ((cert_sk = sk_X509_new_null()) == NULL) {
968
BIO_printf(bio_err, "Memory allocation failure\n");
969
goto end;
970
}
971
if (spkac_file != NULL) {
972
total++;
973
j = certify_spkac(&x, spkac_file, pkey, x509, dgst, sigopts,
974
attribs, db, serial, subj, chtype, multirdn,
975
email_dn, startdate, enddate, days, extensions,
976
conf, verbose, certopt, get_nameopt(), default_op,
977
ext_copy, dateopt);
978
if (j < 0)
979
goto end;
980
if (j > 0) {
981
total_done++;
982
BIO_printf(bio_err, "\n");
983
if (!BN_add_word(serial, 1))
984
goto end;
985
if (!sk_X509_push(cert_sk, x)) {
986
BIO_printf(bio_err, "Memory allocation failure\n");
987
goto end;
988
}
989
}
990
}
991
if (ss_cert_file != NULL) {
992
total++;
993
j = certify_cert(&x, ss_cert_file, certformat, passin, pkey,
994
x509, dgst, sigopts, vfyopts, attribs,
995
db, serial, subj, chtype, multirdn, email_dn,
996
startdate, enddate, days, batch, extensions,
997
conf, verbose, certopt, get_nameopt(), default_op,
998
ext_copy, dateopt);
999
if (j < 0)
1000
goto end;
1001
if (j > 0) {
1002
total_done++;
1003
BIO_printf(bio_err, "\n");
1004
if (!BN_add_word(serial, 1))
1005
goto end;
1006
if (!sk_X509_push(cert_sk, x)) {
1007
BIO_printf(bio_err, "Memory allocation failure\n");
1008
goto end;
1009
}
1010
}
1011
}
1012
if (infile != NULL) {
1013
total++;
1014
j = certify(&x, infile, informat, pkey, x509p, dgst,
1015
sigopts, vfyopts, attribs, db,
1016
serial, subj, chtype, multirdn, email_dn, startdate,
1017
enddate, days, batch, extensions, conf, verbose,
1018
certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt);
1019
if (j < 0)
1020
goto end;
1021
if (j > 0) {
1022
total_done++;
1023
BIO_printf(bio_err, "\n");
1024
if (!BN_add_word(serial, 1))
1025
goto end;
1026
if (!sk_X509_push(cert_sk, x)) {
1027
BIO_printf(bio_err, "Memory allocation failure\n");
1028
goto end;
1029
}
1030
}
1031
}
1032
for (i = 0; i < argc; i++) {
1033
total++;
1034
j = certify(&x, argv[i], informat, pkey, x509p, dgst,
1035
sigopts, vfyopts,
1036
attribs, db,
1037
serial, subj, chtype, multirdn, email_dn, startdate,
1038
enddate, days, batch, extensions, conf, verbose,
1039
certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt);
1040
if (j < 0)
1041
goto end;
1042
if (j > 0) {
1043
total_done++;
1044
BIO_printf(bio_err, "\n");
1045
if (!BN_add_word(serial, 1)) {
1046
X509_free(x);
1047
goto end;
1048
}
1049
if (!sk_X509_push(cert_sk, x)) {
1050
BIO_printf(bio_err, "Memory allocation failure\n");
1051
X509_free(x);
1052
goto end;
1053
}
1054
}
1055
}
1056
/*
1057
* we have a stack of newly certified certificates and a database
1058
* and serial number that need updating
1059
*/
1060
1061
if (sk_X509_num(cert_sk) > 0) {
1062
if (!batch) {
1063
BIO_printf(bio_err,
1064
"\n%d out of %d certificate requests certified, commit? [y/n]",
1065
total_done, total);
1066
(void)BIO_flush(bio_err);
1067
tmp[0] = '\0';
1068
if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
1069
BIO_printf(bio_err, "CERTIFICATION CANCELED: I/O error\n");
1070
ret = 0;
1071
goto end;
1072
}
1073
if (tmp[0] != 'y' && tmp[0] != 'Y') {
1074
BIO_printf(bio_err, "CERTIFICATION CANCELED\n");
1075
ret = 0;
1076
goto end;
1077
}
1078
}
1079
1080
BIO_printf(bio_err, "Write out database with %d new entries\n",
1081
sk_X509_num(cert_sk));
1082
1083
if (serialfile != NULL
1084
&& !save_serial(serialfile, "new", serial, NULL))
1085
goto end;
1086
1087
if (!save_index(dbfile, "new", db))
1088
goto end;
1089
}
1090
1091
outdirlen = OPENSSL_strlcpy(new_cert, outdir, sizeof(new_cert));
1092
#ifndef OPENSSL_SYS_VMS
1093
outdirlen = OPENSSL_strlcat(new_cert, "/", sizeof(new_cert));
1094
#endif
1095
1096
if (verbose)
1097
BIO_printf(bio_err, "writing new certificates\n");
1098
1099
for (i = 0; i < sk_X509_num(cert_sk); i++) {
1100
BIO *Cout = NULL;
1101
X509 *xi = sk_X509_value(cert_sk, i);
1102
const ASN1_INTEGER *serialNumber = X509_get0_serialNumber(xi);
1103
const unsigned char *psn = ASN1_STRING_get0_data(serialNumber);
1104
const int snl = ASN1_STRING_length(serialNumber);
1105
const int filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem");
1106
char *n = new_cert + outdirlen;
1107
1108
if (outdirlen + filen_len > PATH_MAX) {
1109
BIO_printf(bio_err, "certificate file name too long\n");
1110
goto end;
1111
}
1112
1113
if (snl > 0) {
1114
static const char HEX_DIGITS[] = "0123456789ABCDEF";
1115
1116
for (j = 0; j < snl; j++, psn++) {
1117
*n++ = HEX_DIGITS[*psn >> 4];
1118
*n++ = HEX_DIGITS[*psn & 0x0F];
1119
}
1120
} else {
1121
*(n++) = '0';
1122
*(n++) = '0';
1123
}
1124
*(n++) = '.';
1125
*(n++) = 'p';
1126
*(n++) = 'e';
1127
*(n++) = 'm';
1128
*n = '\0'; /* closing new_cert */
1129
if (verbose)
1130
BIO_printf(bio_err, "writing %s\n", new_cert);
1131
1132
Sout = bio_open_default(outfile, 'w',
1133
output_der ? FORMAT_ASN1 : FORMAT_TEXT);
1134
if (Sout == NULL)
1135
goto end;
1136
1137
Cout = BIO_new_file(new_cert, "w");
1138
if (Cout == NULL) {
1139
perror(new_cert);
1140
goto end;
1141
}
1142
write_new_certificate(Cout, xi, 0, notext);
1143
write_new_certificate(Sout, xi, output_der, notext);
1144
BIO_free_all(Cout);
1145
BIO_free_all(Sout);
1146
Sout = NULL;
1147
}
1148
1149
if (sk_X509_num(cert_sk)) {
1150
/* Rename the database and the serial file */
1151
if (serialfile != NULL
1152
&& !rotate_serial(serialfile, "new", "old"))
1153
goto end;
1154
1155
if (!rotate_index(dbfile, "new", "old"))
1156
goto end;
1157
1158
BIO_printf(bio_err, "Database updated\n");
1159
}
1160
}
1161
1162
/*****************************************************************/
1163
if (gencrl) {
1164
int crl_v2 = 0;
1165
1166
if (crl_ext == NULL)
1167
crl_ext = app_conf_try_string(conf, section, ENV_CRLEXT);
1168
if (crl_ext != NULL) {
1169
/* Check syntax of file */
1170
X509V3_CTX ctx;
1171
1172
X509V3_set_ctx_test(&ctx);
1173
X509V3_set_nconf(&ctx, conf);
1174
if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) {
1175
BIO_printf(bio_err,
1176
"Error checking CRL extension section %s\n", crl_ext);
1177
ret = 1;
1178
goto end;
1179
}
1180
}
1181
1182
crlnumberfile = app_conf_try_string(conf, section, ENV_CRLNUMBER);
1183
if (crlnumberfile != NULL) {
1184
if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL))
1185
== NULL) {
1186
BIO_printf(bio_err, "error while loading CRL number\n");
1187
goto end;
1188
}
1189
}
1190
1191
if (!crldays && !crlhours && !crlsec) {
1192
if (!app_conf_try_number(conf, section,
1193
ENV_DEFAULT_CRL_DAYS, &crldays))
1194
crldays = 0;
1195
if (!app_conf_try_number(conf, section,
1196
ENV_DEFAULT_CRL_HOURS, &crlhours))
1197
crlhours = 0;
1198
}
1199
if ((crl_nextupdate == NULL) && (crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
1200
BIO_printf(bio_err,
1201
"cannot lookup how long until the next CRL is issued\n");
1202
goto end;
1203
}
1204
1205
if (verbose)
1206
BIO_printf(bio_err, "making CRL\n");
1207
if ((crl = X509_CRL_new_ex(app_get0_libctx(), app_get0_propq())) == NULL)
1208
goto end;
1209
if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509)))
1210
goto end;
1211
1212
if (!set_crl_lastupdate(crl, crl_lastupdate)) {
1213
BIO_puts(bio_err, "error setting CRL lastUpdate\n");
1214
ret = 1;
1215
goto end;
1216
}
1217
1218
if (!set_crl_nextupdate(crl, crl_nextupdate,
1219
crldays, crlhours, crlsec)) {
1220
BIO_puts(bio_err, "error setting CRL nextUpdate\n");
1221
ret = 1;
1222
goto end;
1223
}
1224
1225
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
1226
pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
1227
if (pp[DB_type][0] == DB_TYPE_REV) {
1228
if ((r = X509_REVOKED_new()) == NULL)
1229
goto end;
1230
j = make_revoked(r, pp[DB_rev_date]);
1231
if (!j)
1232
goto end;
1233
if (j == 2)
1234
crl_v2 = 1;
1235
if (!BN_hex2bn(&serial, pp[DB_serial]))
1236
goto end;
1237
tmpser = BN_to_ASN1_INTEGER(serial, NULL);
1238
BN_free(serial);
1239
serial = NULL;
1240
if (!tmpser)
1241
goto end;
1242
X509_REVOKED_set_serialNumber(r, tmpser);
1243
ASN1_INTEGER_free(tmpser);
1244
X509_CRL_add0_revoked(crl, r);
1245
}
1246
}
1247
1248
/*
1249
* sort the data so it will be written in serial number order
1250
*/
1251
X509_CRL_sort(crl);
1252
1253
/* we now have a CRL */
1254
if (verbose)
1255
BIO_printf(bio_err, "signing CRL\n");
1256
1257
/* Add any extensions asked for */
1258
1259
if (crl_ext != NULL || crlnumberfile != NULL) {
1260
X509V3_CTX crlctx;
1261
1262
X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1263
X509V3_set_nconf(&crlctx, conf);
1264
1265
if (crl_ext != NULL)
1266
if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) {
1267
BIO_printf(bio_err,
1268
"Error adding CRL extensions from section %s\n", crl_ext);
1269
goto end;
1270
}
1271
if (crlnumberfile != NULL) {
1272
tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
1273
if (!tmpser)
1274
goto end;
1275
X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0);
1276
ASN1_INTEGER_free(tmpser);
1277
crl_v2 = 1;
1278
if (!BN_add_word(crlnumber, 1))
1279
goto end;
1280
}
1281
}
1282
if (crl_ext != NULL || crl_v2) {
1283
if (!X509_CRL_set_version(crl, X509_CRL_VERSION_2))
1284
goto end;
1285
}
1286
1287
/* we have a CRL number that need updating */
1288
if (crlnumberfile != NULL
1289
&& !save_serial(crlnumberfile, "new", crlnumber, NULL))
1290
goto end;
1291
1292
BN_free(crlnumber);
1293
crlnumber = NULL;
1294
1295
if (!do_X509_CRL_sign(crl, pkey, dgst, sigopts))
1296
goto end;
1297
1298
Sout = bio_open_default(outfile, 'w',
1299
output_der ? FORMAT_ASN1 : FORMAT_TEXT);
1300
if (Sout == NULL)
1301
goto end;
1302
1303
PEM_write_bio_X509_CRL(Sout, crl);
1304
1305
/* Rename the crlnumber file */
1306
if (crlnumberfile != NULL
1307
&& !rotate_serial(crlnumberfile, "new", "old"))
1308
goto end;
1309
}
1310
/*****************************************************************/
1311
if (dorevoke) {
1312
if (infile == NULL) {
1313
BIO_printf(bio_err, "no input files\n");
1314
goto end;
1315
} else {
1316
X509 *revcert;
1317
1318
revcert = load_cert_pass(infile, informat, 1, passin,
1319
"certificate to be revoked");
1320
if (revcert == NULL)
1321
goto end;
1322
if (dorevoke == 2)
1323
rev_type = REV_VALID;
1324
j = do_revoke(revcert, db, rev_type, rev_arg);
1325
if (j <= 0)
1326
goto end;
1327
X509_free(revcert);
1328
1329
if (!save_index(dbfile, "new", db))
1330
goto end;
1331
1332
if (!rotate_index(dbfile, "new", "old"))
1333
goto end;
1334
1335
BIO_printf(bio_err, "Database updated\n");
1336
}
1337
}
1338
ret = 0;
1339
1340
end:
1341
if (ret)
1342
ERR_print_errors(bio_err);
1343
BIO_free_all(Sout);
1344
BIO_free_all(out);
1345
BIO_free_all(in);
1346
OSSL_STACK_OF_X509_free(cert_sk);
1347
1348
cleanse(passin);
1349
if (free_passin)
1350
OPENSSL_free(passin);
1351
BN_free(serial);
1352
BN_free(crlnumber);
1353
free_index(db);
1354
sk_OPENSSL_STRING_free(sigopts);
1355
sk_OPENSSL_STRING_free(vfyopts);
1356
EVP_PKEY_free(pkey);
1357
X509_free(x509);
1358
X509_CRL_free(crl);
1359
NCONF_free(conf);
1360
NCONF_free(extfile_conf);
1361
release_engine(e);
1362
return ret;
1363
}
1364
1365
static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
1366
{
1367
char *entry = NCONF_get_string(conf, section, tag);
1368
if (entry == NULL)
1369
BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag);
1370
return entry;
1371
}
1372
1373
static int certify(X509 **xret, const char *infile, int informat,
1374
EVP_PKEY *pkey, X509 *x509,
1375
const char *dgst,
1376
STACK_OF(OPENSSL_STRING) *sigopts,
1377
STACK_OF(OPENSSL_STRING) *vfyopts,
1378
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1379
BIGNUM *serial, const char *subj, unsigned long chtype,
1380
int multirdn, int email_dn, const char *startdate,
1381
const char *enddate,
1382
long days, int batch, const char *ext_sect, CONF *lconf,
1383
int verbose, unsigned long certopt, unsigned long nameopt,
1384
int default_op, int ext_copy, int selfsign, unsigned long dateopt)
1385
{
1386
X509_REQ *req = NULL;
1387
EVP_PKEY *pktmp = NULL;
1388
int ok = -1, i;
1389
1390
req = load_csr_autofmt(infile, informat, vfyopts, "certificate request");
1391
if (req == NULL)
1392
goto end;
1393
if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
1394
BIO_printf(bio_err, "Error unpacking public key\n");
1395
goto end;
1396
}
1397
if (verbose)
1398
X509_REQ_print_ex(bio_err, req, nameopt, X509_FLAG_COMPAT);
1399
1400
BIO_printf(bio_err, "Check that the request matches the signature\n");
1401
ok = 0;
1402
1403
if (selfsign && !X509_REQ_check_private_key(req, pkey)) {
1404
BIO_printf(bio_err,
1405
"Certificate request and CA private key do not match\n");
1406
goto end;
1407
}
1408
i = do_X509_REQ_verify(req, pktmp, vfyopts);
1409
if (i < 0) {
1410
BIO_printf(bio_err, "Signature verification problems...\n");
1411
goto end;
1412
}
1413
if (i == 0) {
1414
BIO_printf(bio_err,
1415
"Signature did not match the certificate request\n");
1416
goto end;
1417
}
1418
BIO_printf(bio_err, "Signature ok\n");
1419
1420
ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
1421
chtype, multirdn, email_dn, startdate, enddate, days, batch,
1422
verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
1423
ext_copy, selfsign, dateopt);
1424
1425
end:
1426
ERR_print_errors(bio_err);
1427
X509_REQ_free(req);
1428
return ok;
1429
}
1430
1431
static int certify_cert(X509 **xret, const char *infile, int certformat,
1432
const char *passin, EVP_PKEY *pkey, X509 *x509,
1433
const char *dgst,
1434
STACK_OF(OPENSSL_STRING) *sigopts,
1435
STACK_OF(OPENSSL_STRING) *vfyopts,
1436
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1437
BIGNUM *serial, const char *subj, unsigned long chtype,
1438
int multirdn, int email_dn, const char *startdate,
1439
const char *enddate, long days, int batch, const char *ext_sect,
1440
CONF *lconf, int verbose, unsigned long certopt,
1441
unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt)
1442
{
1443
X509 *template_cert = NULL;
1444
X509_REQ *rreq = NULL;
1445
EVP_PKEY *pktmp = NULL;
1446
int ok = -1, i;
1447
1448
if ((template_cert = load_cert_pass(infile, certformat, 1, passin,
1449
"template certificate"))
1450
== NULL)
1451
goto end;
1452
if (verbose)
1453
X509_print(bio_err, template_cert);
1454
1455
BIO_printf(bio_err, "Check that the request matches the signature\n");
1456
1457
if ((pktmp = X509_get0_pubkey(template_cert)) == NULL) {
1458
BIO_printf(bio_err, "error unpacking public key\n");
1459
goto end;
1460
}
1461
i = do_X509_verify(template_cert, pktmp, vfyopts);
1462
if (i < 0) {
1463
ok = 0;
1464
BIO_printf(bio_err, "Signature verification problems....\n");
1465
goto end;
1466
}
1467
if (i == 0) {
1468
ok = 0;
1469
BIO_printf(bio_err, "Signature did not match the certificate\n");
1470
goto end;
1471
} else {
1472
BIO_printf(bio_err, "Signature ok\n");
1473
}
1474
1475
if ((rreq = X509_to_X509_REQ(template_cert, NULL, NULL)) == NULL)
1476
goto end;
1477
1478
ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
1479
chtype, multirdn, email_dn, startdate, enddate, days, batch,
1480
verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
1481
ext_copy, 0, dateopt);
1482
1483
end:
1484
X509_REQ_free(rreq);
1485
X509_free(template_cert);
1486
return ok;
1487
}
1488
1489
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
1490
const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1491
STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
1492
const char *subj, unsigned long chtype, int multirdn,
1493
int email_dn, const char *startdate, const char *enddate, long days,
1494
int batch, int verbose, X509_REQ *req, const char *ext_sect,
1495
CONF *lconf, unsigned long certopt, unsigned long nameopt,
1496
int default_op, int ext_copy, int selfsign, unsigned long dateopt)
1497
{
1498
const X509_NAME *name = NULL;
1499
X509_NAME *CAname = NULL, *subject = NULL;
1500
const ASN1_TIME *tm;
1501
ASN1_STRING *str, *str2;
1502
ASN1_OBJECT *obj;
1503
X509 *ret = NULL;
1504
X509_NAME_ENTRY *ne, *tne;
1505
EVP_PKEY *pktmp;
1506
int ok = -1, i, j, last, nid;
1507
const char *p;
1508
CONF_VALUE *cv;
1509
OPENSSL_STRING row[DB_NUMBER];
1510
OPENSSL_STRING *irow = NULL;
1511
OPENSSL_STRING *rrow = NULL;
1512
char buf[25];
1513
X509V3_CTX ext_ctx;
1514
1515
for (i = 0; i < DB_NUMBER; i++)
1516
row[i] = NULL;
1517
1518
if (subj) {
1519
X509_NAME *n = parse_name(subj, chtype, multirdn, "subject");
1520
1521
if (!n)
1522
goto end;
1523
X509_REQ_set_subject_name(req, n);
1524
X509_NAME_free(n);
1525
}
1526
1527
if (default_op)
1528
BIO_printf(bio_err, "The Subject's Distinguished Name is as follows\n");
1529
1530
name = X509_REQ_get_subject_name(req);
1531
for (i = 0; i < X509_NAME_entry_count(name); i++) {
1532
ne = X509_NAME_get_entry(name, i);
1533
str = X509_NAME_ENTRY_get_data(ne);
1534
obj = X509_NAME_ENTRY_get_object(ne);
1535
nid = OBJ_obj2nid(obj);
1536
1537
if (msie_hack) {
1538
/* assume all type should be strings */
1539
1540
if (str->type == V_ASN1_UNIVERSALSTRING)
1541
ASN1_UNIVERSALSTRING_to_string(str);
1542
1543
if (str->type == V_ASN1_IA5STRING && nid != NID_pkcs9_emailAddress)
1544
str->type = V_ASN1_T61STRING;
1545
1546
if (nid == NID_pkcs9_emailAddress
1547
&& str->type == V_ASN1_PRINTABLESTRING)
1548
str->type = V_ASN1_IA5STRING;
1549
}
1550
1551
/* If no EMAIL is wanted in the subject */
1552
if (nid == NID_pkcs9_emailAddress && !email_dn)
1553
continue;
1554
1555
/* check some things */
1556
if (nid == NID_pkcs9_emailAddress && str->type != V_ASN1_IA5STRING) {
1557
BIO_printf(bio_err,
1558
"\nemailAddress type needs to be of type IA5STRING\n");
1559
goto end;
1560
}
1561
if (str->type != V_ASN1_BMPSTRING && str->type != V_ASN1_UTF8STRING) {
1562
j = ASN1_PRINTABLE_type(str->data, str->length);
1563
if ((j == V_ASN1_T61STRING && str->type != V_ASN1_T61STRING) || (j == V_ASN1_IA5STRING && str->type == V_ASN1_PRINTABLESTRING)) {
1564
BIO_printf(bio_err,
1565
"\nThe string contains characters that are illegal for the ASN.1 type\n");
1566
goto end;
1567
}
1568
}
1569
1570
if (default_op)
1571
old_entry_print(obj, str);
1572
}
1573
1574
/* Ok, now we check the 'policy' stuff. */
1575
if ((subject = X509_NAME_new()) == NULL) {
1576
BIO_printf(bio_err, "Memory allocation failure\n");
1577
goto end;
1578
}
1579
1580
/* take a copy of the issuer name before we mess with it. */
1581
if (selfsign)
1582
CAname = X509_NAME_dup(name);
1583
else
1584
CAname = X509_NAME_dup(X509_get_subject_name(x509));
1585
if (CAname == NULL)
1586
goto end;
1587
str = str2 = NULL;
1588
1589
for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
1590
cv = sk_CONF_VALUE_value(policy, i); /* get the object id */
1591
if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
1592
BIO_printf(bio_err,
1593
"%s:unknown object type in 'policy' configuration\n",
1594
cv->name);
1595
goto end;
1596
}
1597
obj = OBJ_nid2obj(j);
1598
1599
last = -1;
1600
for (;;) {
1601
X509_NAME_ENTRY *push = NULL;
1602
1603
/* lookup the object in the supplied name list */
1604
j = X509_NAME_get_index_by_OBJ(name, obj, last);
1605
if (j < 0) {
1606
if (last != -1)
1607
break;
1608
tne = NULL;
1609
} else {
1610
tne = X509_NAME_get_entry(name, j);
1611
}
1612
last = j;
1613
1614
/* depending on the 'policy', decide what to do. */
1615
if (strcmp(cv->value, "optional") == 0) {
1616
if (tne != NULL)
1617
push = tne;
1618
} else if (strcmp(cv->value, "supplied") == 0) {
1619
if (tne == NULL) {
1620
BIO_printf(bio_err,
1621
"The %s field needed to be supplied and was missing\n",
1622
cv->name);
1623
goto end;
1624
} else {
1625
push = tne;
1626
}
1627
} else if (strcmp(cv->value, "match") == 0) {
1628
int last2;
1629
1630
if (tne == NULL) {
1631
BIO_printf(bio_err,
1632
"The mandatory %s field was missing\n",
1633
cv->name);
1634
goto end;
1635
}
1636
1637
last2 = -1;
1638
1639
again2:
1640
j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
1641
if ((j < 0) && (last2 == -1)) {
1642
BIO_printf(bio_err,
1643
"The %s field does not exist in the CA certificate,\n"
1644
"the 'policy' is misconfigured\n",
1645
cv->name);
1646
goto end;
1647
}
1648
if (j >= 0) {
1649
push = X509_NAME_get_entry(CAname, j);
1650
str = X509_NAME_ENTRY_get_data(tne);
1651
str2 = X509_NAME_ENTRY_get_data(push);
1652
last2 = j;
1653
if (ASN1_STRING_cmp(str, str2) != 0)
1654
goto again2;
1655
}
1656
if (j < 0) {
1657
BIO_printf(bio_err,
1658
"The %s field is different between\n"
1659
"CA certificate (%s) and the request (%s)\n",
1660
cv->name,
1661
((str2 == NULL) ? "NULL" : (char *)str2->data),
1662
((str == NULL) ? "NULL" : (char *)str->data));
1663
goto end;
1664
}
1665
} else {
1666
BIO_printf(bio_err,
1667
"%s:invalid type in 'policy' configuration\n",
1668
cv->value);
1669
goto end;
1670
}
1671
1672
if (push != NULL) {
1673
if (!X509_NAME_add_entry(subject, push, -1, 0)) {
1674
BIO_printf(bio_err, "Memory allocation failure\n");
1675
goto end;
1676
}
1677
}
1678
if (j < 0)
1679
break;
1680
}
1681
}
1682
1683
if (preserve) {
1684
X509_NAME_free(subject);
1685
/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1686
subject = X509_NAME_dup(name);
1687
if (subject == NULL)
1688
goto end;
1689
}
1690
1691
/* We are now totally happy, lets make and sign the certificate */
1692
if (verbose)
1693
BIO_printf(bio_err,
1694
"Everything appears to be ok, creating and signing the certificate\n");
1695
1696
if ((ret = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL)
1697
goto end;
1698
1699
if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
1700
goto end;
1701
if (selfsign) {
1702
if (!X509_set_issuer_name(ret, subject))
1703
goto end;
1704
} else {
1705
if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
1706
goto end;
1707
}
1708
1709
if (!set_cert_times(ret, startdate, enddate, days, 0))
1710
goto end;
1711
1712
if (enddate != NULL) {
1713
int tdays;
1714
1715
if (!ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret)))
1716
goto end;
1717
days = tdays;
1718
}
1719
1720
if (!X509_set_subject_name(ret, subject))
1721
goto end;
1722
1723
pktmp = X509_REQ_get0_pubkey(req);
1724
i = X509_set_pubkey(ret, pktmp);
1725
if (!i)
1726
goto end;
1727
1728
/* Initialize the context structure */
1729
X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509,
1730
ret, NULL /* no need to give req, needed info is in ret */,
1731
NULL, X509V3_CTX_REPLACE);
1732
/* prepare fallback for AKID, but only if issuer cert equals subject cert */
1733
if (selfsign) {
1734
if (!X509V3_set_issuer_pkey(&ext_ctx, pkey))
1735
goto end;
1736
if (!cert_matches_key(ret, pkey))
1737
BIO_printf(bio_err,
1738
"Warning: Signature key and public key of cert do not match\n");
1739
}
1740
1741
/* Lets add the extensions, if there are any */
1742
if (ext_sect) {
1743
if (extfile_conf != NULL) {
1744
if (verbose)
1745
BIO_printf(bio_err, "Extra configuration file found\n");
1746
1747
/* Use the extfile_conf configuration db LHASH */
1748
X509V3_set_nconf(&ext_ctx, extfile_conf);
1749
1750
/* Adds exts contained in the configuration file */
1751
if (!X509V3_EXT_add_nconf(extfile_conf, &ext_ctx, ext_sect, ret)) {
1752
BIO_printf(bio_err,
1753
"Error adding certificate extensions from extfile section %s\n",
1754
ext_sect);
1755
goto end;
1756
}
1757
if (verbose)
1758
BIO_printf(bio_err,
1759
"Successfully added extensions from file.\n");
1760
} else if (ext_sect) {
1761
/* We found extensions to be set from config file */
1762
X509V3_set_nconf(&ext_ctx, lconf);
1763
1764
if (!X509V3_EXT_add_nconf(lconf, &ext_ctx, ext_sect, ret)) {
1765
BIO_printf(bio_err,
1766
"Error adding certificate extensions from config section %s\n",
1767
ext_sect);
1768
goto end;
1769
}
1770
1771
if (verbose)
1772
BIO_printf(bio_err,
1773
"Successfully added extensions from config\n");
1774
}
1775
}
1776
1777
/* Copy extensions from request (if any) */
1778
1779
if (!copy_extensions(ret, req, ext_copy)) {
1780
BIO_printf(bio_err, "ERROR: adding extensions from request\n");
1781
goto end;
1782
}
1783
1784
if (verbose)
1785
BIO_printf(bio_err,
1786
"The subject name appears to be ok, checking database for clashes\n");
1787
1788
/* Build the correct Subject if no e-mail is wanted in the subject. */
1789
if (!email_dn) {
1790
X509_NAME_ENTRY *tmpne;
1791
X509_NAME *dn_subject;
1792
1793
/*
1794
* Its best to dup the subject DN and then delete any email addresses
1795
* because this retains its structure.
1796
*/
1797
if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
1798
BIO_printf(bio_err, "Memory allocation failure\n");
1799
goto end;
1800
}
1801
i = -1;
1802
while ((i = X509_NAME_get_index_by_NID(dn_subject,
1803
NID_pkcs9_emailAddress,
1804
i))
1805
>= 0) {
1806
tmpne = X509_NAME_delete_entry(dn_subject, i--);
1807
X509_NAME_ENTRY_free(tmpne);
1808
}
1809
1810
if (!X509_set_subject_name(ret, dn_subject)) {
1811
X509_NAME_free(dn_subject);
1812
goto end;
1813
}
1814
X509_NAME_free(dn_subject);
1815
}
1816
1817
row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
1818
if (row[DB_name] == NULL) {
1819
BIO_printf(bio_err, "Memory allocation failure\n");
1820
goto end;
1821
}
1822
1823
if (BN_is_zero(serial))
1824
row[DB_serial] = OPENSSL_strdup("00");
1825
else
1826
row[DB_serial] = BN_bn2hex(serial);
1827
if (row[DB_serial] == NULL) {
1828
BIO_printf(bio_err, "Memory allocation failure\n");
1829
goto end;
1830
}
1831
1832
if (row[DB_name][0] == '\0') {
1833
/*
1834
* An empty subject! We'll use the serial number instead. If
1835
* unique_subject is in use then we don't want different entries with
1836
* empty subjects matching each other.
1837
*/
1838
OPENSSL_free(row[DB_name]);
1839
row[DB_name] = OPENSSL_strdup(row[DB_serial]);
1840
if (row[DB_name] == NULL) {
1841
BIO_printf(bio_err, "Memory allocation failure\n");
1842
goto end;
1843
}
1844
}
1845
1846
if (db->attributes.unique_subject) {
1847
OPENSSL_STRING *crow = row;
1848
1849
rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
1850
if (rrow != NULL) {
1851
BIO_printf(bio_err,
1852
"ERROR:There is already a certificate for %s\n",
1853
row[DB_name]);
1854
}
1855
}
1856
if (rrow == NULL) {
1857
rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
1858
if (rrow != NULL) {
1859
BIO_printf(bio_err,
1860
"ERROR:Serial number %s has already been issued,\n",
1861
row[DB_serial]);
1862
BIO_printf(bio_err,
1863
" check the database/serial_file for corruption\n");
1864
}
1865
}
1866
1867
if (rrow != NULL) {
1868
BIO_printf(bio_err, "The matching entry has the following details\n");
1869
if (rrow[DB_type][0] == DB_TYPE_EXP)
1870
p = "Expired";
1871
else if (rrow[DB_type][0] == DB_TYPE_REV)
1872
p = "Revoked";
1873
else if (rrow[DB_type][0] == DB_TYPE_VAL)
1874
p = "Valid";
1875
else
1876
p = "\ninvalid type, Database error\n";
1877
BIO_printf(bio_err, "Type :%s\n", p);
1878
if (rrow[DB_type][0] == DB_TYPE_REV) {
1879
p = rrow[DB_exp_date];
1880
if (p == NULL)
1881
p = "undef";
1882
BIO_printf(bio_err, "Was revoked on:%s\n", p);
1883
}
1884
p = rrow[DB_exp_date];
1885
if (p == NULL)
1886
p = "undef";
1887
BIO_printf(bio_err, "Expires on :%s\n", p);
1888
p = rrow[DB_serial];
1889
if (p == NULL)
1890
p = "undef";
1891
BIO_printf(bio_err, "Serial Number :%s\n", p);
1892
p = rrow[DB_file];
1893
if (p == NULL)
1894
p = "undef";
1895
BIO_printf(bio_err, "File name :%s\n", p);
1896
p = rrow[DB_name];
1897
if (p == NULL)
1898
p = "undef";
1899
BIO_printf(bio_err, "Subject Name :%s\n", p);
1900
ok = -1; /* This is now a 'bad' error. */
1901
goto end;
1902
}
1903
1904
if (!default_op) {
1905
BIO_printf(bio_err, "Certificate Details:\n");
1906
/*
1907
* Never print signature details because signature not present
1908
*/
1909
certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
1910
X509_print_ex(bio_err, ret, nameopt, certopt);
1911
}
1912
1913
BIO_printf(bio_err, "Certificate is to be certified until ");
1914
ASN1_TIME_print_ex(bio_err, X509_get0_notAfter(ret), dateopt);
1915
if (days)
1916
BIO_printf(bio_err, " (%ld days)", days);
1917
BIO_printf(bio_err, "\n");
1918
1919
if (!batch) {
1920
1921
BIO_printf(bio_err, "Sign the certificate? [y/n]:");
1922
(void)BIO_flush(bio_err);
1923
buf[0] = '\0';
1924
if (fgets(buf, sizeof(buf), stdin) == NULL) {
1925
BIO_printf(bio_err,
1926
"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
1927
ok = 0;
1928
goto end;
1929
}
1930
if (!(buf[0] == 'y' || buf[0] == 'Y')) {
1931
BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n");
1932
ok = 0;
1933
goto end;
1934
}
1935
}
1936
1937
pktmp = X509_get0_pubkey(ret);
1938
if (EVP_PKEY_missing_parameters(pktmp) && !EVP_PKEY_missing_parameters(pkey))
1939
EVP_PKEY_copy_parameters(pktmp, pkey);
1940
1941
if (!do_X509_sign(ret, 0, pkey, dgst, sigopts, &ext_ctx))
1942
goto end;
1943
1944
/* We now just add it to the database as DB_TYPE_VAL('V') */
1945
row[DB_type] = OPENSSL_strdup("V");
1946
tm = X509_get0_notAfter(ret);
1947
row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
1948
memcpy(row[DB_exp_date], tm->data, tm->length);
1949
row[DB_exp_date][tm->length] = '\0';
1950
row[DB_rev_date] = NULL;
1951
row[DB_file] = OPENSSL_strdup("unknown");
1952
if ((row[DB_type] == NULL) || (row[DB_file] == NULL)
1953
|| (row[DB_name] == NULL)) {
1954
BIO_printf(bio_err, "Memory allocation failure\n");
1955
goto end;
1956
}
1957
1958
irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");
1959
for (i = 0; i < DB_NUMBER; i++)
1960
irow[i] = row[i];
1961
irow[DB_NUMBER] = NULL;
1962
1963
if (!TXT_DB_insert(db->db, irow)) {
1964
BIO_printf(bio_err, "failed to update database\n");
1965
BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
1966
goto end;
1967
}
1968
irow = NULL;
1969
ok = 1;
1970
end:
1971
if (ok != 1) {
1972
for (i = 0; i < DB_NUMBER; i++)
1973
OPENSSL_free(row[i]);
1974
}
1975
OPENSSL_free(irow);
1976
1977
X509_NAME_free(CAname);
1978
X509_NAME_free(subject);
1979
if (ok <= 0)
1980
X509_free(ret);
1981
else
1982
*xret = ret;
1983
return ok;
1984
}
1985
1986
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
1987
{
1988
1989
if (output_der) {
1990
(void)i2d_X509_bio(bp, x);
1991
return;
1992
}
1993
if (!notext)
1994
X509_print(bp, x);
1995
PEM_write_bio_X509(bp, x);
1996
}
1997
1998
static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
1999
X509 *x509, const char *dgst,
2000
STACK_OF(OPENSSL_STRING) *sigopts,
2001
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2002
BIGNUM *serial, const char *subj, unsigned long chtype,
2003
int multirdn, int email_dn, const char *startdate,
2004
const char *enddate, long days, const char *ext_sect,
2005
CONF *lconf, int verbose, unsigned long certopt,
2006
unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt)
2007
{
2008
STACK_OF(CONF_VALUE) *sk = NULL;
2009
LHASH_OF(CONF_VALUE) *parms = NULL;
2010
X509_REQ *req = NULL;
2011
CONF_VALUE *cv = NULL;
2012
NETSCAPE_SPKI *spki = NULL;
2013
char *type, *buf;
2014
EVP_PKEY *pktmp = NULL;
2015
X509_NAME *n = NULL;
2016
X509_NAME_ENTRY *ne = NULL;
2017
int ok = -1, i, j;
2018
long errline;
2019
int nid;
2020
2021
/*
2022
* Load input file into a hash table. (This is just an easy
2023
* way to read and parse the file, then put it into a convenient
2024
* STACK format).
2025
*/
2026
parms = CONF_load(NULL, infile, &errline);
2027
if (parms == NULL) {
2028
BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile);
2029
goto end;
2030
}
2031
2032
sk = CONF_get_section(parms, "default");
2033
if (sk_CONF_VALUE_num(sk) == 0) {
2034
BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
2035
goto end;
2036
}
2037
2038
/*
2039
* Now create a dummy X509 request structure. We don't actually
2040
* have an X509 request, but we have many of the components
2041
* (a public key, various DN components). The idea is that we
2042
* put these components into the right X509 request structure
2043
* and we can use the same code as if you had a real X509 request.
2044
*/
2045
req = X509_REQ_new();
2046
if (req == NULL)
2047
goto end;
2048
2049
/*
2050
* Build up the subject name set.
2051
*/
2052
n = X509_REQ_get_subject_name(req);
2053
2054
for (i = 0;; i++) {
2055
if (sk_CONF_VALUE_num(sk) <= i)
2056
break;
2057
2058
cv = sk_CONF_VALUE_value(sk, i);
2059
type = cv->name;
2060
/*
2061
* Skip past any leading X. X: X, etc to allow for multiple instances
2062
*/
2063
for (buf = cv->name; *buf; buf++)
2064
if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
2065
buf++;
2066
if (*buf)
2067
type = buf;
2068
break;
2069
}
2070
2071
buf = cv->value;
2072
if ((nid = OBJ_txt2nid(type)) == NID_undef) {
2073
if (strcmp(type, "SPKAC") == 0) {
2074
spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
2075
if (spki == NULL) {
2076
BIO_printf(bio_err,
2077
"unable to load Netscape SPKAC structure\n");
2078
goto end;
2079
}
2080
}
2081
continue;
2082
}
2083
2084
if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
2085
(unsigned char *)buf, -1, -1, 0))
2086
goto end;
2087
}
2088
if (spki == NULL) {
2089
BIO_printf(bio_err, "Netscape SPKAC structure not found in %s\n",
2090
infile);
2091
goto end;
2092
}
2093
2094
/*
2095
* Now extract the key from the SPKI structure.
2096
*/
2097
2098
BIO_printf(bio_err, "Check that the SPKAC request matches the signature\n");
2099
2100
if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) {
2101
BIO_printf(bio_err, "error unpacking SPKAC public key\n");
2102
goto end;
2103
}
2104
2105
j = NETSCAPE_SPKI_verify(spki, pktmp);
2106
if (j <= 0) {
2107
EVP_PKEY_free(pktmp);
2108
BIO_printf(bio_err,
2109
"signature verification failed on SPKAC public key\n");
2110
goto end;
2111
}
2112
BIO_printf(bio_err, "Signature ok\n");
2113
2114
X509_REQ_set_pubkey(req, pktmp);
2115
EVP_PKEY_free(pktmp);
2116
ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
2117
chtype, multirdn, email_dn, startdate, enddate, days, 1,
2118
verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
2119
ext_copy, 0, dateopt);
2120
end:
2121
X509_REQ_free(req);
2122
CONF_free(parms);
2123
NETSCAPE_SPKI_free(spki);
2124
X509_NAME_ENTRY_free(ne);
2125
2126
return ok;
2127
}
2128
2129
static int check_time_format(const char *str)
2130
{
2131
return ASN1_TIME_set_string(NULL, str);
2132
}
2133
2134
static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
2135
const char *value)
2136
{
2137
const ASN1_TIME *tm = NULL;
2138
char *row[DB_NUMBER], **rrow, **irow;
2139
char *rev_str = NULL;
2140
BIGNUM *bn = NULL;
2141
int ok = -1, i;
2142
2143
for (i = 0; i < DB_NUMBER; i++)
2144
row[i] = NULL;
2145
row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0);
2146
bn = ASN1_INTEGER_to_BN(X509_get0_serialNumber(x509), NULL);
2147
if (!bn)
2148
goto end;
2149
if (BN_is_zero(bn))
2150
row[DB_serial] = OPENSSL_strdup("00");
2151
else
2152
row[DB_serial] = BN_bn2hex(bn);
2153
BN_free(bn);
2154
if (row[DB_name] != NULL && row[DB_name][0] == '\0') {
2155
/* Entries with empty Subjects actually use the serial number instead */
2156
OPENSSL_free(row[DB_name]);
2157
row[DB_name] = OPENSSL_strdup(row[DB_serial]);
2158
}
2159
if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
2160
BIO_printf(bio_err, "Memory allocation failure\n");
2161
goto end;
2162
}
2163
/*
2164
* We have to lookup by serial number because name lookup skips revoked
2165
* certs
2166
*/
2167
rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2168
if (rrow == NULL) {
2169
BIO_printf(bio_err,
2170
"Adding Entry with serial number %s to DB for %s\n",
2171
row[DB_serial], row[DB_name]);
2172
2173
/* We now just add it to the database as DB_TYPE_REV('V') */
2174
row[DB_type] = OPENSSL_strdup("V");
2175
tm = X509_get0_notAfter(x509);
2176
row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data");
2177
memcpy(row[DB_exp_date], tm->data, tm->length);
2178
row[DB_exp_date][tm->length] = '\0';
2179
row[DB_rev_date] = NULL;
2180
row[DB_file] = OPENSSL_strdup("unknown");
2181
2182
if (row[DB_type] == NULL || row[DB_file] == NULL) {
2183
BIO_printf(bio_err, "Memory allocation failure\n");
2184
goto end;
2185
}
2186
2187
irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row ptr");
2188
for (i = 0; i < DB_NUMBER; i++)
2189
irow[i] = row[i];
2190
irow[DB_NUMBER] = NULL;
2191
2192
if (!TXT_DB_insert(db->db, irow)) {
2193
BIO_printf(bio_err, "failed to update database\n");
2194
BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
2195
OPENSSL_free(irow);
2196
goto end;
2197
}
2198
2199
for (i = 0; i < DB_NUMBER; i++)
2200
row[i] = NULL;
2201
2202
/* Revoke Certificate */
2203
if (rev_type == REV_VALID)
2204
ok = 1;
2205
else
2206
/* Retry revocation after DB insertion */
2207
ok = do_revoke(x509, db, rev_type, value);
2208
2209
goto end;
2210
2211
} else if (index_name_cmp_noconst(row, rrow)) {
2212
BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]);
2213
goto end;
2214
} else if (rev_type == REV_VALID) {
2215
BIO_printf(bio_err, "ERROR:Already present, serial number %s\n",
2216
row[DB_serial]);
2217
goto end;
2218
} else if (rrow[DB_type][0] == DB_TYPE_REV) {
2219
BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
2220
row[DB_serial]);
2221
goto end;
2222
} else {
2223
BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]);
2224
rev_str = make_revocation_str(rev_type, value);
2225
if (!rev_str) {
2226
BIO_printf(bio_err, "Error in revocation arguments\n");
2227
goto end;
2228
}
2229
rrow[DB_type][0] = DB_TYPE_REV;
2230
rrow[DB_type][1] = '\0';
2231
rrow[DB_rev_date] = rev_str;
2232
}
2233
ok = 1;
2234
end:
2235
for (i = 0; i < DB_NUMBER; i++)
2236
OPENSSL_free(row[i]);
2237
return ok;
2238
}
2239
2240
static int get_certificate_status(const char *serial, CA_DB *db)
2241
{
2242
char *row[DB_NUMBER], **rrow;
2243
int ok = -1, i;
2244
size_t serial_len = strlen(serial);
2245
2246
/* Free Resources */
2247
for (i = 0; i < DB_NUMBER; i++)
2248
row[i] = NULL;
2249
2250
/* Malloc needed char spaces */
2251
row[DB_serial] = app_malloc(serial_len + 2, "row serial#");
2252
2253
if (serial_len % 2) {
2254
/*
2255
* Set the first char to 0
2256
*/
2257
row[DB_serial][0] = '0';
2258
2259
/* Copy String from serial to row[DB_serial] */
2260
memcpy(row[DB_serial] + 1, serial, serial_len);
2261
row[DB_serial][serial_len + 1] = '\0';
2262
} else {
2263
/* Copy String from serial to row[DB_serial] */
2264
memcpy(row[DB_serial], serial, serial_len);
2265
row[DB_serial][serial_len] = '\0';
2266
}
2267
2268
/* Make it Upper Case */
2269
make_uppercase(row[DB_serial]);
2270
2271
ok = 1;
2272
2273
/* Search for the certificate */
2274
rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2275
if (rrow == NULL) {
2276
BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]);
2277
ok = -1;
2278
goto end;
2279
} else if (rrow[DB_type][0] == DB_TYPE_VAL) {
2280
BIO_printf(bio_err, "%s=Valid (%c)\n",
2281
row[DB_serial], rrow[DB_type][0]);
2282
goto end;
2283
} else if (rrow[DB_type][0] == DB_TYPE_REV) {
2284
BIO_printf(bio_err, "%s=Revoked (%c)\n",
2285
row[DB_serial], rrow[DB_type][0]);
2286
goto end;
2287
} else if (rrow[DB_type][0] == DB_TYPE_EXP) {
2288
BIO_printf(bio_err, "%s=Expired (%c)\n",
2289
row[DB_serial], rrow[DB_type][0]);
2290
goto end;
2291
} else if (rrow[DB_type][0] == DB_TYPE_SUSP) {
2292
BIO_printf(bio_err, "%s=Suspended (%c)\n",
2293
row[DB_serial], rrow[DB_type][0]);
2294
goto end;
2295
} else {
2296
BIO_printf(bio_err, "%s=Unknown (%c).\n",
2297
row[DB_serial], rrow[DB_type][0]);
2298
ok = -1;
2299
}
2300
end:
2301
for (i = 0; i < DB_NUMBER; i++) {
2302
OPENSSL_free(row[i]);
2303
}
2304
return ok;
2305
}
2306
2307
int do_updatedb(CA_DB *db, time_t *now)
2308
{
2309
ASN1_TIME *a_tm = NULL;
2310
int i, cnt = 0;
2311
char **rrow;
2312
2313
a_tm = ASN1_TIME_new();
2314
if (a_tm == NULL)
2315
return -1;
2316
2317
/* get actual time */
2318
if (X509_time_adj(a_tm, 0, now) == NULL) {
2319
ASN1_TIME_free(a_tm);
2320
return -1;
2321
}
2322
2323
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
2324
rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
2325
2326
if (rrow[DB_type][0] == DB_TYPE_VAL) {
2327
/* ignore entries that are not valid */
2328
ASN1_TIME *exp_date = NULL;
2329
2330
exp_date = ASN1_TIME_new();
2331
if (exp_date == NULL) {
2332
ASN1_TIME_free(a_tm);
2333
return -1;
2334
}
2335
2336
if (!ASN1_TIME_set_string(exp_date, rrow[DB_exp_date])) {
2337
ASN1_TIME_free(a_tm);
2338
ASN1_TIME_free(exp_date);
2339
return -1;
2340
}
2341
2342
if (ASN1_TIME_compare(exp_date, a_tm) <= 0) {
2343
rrow[DB_type][0] = DB_TYPE_EXP;
2344
rrow[DB_type][1] = '\0';
2345
cnt++;
2346
2347
BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
2348
}
2349
ASN1_TIME_free(exp_date);
2350
}
2351
}
2352
2353
ASN1_TIME_free(a_tm);
2354
return cnt;
2355
}
2356
2357
static const char *crl_reasons[] = {
2358
/* CRL reason strings */
2359
"unspecified",
2360
"keyCompromise",
2361
"CACompromise",
2362
"affiliationChanged",
2363
"superseded",
2364
"cessationOfOperation",
2365
"certificateHold",
2366
"removeFromCRL",
2367
/* Additional pseudo reasons */
2368
"holdInstruction",
2369
"keyTime",
2370
"CAkeyTime"
2371
};
2372
2373
#define NUM_REASONS OSSL_NELEM(crl_reasons)
2374
2375
/*
2376
* Given revocation information convert to a DB string. The format of the
2377
* string is: revtime[,reason,extra]. Where 'revtime' is the revocation time
2378
* (the current time). 'reason' is the optional CRL reason and 'extra' is any
2379
* additional argument
2380
*/
2381
2382
static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg)
2383
{
2384
char *str;
2385
const char *reason = NULL, *other = NULL;
2386
ASN1_OBJECT *otmp;
2387
ASN1_UTCTIME *revtm = NULL;
2388
int i;
2389
2390
switch (rev_type) {
2391
case REV_NONE:
2392
case REV_VALID:
2393
break;
2394
2395
case REV_CRL_REASON:
2396
for (i = 0; i < 8; i++) {
2397
if (OPENSSL_strcasecmp(rev_arg, crl_reasons[i]) == 0) {
2398
reason = crl_reasons[i];
2399
break;
2400
}
2401
}
2402
if (reason == NULL) {
2403
BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2404
return NULL;
2405
}
2406
break;
2407
2408
case REV_HOLD:
2409
/* Argument is an OID */
2410
otmp = OBJ_txt2obj(rev_arg, 0);
2411
ASN1_OBJECT_free(otmp);
2412
2413
if (otmp == NULL) {
2414
BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
2415
return NULL;
2416
}
2417
2418
reason = "holdInstruction";
2419
other = rev_arg;
2420
break;
2421
2422
case REV_KEY_COMPROMISE:
2423
case REV_CA_COMPROMISE:
2424
/* Argument is the key compromise time */
2425
if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
2426
BIO_printf(bio_err,
2427
"Invalid time format %s. Need YYYYMMDDHHMMSSZ\n",
2428
rev_arg);
2429
return NULL;
2430
}
2431
other = rev_arg;
2432
if (rev_type == REV_KEY_COMPROMISE)
2433
reason = "keyTime";
2434
else
2435
reason = "CAkeyTime";
2436
2437
break;
2438
}
2439
2440
revtm = X509_gmtime_adj(NULL, 0);
2441
2442
if (!revtm)
2443
return NULL;
2444
2445
i = revtm->length + 1;
2446
2447
if (reason)
2448
i += strlen(reason) + 1;
2449
if (other)
2450
i += strlen(other) + 1;
2451
2452
str = app_malloc(i, "revocation reason");
2453
OPENSSL_strlcpy(str, (char *)revtm->data, i);
2454
if (reason) {
2455
OPENSSL_strlcat(str, ",", i);
2456
OPENSSL_strlcat(str, reason, i);
2457
}
2458
if (other) {
2459
OPENSSL_strlcat(str, ",", i);
2460
OPENSSL_strlcat(str, other, i);
2461
}
2462
ASN1_UTCTIME_free(revtm);
2463
return str;
2464
}
2465
2466
/*-
2467
* Convert revocation field to X509_REVOKED entry
2468
* return code:
2469
* 0 error
2470
* 1 OK
2471
* 2 OK and some extensions added (i.e. V2 CRL)
2472
*/
2473
2474
static int make_revoked(X509_REVOKED *rev, const char *str)
2475
{
2476
char *tmp = NULL;
2477
int reason_code = -1;
2478
int i, ret = 0;
2479
ASN1_OBJECT *hold = NULL;
2480
ASN1_GENERALIZEDTIME *comp_time = NULL;
2481
ASN1_ENUMERATED *rtmp = NULL;
2482
2483
ASN1_TIME *revDate = NULL;
2484
2485
i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2486
2487
if (i == 0)
2488
goto end;
2489
2490
if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
2491
goto end;
2492
2493
if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) {
2494
rtmp = ASN1_ENUMERATED_new();
2495
if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code))
2496
goto end;
2497
if (X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0) <= 0)
2498
goto end;
2499
}
2500
2501
if (rev && comp_time) {
2502
if (X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0) <= 0)
2503
goto end;
2504
}
2505
if (rev && hold) {
2506
if (X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0) <= 0)
2507
goto end;
2508
}
2509
2510
if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2511
ret = 2;
2512
else
2513
ret = 1;
2514
2515
end:
2516
2517
OPENSSL_free(tmp);
2518
ASN1_OBJECT_free(hold);
2519
ASN1_GENERALIZEDTIME_free(comp_time);
2520
ASN1_ENUMERATED_free(rtmp);
2521
ASN1_TIME_free(revDate);
2522
2523
return ret;
2524
}
2525
2526
static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str)
2527
{
2528
char buf[25], *pbuf;
2529
const char *p;
2530
int j;
2531
2532
j = i2a_ASN1_OBJECT(bio_err, obj);
2533
pbuf = buf;
2534
for (j = 22 - j; j > 0; j--)
2535
*(pbuf++) = ' ';
2536
*(pbuf++) = ':';
2537
*(pbuf++) = '\0';
2538
BIO_puts(bio_err, buf);
2539
2540
if (str->type == V_ASN1_PRINTABLESTRING)
2541
BIO_printf(bio_err, "PRINTABLE:'");
2542
else if (str->type == V_ASN1_T61STRING)
2543
BIO_printf(bio_err, "T61STRING:'");
2544
else if (str->type == V_ASN1_IA5STRING)
2545
BIO_printf(bio_err, "IA5STRING:'");
2546
else if (str->type == V_ASN1_UNIVERSALSTRING)
2547
BIO_printf(bio_err, "UNIVERSALSTRING:'");
2548
else
2549
BIO_printf(bio_err, "ASN.1 %2d:'", str->type);
2550
2551
p = (const char *)str->data;
2552
for (j = str->length; j > 0; j--) {
2553
if ((*p >= ' ') && (*p <= '~'))
2554
BIO_printf(bio_err, "%c", *p);
2555
else if (*p & 0x80)
2556
BIO_printf(bio_err, "\\0x%02X", *p);
2557
else if ((unsigned char)*p == 0xf7)
2558
BIO_printf(bio_err, "^?");
2559
else
2560
BIO_printf(bio_err, "^%c", *p + '@');
2561
p++;
2562
}
2563
BIO_printf(bio_err, "'\n");
2564
return 1;
2565
}
2566
2567
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
2568
ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2569
{
2570
char *tmp;
2571
char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2572
int reason_code = -1;
2573
int ret = 0;
2574
unsigned int i;
2575
ASN1_OBJECT *hold = NULL;
2576
ASN1_GENERALIZEDTIME *comp_time = NULL;
2577
2578
tmp = OPENSSL_strdup(str);
2579
if (!tmp) {
2580
BIO_printf(bio_err, "memory allocation failure\n");
2581
goto end;
2582
}
2583
2584
p = strchr(tmp, ',');
2585
2586
rtime_str = tmp;
2587
2588
if (p) {
2589
*p = '\0';
2590
p++;
2591
reason_str = p;
2592
p = strchr(p, ',');
2593
if (p) {
2594
*p = '\0';
2595
arg_str = p + 1;
2596
}
2597
}
2598
2599
if (prevtm) {
2600
*prevtm = ASN1_UTCTIME_new();
2601
if (*prevtm == NULL) {
2602
BIO_printf(bio_err, "memory allocation failure\n");
2603
goto end;
2604
}
2605
if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) {
2606
BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
2607
goto end;
2608
}
2609
}
2610
if (reason_str) {
2611
for (i = 0; i < NUM_REASONS; i++) {
2612
if (OPENSSL_strcasecmp(reason_str, crl_reasons[i]) == 0) {
2613
reason_code = i;
2614
break;
2615
}
2616
}
2617
if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) {
2618
BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
2619
goto end;
2620
}
2621
2622
if (reason_code == 7) {
2623
reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2624
} else if (reason_code == 8) { /* Hold instruction */
2625
if (!arg_str) {
2626
BIO_printf(bio_err, "missing hold instruction\n");
2627
goto end;
2628
}
2629
reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2630
hold = OBJ_txt2obj(arg_str, 0);
2631
2632
if (!hold) {
2633
BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
2634
goto end;
2635
}
2636
if (phold)
2637
*phold = hold;
2638
else
2639
ASN1_OBJECT_free(hold);
2640
} else if ((reason_code == 9) || (reason_code == 10)) {
2641
if (!arg_str) {
2642
BIO_printf(bio_err, "missing compromised time\n");
2643
goto end;
2644
}
2645
comp_time = ASN1_GENERALIZEDTIME_new();
2646
if (comp_time == NULL) {
2647
BIO_printf(bio_err, "memory allocation failure\n");
2648
goto end;
2649
}
2650
if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) {
2651
BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
2652
goto end;
2653
}
2654
if (reason_code == 9)
2655
reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2656
else
2657
reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2658
}
2659
}
2660
2661
if (preason)
2662
*preason = reason_code;
2663
if (pinvtm) {
2664
*pinvtm = comp_time;
2665
comp_time = NULL;
2666
}
2667
2668
ret = 1;
2669
2670
end:
2671
2672
OPENSSL_free(tmp);
2673
ASN1_GENERALIZEDTIME_free(comp_time);
2674
2675
return ret;
2676
}
2677
2678