]> git.ipfire.org Git - thirdparty/openssl.git/blame - apps/lib/apps.c
Rename OPENSSL_CTX prefix to OSSL_LIB_CTX
[thirdparty/openssl.git] / apps / lib / apps.c
CommitLineData
846e33c7 1/*
33388b44 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
a661b653 3 *
dffa7520 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
846e33c7
RS
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
a661b653 8 */
d02b48c6 9
fc7dae52 10#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
0f113f3e
MC
11/*
12 * On VMS, you need to define this to get the declaration of fileno(). The
13 * value 2 is to make sure no function defined in POSIX-2 is left undefined.
68d39f3c 14 */
0f113f3e 15# define _POSIX_C_SOURCE 2
83d8fa7d 16#endif
75dd6c1a 17
d02b48c6
RE
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
b379fe6c 21#include <sys/types.h>
a412b891
RL
22#ifndef OPENSSL_NO_POSIX_IO
23# include <sys/stat.h>
24# include <fcntl.h>
25#endif
d652a095 26#include <ctype.h>
a1ad253f 27#include <errno.h>
90ae4673
RL
28#include <openssl/err.h>
29#include <openssl/x509.h>
535d79da 30#include <openssl/x509v3.h>
90ae4673 31#include <openssl/pem.h>
6d382c74 32#include <openssl/store.h>
90ae4673 33#include <openssl/pkcs12.h>
2fe5adc3 34#include <openssl/ui.h>
90ae4673 35#include <openssl/safestack.h>
3eeaab4b 36#ifndef OPENSSL_NO_RSA
0f113f3e 37# include <openssl/rsa.h>
3eeaab4b 38#endif
f0eae953 39#include <openssl/bn.h>
7e1b7485 40#include <openssl/ssl.h>
d610d27f 41#include "apps.h"
d610d27f 42
a1ad253f
AP
43#ifdef _WIN32
44static int WIN32_rename(const char *from, const char *to);
0f113f3e 45# define rename(from,to) WIN32_rename((from),(to))
a1ad253f
AP
46#endif
47
d0cf719e
DMSP
48#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
49# include <conio.h>
50#endif
51
52#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
53# define _kbhit kbhit
54#endif
55
62ca1565
DO
56#define PASS_SOURCE_SIZE_MAX 4
57
852c2ed2 58DEFINE_STACK_OF(CONF)
852c2ed2 59
8ca533e3 60typedef struct {
0f113f3e
MC
61 const char *name;
62 unsigned long flag;
63 unsigned long mask;
8ca533e3
DSH
64} NAME_EX_TBL;
65
b4250010 66static OSSL_LIB_CTX *app_libctx = NULL;
ae89578b 67
0f113f3e
MC
68static int set_table_opts(unsigned long *flags, const char *arg,
69 const NAME_EX_TBL * in_tbl);
70static int set_multi_opts(unsigned long *flags, const char *arg,
71 const NAME_EX_TBL * in_tbl);
8ca533e3 72
d02b48c6 73int app_init(long mesgwin);
0f113f3e 74
7e1b7485 75int chopup_args(ARGS *arg, char *buf)
0f113f3e 76{
7e1b7485 77 int quoted;
4c9b0a03 78 char c = '\0', *p = NULL;
0f113f3e 79
7e1b7485
RS
80 arg->argc = 0;
81 if (arg->size == 0) {
82 arg->size = 20;
b4faea50 83 arg->argv = app_malloc(sizeof(*arg->argv) * arg->size, "argv space");
0f113f3e 84 }
0f113f3e 85
7e1b7485
RS
86 for (p = buf;;) {
87 /* Skip whitespace. */
18295f0c 88 while (*p && isspace(_UC(*p)))
0f113f3e 89 p++;
12a765a5 90 if (*p == '\0')
0f113f3e
MC
91 break;
92
93 /* The start of something good :-) */
7e1b7485 94 if (arg->argc >= arg->size) {
7c0ef843 95 char **tmp;
7e1b7485 96 arg->size += 20;
7c0ef843
DSH
97 tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size);
98 if (tmp == NULL)
0f113f3e 99 return 0;
7c0ef843 100 arg->argv = tmp;
0f113f3e 101 }
7e1b7485
RS
102 quoted = *p == '\'' || *p == '"';
103 if (quoted)
104 c = *p++;
105 arg->argv[arg->argc++] = p;
0f113f3e
MC
106
107 /* now look for the end of this */
7e1b7485
RS
108 if (quoted) {
109 while (*p && *p != c)
0f113f3e 110 p++;
7e1b7485 111 *p++ = '\0';
0f113f3e 112 } else {
18295f0c 113 while (*p && !isspace(_UC(*p)))
0f113f3e 114 p++;
7e1b7485
RS
115 if (*p)
116 *p++ = '\0';
0f113f3e 117 }
0f113f3e 118 }
7e1b7485 119 arg->argv[arg->argc] = NULL;
208fb891 120 return 1;
0f113f3e 121}
d02b48c6
RE
122
123#ifndef APP_INIT
6b691a5c 124int app_init(long mesgwin)
0f113f3e 125{
208fb891 126 return 1;
0f113f3e 127}
d02b48c6 128#endif
53b1899e 129
fd3397fc
RL
130int ctx_set_verify_locations(SSL_CTX *ctx,
131 const char *CAfile, int noCAfile,
132 const char *CApath, int noCApath,
133 const char *CAstore, int noCAstore)
7e1b7485 134{
fd3397fc 135 if (CAfile == NULL && CApath == NULL && CAstore == NULL) {
2b6bcb70
MC
136 if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0)
137 return 0;
138 if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0)
139 return 0;
fd3397fc
RL
140 if (!noCAstore && SSL_CTX_set_default_verify_store(ctx) <= 0)
141 return 0;
2b6bcb70
MC
142
143 return 1;
144 }
fd3397fc
RL
145
146 if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile))
147 return 0;
148 if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath))
149 return 0;
150 if (CAstore != NULL && !SSL_CTX_load_verify_store(ctx, CAstore))
151 return 0;
152 return 1;
7e1b7485
RS
153}
154
b5369582
RP
155#ifndef OPENSSL_NO_CT
156
dd696a55
RP
157int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
158{
2234212c 159 if (path == NULL)
328f36c5 160 return SSL_CTX_set_default_ctlog_list_file(ctx);
dd696a55
RP
161
162 return SSL_CTX_set_ctlog_list_file(ctx, path);
163}
164
b5369582
RP
165#endif
166
b5c4209b
DB
167static unsigned long nmflag = 0;
168static char nmflag_set = 0;
169
170int set_nameopt(const char *arg)
954ef7ef 171{
b5c4209b
DB
172 int ret = set_name_ex(&nmflag, arg);
173
174 if (ret)
175 nmflag_set = 1;
176
177 return ret;
178}
54a656ef 179
b5c4209b
DB
180unsigned long get_nameopt(void)
181{
182 return (nmflag_set) ? nmflag : XN_FLAG_ONELINE;
183}
954ef7ef 184
b5c4209b
DB
185int dump_cert_text(BIO *out, X509 *x)
186{
187 print_name(out, "subject=", X509_get_subject_name(x), get_nameopt());
188 BIO_puts(out, "\n");
189 print_name(out, "issuer=", X509_get_issuer_name(x), get_nameopt());
0f113f3e 190 BIO_puts(out, "\n");
54a656ef 191
0f113f3e 192 return 0;
954ef7ef 193}
a3fe382e 194
229446df
RS
195int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata)
196{
197 return password_callback(buf, bufsiz, verify, (PW_CB_DATA *)userdata);
198}
199
a43ce58f 200
cc696296 201static char *app_get_pass(const char *arg, int keepbio);
a3fe382e 202
6d382c74
DDO
203char *get_passwd(const char *pass, const char *desc)
204{
205 char *result = NULL;
206
207 if (desc == NULL)
208 desc = "<unknown>";
209 if (!app_passwd(pass, NULL, &result, NULL))
210 BIO_printf(bio_err, "Error getting password for %s\n", desc);
211 if (pass != NULL && result == NULL) {
212 BIO_printf(bio_err,
213 "Trying plain input string (better precede with 'pass:')\n");
214 result = OPENSSL_strdup(pass);
215 if (result == NULL)
216 BIO_printf(bio_err, "Out of memory getting password for %s\n", desc);
217 }
218 return result;
219}
220
cc696296 221int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2)
a3fe382e 222{
229446df
RS
223 int same = arg1 != NULL && arg2 != NULL && strcmp(arg1, arg2) == 0;
224
2234212c 225 if (arg1 != NULL) {
7e1b7485 226 *pass1 = app_get_pass(arg1, same);
2234212c 227 if (*pass1 == NULL)
0f113f3e 228 return 0;
2234212c 229 } else if (pass1 != NULL) {
0f113f3e 230 *pass1 = NULL;
2234212c
PY
231 }
232 if (arg2 != NULL) {
7e1b7485 233 *pass2 = app_get_pass(arg2, same ? 2 : 0);
2234212c 234 if (*pass2 == NULL)
0f113f3e 235 return 0;
2234212c 236 } else if (pass2 != NULL) {
0f113f3e 237 *pass2 = NULL;
2234212c 238 }
0f113f3e 239 return 1;
a3fe382e
DSH
240}
241
cc696296 242static char *app_get_pass(const char *arg, int keepbio)
a3fe382e 243{
0f113f3e 244 static BIO *pwdbio = NULL;
229446df 245 char *tmp, tpass[APP_PASS_LEN];
0f113f3e 246 int i;
86885c28 247
62ca1565 248 /* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */
86885c28 249 if (strncmp(arg, "pass:", 5) == 0)
7644a9ae 250 return OPENSSL_strdup(arg + 5);
86885c28 251 if (strncmp(arg, "env:", 4) == 0) {
0f113f3e 252 tmp = getenv(arg + 4);
2234212c 253 if (tmp == NULL) {
229446df 254 BIO_printf(bio_err, "No environment variable %s\n", arg + 4);
0f113f3e
MC
255 return NULL;
256 }
7644a9ae 257 return OPENSSL_strdup(tmp);
0f113f3e 258 }
2234212c 259 if (!keepbio || pwdbio == NULL) {
86885c28 260 if (strncmp(arg, "file:", 5) == 0) {
0f113f3e 261 pwdbio = BIO_new_file(arg + 5, "r");
2234212c 262 if (pwdbio == NULL) {
7e1b7485 263 BIO_printf(bio_err, "Can't open file %s\n", arg + 5);
0f113f3e
MC
264 return NULL;
265 }
eff7cb41 266#if !defined(_WIN32)
0f113f3e
MC
267 /*
268 * Under _WIN32, which covers even Win64 and CE, file
269 * descriptors referenced by BIO_s_fd are not inherited
270 * by child process and therefore below is not an option.
271 * It could have been an option if bss_fd.c was operating
272 * on real Windows descriptors, such as those obtained
273 * with CreateFile.
274 */
86885c28 275 } else if (strncmp(arg, "fd:", 3) == 0) {
0f113f3e
MC
276 BIO *btmp;
277 i = atoi(arg + 3);
278 if (i >= 0)
279 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
280 if ((i < 0) || !pwdbio) {
7e1b7485 281 BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3);
0f113f3e
MC
282 return NULL;
283 }
284 /*
285 * Can't do BIO_gets on an fd BIO so add a buffering BIO
286 */
287 btmp = BIO_new(BIO_f_buffer());
288 pwdbio = BIO_push(btmp, pwdbio);
289#endif
86885c28 290 } else if (strcmp(arg, "stdin") == 0) {
a60994df 291 pwdbio = dup_bio_in(FORMAT_TEXT);
12a765a5 292 if (pwdbio == NULL) {
7e1b7485 293 BIO_printf(bio_err, "Can't open BIO for stdin\n");
0f113f3e
MC
294 return NULL;
295 }
296 } else {
62ca1565
DO
297 /* argument syntax error; do not reveal too much about arg */
298 tmp = strchr(arg, ':');
299 if (tmp == NULL || tmp - arg > PASS_SOURCE_SIZE_MAX)
300 BIO_printf(bio_err,
301 "Invalid password argument, missing ':' within the first %d chars\n",
302 PASS_SOURCE_SIZE_MAX + 1);
303 else
304 BIO_printf(bio_err,
305 "Invalid password argument, starting with \"%.*s\"\n",
306 (int)(tmp - arg + 1), arg);
0f113f3e
MC
307 return NULL;
308 }
309 }
310 i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
311 if (keepbio != 1) {
312 BIO_free_all(pwdbio);
313 pwdbio = NULL;
314 }
315 if (i <= 0) {
7e1b7485 316 BIO_printf(bio_err, "Error reading password from BIO\n");
0f113f3e
MC
317 return NULL;
318 }
319 tmp = strchr(tpass, '\n');
2234212c 320 if (tmp != NULL)
0f113f3e 321 *tmp = 0;
7644a9ae 322 return OPENSSL_strdup(tpass);
a3fe382e 323}
90ae4673 324
b4250010 325OSSL_LIB_CTX *app_get0_libctx(void)
ae89578b
SL
326{
327 return app_libctx;
328}
329
6725682d
SL
330/* TODO(3.0): Make this an environment variable if required */
331const char *app_get0_propq(void)
332{
333 return NULL;
334}
335
b4250010 336OSSL_LIB_CTX *app_create_libctx(void)
ae89578b
SL
337{
338 /*
339 * Load the NULL provider into the default library context and create a
340 * library context which will then be used for any OPT_PROV options.
341 */
342 if (app_libctx == NULL) {
343
344 if (!app_provider_load(NULL, "null")) {
345 BIO_puts(bio_err, "Failed to create null provider\n");
346 return NULL;
347 }
b4250010 348 app_libctx = OSSL_LIB_CTX_new();
ae89578b
SL
349 }
350 if (app_libctx == NULL)
351 BIO_puts(bio_err, "Failed to create library context\n");
352 return app_libctx;
353}
354
bfa470a4 355CONF *app_load_config_bio(BIO *in, const char *filename)
cc01d217
RS
356{
357 long errorline = -1;
358 CONF *conf;
359 int i;
cc01d217 360
d8652be0 361 conf = NCONF_new_ex(app_libctx, NULL);
cc01d217 362 i = NCONF_load_bio(conf, in, &errorline);
cc01d217
RS
363 if (i > 0)
364 return conf;
365
bfa470a4
RL
366 if (errorline <= 0) {
367 BIO_printf(bio_err, "%s: Can't load ", opt_getprog());
368 } else {
369 BIO_printf(bio_err, "%s: Error on line %ld of ", opt_getprog(),
370 errorline);
371 }
372 if (filename != NULL)
373 BIO_printf(bio_err, "config file \"%s\"\n", filename);
cc01d217 374 else
bfa470a4
RL
375 BIO_printf(bio_err, "config input");
376
cc01d217
RS
377 NCONF_free(conf);
378 return NULL;
379}
2234212c 380
296f54ee
RL
381CONF *app_load_config(const char *filename)
382{
383 BIO *in;
384 CONF *conf;
385
bdd58d98 386 in = bio_open_default(filename, 'r', FORMAT_TEXT);
296f54ee
RL
387 if (in == NULL)
388 return NULL;
389
bfa470a4 390 conf = app_load_config_bio(in, filename);
296f54ee
RL
391 BIO_free(in);
392 return conf;
393}
2234212c 394
296f54ee
RL
395CONF *app_load_config_quiet(const char *filename)
396{
397 BIO *in;
398 CONF *conf;
399
bdd58d98 400 in = bio_open_default_quiet(filename, 'r', FORMAT_TEXT);
296f54ee
RL
401 if (in == NULL)
402 return NULL;
403
bfa470a4 404 conf = app_load_config_bio(in, filename);
296f54ee
RL
405 BIO_free(in);
406 return conf;
407}
408
409int app_load_modules(const CONF *config)
410{
411 CONF *to_free = NULL;
412
413 if (config == NULL)
dccd20d1 414 config = to_free = app_load_config_quiet(default_config_file);
296f54ee 415 if (config == NULL)
dccd20d1 416 return 1;
296f54ee
RL
417
418 if (CONF_modules_load(config, NULL, 0) <= 0) {
419 BIO_printf(bio_err, "Error configuring OpenSSL modules\n");
420 ERR_print_errors(bio_err);
421 NCONF_free(to_free);
422 return 0;
423 }
424 NCONF_free(to_free);
425 return 1;
426}
cc01d217 427
7e1b7485 428int add_oid_section(CONF *conf)
0f113f3e
MC
429{
430 char *p;
431 STACK_OF(CONF_VALUE) *sktmp;
432 CONF_VALUE *cnf;
433 int i;
75ebbd9a
RS
434
435 if ((p = NCONF_get_string(conf, NULL, "oid_section")) == NULL) {
0f113f3e
MC
436 ERR_clear_error();
437 return 1;
438 }
75ebbd9a 439 if ((sktmp = NCONF_get_section(conf, p)) == NULL) {
7e1b7485 440 BIO_printf(bio_err, "problem loading oid section %s\n", p);
0f113f3e
MC
441 return 0;
442 }
443 for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
444 cnf = sk_CONF_VALUE_value(sktmp, i);
445 if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
7e1b7485 446 BIO_printf(bio_err, "problem creating object %s=%s\n",
0f113f3e
MC
447 cnf->name, cnf->value);
448 return 0;
449 }
450 }
451 return 1;
431b0cce
RL
452}
453
ae89578b
SL
454CONF *app_load_config_modules(const char *configfile)
455{
456 CONF *conf = NULL;
457
458 if (configfile != NULL) {
459 BIO_printf(bio_err, "Using configuration from %s\n", configfile);
460
461 if ((conf = app_load_config(configfile)) == NULL)
462 return NULL;
463 if (configfile != default_config_file && !app_load_modules(conf)) {
464 NCONF_free(conf);
465 conf = NULL;
466 }
467 }
468 return conf;
469}
470
6d382c74
DDO
471X509 *load_cert_pass(const char *uri, int maybe_stdin,
472 const char *pass, const char *desc)
0f113f3e 473{
6d382c74 474 X509 *cert = NULL;
0f113f3e 475
6d382c74
DDO
476 if (desc == NULL)
477 desc = "certificate";
b3c5aadf
DDO
478 (void)load_key_certs_crls(uri, maybe_stdin, pass, desc,
479 NULL, NULL, &cert, NULL, NULL, NULL);
6d382c74 480 if (cert == NULL) {
01c12100 481 BIO_printf(bio_err, "Unable to load %s\n", desc);
7e1b7485 482 ERR_print_errors(bio_err);
0f113f3e 483 }
6d382c74 484 return cert;
0f113f3e 485}
90ae4673 486
6d382c74
DDO
487/* the format parameter is meanwhile not needed anymore and thus ignored */
488X509_CRL *load_crl(const char *uri, int format, const char *desc)
489{
490 X509_CRL *crl = NULL;
9d5aca65 491
6d382c74
DDO
492 if (desc == NULL)
493 desc = "CRL";
b3c5aadf
DDO
494 (void)load_key_certs_crls(uri, 0, NULL, desc,
495 NULL, NULL, NULL, NULL, &crl, NULL);
6d382c74 496 if (crl == NULL) {
01c12100 497 BIO_printf(bio_err, "Unable to load %s\n", desc);
0f113f3e 498 ERR_print_errors(bio_err);
0f113f3e 499 }
6d382c74 500 return crl;
9d5aca65
DO
501}
502
503X509_REQ *load_csr(const char *file, int format, const char *desc)
504{
505 X509_REQ *req = NULL;
506 BIO *in;
507
6d382c74
DDO
508 if (desc == NULL)
509 desc = "CSR";
9d5aca65
DO
510 in = bio_open_default(file, 'r', format);
511 if (in == NULL)
512 goto end;
513
514 if (format == FORMAT_ASN1)
515 req = d2i_X509_REQ_bio(in, NULL);
516 else if (format == FORMAT_PEM)
517 req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
3ee4e8ce 518 else
51c833ac 519 print_format_error(format, OPT_FMT_PEMDER);
fdb78f3d 520
0f113f3e 521 end:
6d382c74 522 if (req == NULL) {
01c12100 523 BIO_printf(bio_err, "Unable to load %s\n", desc);
9d5aca65
DO
524 ERR_print_errors(bio_err);
525 }
0f113f3e 526 BIO_free(in);
9d5aca65 527 return req;
0f113f3e 528}
fdb78f3d 529
6d382c74
DDO
530void cleanse(char *str)
531{
532 if (str != NULL)
533 OPENSSL_cleanse(str, strlen(str));
534}
535
536void clear_free(char *str)
537{
538 if (str != NULL)
539 OPENSSL_clear_free(str, strlen(str));
540}
541
542EVP_PKEY *load_key(const char *uri, int format, int may_stdin,
9d5aca65 543 const char *pass, ENGINE *e, const char *desc)
0f113f3e 544{
0f113f3e 545 EVP_PKEY *pkey = NULL;
0f113f3e 546
6d382c74
DDO
547 if (desc == NULL)
548 desc = "private key";
0f113f3e 549
0f113f3e 550 if (format == FORMAT_ENGINE) {
2234212c 551 if (e == NULL) {
6d382c74 552 BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
2234212c 553 } else {
6514dee7 554 pkey = load_engine_private_key(e, uri, pass, desc);
6d382c74 555 if (pkey == NULL) {
01c12100 556 BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
7e1b7485 557 ERR_print_errors(bio_err);
0f113f3e
MC
558 }
559 }
2234212c 560 } else {
b3c5aadf
DDO
561 (void)load_key_certs_crls(uri, may_stdin, pass, desc,
562 &pkey, NULL, NULL, NULL, NULL, NULL);
0f113f3e 563 }
3ee4e8ce 564
6d382c74 565 if (pkey == NULL) {
01c12100 566 BIO_printf(bio_err, "Unable to load %s\n", desc);
7e1b7485 567 ERR_print_errors(bio_err);
0f113f3e 568 }
26a7d938 569 return pkey;
0f113f3e 570}
90ae4673 571
6d382c74 572EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
9d5aca65 573 const char *pass, ENGINE *e, const char *desc)
0f113f3e 574{
0f113f3e 575 EVP_PKEY *pkey = NULL;
0f113f3e 576
6d382c74
DDO
577 if (desc == NULL)
578 desc = "public key";
0f113f3e 579
0f113f3e 580 if (format == FORMAT_ENGINE) {
2234212c 581 if (e == NULL) {
6d382c74 582 BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
2234212c 583 } else {
6514dee7 584 pkey = load_engine_public_key(e, uri, pass, desc);
6d382c74 585 if (pkey == NULL) {
01c12100 586 BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
0c20802c
VD
587 ERR_print_errors(bio_err);
588 }
0c20802c 589 }
2234212c 590 } else {
b3c5aadf
DDO
591 (void)load_key_certs_crls(uri, maybe_stdin, pass, desc,
592 NULL, &pkey, NULL, NULL, NULL, NULL);
2234212c 593 }
6d382c74 594 if (pkey == NULL) {
01c12100 595 BIO_printf(bio_err, "Unable to load %s\n", desc);
9d5aca65
DO
596 ERR_print_errors(bio_err);
597 }
26a7d938 598 return pkey;
0f113f3e 599}
bd08a2bd 600
e306f83c
RL
601void app_bail_out(char *fmt, ...)
602{
603 va_list args;
604
605 va_start(args, fmt);
606 BIO_vprintf(bio_err, fmt, args);
607 va_end(args);
608 ERR_print_errors(bio_err);
609 exit(1);
610}
611
68dc6824
RS
612void* app_malloc(int sz, const char *what)
613{
614 void *vp = OPENSSL_malloc(sz);
615
e306f83c
RL
616 if (vp == NULL)
617 app_bail_out("%s: Could not allocate %d bytes for %s\n",
618 opt_getprog(), sz, what);
68dc6824
RS
619 return vp;
620}
621
0996dc54 622/*
6b4a77f5 623 * Initialize or extend, if *certs != NULL, a certificate stack.
c4adc5ba 624 * The caller is responsible for freeing *certs if its value is left not NULL.
0996dc54 625 */
b3c5aadf 626int load_certs(const char *uri, STACK_OF(X509) **certs,
a773b52a 627 const char *pass, const char *desc)
0f113f3e 628{
c4adc5ba
DDO
629 int was_NULL = *certs == NULL;
630 int ret = load_key_certs_crls(uri, 0, pass, desc, NULL, NULL,
631 NULL, certs, NULL, NULL);
632
633 if (!ret && was_NULL) {
634 sk_X509_pop_free(*certs, X509_free);
635 *certs = NULL;
636 }
637 return ret;
0f113f3e 638}
245d2ee3 639
0996dc54 640/*
6b4a77f5 641 * Initialize or extend, if *crls != NULL, a certificate stack.
c4adc5ba 642 * The caller is responsible for freeing *crls if its value is left not NULL.
0996dc54 643 */
b3c5aadf 644int load_crls(const char *uri, STACK_OF(X509_CRL) **crls,
a773b52a 645 const char *pass, const char *desc)
0f113f3e 646{
c4adc5ba
DDO
647 int was_NULL = *crls == NULL;
648 int ret = load_key_certs_crls(uri, 0, pass, desc, NULL, NULL,
649 NULL, NULL, NULL, crls);
650
651 if (!ret && was_NULL) {
652 sk_X509_CRL_pop_free(*crls, X509_CRL_free);
653 *crls = NULL;
654 }
655 return ret;
0f113f3e
MC
656}
657
6d382c74
DDO
658/*
659 * Load those types of credentials for which the result pointer is not NULL.
660 * Reads from stdio if uri is NULL and maybe_stdin is nonzero.
b3c5aadf
DDO
661 * For non-NULL ppkey, pcert, and pcrl the first suitable value found is loaded.
662 * If pcerts is non-NULL and *pcerts == NULL then a new cert list is allocated.
663 * If pcerts is non-NULL then all available certificates are appended to *pcerts
664 * except any certificate assigned to *pcert.
665 * If pcrls is non-NULL and *pcrls == NULL then a new list of CRLs is allocated.
666 * If pcrls is non-NULL then all available CRLs are appended to *pcerts
667 * except any CRL assigned to *pcrl.
668 * In any case (also on error) the caller is responsible for freeing all members
669 * of *pcerts and *pcrls (as far as they are not NULL).
6d382c74 670 */
b3c5aadf
DDO
671int load_key_certs_crls(const char *uri, int maybe_stdin,
672 const char *pass, const char *desc,
673 EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
674 X509 **pcert, STACK_OF(X509) **pcerts,
675 X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls)
6d382c74
DDO
676{
677 PW_CB_DATA uidata;
678 OSSL_STORE_CTX *ctx = NULL;
b4250010 679 OSSL_LIB_CTX *libctx = app_get0_libctx();
6725682d 680 const char *propq = app_get0_propq();
b3c5aadf
DDO
681 int ncerts = 0;
682 int ncrls = 0;
50eb2a50
DDO
683 const char *failed =
684 ppkey != NULL ? "key" : ppubkey != NULL ? "public key" :
685 pcert != NULL ? "cert" : pcrl != NULL ? "CRL" :
686 pcerts != NULL ? "certs" : pcrls != NULL ? "CRLs" : NULL;
6d382c74
DDO
687 /* TODO make use of the engine reference 'eng' when loading pkeys */
688
689 if (ppkey != NULL)
690 *ppkey = NULL;
2274d22d
RL
691 if (ppubkey != NULL)
692 *ppubkey = NULL;
6d382c74
DDO
693 if (pcert != NULL)
694 *pcert = NULL;
50eb2a50
DDO
695 if (failed == NULL) {
696 BIO_printf(bio_err, "Internal error: nothing to load into from %s\n",
697 uri != NULL ? uri : "<stdin>");
698 return 0;
699 }
700
b3c5aadf
DDO
701 if (pcerts != NULL && *pcerts == NULL
702 && (*pcerts = sk_X509_new_null()) == NULL) {
50eb2a50 703 BIO_printf(bio_err, "Out of memory loading");
87495d56 704 goto end;
b3c5aadf 705 }
6d382c74
DDO
706 if (pcrl != NULL)
707 *pcrl = NULL;
b3c5aadf
DDO
708 if (pcrls != NULL && *pcrls == NULL
709 && (*pcrls = sk_X509_CRL_new_null()) == NULL) {
50eb2a50 710 BIO_printf(bio_err, "Out of memory loading");
87495d56 711 goto end;
b3c5aadf 712 }
6d382c74 713
6d382c74
DDO
714 uidata.password = pass;
715 uidata.prompt_info = uri;
716
717 if (uri == NULL) {
718 BIO *bio;
719
720 if (!maybe_stdin) {
50eb2a50 721 BIO_printf(bio_err, "No filename or uri specified for loading");
6d382c74
DDO
722 goto end;
723 }
50eb2a50 724 uri = "<stdin>";
6d382c74
DDO
725 unbuffer(stdin);
726 bio = BIO_new_fp(stdin, 0);
727 if (bio != NULL)
6725682d 728 ctx = OSSL_STORE_attach(bio, "file", libctx, propq,
6d382c74 729 get_ui_method(), &uidata, NULL, NULL);
6d382c74 730 } else {
d8652be0
MC
731 ctx = OSSL_STORE_open_ex(uri, libctx, propq, get_ui_method(), &uidata,
732 NULL, NULL);
6d382c74
DDO
733 }
734 if (ctx == NULL) {
50eb2a50 735 BIO_printf(bio_err, "Could not open file or uri for loading");
6d382c74
DDO
736 goto end;
737 }
738
87495d56 739 failed = NULL;
b3c5aadf 740 while (!OSSL_STORE_eof(ctx)) {
6d382c74 741 OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
50eb2a50 742 int type, ok = 1;
6d382c74 743
50eb2a50
DDO
744 if (info == NULL)
745 break;
746 type = OSSL_STORE_INFO_get_type(info);
6d382c74
DDO
747 switch (type) {
748 case OSSL_STORE_INFO_PKEY:
749 if (ppkey != NULL && *ppkey == NULL)
b3c5aadf 750 ok = (*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL;
2274d22d
RL
751
752 /*
753 * An EVP_PKEY with private parts also holds the public parts,
754 * so if the caller asked for a public key, and we got a private
755 * key, we can still pass it back.
756 */
b3c5aadf
DDO
757 if (ok && ppubkey != NULL && *ppubkey == NULL)
758 ok = ((*ppubkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL);
2274d22d
RL
759 break;
760 case OSSL_STORE_INFO_PUBKEY:
761 if (ppubkey != NULL && *ppubkey == NULL)
b3c5aadf 762 ok = ((*ppubkey = OSSL_STORE_INFO_get1_PUBKEY(info)) != NULL);
6d382c74
DDO
763 break;
764 case OSSL_STORE_INFO_CERT:
765 if (pcert != NULL && *pcert == NULL)
b3c5aadf
DDO
766 ok = (*pcert = OSSL_STORE_INFO_get1_CERT(info)) != NULL;
767 else if (pcerts != NULL)
768 ok = X509_add_cert(*pcerts,
769 OSSL_STORE_INFO_get1_CERT(info),
770 X509_ADD_FLAG_DEFAULT);
771 ncerts += ok;
6d382c74
DDO
772 break;
773 case OSSL_STORE_INFO_CRL:
774 if (pcrl != NULL && *pcrl == NULL)
b3c5aadf
DDO
775 ok = (*pcrl = OSSL_STORE_INFO_get1_CRL(info)) != NULL;
776 else if (pcrls != NULL)
777 ok = sk_X509_CRL_push(*pcrls, OSSL_STORE_INFO_get1_CRL(info));
778 ncrls += ok;
6d382c74
DDO
779 break;
780 default:
781 /* skip any other type */
782 break;
783 }
784 OSSL_STORE_INFO_free(info);
b3c5aadf
DDO
785 if (!ok) {
786 failed = info == NULL ? NULL : OSSL_STORE_INFO_type_string(type);
50eb2a50 787 BIO_printf(bio_err, "Error reading");
6d382c74
DDO
788 break;
789 }
790 }
791
792 end:
793 OSSL_STORE_close(ctx);
87495d56 794 if (failed == NULL) {
50eb2a50
DDO
795 int any = 0;
796
797 if (ppkey != NULL && *ppkey == NULL) {
87495d56 798 failed = "key";
50eb2a50
DDO
799 } else if ((pcert != NULL || pcerts != NULL) && ncerts == 0) {
800 if (pcert == NULL)
801 any = 1;
87495d56 802 failed = "cert";
50eb2a50
DDO
803 } else if ((pcrl != NULL || pcrls != NULL) && ncrls == 0) {
804 if (pcrl == NULL)
805 any = 1;
87495d56 806 failed = "CRL";
50eb2a50 807 }
87495d56 808 if (failed != NULL)
50eb2a50
DDO
809 BIO_printf(bio_err, "Could not read");
810 if (any)
811 BIO_printf(bio_err, " any");
b3c5aadf 812 }
50eb2a50
DDO
813 if (failed != NULL) {
814 if (desc != NULL && strstr(desc, failed) != NULL) {
815 BIO_printf(bio_err, " %s", desc);
816 } else {
817 BIO_printf(bio_err, " %s", failed);
818 if (desc != NULL)
819 BIO_printf(bio_err, " of %s", desc);
820 }
821 if (uri != NULL)
822 BIO_printf(bio_err, " from %s", uri);
823 BIO_printf(bio_err, "\n");
87495d56 824 ERR_print_errors(bio_err);
50eb2a50 825 }
b3c5aadf 826 return failed == NULL;
6d382c74
DDO
827}
828
829
0f113f3e 830#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
8ca533e3 831/* Return error for unknown extensions */
0f113f3e 832#define X509V3_EXT_DEFAULT 0
8ca533e3 833/* Print error for unknown extensions */
0f113f3e 834#define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
8ca533e3 835/* ASN1 parse unknown extensions */
0f113f3e 836#define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
8ca533e3 837/* BIO_dump unknown extensions */
0f113f3e 838#define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
8ca533e3 839
535d79da 840#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
0f113f3e 841 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
535d79da 842
8ca533e3
DSH
843int set_cert_ex(unsigned long *flags, const char *arg)
844{
0f113f3e
MC
845 static const NAME_EX_TBL cert_tbl[] = {
846 {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
847 {"ca_default", X509_FLAG_CA, 0xffffffffl},
848 {"no_header", X509_FLAG_NO_HEADER, 0},
849 {"no_version", X509_FLAG_NO_VERSION, 0},
850 {"no_serial", X509_FLAG_NO_SERIAL, 0},
851 {"no_signame", X509_FLAG_NO_SIGNAME, 0},
852 {"no_validity", X509_FLAG_NO_VALIDITY, 0},
853 {"no_subject", X509_FLAG_NO_SUBJECT, 0},
854 {"no_issuer", X509_FLAG_NO_ISSUER, 0},
855 {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
856 {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
857 {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
858 {"no_aux", X509_FLAG_NO_AUX, 0},
859 {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
860 {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
861 {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
862 {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
863 {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
864 {NULL, 0, 0}
865 };
866 return set_multi_opts(flags, arg, cert_tbl);
8ca533e3 867}
a657546f
DSH
868
869int set_name_ex(unsigned long *flags, const char *arg)
870{
0f113f3e
MC
871 static const NAME_EX_TBL ex_tbl[] = {
872 {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
bc776510 873 {"esc_2254", ASN1_STRFLGS_ESC_2254, 0},
0f113f3e
MC
874 {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
875 {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
876 {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
877 {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
878 {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
879 {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
880 {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
881 {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
882 {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
883 {"compat", XN_FLAG_COMPAT, 0xffffffffL},
884 {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
885 {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
886 {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
887 {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
888 {"dn_rev", XN_FLAG_DN_REV, 0},
889 {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
890 {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
891 {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
892 {"align", XN_FLAG_FN_ALIGN, 0},
893 {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
894 {"space_eq", XN_FLAG_SPC_EQ, 0},
895 {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
896 {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
897 {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
898 {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
899 {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
900 {NULL, 0, 0}
901 };
03706afa
DSH
902 if (set_multi_opts(flags, arg, ex_tbl) == 0)
903 return 0;
3190d1dc
RL
904 if (*flags != XN_FLAG_COMPAT
905 && (*flags & XN_FLAG_SEP_MASK) == 0)
03706afa
DSH
906 *flags |= XN_FLAG_SEP_CPLUS_SPC;
907 return 1;
535d79da
DSH
908}
909
791bd0cd
DSH
910int set_ext_copy(int *copy_type, const char *arg)
911{
86885c28 912 if (strcasecmp(arg, "none") == 0)
0f113f3e 913 *copy_type = EXT_COPY_NONE;
86885c28 914 else if (strcasecmp(arg, "copy") == 0)
0f113f3e 915 *copy_type = EXT_COPY_ADD;
86885c28 916 else if (strcasecmp(arg, "copyall") == 0)
0f113f3e
MC
917 *copy_type = EXT_COPY_ALL;
918 else
919 return 0;
920 return 1;
791bd0cd
DSH
921}
922
923int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
924{
0f113f3e
MC
925 STACK_OF(X509_EXTENSION) *exts = NULL;
926 X509_EXTENSION *ext, *tmpext;
927 ASN1_OBJECT *obj;
928 int i, idx, ret = 0;
929 if (!x || !req || (copy_type == EXT_COPY_NONE))
930 return 1;
931 exts = X509_REQ_get_extensions(req);
932
933 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
934 ext = sk_X509_EXTENSION_value(exts, i);
935 obj = X509_EXTENSION_get_object(ext);
936 idx = X509_get_ext_by_OBJ(x, obj, -1);
937 /* Does extension exist? */
938 if (idx != -1) {
939 /* If normal copy don't override existing extension */
940 if (copy_type == EXT_COPY_ADD)
941 continue;
942 /* Delete all extensions of same type */
943 do {
944 tmpext = X509_get_ext(x, idx);
945 X509_delete_ext(x, idx);
946 X509_EXTENSION_free(tmpext);
947 idx = X509_get_ext_by_OBJ(x, obj, -1);
948 } while (idx != -1);
949 }
950 if (!X509_add_ext(x, ext, -1))
951 goto end;
952 }
953
954 ret = 1;
955
956 end:
957
958 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
959
960 return ret;
961}
962
963static int set_multi_opts(unsigned long *flags, const char *arg,
964 const NAME_EX_TBL * in_tbl)
965{
966 STACK_OF(CONF_VALUE) *vals;
967 CONF_VALUE *val;
968 int i, ret = 1;
969 if (!arg)
970 return 0;
971 vals = X509V3_parse_list(arg);
972 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
973 val = sk_CONF_VALUE_value(vals, i);
974 if (!set_table_opts(flags, val->name, in_tbl))
975 ret = 0;
976 }
977 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
978 return ret;
979}
980
981static int set_table_opts(unsigned long *flags, const char *arg,
982 const NAME_EX_TBL * in_tbl)
983{
984 char c;
985 const NAME_EX_TBL *ptbl;
986 c = arg[0];
987
988 if (c == '-') {
989 c = 0;
990 arg++;
991 } else if (c == '+') {
992 c = 1;
993 arg++;
2234212c 994 } else {
0f113f3e 995 c = 1;
2234212c 996 }
0f113f3e
MC
997
998 for (ptbl = in_tbl; ptbl->name; ptbl++) {
86885c28 999 if (strcasecmp(arg, ptbl->name) == 0) {
0f113f3e
MC
1000 *flags &= ~ptbl->mask;
1001 if (c)
1002 *flags |= ptbl->flag;
1003 else
1004 *flags &= ~ptbl->flag;
1005 return 1;
1006 }
1007 }
1008 return 0;
1009}
1010
8cc86b81 1011void print_name(BIO *out, const char *title, const X509_NAME *nm,
0f113f3e
MC
1012 unsigned long lflags)
1013{
1014 char *buf;
1015 char mline = 0;
1016 int indent = 0;
1017
1018 if (title)
1019 BIO_puts(out, title);
1020 if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1021 mline = 1;
1022 indent = 4;
1023 }
1024 if (lflags == XN_FLAG_COMPAT) {
1025 buf = X509_NAME_oneline(nm, 0, 0);
1026 BIO_puts(out, buf);
1027 BIO_puts(out, "\n");
1028 OPENSSL_free(buf);
1029 } else {
1030 if (mline)
1031 BIO_puts(out, "\n");
1032 X509_NAME_print_ex(out, nm, indent, lflags);
1033 BIO_puts(out, "\n");
1034 }
a657546f
DSH
1035}
1036
2ac6115d 1037void print_bignum_var(BIO *out, const BIGNUM *in, const char *var,
7e1b7485 1038 int len, unsigned char *buffer)
81f169e9 1039{
7e1b7485 1040 BIO_printf(out, " static unsigned char %s_%d[] = {", var, len);
2234212c 1041 if (BN_is_zero(in)) {
06deb932 1042 BIO_printf(out, "\n 0x00");
2234212c 1043 } else {
7e1b7485
RS
1044 int i, l;
1045
1046 l = BN_bn2bin(in, buffer);
1047 for (i = 0; i < l; i++) {
06deb932 1048 BIO_printf(out, (i % 10) == 0 ? "\n " : " ");
7e1b7485 1049 if (i < l - 1)
06deb932 1050 BIO_printf(out, "0x%02X,", buffer[i]);
7e1b7485
RS
1051 else
1052 BIO_printf(out, "0x%02X", buffer[i]);
1053 }
1054 }
1055 BIO_printf(out, "\n };\n");
1056}
2234212c 1057
7e1b7485
RS
1058void print_array(BIO *out, const char* title, int len, const unsigned char* d)
1059{
1060 int i;
1061
1062 BIO_printf(out, "unsigned char %s[%d] = {", title, len);
1063 for (i = 0; i < len; i++) {
1064 if ((i % 10) == 0)
1065 BIO_printf(out, "\n ");
1066 if (i < len - 1)
1067 BIO_printf(out, "0x%02X, ", d[i]);
1068 else
1069 BIO_printf(out, "0x%02X", d[i]);
1070 }
1071 BIO_printf(out, "\n};\n");
1072}
1073
fd3397fc
RL
1074X509_STORE *setup_verify(const char *CAfile, int noCAfile,
1075 const char *CApath, int noCApath,
1076 const char *CAstore, int noCAstore)
7e1b7485
RS
1077{
1078 X509_STORE *store = X509_STORE_new();
0f113f3e 1079 X509_LOOKUP *lookup;
b4250010 1080 OSSL_LIB_CTX *libctx = app_get0_libctx();
6725682d 1081 const char *propq = app_get0_propq();
7e1b7485 1082
96487cdd 1083 if (store == NULL)
0f113f3e 1084 goto end;
2b6bcb70 1085
e8aa8b6c 1086 if (CAfile != NULL || !noCAfile) {
2b6bcb70
MC
1087 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1088 if (lookup == NULL)
0f113f3e 1089 goto end;
fd3397fc 1090 if (CAfile != NULL) {
d8652be0
MC
1091 if (!X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM,
1092 libctx, propq)) {
2b6bcb70
MC
1093 BIO_printf(bio_err, "Error loading file %s\n", CAfile);
1094 goto end;
1095 }
2234212c 1096 } else {
d8652be0
MC
1097 X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT,
1098 libctx, propq);
2234212c 1099 }
2b6bcb70 1100 }
0f113f3e 1101
e8aa8b6c 1102 if (CApath != NULL || !noCApath) {
2b6bcb70
MC
1103 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1104 if (lookup == NULL)
0f113f3e 1105 goto end;
fd3397fc 1106 if (CApath != NULL) {
2b6bcb70
MC
1107 if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1108 BIO_printf(bio_err, "Error loading directory %s\n", CApath);
1109 goto end;
1110 }
2234212c 1111 } else {
2b6bcb70 1112 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
2234212c 1113 }
2b6bcb70 1114 }
0f113f3e 1115
fd3397fc
RL
1116 if (CAstore != NULL || !noCAstore) {
1117 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store());
1118 if (lookup == NULL)
1119 goto end;
d8652be0 1120 if (!X509_LOOKUP_add_store_ex(lookup, CAstore, libctx, propq)) {
fd3397fc
RL
1121 if (CAstore != NULL)
1122 BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
1123 goto end;
1124 }
1125 }
1126
0f113f3e
MC
1127 ERR_clear_error();
1128 return store;
1129 end:
01c12100 1130 ERR_print_errors(bio_err);
0f113f3e
MC
1131 X509_STORE_free(store);
1132 return NULL;
81f169e9 1133}
531d630b 1134
c869da88 1135static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
0f113f3e
MC
1136{
1137 const char *n;
f85b68cd 1138
0f113f3e
MC
1139 n = a[DB_serial];
1140 while (*n == '0')
1141 n++;
739a1eb1 1142 return OPENSSL_LH_strhash(n);
0f113f3e 1143}
f85b68cd 1144
0f113f3e
MC
1145static int index_serial_cmp(const OPENSSL_CSTRING *a,
1146 const OPENSSL_CSTRING *b)
1147{
1148 const char *aa, *bb;
f85b68cd 1149
0f113f3e
MC
1150 for (aa = a[DB_serial]; *aa == '0'; aa++) ;
1151 for (bb = b[DB_serial]; *bb == '0'; bb++) ;
26a7d938 1152 return strcmp(aa, bb);
0f113f3e 1153}
f85b68cd
RL
1154
1155static int index_name_qual(char **a)
0f113f3e
MC
1156{
1157 return (a[0][0] == 'V');
1158}
f85b68cd 1159
c869da88 1160static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
0f113f3e 1161{
739a1eb1 1162 return OPENSSL_LH_strhash(a[DB_name]);
0f113f3e 1163}
f85b68cd 1164
c869da88 1165int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
0f113f3e 1166{
26a7d938 1167 return strcmp(a[DB_name], b[DB_name]);
0f113f3e 1168}
f85b68cd 1169
c869da88
DSH
1170static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1171static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1172static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1173static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
f85b68cd
RL
1174#undef BSIZE
1175#define BSIZE 256
cc696296 1176BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai)
0f113f3e
MC
1177{
1178 BIO *in = NULL;
1179 BIGNUM *ret = NULL;
68b00c23 1180 char buf[1024];
0f113f3e
MC
1181 ASN1_INTEGER *ai = NULL;
1182
1183 ai = ASN1_INTEGER_new();
1184 if (ai == NULL)
1185 goto err;
1186
7e1b7485
RS
1187 in = BIO_new_file(serialfile, "r");
1188 if (in == NULL) {
0f113f3e
MC
1189 if (!create) {
1190 perror(serialfile);
1191 goto err;
0f113f3e 1192 }
7e1b7485
RS
1193 ERR_clear_error();
1194 ret = BN_new();
1195 if (ret == NULL || !rand_serial(ret, ai))
1196 BIO_printf(bio_err, "Out of memory\n");
0f113f3e
MC
1197 } else {
1198 if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
01c12100 1199 BIO_printf(bio_err, "Unable to load number from %s\n",
0f113f3e
MC
1200 serialfile);
1201 goto err;
1202 }
1203 ret = ASN1_INTEGER_to_BN(ai, NULL);
1204 if (ret == NULL) {
01c12100 1205 BIO_printf(bio_err, "Error converting number from bin to BIGNUM\n");
0f113f3e
MC
1206 goto err;
1207 }
1208 }
1209
1210 if (ret && retai) {
1211 *retai = ai;
1212 ai = NULL;
1213 }
f85b68cd 1214 err:
01c12100 1215 ERR_print_errors(bio_err);
ca3a82c3 1216 BIO_free(in);
2ace7450 1217 ASN1_INTEGER_free(ai);
26a7d938 1218 return ret;
0f113f3e
MC
1219}
1220
cc696296 1221int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial,
0f113f3e
MC
1222 ASN1_INTEGER **retai)
1223{
1224 char buf[1][BSIZE];
1225 BIO *out = NULL;
1226 int ret = 0;
1227 ASN1_INTEGER *ai = NULL;
1228 int j;
1229
1230 if (suffix == NULL)
1231 j = strlen(serialfile);
1232 else
1233 j = strlen(serialfile) + strlen(suffix) + 1;
1234 if (j >= BSIZE) {
01c12100 1235 BIO_printf(bio_err, "File name too long\n");
0f113f3e
MC
1236 goto err;
1237 }
1238
1239 if (suffix == NULL)
7644a9ae 1240 OPENSSL_strlcpy(buf[0], serialfile, BSIZE);
0f113f3e 1241 else {
4c771796 1242#ifndef OPENSSL_SYS_VMS
cbe29648 1243 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, suffix);
4c771796 1244#else
cbe29648 1245 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, suffix);
4c771796 1246#endif
0f113f3e 1247 }
7e1b7485 1248 out = BIO_new_file(buf[0], "w");
0f113f3e 1249 if (out == NULL) {
0f113f3e
MC
1250 goto err;
1251 }
0f113f3e
MC
1252
1253 if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1254 BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
1255 goto err;
1256 }
1257 i2a_ASN1_INTEGER(out, ai);
1258 BIO_puts(out, "\n");
1259 ret = 1;
1260 if (retai) {
1261 *retai = ai;
1262 ai = NULL;
1263 }
1264 err:
01c12100
DDO
1265 if (!ret)
1266 ERR_print_errors(bio_err);
ca3a82c3 1267 BIO_free_all(out);
2ace7450 1268 ASN1_INTEGER_free(ai);
26a7d938 1269 return ret;
0f113f3e 1270}
f85b68cd 1271
cc696296
F
1272int rotate_serial(const char *serialfile, const char *new_suffix,
1273 const char *old_suffix)
0f113f3e 1274{
bde136c8 1275 char buf[2][BSIZE];
0f113f3e
MC
1276 int i, j;
1277
1278 i = strlen(serialfile) + strlen(old_suffix);
1279 j = strlen(serialfile) + strlen(new_suffix);
1280 if (i > j)
1281 j = i;
1282 if (j + 1 >= BSIZE) {
01c12100 1283 BIO_printf(bio_err, "File name too long\n");
0f113f3e
MC
1284 goto err;
1285 }
4c771796 1286#ifndef OPENSSL_SYS_VMS
cbe29648
RS
1287 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, new_suffix);
1288 j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", serialfile, old_suffix);
4c771796 1289#else
cbe29648
RS
1290 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, new_suffix);
1291 j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", serialfile, old_suffix);
a1ad253f 1292#endif
0f113f3e 1293 if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
4c771796 1294#ifdef ENOTDIR
0f113f3e
MC
1295 && errno != ENOTDIR
1296#endif
1297 ) {
1298 BIO_printf(bio_err,
01c12100 1299 "Unable to rename %s to %s\n", serialfile, buf[1]);
0f113f3e
MC
1300 perror("reason");
1301 goto err;
1302 }
0f113f3e
MC
1303 if (rename(buf[0], serialfile) < 0) {
1304 BIO_printf(bio_err,
01c12100 1305 "Unable to rename %s to %s\n", buf[0], serialfile);
0f113f3e
MC
1306 perror("reason");
1307 rename(buf[1], serialfile);
1308 goto err;
1309 }
1310 return 1;
4c771796 1311 err:
01c12100 1312 ERR_print_errors(bio_err);
0f113f3e
MC
1313 return 0;
1314}
4c771796 1315
64674bcc 1316int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
0f113f3e
MC
1317{
1318 BIGNUM *btmp;
1319 int ret = 0;
23a1d5e9 1320
ffb46830 1321 btmp = b == NULL ? BN_new() : b;
96487cdd 1322 if (btmp == NULL)
0f113f3e
MC
1323 return 0;
1324
ffb46830 1325 if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
0f113f3e
MC
1326 goto error;
1327 if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1328 goto error;
1329
1330 ret = 1;
1331
1332 error:
1333
23a1d5e9 1334 if (btmp != b)
0f113f3e
MC
1335 BN_free(btmp);
1336
1337 return ret;
1338}
64674bcc 1339
cc696296 1340CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
0f113f3e
MC
1341{
1342 CA_DB *retdb = NULL;
1343 TXT_DB *tmpdb = NULL;
7e1b7485 1344 BIO *in;
0f113f3e 1345 CONF *dbattr_conf = NULL;
cc01d217 1346 char buf[BSIZE];
c7d5ea26
VD
1347#ifndef OPENSSL_NO_POSIX_IO
1348 FILE *dbfp;
1349 struct stat dbst;
1350#endif
0f113f3e 1351
7e1b7485 1352 in = BIO_new_file(dbfile, "r");
01c12100 1353 if (in == NULL)
0f113f3e 1354 goto err;
c7d5ea26
VD
1355
1356#ifndef OPENSSL_NO_POSIX_IO
1357 BIO_get_fp(in, &dbfp);
1358 if (fstat(fileno(dbfp), &dbst) == -1) {
ff988500
RS
1359 ERR_raise_data(ERR_LIB_SYS, errno,
1360 "calling fstat(%s)", dbfile);
c7d5ea26
VD
1361 goto err;
1362 }
1363#endif
1364
0f113f3e
MC
1365 if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1366 goto err;
f85b68cd
RL
1367
1368#ifndef OPENSSL_SYS_VMS
cbe29648 1369 BIO_snprintf(buf, sizeof(buf), "%s.attr", dbfile);
f85b68cd 1370#else
cbe29648 1371 BIO_snprintf(buf, sizeof(buf), "%s-attr", dbfile);
0f113f3e 1372#endif
ac454d8d 1373 dbattr_conf = app_load_config_quiet(buf);
0f113f3e 1374
b4faea50 1375 retdb = app_malloc(sizeof(*retdb), "new DB");
0f113f3e
MC
1376 retdb->db = tmpdb;
1377 tmpdb = NULL;
1378 if (db_attr)
1379 retdb->attributes = *db_attr;
1380 else {
1381 retdb->attributes.unique_subject = 1;
1382 }
1383
1384 if (dbattr_conf) {
1385 char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1386 if (p) {
0f113f3e
MC
1387 retdb->attributes.unique_subject = parse_yesno(p, 1);
1388 }
1389 }
f85b68cd 1390
c7d5ea26
VD
1391 retdb->dbfname = OPENSSL_strdup(dbfile);
1392#ifndef OPENSSL_NO_POSIX_IO
1393 retdb->dbst = dbst;
1394#endif
1395
f85b68cd 1396 err:
01c12100 1397 ERR_print_errors(bio_err);
efa7dd64 1398 NCONF_free(dbattr_conf);
895cba19 1399 TXT_DB_free(tmpdb);
ca3a82c3 1400 BIO_free_all(in);
0f113f3e
MC
1401 return retdb;
1402}
f85b68cd 1403
a4107d73
VD
1404/*
1405 * Returns > 0 on success, <= 0 on error
1406 */
f85b68cd 1407int index_index(CA_DB *db)
0f113f3e
MC
1408{
1409 if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1410 LHASH_HASH_FN(index_serial),
1411 LHASH_COMP_FN(index_serial))) {
1412 BIO_printf(bio_err,
01c12100 1413 "Error creating serial number index:(%ld,%ld,%ld)\n",
0f113f3e 1414 db->db->error, db->db->arg1, db->db->arg2);
01c12100 1415 goto err;
0f113f3e
MC
1416 }
1417
1418 if (db->attributes.unique_subject
1419 && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1420 LHASH_HASH_FN(index_name),
1421 LHASH_COMP_FN(index_name))) {
01c12100 1422 BIO_printf(bio_err, "Error creating name index:(%ld,%ld,%ld)\n",
0f113f3e 1423 db->db->error, db->db->arg1, db->db->arg2);
01c12100 1424 goto err;
0f113f3e
MC
1425 }
1426 return 1;
01c12100
DDO
1427 err:
1428 ERR_print_errors(bio_err);
1429 return 0;
0f113f3e 1430}
f85b68cd 1431
7d727231 1432int save_index(const char *dbfile, const char *suffix, CA_DB *db)
0f113f3e
MC
1433{
1434 char buf[3][BSIZE];
7e1b7485 1435 BIO *out;
0f113f3e
MC
1436 int j;
1437
0f113f3e
MC
1438 j = strlen(dbfile) + strlen(suffix);
1439 if (j + 6 >= BSIZE) {
01c12100 1440 BIO_printf(bio_err, "File name too long\n");
0f113f3e
MC
1441 goto err;
1442 }
f85b68cd 1443#ifndef OPENSSL_SYS_VMS
cbe29648
RS
1444 j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr", dbfile);
1445 j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s.attr.%s", dbfile, suffix);
1446 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, suffix);
f85b68cd 1447#else
cbe29648
RS
1448 j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr", dbfile);
1449 j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s-attr-%s", dbfile, suffix);
1450 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, suffix);
63b6fe2b 1451#endif
7e1b7485
RS
1452 out = BIO_new_file(buf[0], "w");
1453 if (out == NULL) {
0f113f3e 1454 perror(dbfile);
01c12100 1455 BIO_printf(bio_err, "Unable to open '%s'\n", dbfile);
0f113f3e
MC
1456 goto err;
1457 }
1458 j = TXT_DB_write(out, db->db);
7e1b7485 1459 BIO_free(out);
0f113f3e
MC
1460 if (j <= 0)
1461 goto err;
1462
7e1b7485 1463 out = BIO_new_file(buf[1], "w");
7e1b7485 1464 if (out == NULL) {
0f113f3e 1465 perror(buf[2]);
01c12100 1466 BIO_printf(bio_err, "Unable to open '%s'\n", buf[2]);
0f113f3e
MC
1467 goto err;
1468 }
1469 BIO_printf(out, "unique_subject = %s\n",
1470 db->attributes.unique_subject ? "yes" : "no");
1471 BIO_free(out);
1472
1473 return 1;
f85b68cd 1474 err:
01c12100 1475 ERR_print_errors(bio_err);
0f113f3e
MC
1476 return 0;
1477}
f85b68cd 1478
0f113f3e
MC
1479int rotate_index(const char *dbfile, const char *new_suffix,
1480 const char *old_suffix)
1481{
1482 char buf[5][BSIZE];
1483 int i, j;
1484
1485 i = strlen(dbfile) + strlen(old_suffix);
1486 j = strlen(dbfile) + strlen(new_suffix);
1487 if (i > j)
1488 j = i;
1489 if (j + 6 >= BSIZE) {
01c12100 1490 BIO_printf(bio_err, "File name too long\n");
0f113f3e
MC
1491 goto err;
1492 }
f85b68cd 1493#ifndef OPENSSL_SYS_VMS
cbe29648
RS
1494 j = BIO_snprintf(buf[4], sizeof(buf[4]), "%s.attr", dbfile);
1495 j = BIO_snprintf(buf[3], sizeof(buf[3]), "%s.attr.%s", dbfile, old_suffix);
1496 j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr.%s", dbfile, new_suffix);
1497 j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", dbfile, old_suffix);
1498 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, new_suffix);
f85b68cd 1499#else
cbe29648
RS
1500 j = BIO_snprintf(buf[4], sizeof(buf[4]), "%s-attr", dbfile);
1501 j = BIO_snprintf(buf[3], sizeof(buf[3]), "%s-attr-%s", dbfile, old_suffix);
1502 j = BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr-%s", dbfile, new_suffix);
1503 j = BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", dbfile, old_suffix);
1504 j = BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, new_suffix);
63b6fe2b 1505#endif
0f113f3e 1506 if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
a1ad253f 1507#ifdef ENOTDIR
0f113f3e 1508 && errno != ENOTDIR
a1ad253f 1509#endif
0f113f3e 1510 ) {
01c12100 1511 BIO_printf(bio_err, "Unable to rename %s to %s\n", dbfile, buf[1]);
0f113f3e
MC
1512 perror("reason");
1513 goto err;
1514 }
0f113f3e 1515 if (rename(buf[0], dbfile) < 0) {
01c12100 1516 BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[0], dbfile);
0f113f3e
MC
1517 perror("reason");
1518 rename(buf[1], dbfile);
1519 goto err;
1520 }
0f113f3e 1521 if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
a1ad253f 1522#ifdef ENOTDIR
0f113f3e
MC
1523 && errno != ENOTDIR
1524#endif
1525 ) {
01c12100 1526 BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[4], buf[3]);
0f113f3e
MC
1527 perror("reason");
1528 rename(dbfile, buf[0]);
1529 rename(buf[1], dbfile);
1530 goto err;
1531 }
0f113f3e 1532 if (rename(buf[2], buf[4]) < 0) {
01c12100 1533 BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[2], buf[4]);
0f113f3e
MC
1534 perror("reason");
1535 rename(buf[3], buf[4]);
1536 rename(dbfile, buf[0]);
1537 rename(buf[1], dbfile);
1538 goto err;
1539 }
1540 return 1;
f85b68cd 1541 err:
01c12100 1542 ERR_print_errors(bio_err);
0f113f3e
MC
1543 return 0;
1544}
f85b68cd
RL
1545
1546void free_index(CA_DB *db)
0f113f3e
MC
1547{
1548 if (db) {
895cba19 1549 TXT_DB_free(db->db);
c7d5ea26 1550 OPENSSL_free(db->dbfname);
0f113f3e
MC
1551 OPENSSL_free(db);
1552 }
1553}
6d5ffb59 1554
ff990440 1555int parse_yesno(const char *str, int def)
0f113f3e 1556{
0f113f3e
MC
1557 if (str) {
1558 switch (*str) {
1559 case 'f': /* false */
1560 case 'F': /* FALSE */
1561 case 'n': /* no */
1562 case 'N': /* NO */
1563 case '0': /* 0 */
1bb2daea 1564 return 0;
0f113f3e
MC
1565 case 't': /* true */
1566 case 'T': /* TRUE */
1567 case 'y': /* yes */
1568 case 'Y': /* YES */
1569 case '1': /* 1 */
1bb2daea 1570 return 1;
0f113f3e
MC
1571 }
1572 }
1bb2daea 1573 return def;
0f113f3e 1574}
03ddbdd9 1575
6d5ffb59 1576/*
db4c08f0 1577 * name is expected to be in the format /type0=value0/type1=value1/type2=...
5a0991d0
DDO
1578 * where + can be used instead of / to form multi-valued RDNs if canmulti
1579 * and characters may be escaped by \
6d5ffb59 1580 */
57c05c57
DDO
1581X509_NAME *parse_name(const char *cp, int chtype, int canmulti,
1582 const char *desc)
0f113f3e 1583{
db4c08f0
RS
1584 int nextismulti = 0;
1585 char *work;
1586 X509_NAME *n;
0f113f3e 1587
2167640b
EC
1588 if (*cp++ != '/') {
1589 BIO_printf(bio_err,
57c05c57 1590 "%s: %s name is expected to be in the format "
2167640b
EC
1591 "/type0=value0/type1=value1/type2=... where characters may "
1592 "be escaped by \\. This name is not in that format: '%s'\n",
57c05c57 1593 opt_getprog(), desc, --cp);
db4c08f0 1594 return NULL;
2167640b 1595 }
db4c08f0
RS
1596
1597 n = X509_NAME_new();
57c05c57
DDO
1598 if (n == NULL) {
1599 BIO_printf(bio_err, "%s: Out of memory\n", opt_getprog());
db4c08f0 1600 return NULL;
57c05c57 1601 }
a3ed492f 1602 work = OPENSSL_strdup(cp);
52958608 1603 if (work == NULL) {
57c05c57
DDO
1604 BIO_printf(bio_err, "%s: Error copying %s name input\n",
1605 opt_getprog(), desc);
db4c08f0 1606 goto err;
52958608 1607 }
db4c08f0 1608
7e998a0f 1609 while (*cp != '\0') {
db4c08f0
RS
1610 char *bp = work;
1611 char *typestr = bp;
1612 unsigned char *valstr;
1613 int nid;
1614 int ismulti = nextismulti;
1615 nextismulti = 0;
1616
1617 /* Collect the type */
7e998a0f 1618 while (*cp != '\0' && *cp != '=')
db4c08f0 1619 *bp++ = *cp++;
57c05c57 1620 *bp++ = '\0';
db4c08f0 1621 if (*cp == '\0') {
0f113f3e 1622 BIO_printf(bio_err,
57c05c57
DDO
1623 "%s: Missing '=' after RDN type string '%s' in %s name string\n",
1624 opt_getprog(), typestr, desc);
db4c08f0 1625 goto err;
0f113f3e 1626 }
db4c08f0
RS
1627 ++cp;
1628
1629 /* Collect the value. */
1630 valstr = (unsigned char *)bp;
7e998a0f 1631 for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) {
5a0991d0 1632 /* unescaped '+' symbol string signals further member of multiRDN */
db4c08f0
RS
1633 if (canmulti && *cp == '+') {
1634 nextismulti = 1;
0f113f3e 1635 break;
db4c08f0
RS
1636 }
1637 if (*cp == '\\' && *++cp == '\0') {
1638 BIO_printf(bio_err,
57c05c57
DDO
1639 "%s: Escape character at end of %s name string\n",
1640 opt_getprog(), desc);
db4c08f0
RS
1641 goto err;
1642 }
0f113f3e
MC
1643 }
1644 *bp++ = '\0';
0f113f3e 1645
db4c08f0 1646 /* If not at EOS (must be + or /), move forward. */
7e998a0f 1647 if (*cp != '\0')
db4c08f0 1648 ++cp;
0f113f3e 1649
db4c08f0
RS
1650 /* Parse */
1651 nid = OBJ_txt2nid(typestr);
1652 if (nid == NID_undef) {
57c05c57
DDO
1653 BIO_printf(bio_err,
1654 "%s: Skipping unknown %s name attribute \"%s\"\n",
1655 opt_getprog(), desc, typestr);
5a0991d0
DDO
1656 if (ismulti)
1657 BIO_printf(bio_err,
1658 "Hint: a '+' in a value string needs be escaped using '\\' else a new member of a multi-valued RDN is expected\n");
0f113f3e
MC
1659 continue;
1660 }
3d362f19
BK
1661 if (*valstr == '\0') {
1662 BIO_printf(bio_err,
57c05c57
DDO
1663 "%s: No value provided for %s name attribute \"%s\", skipped\n",
1664 opt_getprog(), desc, typestr);
3d362f19
BK
1665 continue;
1666 }
db4c08f0
RS
1667 if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1668 valstr, strlen((char *)valstr),
52958608 1669 -1, ismulti ? -1 : 0)) {
7e998a0f 1670 ERR_print_errors(bio_err);
57c05c57
DDO
1671 BIO_printf(bio_err,
1672 "%s: Error adding %s name attribute \"/%s=%s\"\n",
1673 opt_getprog(), desc, typestr ,valstr);
db4c08f0 1674 goto err;
52958608 1675 }
0f113f3e
MC
1676 }
1677
a3ed492f 1678 OPENSSL_free(work);
0f113f3e
MC
1679 return n;
1680
db4c08f0 1681 err:
0f113f3e 1682 X509_NAME_free(n);
a3ed492f 1683 OPENSSL_free(work);
0f113f3e 1684 return NULL;
6d5ffb59
RL
1685}
1686
0f113f3e
MC
1687/*
1688 * Read whole contents of a BIO into an allocated memory buffer and return
1689 * it.
a9164153
DSH
1690 */
1691
1692int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
0f113f3e
MC
1693{
1694 BIO *mem;
1695 int len, ret;
1696 unsigned char tbuf[1024];
bde136c8 1697
0f113f3e 1698 mem = BIO_new(BIO_s_mem());
96487cdd 1699 if (mem == NULL)
0f113f3e
MC
1700 return -1;
1701 for (;;) {
1702 if ((maxlen != -1) && maxlen < 1024)
1703 len = maxlen;
1704 else
1705 len = 1024;
1706 len = BIO_read(in, tbuf, len);
0c20802c
VD
1707 if (len < 0) {
1708 BIO_free(mem);
1709 return -1;
1710 }
1711 if (len == 0)
0f113f3e
MC
1712 break;
1713 if (BIO_write(mem, tbuf, len) != len) {
1714 BIO_free(mem);
1715 return -1;
1716 }
1717 maxlen -= len;
1718
1719 if (maxlen == 0)
1720 break;
1721 }
1722 ret = BIO_get_mem_data(mem, (char **)out);
1723 BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
1724 BIO_free(mem);
1725 return ret;
1726}
a9164153 1727
0c20802c 1728int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value)
0f113f3e
MC
1729{
1730 int rv;
1731 char *stmp, *vtmp = NULL;
7644a9ae 1732 stmp = OPENSSL_strdup(value);
0f113f3e
MC
1733 if (!stmp)
1734 return -1;
1735 vtmp = strchr(stmp, ':');
1736 if (vtmp) {
1737 *vtmp = 0;
1738 vtmp++;
1739 }
1740 rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
1741 OPENSSL_free(stmp);
1742 return rv;
1743}
a2318e86 1744
ecf3a1fb 1745static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
0f113f3e
MC
1746{
1747 X509_POLICY_NODE *node;
1748 int i;
ecf3a1fb
RS
1749
1750 BIO_printf(bio_err, "%s Policies:", name);
0f113f3e 1751 if (nodes) {
ecf3a1fb 1752 BIO_puts(bio_err, "\n");
0f113f3e
MC
1753 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
1754 node = sk_X509_POLICY_NODE_value(nodes, i);
ecf3a1fb 1755 X509_POLICY_NODE_print(bio_err, node, 2);
0f113f3e 1756 }
2234212c 1757 } else {
ecf3a1fb 1758 BIO_puts(bio_err, " <empty>\n");
2234212c 1759 }
0f113f3e 1760}
c431798e 1761
ecf3a1fb 1762void policies_print(X509_STORE_CTX *ctx)
0f113f3e
MC
1763{
1764 X509_POLICY_TREE *tree;
1765 int explicit_policy;
0f113f3e
MC
1766 tree = X509_STORE_CTX_get0_policy_tree(ctx);
1767 explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
1768
ecf3a1fb 1769 BIO_printf(bio_err, "Require explicit Policy: %s\n",
0f113f3e
MC
1770 explicit_policy ? "True" : "False");
1771
ecf3a1fb
RS
1772 nodes_print("Authority", X509_policy_tree_get0_policies(tree));
1773 nodes_print("User", X509_policy_tree_get0_user_policies(tree));
0f113f3e 1774}
ffa10187 1775
3a83462d
MC
1776/*-
1777 * next_protos_parse parses a comma separated list of strings into a string
71fa4513
BL
1778 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
1779 * outlen: (output) set to the length of the resulting buffer on success.
1780 * err: (maybe NULL) on failure, an error message line is written to this BIO.
8483a003 1781 * in: a NUL terminated string like "abc,def,ghi"
71fa4513 1782 *
8483a003 1783 * returns: a malloc'd buffer or NULL on failure.
71fa4513 1784 */
817cd0d5 1785unsigned char *next_protos_parse(size_t *outlen, const char *in)
0f113f3e
MC
1786{
1787 size_t len;
1788 unsigned char *out;
1789 size_t i, start = 0;
e78253f2 1790 size_t skipped = 0;
0f113f3e
MC
1791
1792 len = strlen(in);
e78253f2 1793 if (len == 0 || len >= 65535)
0f113f3e
MC
1794 return NULL;
1795
e78253f2 1796 out = app_malloc(len + 1, "NPN buffer");
0f113f3e
MC
1797 for (i = 0; i <= len; ++i) {
1798 if (i == len || in[i] == ',') {
e78253f2
VD
1799 /*
1800 * Zero-length ALPN elements are invalid on the wire, we could be
1801 * strict and reject the entire string, but just ignoring extra
1802 * commas seems harmless and more friendly.
1803 *
1804 * Every comma we skip in this way puts the input buffer another
1805 * byte ahead of the output buffer, so all stores into the output
1806 * buffer need to be decremented by the number commas skipped.
1807 */
1808 if (i == start) {
1809 ++start;
1810 ++skipped;
1811 continue;
1812 }
0f113f3e
MC
1813 if (i - start > 255) {
1814 OPENSSL_free(out);
1815 return NULL;
1816 }
e78253f2 1817 out[start-skipped] = (unsigned char)(i - start);
0f113f3e 1818 start = i + 1;
2234212c 1819 } else {
e78253f2 1820 out[i + 1 - skipped] = in[i];
2234212c 1821 }
0f113f3e
MC
1822 }
1823
e78253f2
VD
1824 if (len <= skipped) {
1825 OPENSSL_free(out);
1826 return NULL;
1827 }
1828
1829 *outlen = len + 1 - skipped;
0f113f3e
MC
1830 return out;
1831}
71fa4513 1832
a70da5b3 1833void print_cert_checks(BIO *bio, X509 *x,
0f113f3e
MC
1834 const char *checkhost,
1835 const char *checkemail, const char *checkip)
1836{
1837 if (x == NULL)
1838 return;
1839 if (checkhost) {
1840 BIO_printf(bio, "Hostname %s does%s match certificate\n",
7e1b7485
RS
1841 checkhost,
1842 X509_check_host(x, checkhost, 0, 0, NULL) == 1
1843 ? "" : " NOT");
0f113f3e
MC
1844 }
1845
1846 if (checkemail) {
1847 BIO_printf(bio, "Email %s does%s match certificate\n",
7e1b7485
RS
1848 checkemail, X509_check_email(x, checkemail, 0, 0)
1849 ? "" : " NOT");
0f113f3e
MC
1850 }
1851
1852 if (checkip) {
1853 BIO_printf(bio, "IP %s does%s match certificate\n",
1854 checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT");
1855 }
1856}
a70da5b3 1857
0090a686
DSH
1858/* Get first http URL from a DIST_POINT structure */
1859
1860static const char *get_dp_url(DIST_POINT *dp)
0f113f3e
MC
1861{
1862 GENERAL_NAMES *gens;
1863 GENERAL_NAME *gen;
1864 int i, gtype;
1865 ASN1_STRING *uri;
1866 if (!dp->distpoint || dp->distpoint->type != 0)
1867 return NULL;
1868 gens = dp->distpoint->name.fullname;
1869 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1870 gen = sk_GENERAL_NAME_value(gens, i);
1871 uri = GENERAL_NAME_get0_value(gen, &gtype);
1872 if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
17ebf85a 1873 const char *uptr = (const char *)ASN1_STRING_get0_data(uri);
86885c28 1874 if (strncmp(uptr, "http://", 7) == 0)
0f113f3e
MC
1875 return uptr;
1876 }
1877 }
1878 return NULL;
1879}
1880
1881/*
1882 * Look through a CRLDP structure and attempt to find an http URL to
1883 * downloads a CRL from.
0090a686
DSH
1884 */
1885
1886static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
0f113f3e
MC
1887{
1888 int i;
1889 const char *urlptr = NULL;
1890 for (i = 0; i < sk_DIST_POINT_num(crldp); i++) {
1891 DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
1892 urlptr = get_dp_url(dp);
1893 if (urlptr)
9d5aca65 1894 return load_crl(urlptr, FORMAT_HTTP, "CRL via CDP");
0f113f3e
MC
1895 }
1896 return NULL;
1897}
1898
1899/*
0aa87e86
DDO
1900 * Example of downloading CRLs from CRLDP:
1901 * not usable for real world as it always downloads and doesn't cache anything.
0090a686
DSH
1902 */
1903
8cc86b81
DDO
1904static STACK_OF(X509_CRL) *crls_http_cb(const X509_STORE_CTX *ctx,
1905 const X509_NAME *nm)
0f113f3e
MC
1906{
1907 X509 *x;
1908 STACK_OF(X509_CRL) *crls = NULL;
1909 X509_CRL *crl;
1910 STACK_OF(DIST_POINT) *crldp;
7e1b7485
RS
1911
1912 crls = sk_X509_CRL_new_null();
1913 if (!crls)
1914 return NULL;
0f113f3e
MC
1915 x = X509_STORE_CTX_get_current_cert(ctx);
1916 crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
1917 crl = load_crl_crldp(crldp);
1918 sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
fe2b7dfd
MC
1919 if (!crl) {
1920 sk_X509_CRL_free(crls);
0f113f3e 1921 return NULL;
fe2b7dfd 1922 }
0f113f3e
MC
1923 sk_X509_CRL_push(crls, crl);
1924 /* Try to download delta CRL */
1925 crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL);
1926 crl = load_crl_crldp(crldp);
1927 sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
1928 if (crl)
1929 sk_X509_CRL_push(crls, crl);
1930 return crls;
1931}
0090a686
DSH
1932
1933void store_setup_crl_download(X509_STORE *st)
0f113f3e
MC
1934{
1935 X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
1936}
0090a686 1937
29f178bd
DDO
1938#ifndef OPENSSL_NO_SOCK
1939static const char *tls_error_hint(void)
1940{
1941 unsigned long err = ERR_peek_error();
1942
1943 if (ERR_GET_LIB(err) != ERR_LIB_SSL)
1944 err = ERR_peek_last_error();
1945 if (ERR_GET_LIB(err) != ERR_LIB_SSL)
1946 return NULL;
1947
1948 switch (ERR_GET_REASON(err)) {
1949 case SSL_R_WRONG_VERSION_NUMBER:
1950 return "The server does not support (a suitable version of) TLS";
1951 case SSL_R_UNKNOWN_PROTOCOL:
1952 return "The server does not support HTTPS";
1953 case SSL_R_CERTIFICATE_VERIFY_FAILED:
1954 return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status";
1955 case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA:
1956 return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status";
1957 case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE:
1958 return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it";
1959 default: /* no error or no hint available for error */
1960 return NULL;
1961 }
1962}
1963
1964/* HTTP callback function that supports TLS connection also via HTTPS proxy */
1965BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
1966{
1967 APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
1968 SSL_CTX *ssl_ctx = info->ssl_ctx;
1969 SSL *ssl;
1970 BIO *sbio = NULL;
1971
1972 if (connect && detail) { /* connecting with TLS */
1973 if ((info->use_proxy
1974 && !OSSL_HTTP_proxy_connect(hbio, info->server, info->port,
1975 NULL, NULL, /* no proxy credentials */
1976 info->timeout, bio_err, opt_getprog()))
1977 || (sbio = BIO_new(BIO_f_ssl())) == NULL) {
1978 return NULL;
1979 }
1980 if (ssl_ctx == NULL || (ssl = SSL_new(ssl_ctx)) == NULL) {
1981 BIO_free(sbio);
1982 return NULL;
1983 }
1984
1985 SSL_set_tlsext_host_name(ssl, info->server);
1986
1987 SSL_set_connect_state(ssl);
1988 BIO_set_ssl(sbio, ssl, BIO_CLOSE);
1989
1990 hbio = BIO_push(sbio, hbio);
1991 } else if (!connect && !detail) { /* disconnecting after error */
1992 const char *hint = tls_error_hint();
1993 if (hint != NULL)
afe554c2 1994 ERR_add_error_data(2, " : ", hint);
29f178bd
DDO
1995 /*
1996 * If we pop sbio and BIO_free() it this may lead to libssl double free.
1997 * Rely on BIO_free_all() done by OSSL_HTTP_transfer() in http_client.c
1998 */
1999 }
2000 return hbio;
2001}
2002
2003ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
afe554c2 2004 const char *no_proxy, SSL_CTX *ssl_ctx,
29f178bd
DDO
2005 const STACK_OF(CONF_VALUE) *headers,
2006 long timeout, const char *expected_content_type,
2007 const ASN1_ITEM *it)
2008{
2009 APP_HTTP_TLS_INFO info;
2010 char *server;
2011 char *port;
2012 int use_ssl;
2013 ASN1_VALUE *resp = NULL;
2014
2015 if (url == NULL || it == NULL) {
2016 HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
2017 return NULL;
2018 }
2019
d7fcee3b 2020 if (!OSSL_HTTP_parse_url(url, &server, &port, NULL, NULL, &use_ssl))
29f178bd
DDO
2021 return NULL;
2022 if (use_ssl && ssl_ctx == NULL) {
2023 HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
2024 ERR_add_error_data(1, "missing SSL_CTX");
2025 goto end;
2026 }
2027
2028 info.server = server;
2029 info.port = port;
2030 info.use_proxy = proxy != NULL;
2031 info.timeout = timeout;
2032 info.ssl_ctx = ssl_ctx;
afe554c2 2033 resp = OSSL_HTTP_get_asn1(url, proxy, no_proxy,
29f178bd
DDO
2034 NULL, NULL, app_http_tls_cb, &info,
2035 headers, 0 /* maxline */, 0 /* max_resp_len */,
2036 timeout, expected_content_type, it);
2037 end:
2038 OPENSSL_free(server);
2039 OPENSSL_free(port);
2040 return resp;
2041
2042}
2043
2044ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
2045 const char *path, const char *proxy,
afe554c2 2046 const char *no_proxy, SSL_CTX *ssl_ctx,
29f178bd
DDO
2047 const STACK_OF(CONF_VALUE) *headers,
2048 const char *content_type,
2049 ASN1_VALUE *req, const ASN1_ITEM *req_it,
2050 long timeout, const ASN1_ITEM *rsp_it)
2051{
2052 APP_HTTP_TLS_INFO info;
2053
2054 info.server = host;
2055 info.port = port;
2056 info.use_proxy = proxy != NULL;
2057 info.timeout = timeout;
2058 info.ssl_ctx = ssl_ctx;
2059 return OSSL_HTTP_post_asn1(host, port, path, ssl_ctx != NULL,
afe554c2 2060 proxy, no_proxy,
29f178bd
DDO
2061 NULL, NULL, app_http_tls_cb, &info,
2062 headers, content_type, req, req_it,
2063 0 /* maxline */,
2064 0 /* max_resp_len */, timeout, NULL, rsp_it);
2065}
2066
2067#endif
2068
0a39d8f2
AP
2069/*
2070 * Platform-specific sections
2071 */
ffa10187 2072#if defined(_WIN32)
a1ad253f
AP
2073# ifdef fileno
2074# undef fileno
2075# define fileno(a) (int)_fileno(a)
2076# endif
2077
2078# include <windows.h>
2079# include <tchar.h>
2080
2081static int WIN32_rename(const char *from, const char *to)
0f113f3e
MC
2082{
2083 TCHAR *tfrom = NULL, *tto;
2084 DWORD err;
2085 int ret = 0;
2086
2087 if (sizeof(TCHAR) == 1) {
2088 tfrom = (TCHAR *)from;
2089 tto = (TCHAR *)to;
2090 } else { /* UNICODE path */
2091
2092 size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
b1ad95e3 2093 tfrom = malloc(sizeof(*tfrom) * (flen + tlen));
0f113f3e
MC
2094 if (tfrom == NULL)
2095 goto err;
2096 tto = tfrom + flen;
2097# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2098 if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
2099# endif
2100 for (i = 0; i < flen; i++)
2101 tfrom[i] = (TCHAR)from[i];
2102# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2103 if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
2104# endif
2105 for (i = 0; i < tlen; i++)
2106 tto[i] = (TCHAR)to[i];
2107 }
2108
2109 if (MoveFile(tfrom, tto))
2110 goto ok;
2111 err = GetLastError();
2112 if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
2113 if (DeleteFile(tto) && MoveFile(tfrom, tto))
2114 goto ok;
2115 err = GetLastError();
2116 }
2117 if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
2118 errno = ENOENT;
2119 else if (err == ERROR_ACCESS_DENIED)
2120 errno = EACCES;
2121 else
2122 errno = EINVAL; /* we could map more codes... */
2123 err:
2124 ret = -1;
2125 ok:
2126 if (tfrom != NULL && tfrom != (TCHAR *)from)
2127 free(tfrom);
2128 return ret;
2129}
0a39d8f2
AP
2130#endif
2131
2132/* app_tminterval section */
2133#if defined(_WIN32)
0f113f3e
MC
2134double app_tminterval(int stop, int usertime)
2135{
2136 FILETIME now;
2137 double ret = 0;
2138 static ULARGE_INTEGER tmstart;
2139 static int warning = 1;
2140# ifdef _WIN32_WINNT
2141 static HANDLE proc = NULL;
2142
2143 if (proc == NULL) {
2144 if (check_winnt())
2145 proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
2146 GetCurrentProcessId());
2147 if (proc == NULL)
2148 proc = (HANDLE) - 1;
2149 }
2150
2151 if (usertime && proc != (HANDLE) - 1) {
2152 FILETIME junk;
2153 GetProcessTimes(proc, &junk, &junk, &junk, &now);
2154 } else
2155# endif
2156 {
2157 SYSTEMTIME systime;
9135fddb 2158
0f113f3e
MC
2159 if (usertime && warning) {
2160 BIO_printf(bio_err, "To get meaningful results, run "
2161 "this program on idle system.\n");
2162 warning = 0;
2163 }
2164 GetSystemTime(&systime);
2165 SystemTimeToFileTime(&systime, &now);
2166 }
9135fddb 2167
0f113f3e
MC
2168 if (stop == TM_START) {
2169 tmstart.u.LowPart = now.dwLowDateTime;
2170 tmstart.u.HighPart = now.dwHighDateTime;
2171 } else {
2172 ULARGE_INTEGER tmstop;
9135fddb 2173
0f113f3e
MC
2174 tmstop.u.LowPart = now.dwLowDateTime;
2175 tmstop.u.HighPart = now.dwHighDateTime;
9135fddb 2176
0f113f3e
MC
2177 ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
2178 }
9135fddb 2179
26a7d938 2180 return ret;
0f113f3e 2181}
5c8b7b4c 2182#elif defined(OPENSSL_SYS_VXWORKS)
0f113f3e 2183# include <time.h>
0a39d8f2 2184
0f113f3e
MC
2185double app_tminterval(int stop, int usertime)
2186{
2187 double ret = 0;
2188# ifdef CLOCK_REALTIME
2189 static struct timespec tmstart;
2190 struct timespec now;
2191# else
2192 static unsigned long tmstart;
2193 unsigned long now;
2194# endif
2195 static int warning = 1;
2196
2197 if (usertime && warning) {
2198 BIO_printf(bio_err, "To get meaningful results, run "
2199 "this program on idle system.\n");
2200 warning = 0;
2201 }
2202# ifdef CLOCK_REALTIME
2203 clock_gettime(CLOCK_REALTIME, &now);
2204 if (stop == TM_START)
2205 tmstart = now;
2206 else
2207 ret = ((now.tv_sec + now.tv_nsec * 1e-9)
2208 - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
2209# else
2210 now = tickGet();
2211 if (stop == TM_START)
2212 tmstart = now;
2213 else
2214 ret = (now - tmstart) / (double)sysClkRateGet();
2215# endif
26a7d938 2216 return ret;
0f113f3e 2217}
0a39d8f2 2218
0f113f3e
MC
2219#elif defined(_SC_CLK_TCK) /* by means of unistd.h */
2220# include <sys/times.h>
0a39d8f2 2221
0f113f3e
MC
2222double app_tminterval(int stop, int usertime)
2223{
2224 double ret = 0;
db71d315 2225 struct tms rus;
2bd928a1
TM
2226 clock_t now = times(&rus);
2227 static clock_t tmstart;
0f113f3e
MC
2228
2229 if (usertime)
2230 now = rus.tms_utime;
2231
2234212c 2232 if (stop == TM_START) {
0f113f3e 2233 tmstart = now;
2234212c 2234 } else {
2bd928a1 2235 long int tck = sysconf(_SC_CLK_TCK);
0f113f3e
MC
2236 ret = (now - tmstart) / (double)tck;
2237 }
2238
26a7d938 2239 return ret;
0f113f3e 2240}
0a39d8f2 2241
0f113f3e
MC
2242#else
2243# include <sys/time.h>
2244# include <sys/resource.h>
0a39d8f2 2245
0f113f3e
MC
2246double app_tminterval(int stop, int usertime)
2247{
2248 double ret = 0;
2249 struct rusage rus;
2250 struct timeval now;
2251 static struct timeval tmstart;
2252
2253 if (usertime)
2254 getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
2255 else
2256 gettimeofday(&now, NULL);
2257
2258 if (stop == TM_START)
2259 tmstart = now;
2260 else
2261 ret = ((now.tv_sec + now.tv_usec * 1e-6)
2262 - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
2263
2264 return ret;
2265}
0a39d8f2 2266#endif
a1ad253f 2267
7e1b7485
RS
2268int app_access(const char* name, int flag)
2269{
2270#ifdef _WIN32
2271 return _access(name, flag);
2272#else
2273 return access(name, flag);
2274#endif
2275}
2276
ffa10187 2277int app_isdir(const char *name)
0f113f3e 2278{
a43ce58f 2279 return opt_isdir(name);
0f113f3e 2280}
ffa10187 2281
0a39d8f2 2282/* raw_read|write section */
51e5133d
RL
2283#if defined(__VMS)
2284# include "vms_term_sock.h"
2285static int stdin_sock = -1;
2286
2287static void close_stdin_sock(void)
2288{
2289 TerminalSocket (TERM_SOCK_DELETE, &stdin_sock);
2290}
2291
2292int fileno_stdin(void)
2293{
2294 if (stdin_sock == -1) {
2295 TerminalSocket(TERM_SOCK_CREATE, &stdin_sock);
2296 atexit(close_stdin_sock);
2297 }
2298
2299 return stdin_sock;
2300}
2301#else
2302int fileno_stdin(void)
2303{
2304 return fileno(stdin);
2305}
2306#endif
2307
2308int fileno_stdout(void)
2309{
2310 return fileno(stdout);
2311}
2312
ffa10187 2313#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
0f113f3e
MC
2314int raw_read_stdin(void *buf, int siz)
2315{
2316 DWORD n;
2317 if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
26a7d938 2318 return n;
0f113f3e 2319 else
26a7d938 2320 return -1;
0f113f3e 2321}
51e5133d 2322#elif defined(__VMS)
2234212c 2323# include <sys/socket.h>
a19228b7 2324
51e5133d
RL
2325int raw_read_stdin(void *buf, int siz)
2326{
2327 return recv(fileno_stdin(), buf, siz, 0);
2328}
ffa10187 2329#else
08073700
RB
2330# if defined(__TANDEM)
2331# if defined(OPENSSL_TANDEM_FLOSS)
2332# include <floss.h(floss_read)>
2333# endif
2334# endif
0f113f3e
MC
2335int raw_read_stdin(void *buf, int siz)
2336{
51e5133d 2337 return read(fileno_stdin(), buf, siz);
0f113f3e 2338}
ffa10187
AP
2339#endif
2340
2341#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
0f113f3e
MC
2342int raw_write_stdout(const void *buf, int siz)
2343{
2344 DWORD n;
2345 if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
26a7d938 2346 return n;
0f113f3e 2347 else
26a7d938 2348 return -1;
0f113f3e 2349}
cdb5129e 2350#elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) && defined(_SPT_MODEL_)
08073700
RB
2351# if defined(__TANDEM)
2352# if defined(OPENSSL_TANDEM_FLOSS)
2353# include <floss.h(floss_write)>
2354# endif
2355# endif
2356int raw_write_stdout(const void *buf,int siz)
2357{
2358 return write(fileno(stdout),(void*)buf,siz);
2359}
ffa10187 2360#else
08073700
RB
2361# if defined(__TANDEM)
2362# if defined(OPENSSL_TANDEM_FLOSS)
2363# include <floss.h(floss_write)>
2364# endif
2365# endif
0f113f3e
MC
2366int raw_write_stdout(const void *buf, int siz)
2367{
51e5133d 2368 return write(fileno_stdout(), buf, siz);
0f113f3e 2369}
ffa10187 2370#endif
a412b891
RL
2371
2372/*
a43ce58f 2373 * Centralized handling of input and output files with format specification
a412b891
RL
2374 * The format is meant to show what the input and output is supposed to be,
2375 * and is therefore a show of intent more than anything else. However, it
a43ce58f 2376 * does impact behavior on some platforms, such as differentiating between
a412b891
RL
2377 * text and binary input/output on non-Unix platforms
2378 */
a60994df 2379BIO *dup_bio_in(int format)
a412b891 2380{
a60994df 2381 return BIO_new_fp(stdin,
a43ce58f 2382 BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
a60994df
RL
2383}
2384
2385BIO *dup_bio_out(int format)
2386{
2387 BIO *b = BIO_new_fp(stdout,
a43ce58f 2388 BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
71bb86f0
RL
2389 void *prefix = NULL;
2390
a412b891 2391#ifdef OPENSSL_SYS_VMS
a43ce58f 2392 if (FMT_istext(format))
a60994df 2393 b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
149bd5d6 2394#endif
71bb86f0 2395
682b444f
RL
2396 if (FMT_istext(format)
2397 && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) {
e79ae962
RL
2398 b = BIO_push(BIO_new(BIO_f_prefix()), b);
2399 BIO_set_prefix(b, prefix);
71bb86f0
RL
2400 }
2401
149bd5d6
RL
2402 return b;
2403}
2404
2405BIO *dup_bio_err(int format)
2406{
2407 BIO *b = BIO_new_fp(stderr,
a43ce58f 2408 BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
149bd5d6 2409#ifdef OPENSSL_SYS_VMS
a43ce58f 2410 if (FMT_istext(format))
149bd5d6 2411 b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
a412b891
RL
2412#endif
2413 return b;
2414}
2415
2416void unbuffer(FILE *fp)
2417{
90dbd250
RL
2418/*
2419 * On VMS, setbuf() will only take 32-bit pointers, and a compilation
2420 * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here.
2421 * However, we trust that the C RTL will never give us a FILE pointer
2422 * above the first 4 GB of memory, so we simply turn off the warning
2423 * temporarily.
2424 */
2425#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
2426# pragma environment save
2427# pragma message disable maylosedata2
2428#endif
a412b891 2429 setbuf(fp, NULL);
90dbd250
RL
2430#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
2431# pragma environment restore
2432#endif
a412b891
RL
2433}
2434
2435static const char *modestr(char mode, int format)
2436{
2437 OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w');
2438
2439 switch (mode) {
2440 case 'a':
a43ce58f 2441 return FMT_istext(format) ? "a" : "ab";
a412b891 2442 case 'r':
a43ce58f 2443 return FMT_istext(format) ? "r" : "rb";
a412b891 2444 case 'w':
a43ce58f 2445 return FMT_istext(format) ? "w" : "wb";
a412b891
RL
2446 }
2447 /* The assert above should make sure we never reach this point */
2448 return NULL;
2449}
2450
2451static const char *modeverb(char mode)
2452{
2453 switch (mode) {
2454 case 'a':
2455 return "appending";
2456 case 'r':
2457 return "reading";
2458 case 'w':
2459 return "writing";
2460 }
2461 return "(doing something)";
2462}
2463
2464/*
2465 * Open a file for writing, owner-read-only.
2466 */
2467BIO *bio_open_owner(const char *filename, int format, int private)
2468{
2469 FILE *fp = NULL;
2470 BIO *b = NULL;
1cd5cc36 2471 int fd = -1, bflags, mode, textmode;
a412b891
RL
2472
2473 if (!private || filename == NULL || strcmp(filename, "-") == 0)
2474 return bio_open_default(filename, 'w', format);
2475
2476 mode = O_WRONLY;
2477#ifdef O_CREAT
2478 mode |= O_CREAT;
2479#endif
2480#ifdef O_TRUNC
2481 mode |= O_TRUNC;
2482#endif
a43ce58f 2483 textmode = FMT_istext(format);
1cd5cc36 2484 if (!textmode) {
a412b891
RL
2485#ifdef O_BINARY
2486 mode |= O_BINARY;
2487#elif defined(_O_BINARY)
2488 mode |= _O_BINARY;
2489#endif
2490 }
2491
fbd03b09
RL
2492#ifdef OPENSSL_SYS_VMS
2493 /* VMS doesn't have O_BINARY, it just doesn't make sense. But,
2494 * it still needs to know that we're going binary, or fdopen()
2495 * will fail with "invalid argument"... so we tell VMS what the
2496 * context is.
2497 */
2498 if (!textmode)
2499 fd = open(filename, mode, 0600, "ctx=bin");
2500 else
2501#endif
2502 fd = open(filename, mode, 0600);
a412b891
RL
2503 if (fd < 0)
2504 goto err;
2505 fp = fdopen(fd, modestr('w', format));
2506 if (fp == NULL)
2507 goto err;
2508 bflags = BIO_CLOSE;
1cd5cc36 2509 if (textmode)
a412b891
RL
2510 bflags |= BIO_FP_TEXT;
2511 b = BIO_new_fp(fp, bflags);
2512 if (b)
2513 return b;
2514
2515 err:
2516 BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n",
2517 opt_getprog(), filename, strerror(errno));
2518 ERR_print_errors(bio_err);
2519 /* If we have fp, then fdopen took over fd, so don't close both. */
2520 if (fp)
2521 fclose(fp);
2522 else if (fd >= 0)
2523 close(fd);
2524 return NULL;
2525}
2526
2527static BIO *bio_open_default_(const char *filename, char mode, int format,
2528 int quiet)
2529{
2530 BIO *ret;
2531
2532 if (filename == NULL || strcmp(filename, "-") == 0) {
a60994df 2533 ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format);
a412b891
RL
2534 if (quiet) {
2535 ERR_clear_error();
2536 return ret;
2537 }
2538 if (ret != NULL)
2539 return ret;
2540 BIO_printf(bio_err,
2541 "Can't open %s, %s\n",
2542 mode == 'r' ? "stdin" : "stdout", strerror(errno));
2543 } else {
2544 ret = BIO_new_file(filename, modestr(mode, format));
2545 if (quiet) {
2546 ERR_clear_error();
2547 return ret;
2548 }
2549 if (ret != NULL)
2550 return ret;
2551 BIO_printf(bio_err,
2552 "Can't open %s for %s, %s\n",
2553 filename, modeverb(mode), strerror(errno));
2554 }
2555 ERR_print_errors(bio_err);
2556 return NULL;
2557}
2558
2559BIO *bio_open_default(const char *filename, char mode, int format)
2560{
2561 return bio_open_default_(filename, mode, format, 0);
2562}
2563
2564BIO *bio_open_default_quiet(const char *filename, char mode, int format)
2565{
2566 return bio_open_default_(filename, mode, format, 1);
2567}
2568
e1b9840e
MC
2569void wait_for_async(SSL *s)
2570{
d6e03b70
MC
2571 /* On Windows select only works for sockets, so we simply don't wait */
2572#ifndef OPENSSL_SYS_WINDOWS
ff75a257 2573 int width = 0;
e1b9840e 2574 fd_set asyncfds;
ff75a257
MC
2575 OSSL_ASYNC_FD *fds;
2576 size_t numfds;
0a345252 2577 size_t i;
e1b9840e 2578
ff75a257
MC
2579 if (!SSL_get_all_async_fds(s, NULL, &numfds))
2580 return;
2581 if (numfds == 0)
e1b9840e 2582 return;
589902b2 2583 fds = app_malloc(sizeof(OSSL_ASYNC_FD) * numfds, "allocate async fds");
ff75a257
MC
2584 if (!SSL_get_all_async_fds(s, fds, &numfds)) {
2585 OPENSSL_free(fds);
0a345252 2586 return;
ff75a257 2587 }
e1b9840e 2588
e1b9840e 2589 FD_ZERO(&asyncfds);
0a345252
P
2590 for (i = 0; i < numfds; i++) {
2591 if (width <= (int)fds[i])
2592 width = (int)fds[i] + 1;
2593 openssl_fdset((int)fds[i], &asyncfds);
ff75a257 2594 }
e1b9840e 2595 select(width, (void *)&asyncfds, NULL, NULL, NULL);
0a345252 2596 OPENSSL_free(fds);
d6e03b70 2597#endif
e1b9840e 2598}
75dd6c1a
MC
2599
2600/* if OPENSSL_SYS_WINDOWS is defined then so is OPENSSL_SYS_MSDOS */
2601#if defined(OPENSSL_SYS_MSDOS)
2602int has_stdin_waiting(void)
2603{
2604# if defined(OPENSSL_SYS_WINDOWS)
2605 HANDLE inhand = GetStdHandle(STD_INPUT_HANDLE);
2606 DWORD events = 0;
2607 INPUT_RECORD inputrec;
2608 DWORD insize = 1;
2609 BOOL peeked;
2610
2611 if (inhand == INVALID_HANDLE_VALUE) {
2612 return 0;
2613 }
2614
2615 peeked = PeekConsoleInput(inhand, &inputrec, insize, &events);
2616 if (!peeked) {
2617 /* Probably redirected input? _kbhit() does not work in this case */
2618 if (!feof(stdin)) {
2619 return 1;
2620 }
2621 return 0;
2622 }
2623# endif
2624 return _kbhit();
2625}
2626#endif
17ebf85a
DSH
2627
2628/* Corrupt a signature by modifying final byte */
a0754084 2629void corrupt_signature(const ASN1_STRING *signature)
17ebf85a 2630{
a0754084
DSH
2631 unsigned char *s = signature->data;
2632 s[signature->length - 1] ^= 0x1;
17ebf85a 2633}
dc047d31
DSH
2634
2635int set_cert_times(X509 *x, const char *startdate, const char *enddate,
2636 int days)
2637{
dc047d31 2638 if (startdate == NULL || strcmp(startdate, "today") == 0) {
0b7347ef
DSH
2639 if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL)
2640 return 0;
2641 } else {
04e62715 2642 if (!ASN1_TIME_set_string_X509(X509_getm_notBefore(x), startdate))
0b7347ef 2643 return 0;
dc047d31 2644 }
dc047d31 2645 if (enddate == NULL) {
0b7347ef
DSH
2646 if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL)
2647 == NULL)
2648 return 0;
04e62715 2649 } else if (!ASN1_TIME_set_string_X509(X509_getm_notAfter(x), enddate)) {
0b7347ef 2650 return 0;
dc047d31 2651 }
0b7347ef 2652 return 1;
dc047d31 2653}
20967afb 2654
64713cb1
CN
2655int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate)
2656{
2657 int ret = 0;
2658 ASN1_TIME *tm = ASN1_TIME_new();
2659
2660 if (tm == NULL)
2661 goto end;
2662
2663 if (lastupdate == NULL) {
2664 if (X509_gmtime_adj(tm, 0) == NULL)
2665 goto end;
2666 } else {
2667 if (!ASN1_TIME_set_string_X509(tm, lastupdate))
2668 goto end;
2669 }
2670
2671 if (!X509_CRL_set1_lastUpdate(crl, tm))
2672 goto end;
2673
2674 ret = 1;
2675end:
2676 ASN1_TIME_free(tm);
2677 return ret;
2678}
2679
2680int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate,
2681 long days, long hours, long secs)
2682{
2683 int ret = 0;
2684 ASN1_TIME *tm = ASN1_TIME_new();
2685
2686 if (tm == NULL)
2687 goto end;
2688
2689 if (nextupdate == NULL) {
2690 if (X509_time_adj_ex(tm, days, hours * 60 * 60 + secs, NULL) == NULL)
2691 goto end;
2692 } else {
2693 if (!ASN1_TIME_set_string_X509(tm, nextupdate))
2694 goto end;
2695 }
2696
2697 if (!X509_CRL_set1_nextUpdate(crl, tm))
2698 goto end;
2699
2700 ret = 1;
2701end:
2702 ASN1_TIME_free(tm);
2703 return ret;
2704}
2705
20967afb
RS
2706void make_uppercase(char *string)
2707{
2708 int i;
2709
2710 for (i = 0; string[i] != '\0'; i++)
2711 string[i] = toupper((unsigned char)string[i]);
2712}
a43ce58f
SL
2713
2714int opt_printf_stderr(const char *fmt, ...)
2715{
2716 va_list ap;
2717 int ret;
2718
2719 va_start(ap, fmt);
2720 ret = BIO_vprintf(bio_err, fmt, ap);
2721 va_end(ap);
2722 return ret;
2723}
95214b43
SL
2724
2725OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
2726 const OSSL_PARAM *paramdefs)
2727{
2728 OSSL_PARAM *params = NULL;
2729 size_t sz = (size_t)sk_OPENSSL_STRING_num(opts);
2730 size_t params_n;
2731 char *opt = "", *stmp, *vtmp = NULL;
e1dcac22 2732 int found = 1;
95214b43
SL
2733
2734 if (opts == NULL)
2735 return NULL;
2736
2737 params = OPENSSL_zalloc(sizeof(OSSL_PARAM) * (sz + 1));
2738 if (params == NULL)
2739 return NULL;
2740
2741 for (params_n = 0; params_n < sz; params_n++) {
2742 opt = sk_OPENSSL_STRING_value(opts, (int)params_n);
2743 if ((stmp = OPENSSL_strdup(opt)) == NULL
2744 || (vtmp = strchr(stmp, ':')) == NULL)
2745 goto err;
2746 /* Replace ':' with 0 to terminate the string pointed to by stmp */
2747 *vtmp = 0;
2748 /* Skip over the separator so that vmtp points to the value */
2749 vtmp++;
2750 if (!OSSL_PARAM_allocate_from_text(&params[params_n], paramdefs,
e1dcac22 2751 stmp, vtmp, strlen(vtmp), &found))
95214b43
SL
2752 goto err;
2753 OPENSSL_free(stmp);
2754 }
2755 params[params_n] = OSSL_PARAM_construct_end();
2756 return params;
2757err:
2758 OPENSSL_free(stmp);
e1dcac22
P
2759 BIO_printf(bio_err, "Parameter %s '%s'\n", found ? "error" : "unknown",
2760 opt);
95214b43
SL
2761 ERR_print_errors(bio_err);
2762 app_params_free(params);
2763 return NULL;
2764}
2765
2766void app_params_free(OSSL_PARAM *params)
2767{
2768 int i;
2769
2770 if (params != NULL) {
2771 for (i = 0; params[i].key != NULL; ++i)
2772 OPENSSL_free(params[i].data);
2773 OPENSSL_free(params);
2774 }
2775}