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