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