xref: /freebsd/crypto/openssl/apps/lib/apps.c (revision 10a428653ee7216475f1ddce3fb4cbf1200319f8)
1 /*
2  * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
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.
14  */
15 #define _POSIX_C_SOURCE 2
16 #endif
17 
18 #ifndef OPENSSL_NO_ENGINE
19 /* We need to use some deprecated APIs */
20 #define OPENSSL_SUPPRESS_DEPRECATED
21 #include <openssl/engine.h>
22 #endif
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #ifndef OPENSSL_NO_POSIX_IO
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #endif
32 #include <ctype.h>
33 #include <errno.h>
34 #include <openssl/err.h>
35 #include <openssl/x509.h>
36 #include <openssl/x509v3.h>
37 #include <openssl/http.h>
38 #include <openssl/pem.h>
39 #include <openssl/store.h>
40 #include <openssl/pkcs12.h>
41 #include <openssl/ui.h>
42 #include <openssl/safestack.h>
43 #include <openssl/rsa.h>
44 #include <openssl/rand.h>
45 #include <openssl/bn.h>
46 #include <openssl/ssl.h>
47 #include <openssl/core_names.h>
48 #include "s_apps.h"
49 #include "apps.h"
50 
51 #include "internal/sockets.h" /* for openssl_fdset() */
52 #include "internal/numbers.h" /* for LONG_MAX */
53 #include "internal/e_os.h"
54 
55 #ifdef _WIN32
56 static int WIN32_rename(const char *from, const char *to);
57 #define rename(from, to) WIN32_rename((from), (to))
58 #endif
59 
60 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
61 #include <conio.h>
62 #endif
63 
64 #if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) || defined(__BORLANDC__)
65 #define _kbhit kbhit
66 #endif
67 
68 static BIO *bio_open_default_(const char *filename, char mode, int format,
69     int quiet);
70 
71 #define PASS_SOURCE_SIZE_MAX 4
72 
73 DEFINE_STACK_OF(CONF)
74 
75 typedef struct {
76     const char *name;
77     unsigned long flag;
78     unsigned long mask;
79 } NAME_EX_TBL;
80 
81 static int set_table_opts(unsigned long *flags, const char *arg,
82     const NAME_EX_TBL *in_tbl);
83 static int set_multi_opts(unsigned long *flags, const char *arg,
84     const NAME_EX_TBL *in_tbl);
85 int app_init(long mesgwin);
86 
87 #ifndef APP_INIT
app_init(long mesgwin)88 int app_init(long mesgwin)
89 {
90     return 1;
91 }
92 #endif
93 
ctx_set_verify_locations(SSL_CTX * ctx,const char * CAfile,int noCAfile,const char * CApath,int noCApath,const char * CAstore,int noCAstore)94 int ctx_set_verify_locations(SSL_CTX *ctx,
95     const char *CAfile, int noCAfile,
96     const char *CApath, int noCApath,
97     const char *CAstore, int noCAstore)
98 {
99     if (CAfile == NULL && CApath == NULL && CAstore == NULL) {
100         if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0)
101             return 0;
102         if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0)
103             return 0;
104         if (!noCAstore && SSL_CTX_set_default_verify_store(ctx) <= 0)
105             return 0;
106 
107         return 1;
108     }
109 
110     if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile))
111         return 0;
112     if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath))
113         return 0;
114     if (CAstore != NULL && !SSL_CTX_load_verify_store(ctx, CAstore))
115         return 0;
116     return 1;
117 }
118 
119 #ifndef OPENSSL_NO_CT
120 
ctx_set_ctlog_list_file(SSL_CTX * ctx,const char * path)121 int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
122 {
123     if (path == NULL)
124         return SSL_CTX_set_default_ctlog_list_file(ctx);
125 
126     return SSL_CTX_set_ctlog_list_file(ctx, path);
127 }
128 
129 #endif
130 
131 static unsigned long nmflag = 0;
132 static char nmflag_set = 0;
133 
set_nameopt(const char * arg)134 int set_nameopt(const char *arg)
135 {
136     int ret = set_name_ex(&nmflag, arg);
137 
138     if (ret)
139         nmflag_set = 1;
140 
141     return ret;
142 }
143 
get_nameopt(void)144 unsigned long get_nameopt(void)
145 {
146     return nmflag_set ? nmflag : XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_DUMP_UNKNOWN | ASN1_STRFLGS_DUMP_DER;
147 }
148 
dump_cert_text(BIO * out,X509 * x)149 void dump_cert_text(BIO *out, X509 *x)
150 {
151     print_name(out, "subject=", X509_get_subject_name(x));
152     print_name(out, "issuer=", X509_get_issuer_name(x));
153 }
154 
wrap_password_callback(char * buf,int bufsiz,int verify,void * userdata)155 int wrap_password_callback(char *buf, int bufsiz, int verify, void *userdata)
156 {
157     return password_callback(buf, bufsiz, verify, (PW_CB_DATA *)userdata);
158 }
159 
160 static char *app_get_pass(const char *arg, int keepbio);
161 
get_passwd(const char * pass,const char * desc)162 char *get_passwd(const char *pass, const char *desc)
163 {
164     char *result = NULL;
165 
166     if (desc == NULL)
167         desc = "<unknown>";
168     if (!app_passwd(pass, NULL, &result, NULL))
169         BIO_printf(bio_err, "Error getting password for %s\n", desc);
170     if (pass != NULL && result == NULL) {
171         BIO_printf(bio_err,
172             "Trying plain input string (better precede with 'pass:')\n");
173         result = OPENSSL_strdup(pass);
174         if (result == NULL)
175             BIO_printf(bio_err,
176                 "Out of memory getting password for %s\n", desc);
177     }
178     return result;
179 }
180 
app_passwd(const char * arg1,const char * arg2,char ** pass1,char ** pass2)181 int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2)
182 {
183     int same = arg1 != NULL && arg2 != NULL && strcmp(arg1, arg2) == 0;
184 
185     if (arg1 != NULL) {
186         *pass1 = app_get_pass(arg1, same);
187         if (*pass1 == NULL)
188             return 0;
189     } else if (pass1 != NULL) {
190         *pass1 = NULL;
191     }
192     if (arg2 != NULL) {
193         *pass2 = app_get_pass(arg2, same ? 2 : 0);
194         if (*pass2 == NULL) {
195             if (pass1 != NULL) {
196                 clear_free(*pass1);
197                 *pass1 = NULL;
198             }
199             return 0;
200         }
201     } else if (pass2 != NULL) {
202         *pass2 = NULL;
203     }
204     return 1;
205 }
206 
app_get_pass(const char * arg,int keepbio)207 static char *app_get_pass(const char *arg, int keepbio)
208 {
209     static BIO *pwdbio = NULL;
210     char *tmp, tpass[APP_PASS_LEN];
211     int i;
212 
213     /* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */
214     if (CHECK_AND_SKIP_PREFIX(arg, "pass:"))
215         return OPENSSL_strdup(arg);
216     if (CHECK_AND_SKIP_PREFIX(arg, "env:")) {
217         tmp = getenv(arg);
218         if (tmp == NULL) {
219             BIO_printf(bio_err, "No environment variable %s\n", arg);
220             return NULL;
221         }
222         return OPENSSL_strdup(tmp);
223     }
224     if (!keepbio || pwdbio == NULL) {
225         if (CHECK_AND_SKIP_PREFIX(arg, "file:")) {
226             pwdbio = BIO_new_file(arg, "r");
227             if (pwdbio == NULL) {
228                 BIO_printf(bio_err, "Can't open file %s\n", arg);
229                 return NULL;
230             }
231 #if !defined(_WIN32)
232             /*
233              * Under _WIN32, which covers even Win64 and CE, file
234              * descriptors referenced by BIO_s_fd are not inherited
235              * by child process and therefore below is not an option.
236              * It could have been an option if bss_fd.c was operating
237              * on real Windows descriptors, such as those obtained
238              * with CreateFile.
239              */
240         } else if (CHECK_AND_SKIP_PREFIX(arg, "fd:")) {
241             BIO *btmp;
242 
243             i = atoi(arg);
244             if (i >= 0)
245                 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
246             if ((i < 0) || pwdbio == NULL) {
247                 BIO_printf(bio_err, "Can't access file descriptor %s\n", arg);
248                 return NULL;
249             }
250             /*
251              * Can't do BIO_gets on an fd BIO so add a buffering BIO
252              */
253             btmp = BIO_new(BIO_f_buffer());
254             if (btmp == NULL) {
255                 BIO_free_all(pwdbio);
256                 pwdbio = NULL;
257                 BIO_printf(bio_err, "Out of memory\n");
258                 return NULL;
259             }
260             pwdbio = BIO_push(btmp, pwdbio);
261 #endif
262         } else if (strcmp(arg, "stdin") == 0) {
263             unbuffer(stdin);
264             pwdbio = dup_bio_in(FORMAT_TEXT);
265             if (pwdbio == NULL) {
266                 BIO_printf(bio_err, "Can't open BIO for stdin\n");
267                 return NULL;
268             }
269         } else {
270             /* argument syntax error; do not reveal too much about arg */
271             const char *arg_ptr = strchr(arg, ':');
272             if (arg_ptr == NULL || arg_ptr - arg > PASS_SOURCE_SIZE_MAX)
273                 BIO_printf(bio_err,
274                     "Invalid password argument, missing ':' within the first %d chars\n",
275                     PASS_SOURCE_SIZE_MAX + 1);
276             else
277                 BIO_printf(bio_err,
278                     "Invalid password argument, starting with \"%.*s\"\n",
279                     (int)(arg_ptr - arg + 1), arg);
280             return NULL;
281         }
282     }
283     i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
284     if (keepbio != 1) {
285         BIO_free_all(pwdbio);
286         pwdbio = NULL;
287     }
288     if (i <= 0) {
289         BIO_printf(bio_err, "Error reading password from BIO\n");
290         return NULL;
291     }
292     tmp = strchr(tpass, '\n');
293     if (tmp != NULL)
294         *tmp = 0;
295     return OPENSSL_strdup(tpass);
296 }
297 
app_conf_try_string(const CONF * conf,const char * group,const char * name)298 char *app_conf_try_string(const CONF *conf, const char *group, const char *name)
299 {
300     char *res;
301 
302     ERR_set_mark();
303     res = NCONF_get_string(conf, group, name);
304     if (res == NULL)
305         ERR_pop_to_mark();
306     else
307         ERR_clear_last_mark();
308     return res;
309 }
310 
app_conf_try_number(const CONF * conf,const char * group,const char * name,long * result)311 int app_conf_try_number(const CONF *conf, const char *group, const char *name,
312     long *result)
313 {
314     int ok;
315 
316     ERR_set_mark();
317     ok = NCONF_get_number(conf, group, name, result);
318     if (!ok)
319         ERR_pop_to_mark();
320     else
321         ERR_clear_last_mark();
322     return ok;
323 }
324 
app_load_config_bio(BIO * in,const char * filename)325 CONF *app_load_config_bio(BIO *in, const char *filename)
326 {
327     long errorline = -1;
328     CONF *conf;
329     int i;
330 
331     conf = NCONF_new_ex(app_get0_libctx(), NULL);
332     i = NCONF_load_bio(conf, in, &errorline);
333     if (i > 0)
334         return conf;
335 
336     if (errorline <= 0) {
337         BIO_printf(bio_err, "%s: Can't load ", opt_getprog());
338     } else {
339         BIO_printf(bio_err, "%s: Error on line %ld of ", opt_getprog(),
340             errorline);
341     }
342     if (filename != NULL)
343         BIO_printf(bio_err, "config file \"%s\"\n", filename);
344     else
345         BIO_printf(bio_err, "config input");
346 
347     NCONF_free(conf);
348     return NULL;
349 }
350 
app_load_config_verbose(const char * filename,int verbose)351 CONF *app_load_config_verbose(const char *filename, int verbose)
352 {
353     if (verbose) {
354         if (*filename == '\0')
355             BIO_printf(bio_err, "No configuration used\n");
356         else
357             BIO_printf(bio_err, "Using configuration from %s\n", filename);
358     }
359     return app_load_config_internal(filename, 0);
360 }
361 
app_load_config_internal(const char * filename,int quiet)362 CONF *app_load_config_internal(const char *filename, int quiet)
363 {
364     BIO *in;
365     CONF *conf;
366 
367     if (filename == NULL || *filename != '\0') {
368         if ((in = bio_open_default_(filename, 'r', FORMAT_TEXT, quiet)) == NULL)
369             return NULL;
370         conf = app_load_config_bio(in, filename);
371         BIO_free(in);
372     } else {
373         /* Return empty config if filename is empty string. */
374         conf = NCONF_new_ex(app_get0_libctx(), NULL);
375     }
376     return conf;
377 }
378 
app_load_modules(const CONF * config)379 int app_load_modules(const CONF *config)
380 {
381     CONF *to_free = NULL;
382 
383     if (config == NULL)
384         config = to_free = app_load_config_quiet(default_config_file);
385     if (config == NULL)
386         return 1;
387 
388     if (CONF_modules_load(config, NULL, 0) <= 0) {
389         BIO_printf(bio_err, "Error configuring OpenSSL modules\n");
390         ERR_print_errors(bio_err);
391         NCONF_free(to_free);
392         return 0;
393     }
394     NCONF_free(to_free);
395     return 1;
396 }
397 
add_oid_section(CONF * conf)398 int add_oid_section(CONF *conf)
399 {
400     char *p;
401     STACK_OF(CONF_VALUE) *sktmp;
402     CONF_VALUE *cnf;
403     int i;
404 
405     if ((p = app_conf_try_string(conf, NULL, "oid_section")) == NULL)
406         return 1;
407     if ((sktmp = NCONF_get_section(conf, p)) == NULL) {
408         BIO_printf(bio_err, "problem loading oid section %s\n", p);
409         return 0;
410     }
411     for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
412         cnf = sk_CONF_VALUE_value(sktmp, i);
413         if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
414             BIO_printf(bio_err, "problem creating object %s=%s\n",
415                 cnf->name, cnf->value);
416             return 0;
417         }
418     }
419     return 1;
420 }
421 
app_load_config_modules(const char * configfile)422 CONF *app_load_config_modules(const char *configfile)
423 {
424     CONF *conf = NULL;
425 
426     if (configfile != NULL) {
427         if ((conf = app_load_config_verbose(configfile, 1)) == NULL)
428             return NULL;
429         if (configfile != default_config_file && !app_load_modules(conf)) {
430             NCONF_free(conf);
431             conf = NULL;
432         }
433     }
434     return conf;
435 }
436 
437 #define IS_HTTP(uri) ((uri) != NULL && HAS_PREFIX(uri, OSSL_HTTP_PREFIX))
438 #define IS_HTTPS(uri) ((uri) != NULL && HAS_PREFIX(uri, OSSL_HTTPS_PREFIX))
439 
load_cert_pass(const char * uri,int format,int maybe_stdin,const char * pass,const char * desc)440 X509 *load_cert_pass(const char *uri, int format, int maybe_stdin,
441     const char *pass, const char *desc)
442 {
443     X509 *cert = NULL;
444 
445     if (desc == NULL)
446         desc = "certificate";
447     if (IS_HTTPS(uri)) {
448         BIO_printf(bio_err, "Loading %s over HTTPS is unsupported\n", desc);
449     } else if (IS_HTTP(uri)) {
450         cert = X509_load_http(uri, NULL, NULL, 0 /* timeout */);
451         if (cert == NULL) {
452             ERR_print_errors(bio_err);
453             BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri);
454         }
455     } else {
456         (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0,
457             NULL, NULL, NULL, &cert, NULL, NULL, NULL);
458     }
459     return cert;
460 }
461 
load_crl(const char * uri,int format,int maybe_stdin,const char * desc)462 X509_CRL *load_crl(const char *uri, int format, int maybe_stdin,
463     const char *desc)
464 {
465     X509_CRL *crl = NULL;
466 
467     if (desc == NULL)
468         desc = "CRL";
469     if (IS_HTTPS(uri)) {
470         BIO_printf(bio_err, "Loading %s over HTTPS is unsupported\n", desc);
471     } else if (IS_HTTP(uri)) {
472         crl = X509_CRL_load_http(uri, NULL, NULL, 0 /* timeout */);
473         if (crl == NULL) {
474             ERR_print_errors(bio_err);
475             BIO_printf(bio_err, "Unable to load %s from %s\n", desc, uri);
476         }
477     } else {
478         (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc, 0,
479             NULL, NULL, NULL, NULL, NULL, &crl, NULL);
480     }
481     return crl;
482 }
483 
484 /* Could be simplified if OSSL_STORE supported CSRs, see FR #15725 */
load_csr(const char * file,int format,const char * desc)485 X509_REQ *load_csr(const char *file, int format, const char *desc)
486 {
487     X509_REQ *req = NULL;
488     BIO *in;
489 
490     if (format == FORMAT_UNDEF)
491         format = FORMAT_PEM;
492     in = bio_open_default(file, 'r', format);
493     if (in == NULL)
494         goto end;
495 
496     if (format == FORMAT_ASN1)
497         req = d2i_X509_REQ_bio(in, NULL);
498     else if (format == FORMAT_PEM)
499         req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
500     else
501         print_format_error(format, OPT_FMT_PEMDER);
502 
503 end:
504     if (req == NULL) {
505         ERR_print_errors(bio_err);
506         if (desc != NULL)
507             BIO_printf(bio_err, "Unable to load %s\n", desc);
508     }
509     BIO_free(in);
510     return req;
511 }
512 
513 /* Better extend OSSL_STORE to support CSRs, see FR #15725 */
load_csr_autofmt(const char * infile,int format,STACK_OF (OPENSSL_STRING)* vfyopts,const char * desc)514 X509_REQ *load_csr_autofmt(const char *infile, int format,
515     STACK_OF(OPENSSL_STRING) *vfyopts, const char *desc)
516 {
517     X509_REQ *csr;
518 
519     if (format != FORMAT_UNDEF) {
520         csr = load_csr(infile, format, desc);
521     } else { /* try PEM, then DER */
522         BIO *bio_bak = bio_err;
523 
524         bio_err = NULL; /* do not show errors on more than one try */
525         csr = load_csr(infile, FORMAT_PEM, NULL /* desc */);
526         bio_err = bio_bak;
527         if (csr == NULL) {
528             ERR_clear_error();
529             csr = load_csr(infile, FORMAT_ASN1, NULL /* desc */);
530         }
531         if (csr == NULL) {
532             BIO_printf(bio_err, "error: unable to load %s from file '%s'\n",
533                 desc, infile);
534         }
535     }
536     if (csr != NULL) {
537         EVP_PKEY *pkey = X509_REQ_get0_pubkey(csr);
538         int ret = do_X509_REQ_verify(csr, pkey, vfyopts);
539 
540         if (pkey == NULL || ret < 0)
541             BIO_puts(bio_err, "Warning: error while verifying CSR self-signature\n");
542         else if (ret == 0)
543             BIO_puts(bio_err, "Warning: CSR self-signature does not match the contents\n");
544         return csr;
545     }
546     return csr;
547 }
548 
cleanse(char * str)549 void cleanse(char *str)
550 {
551     if (str != NULL)
552         OPENSSL_cleanse(str, strlen(str));
553 }
554 
clear_free(char * str)555 void clear_free(char *str)
556 {
557     if (str != NULL)
558         OPENSSL_clear_free(str, strlen(str));
559 }
560 
load_key(const char * uri,int format,int may_stdin,const char * pass,ENGINE * e,const char * desc)561 EVP_PKEY *load_key(const char *uri, int format, int may_stdin,
562     const char *pass, ENGINE *e, const char *desc)
563 {
564     EVP_PKEY *pkey = NULL;
565     char *allocated_uri = NULL;
566 
567     if (desc == NULL)
568         desc = "private key";
569 
570     if (format == FORMAT_ENGINE)
571         uri = allocated_uri = make_engine_uri(e, uri, desc);
572     (void)load_key_certs_crls(uri, format, may_stdin, pass, desc, 0,
573         &pkey, NULL, NULL, NULL, NULL, NULL, NULL);
574 
575     OPENSSL_free(allocated_uri);
576     return pkey;
577 }
578 
579 /* first try reading public key, on failure resort to loading private key */
load_pubkey(const char * uri,int format,int maybe_stdin,const char * pass,ENGINE * e,const char * desc)580 EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
581     const char *pass, ENGINE *e, const char *desc)
582 {
583     EVP_PKEY *pkey = NULL;
584     char *allocated_uri = NULL;
585 
586     if (desc == NULL)
587         desc = "public key";
588 
589     if (format == FORMAT_ENGINE)
590         uri = allocated_uri = make_engine_uri(e, uri, desc);
591     (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 1,
592         NULL, &pkey, NULL, NULL, NULL, NULL, NULL);
593     if (pkey == NULL)
594         (void)load_key_certs_crls(uri, format, maybe_stdin, pass, desc, 0,
595             &pkey, NULL, NULL, NULL, NULL, NULL, NULL);
596     OPENSSL_free(allocated_uri);
597     return pkey;
598 }
599 
load_keyparams_suppress(const char * uri,int format,int maybe_stdin,const char * keytype,const char * desc,int suppress_decode_errors)600 EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin,
601     const char *keytype, const char *desc,
602     int suppress_decode_errors)
603 {
604     EVP_PKEY *params = NULL;
605 
606     if (desc == NULL)
607         desc = "key parameters";
608     (void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc,
609         suppress_decode_errors,
610         NULL, NULL, &params, NULL, NULL, NULL, NULL);
611     if (params != NULL && keytype != NULL && !EVP_PKEY_is_a(params, keytype)) {
612         ERR_print_errors(bio_err);
613         BIO_printf(bio_err,
614             "Unable to load %s from %s (unexpected parameters type)\n",
615             desc, uri);
616         EVP_PKEY_free(params);
617         params = NULL;
618     }
619     return params;
620 }
621 
load_keyparams(const char * uri,int format,int maybe_stdin,const char * keytype,const char * desc)622 EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin,
623     const char *keytype, const char *desc)
624 {
625     return load_keyparams_suppress(uri, format, maybe_stdin, keytype, desc, 0);
626 }
627 
app_bail_out(char * fmt,...)628 void app_bail_out(char *fmt, ...)
629 {
630     va_list args;
631 
632     va_start(args, fmt);
633     BIO_vprintf(bio_err, fmt, args);
634     va_end(args);
635     ERR_print_errors(bio_err);
636     exit(EXIT_FAILURE);
637 }
638 
app_malloc(size_t sz,const char * what)639 void *app_malloc(size_t sz, const char *what)
640 {
641     void *vp = OPENSSL_malloc(sz);
642 
643     if (vp == NULL)
644         app_bail_out("%s: Could not allocate %zu bytes for %s\n",
645             opt_getprog(), sz, what);
646     return vp;
647 }
648 
next_item(char * opt)649 char *next_item(char *opt) /* in list separated by comma and/or space */
650 {
651     /* advance to separator (comma or whitespace), if any */
652     while (*opt != ',' && !isspace(_UC(*opt)) && *opt != '\0')
653         opt++;
654     if (*opt != '\0') {
655         /* terminate current item */
656         *opt++ = '\0';
657         /* skip over any whitespace after separator */
658         while (isspace(_UC(*opt)))
659             opt++;
660     }
661     return *opt == '\0' ? NULL : opt; /* NULL indicates end of input */
662 }
663 
warn_cert_msg(const char * uri,X509 * cert,const char * msg)664 static void warn_cert_msg(const char *uri, X509 *cert, const char *msg)
665 {
666     char *subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
667 
668     BIO_printf(bio_err, "Warning: certificate from '%s' with subject '%s' %s\n",
669         uri, subj, msg);
670     OPENSSL_free(subj);
671 }
672 
warn_cert(const char * uri,X509 * cert,int warn_EE,X509_VERIFY_PARAM * vpm)673 static void warn_cert(const char *uri, X509 *cert, int warn_EE,
674     X509_VERIFY_PARAM *vpm)
675 {
676     uint32_t ex_flags = X509_get_extension_flags(cert);
677     int res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert),
678         X509_get0_notAfter(cert));
679 
680     if (res != 0)
681         warn_cert_msg(uri, cert, res > 0 ? "has expired" : "not yet valid");
682     if (warn_EE && (ex_flags & EXFLAG_V1) == 0 && (ex_flags & EXFLAG_CA) == 0)
683         warn_cert_msg(uri, cert, "is not a CA cert");
684 }
685 
warn_certs(const char * uri,STACK_OF (X509)* certs,int warn_EE,X509_VERIFY_PARAM * vpm)686 static void warn_certs(const char *uri, STACK_OF(X509) *certs, int warn_EE,
687     X509_VERIFY_PARAM *vpm)
688 {
689     int i;
690 
691     for (i = 0; i < sk_X509_num(certs); i++)
692         warn_cert(uri, sk_X509_value(certs, i), warn_EE, vpm);
693 }
694 
load_cert_certs(const char * uri,X509 ** pcert,STACK_OF (X509)** pcerts,int exclude_http,const char * pass,const char * desc,X509_VERIFY_PARAM * vpm)695 int load_cert_certs(const char *uri,
696     X509 **pcert, STACK_OF(X509) **pcerts,
697     int exclude_http, const char *pass, const char *desc,
698     X509_VERIFY_PARAM *vpm)
699 {
700     int ret = 0;
701     char *pass_string;
702 
703     if (desc == NULL)
704         desc = pcerts == NULL ? "certificate" : "certificates";
705     if (exclude_http && (HAS_CASE_PREFIX(uri, "http://") || HAS_CASE_PREFIX(uri, "https://"))) {
706         BIO_printf(bio_err, "error: HTTP retrieval not allowed for %s\n", desc);
707         return ret;
708     }
709     pass_string = get_passwd(pass, desc);
710     ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass_string, desc, 0,
711         NULL, NULL, NULL, pcert, pcerts, NULL, NULL);
712     clear_free(pass_string);
713 
714     if (ret) {
715         if (pcert != NULL)
716             warn_cert(uri, *pcert, 0, vpm);
717         if (pcerts != NULL)
718             warn_certs(uri, *pcerts, 1, vpm);
719     } else {
720         if (pcerts != NULL) {
721             OSSL_STACK_OF_X509_free(*pcerts);
722             *pcerts = NULL;
723         }
724     }
725     return ret;
726 }
727 
STACK_OF(X509)728 STACK_OF(X509) *load_certs_multifile(char *files, const char *pass,
729     const char *desc, X509_VERIFY_PARAM *vpm)
730 {
731     STACK_OF(X509) *certs = NULL;
732     STACK_OF(X509) *result = sk_X509_new_null();
733 
734     if (files == NULL)
735         goto err;
736     if (result == NULL)
737         goto oom;
738 
739     while (files != NULL) {
740         char *next = next_item(files);
741 
742         if (!load_cert_certs(files, NULL, &certs, 0, pass, desc, vpm))
743             goto err;
744         if (!X509_add_certs(result, certs,
745                 X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
746             goto oom;
747         OSSL_STACK_OF_X509_free(certs);
748         certs = NULL;
749         files = next;
750     }
751     return result;
752 
753 oom:
754     BIO_printf(bio_err, "out of memory\n");
755 err:
756     OSSL_STACK_OF_X509_free(certs);
757     OSSL_STACK_OF_X509_free(result);
758     return NULL;
759 }
760 
sk_X509_to_store(X509_STORE * store,const STACK_OF (X509)* certs)761 static X509_STORE *sk_X509_to_store(X509_STORE *store /* may be NULL */,
762     const STACK_OF(X509) *certs /* may NULL */)
763 {
764     int i;
765 
766     if (store == NULL)
767         store = X509_STORE_new();
768     if (store == NULL)
769         return NULL;
770     for (i = 0; i < sk_X509_num(certs); i++) {
771         if (!X509_STORE_add_cert(store, sk_X509_value(certs, i))) {
772             X509_STORE_free(store);
773             return NULL;
774         }
775     }
776     return store;
777 }
778 
779 /*
780  * Create cert store structure with certificates read from given file(s).
781  * Returns pointer to created X509_STORE on success, NULL on error.
782  */
load_certstore(char * input,const char * pass,const char * desc,X509_VERIFY_PARAM * vpm)783 X509_STORE *load_certstore(char *input, const char *pass, const char *desc,
784     X509_VERIFY_PARAM *vpm)
785 {
786     X509_STORE *store = NULL;
787     STACK_OF(X509) *certs = NULL;
788 
789     while (input != NULL) {
790         char *next = next_item(input);
791         int ok;
792 
793         if (!load_cert_certs(input, NULL, &certs, 1, pass, desc, vpm)) {
794             X509_STORE_free(store);
795             return NULL;
796         }
797         ok = (store = sk_X509_to_store(store, certs)) != NULL;
798         OSSL_STACK_OF_X509_free(certs);
799         certs = NULL;
800         if (!ok)
801             return NULL;
802         input = next;
803     }
804     return store;
805 }
806 
807 /*
808  * Initialize or extend, if *certs != NULL, a certificate stack.
809  * The caller is responsible for freeing *certs if its value is left not NULL.
810  */
load_certs(const char * uri,int maybe_stdin,STACK_OF (X509)** certs,const char * pass,const char * desc)811 int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs,
812     const char *pass, const char *desc)
813 {
814     int ret, was_NULL = *certs == NULL;
815 
816     if (desc == NULL)
817         desc = "certificates";
818     ret = load_key_certs_crls(uri, FORMAT_UNDEF, maybe_stdin, pass, desc, 0,
819         NULL, NULL, NULL, NULL, certs, NULL, NULL);
820 
821     if (!ret && was_NULL) {
822         OSSL_STACK_OF_X509_free(*certs);
823         *certs = NULL;
824     }
825     return ret;
826 }
827 
828 /*
829  * Initialize or extend, if *crls != NULL, a certificate stack.
830  * The caller is responsible for freeing *crls if its value is left not NULL.
831  */
load_crls(const char * uri,STACK_OF (X509_CRL)** crls,const char * pass,const char * desc)832 int load_crls(const char *uri, STACK_OF(X509_CRL) **crls,
833     const char *pass, const char *desc)
834 {
835     int ret, was_NULL = *crls == NULL;
836 
837     if (desc == NULL)
838         desc = "CRLs";
839     ret = load_key_certs_crls(uri, FORMAT_UNDEF, 0, pass, desc, 0,
840         NULL, NULL, NULL, NULL, NULL, NULL, crls);
841 
842     if (!ret && was_NULL) {
843         sk_X509_CRL_pop_free(*crls, X509_CRL_free);
844         *crls = NULL;
845     }
846     return ret;
847 }
848 
format2string(int format)849 static const char *format2string(int format)
850 {
851     switch (format) {
852     case FORMAT_PEM:
853         return "PEM";
854     case FORMAT_ASN1:
855         return "DER";
856     case FORMAT_PVK:
857         return "PVK";
858     case FORMAT_MSBLOB:
859         return "MSBLOB";
860     }
861     return NULL;
862 }
863 
864 /* Set type expectation, but set to 0 if objects of multiple types expected. */
865 #define SET_EXPECT(val) \
866     (expect = expect < 0 ? (val) : (expect == (val) ? (val) : 0))
867 #define SET_EXPECT1(pvar, val) \
868     if ((pvar) != NULL) {      \
869         *(pvar) = NULL;        \
870         SET_EXPECT(val);       \
871     }
872 /* Provide (error msg) text for some of the credential types to be loaded. */
873 #define FAIL_NAME                                                       \
874     (ppkey != NULL ? "private key" : ppubkey != NULL ? "public key"     \
875             : pparams != NULL                        ? "key parameters" \
876             : pcert != NULL                          ? "certificate"    \
877             : pcerts != NULL                         ? "certificates"   \
878             : pcrl != NULL                           ? "CRL"            \
879             : pcrls != NULL                          ? "CRLs"           \
880                                                      : NULL)
881 /*
882  * Load those types of credentials for which the result pointer is not NULL.
883  * Reads from stdin if 'uri' is NULL and 'maybe_stdin' is nonzero.
884  * 'format' parameter may be FORMAT_PEM, FORMAT_ASN1, or 0 for no hint.
885  * desc may contain more detail on the credential(s) to be loaded for error msg
886  * For non-NULL ppkey, pcert, and pcrl the first suitable value found is loaded.
887  * If pcerts is non-NULL and *pcerts == NULL then a new cert list is allocated.
888  * If pcerts is non-NULL then all available certificates are appended to *pcerts
889  * except any certificate assigned to *pcert.
890  * If pcrls is non-NULL and *pcrls == NULL then a new list of CRLs is allocated.
891  * If pcrls is non-NULL then all available CRLs are appended to *pcerts
892  * except any CRL assigned to *pcrl.
893  * In any case (also on error) the caller is responsible for freeing all members
894  * of *pcerts and *pcrls (as far as they are not NULL).
895  */
load_key_certs_crls(const char * uri,int format,int maybe_stdin,const char * pass,const char * desc,int quiet,EVP_PKEY ** ppkey,EVP_PKEY ** ppubkey,EVP_PKEY ** pparams,X509 ** pcert,STACK_OF (X509)** pcerts,X509_CRL ** pcrl,STACK_OF (X509_CRL)** pcrls)896 int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
897     const char *pass, const char *desc, int quiet,
898     EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
899     EVP_PKEY **pparams,
900     X509 **pcert, STACK_OF(X509) **pcerts,
901     X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls)
902 {
903     PW_CB_DATA uidata;
904     OSSL_STORE_CTX *ctx = NULL;
905     OSSL_LIB_CTX *libctx = app_get0_libctx();
906     const char *propq = app_get0_propq();
907     int ncerts = 0, ncrls = 0, expect = -1;
908     const char *failed = FAIL_NAME;
909     const char *input_type;
910     OSSL_PARAM itp[2];
911     const OSSL_PARAM *params = NULL;
912 
913     /* 'failed' describes type of credential to load for potential error msg */
914     if (failed == NULL) {
915         if (!quiet)
916             BIO_printf(bio_err, "Internal error: nothing was requested to load from %s\n",
917                 uri != NULL ? uri : "<stdin>");
918         return 0;
919     }
920     /* suppress any extraneous errors left over from failed parse attempts */
921     ERR_set_mark();
922 
923     SET_EXPECT1(ppkey, OSSL_STORE_INFO_PKEY);
924     SET_EXPECT1(ppubkey, OSSL_STORE_INFO_PUBKEY);
925     SET_EXPECT1(pparams, OSSL_STORE_INFO_PARAMS);
926     SET_EXPECT1(pcert, OSSL_STORE_INFO_CERT);
927     /*
928      * Up to here, the following holds.
929      * If just one of the ppkey, ppubkey, pparams, and pcert function parameters
930      * is nonzero, expect > 0 indicates which type of credential is expected.
931      * If expect == 0, more than one of them is nonzero (multiple types expected).
932      */
933 
934     if (pcerts != NULL) {
935         if (*pcerts == NULL && (*pcerts = sk_X509_new_null()) == NULL) {
936             if (!quiet)
937                 BIO_printf(bio_err, "Out of memory loading");
938             goto end;
939         }
940         /*
941          * Adapt the 'expect' variable:
942          * set to OSSL_STORE_INFO_CERT if no other type is expected so far,
943          * otherwise set to 0 (indicating that multiple types are expected).
944          */
945         SET_EXPECT(OSSL_STORE_INFO_CERT);
946     }
947     SET_EXPECT1(pcrl, OSSL_STORE_INFO_CRL);
948     if (pcrls != NULL) {
949         if (*pcrls == NULL && (*pcrls = sk_X509_CRL_new_null()) == NULL) {
950             if (!quiet)
951                 BIO_printf(bio_err, "Out of memory loading");
952             goto end;
953         }
954         /*
955          * Adapt the 'expect' variable:
956          * set to OSSL_STORE_INFO_CRL if no other type is expected so far,
957          * otherwise set to 0 (indicating that multiple types are expected).
958          */
959         SET_EXPECT(OSSL_STORE_INFO_CRL);
960     }
961 
962     uidata.password = pass;
963     uidata.prompt_info = uri;
964 
965     if ((input_type = format2string(format)) != NULL) {
966         itp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_INPUT_TYPE,
967             (char *)input_type, 0);
968         itp[1] = OSSL_PARAM_construct_end();
969         params = itp;
970     }
971 
972     if (uri == NULL) {
973         BIO *bio;
974 
975         if (!maybe_stdin) {
976             if (!quiet)
977                 BIO_printf(bio_err, "No filename or uri specified for loading\n");
978             goto end;
979         }
980         uri = "<stdin>";
981         unbuffer(stdin);
982         bio = BIO_new_fp(stdin, 0);
983         if (bio != NULL) {
984             ctx = OSSL_STORE_attach(bio, "file", libctx, propq,
985                 get_ui_method(), &uidata, params,
986                 NULL, NULL);
987             BIO_free(bio);
988         }
989     } else {
990         ctx = OSSL_STORE_open_ex(uri, libctx, propq, get_ui_method(), &uidata,
991             params, NULL, NULL);
992     }
993     if (ctx == NULL) {
994         if (!quiet)
995             BIO_printf(bio_err, "Could not open file or uri for loading");
996         goto end;
997     }
998     /* expect == 0 means here multiple types of credentials are to be loaded */
999     if (expect > 0 && !OSSL_STORE_expect(ctx, expect)) {
1000         if (!quiet)
1001             BIO_printf(bio_err, "Internal error trying to load");
1002         goto end;
1003     }
1004 
1005     failed = NULL;
1006     /* from here, failed != NULL only if actually an error has been detected */
1007 
1008     while ((ppkey != NULL || ppubkey != NULL || pparams != NULL
1009                || pcert != NULL || pcerts != NULL || pcrl != NULL || pcrls != NULL)
1010         && !OSSL_STORE_eof(ctx)) {
1011         OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
1012         int type, ok = 1;
1013 
1014         /*
1015          * This can happen (for example) if we attempt to load a file with
1016          * multiple different types of things in it - but the thing we just
1017          * tried to load wasn't one of the ones we wanted, e.g. if we're trying
1018          * to load a certificate but the file has both the private key and the
1019          * certificate in it. We just retry until eof.
1020          */
1021         if (info == NULL) {
1022             continue;
1023         }
1024 
1025         type = OSSL_STORE_INFO_get_type(info);
1026         switch (type) {
1027         case OSSL_STORE_INFO_PKEY:
1028             if (ppkey != NULL) {
1029                 ok = (*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL;
1030                 if (ok)
1031                     ppkey = NULL;
1032                 break;
1033             }
1034             /*
1035              * An EVP_PKEY with private parts also holds the public parts,
1036              * so if the caller asked for a public key, and we got a private
1037              * key, we can still pass it back.
1038              */
1039             /* fall through */
1040         case OSSL_STORE_INFO_PUBKEY:
1041             if (ppubkey != NULL) {
1042                 ok = (*ppubkey = OSSL_STORE_INFO_get1_PUBKEY(info)) != NULL;
1043                 if (ok)
1044                     ppubkey = NULL;
1045             }
1046             break;
1047         case OSSL_STORE_INFO_PARAMS:
1048             if (pparams != NULL) {
1049                 ok = (*pparams = OSSL_STORE_INFO_get1_PARAMS(info)) != NULL;
1050                 if (ok)
1051                     pparams = NULL;
1052             }
1053             break;
1054         case OSSL_STORE_INFO_CERT:
1055             if (pcert != NULL) {
1056                 ok = (*pcert = OSSL_STORE_INFO_get1_CERT(info)) != NULL;
1057                 if (ok)
1058                     pcert = NULL;
1059             } else if (pcerts != NULL) {
1060                 ok = X509_add_cert(*pcerts,
1061                     OSSL_STORE_INFO_get1_CERT(info),
1062                     X509_ADD_FLAG_DEFAULT);
1063             }
1064             ncerts += ok;
1065             break;
1066         case OSSL_STORE_INFO_CRL:
1067             if (pcrl != NULL) {
1068                 ok = (*pcrl = OSSL_STORE_INFO_get1_CRL(info)) != NULL;
1069                 if (ok)
1070                     pcrl = NULL;
1071             } else if (pcrls != NULL) {
1072                 ok = sk_X509_CRL_push(*pcrls, OSSL_STORE_INFO_get1_CRL(info));
1073             }
1074             ncrls += ok;
1075             break;
1076         default:
1077             /* skip any other type; ok stays == 1 */
1078             break;
1079         }
1080         OSSL_STORE_INFO_free(info);
1081         if (!ok) {
1082             failed = OSSL_STORE_INFO_type_string(type);
1083             if (!quiet)
1084                 BIO_printf(bio_err, "Error reading");
1085             break;
1086         }
1087     }
1088 
1089 end:
1090     OSSL_STORE_close(ctx);
1091 
1092     /* see if any of the requested types of credentials was not found */
1093     if (failed == NULL) {
1094         if (ncerts > 0)
1095             pcerts = NULL;
1096         if (ncrls > 0)
1097             pcrls = NULL;
1098         failed = FAIL_NAME;
1099         if (failed != NULL && !quiet)
1100             BIO_printf(bio_err, "Could not find");
1101     }
1102 
1103     if (failed != NULL && !quiet) {
1104         unsigned long err = ERR_peek_last_error();
1105 
1106         /* continue the error message with the type of credential affected */
1107         if (desc != NULL && strstr(desc, failed) != NULL) {
1108             BIO_printf(bio_err, " %s", desc);
1109         } else {
1110             BIO_printf(bio_err, " %s", failed);
1111             if (desc != NULL)
1112                 BIO_printf(bio_err, " of %s", desc);
1113         }
1114         if (uri != NULL)
1115             BIO_printf(bio_err, " from %s", uri);
1116         if (ERR_SYSTEM_ERROR(err)) {
1117             /* provide more readable diagnostic output */
1118             BIO_printf(bio_err, ": %s", strerror(ERR_GET_REASON(err)));
1119             ERR_pop_to_mark();
1120             ERR_set_mark();
1121         }
1122         BIO_printf(bio_err, "\n");
1123         ERR_print_errors(bio_err);
1124     }
1125     if (quiet || failed == NULL)
1126         /* clear any suppressed or spurious errors */
1127         ERR_pop_to_mark();
1128     else
1129         ERR_clear_last_mark();
1130     return failed == NULL;
1131 }
1132 
1133 #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
1134 #define X509V3_EXT_DEFAULT 0 /* Return error for unknown exts */
1135 #define X509V3_EXT_ERROR_UNKNOWN (1L << 16) /* Print error for unknown exts */
1136 #define X509V3_EXT_PARSE_UNKNOWN (2L << 16) /* ASN1 parse unknown extensions */
1137 #define X509V3_EXT_DUMP_UNKNOWN (3L << 16) /* BIO_dump unknown extensions */
1138 
1139 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
1140 
set_cert_ex(unsigned long * flags,const char * arg)1141 int set_cert_ex(unsigned long *flags, const char *arg)
1142 {
1143     static const NAME_EX_TBL cert_tbl[] = {
1144         { "compatible", X509_FLAG_COMPAT, 0xffffffffl },
1145         { "ca_default", X509_FLAG_CA, 0xffffffffl },
1146         { "no_header", X509_FLAG_NO_HEADER, 0 },
1147         { "no_version", X509_FLAG_NO_VERSION, 0 },
1148         { "no_serial", X509_FLAG_NO_SERIAL, 0 },
1149         { "no_signame", X509_FLAG_NO_SIGNAME, 0 },
1150         { "no_validity", X509_FLAG_NO_VALIDITY, 0 },
1151         { "no_subject", X509_FLAG_NO_SUBJECT, 0 },
1152         { "no_issuer", X509_FLAG_NO_ISSUER, 0 },
1153         { "no_pubkey", X509_FLAG_NO_PUBKEY, 0 },
1154         { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0 },
1155         { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0 },
1156         { "no_aux", X509_FLAG_NO_AUX, 0 },
1157         { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0 },
1158         { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK },
1159         { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK },
1160         { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK },
1161         { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK },
1162         { NULL, 0, 0 }
1163     };
1164     return set_multi_opts(flags, arg, cert_tbl);
1165 }
1166 
set_name_ex(unsigned long * flags,const char * arg)1167 int set_name_ex(unsigned long *flags, const char *arg)
1168 {
1169     static const NAME_EX_TBL ex_tbl[] = {
1170         { "esc_2253", ASN1_STRFLGS_ESC_2253, 0 },
1171         { "esc_2254", ASN1_STRFLGS_ESC_2254, 0 },
1172         { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0 },
1173         { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0 },
1174         { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0 },
1175         { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0 },
1176         { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0 },
1177         { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0 },
1178         { "dump_all", ASN1_STRFLGS_DUMP_ALL, 0 },
1179         { "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0 },
1180         { "dump_der", ASN1_STRFLGS_DUMP_DER, 0 },
1181         { "compat", XN_FLAG_COMPAT, 0xffffffffL },
1182         { "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK },
1183         { "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK },
1184         { "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK },
1185         { "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK },
1186         { "dn_rev", XN_FLAG_DN_REV, 0 },
1187         { "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK },
1188         { "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK },
1189         { "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK },
1190         { "align", XN_FLAG_FN_ALIGN, 0 },
1191         { "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK },
1192         { "space_eq", XN_FLAG_SPC_EQ, 0 },
1193         { "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0 },
1194         { "RFC2253", XN_FLAG_RFC2253, 0xffffffffL },
1195         { "oneline", XN_FLAG_ONELINE, 0xffffffffL },
1196         { "multiline", XN_FLAG_MULTILINE, 0xffffffffL },
1197         { "ca_default", XN_FLAG_MULTILINE, 0xffffffffL },
1198         { NULL, 0, 0 }
1199     };
1200     if (set_multi_opts(flags, arg, ex_tbl) == 0)
1201         return 0;
1202     if (*flags != XN_FLAG_COMPAT
1203         && (*flags & XN_FLAG_SEP_MASK) == 0)
1204         *flags |= XN_FLAG_SEP_CPLUS_SPC;
1205     return 1;
1206 }
1207 
set_dateopt(unsigned long * dateopt,const char * arg)1208 int set_dateopt(unsigned long *dateopt, const char *arg)
1209 {
1210     if (OPENSSL_strcasecmp(arg, "rfc_822") == 0)
1211         *dateopt = ASN1_DTFLGS_RFC822;
1212     else if (OPENSSL_strcasecmp(arg, "iso_8601") == 0)
1213         *dateopt = ASN1_DTFLGS_ISO8601;
1214     else
1215         return 0;
1216     return 1;
1217 }
1218 
set_ext_copy(int * copy_type,const char * arg)1219 int set_ext_copy(int *copy_type, const char *arg)
1220 {
1221     if (OPENSSL_strcasecmp(arg, "none") == 0)
1222         *copy_type = EXT_COPY_NONE;
1223     else if (OPENSSL_strcasecmp(arg, "copy") == 0)
1224         *copy_type = EXT_COPY_ADD;
1225     else if (OPENSSL_strcasecmp(arg, "copyall") == 0)
1226         *copy_type = EXT_COPY_ALL;
1227     else
1228         return 0;
1229     return 1;
1230 }
1231 
copy_extensions(X509 * x,X509_REQ * req,int copy_type)1232 int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1233 {
1234     STACK_OF(X509_EXTENSION) *exts;
1235     int i, ret = 0;
1236 
1237     if (x == NULL || req == NULL)
1238         return 0;
1239     if (copy_type == EXT_COPY_NONE)
1240         return 1;
1241     exts = X509_REQ_get_extensions(req);
1242 
1243     for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1244         X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
1245         ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext);
1246         int idx = X509_get_ext_by_OBJ(x, obj, -1);
1247 
1248         /* Does extension exist in target? */
1249         if (idx != -1) {
1250             /* If normal copy don't override existing extension */
1251             if (copy_type == EXT_COPY_ADD)
1252                 continue;
1253             /* Delete all extensions of same type */
1254             do {
1255                 X509_EXTENSION_free(X509_delete_ext(x, idx));
1256                 idx = X509_get_ext_by_OBJ(x, obj, -1);
1257             } while (idx != -1);
1258         }
1259         if (!X509_add_ext(x, ext, -1))
1260             goto end;
1261     }
1262     ret = 1;
1263 
1264 end:
1265     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
1266     return ret;
1267 }
1268 
set_multi_opts(unsigned long * flags,const char * arg,const NAME_EX_TBL * in_tbl)1269 static int set_multi_opts(unsigned long *flags, const char *arg,
1270     const NAME_EX_TBL *in_tbl)
1271 {
1272     STACK_OF(CONF_VALUE) *vals;
1273     CONF_VALUE *val;
1274     int i, ret = 1;
1275 
1276     if (!arg)
1277         return 0;
1278     vals = X509V3_parse_list(arg);
1279     for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1280         val = sk_CONF_VALUE_value(vals, i);
1281         if (!set_table_opts(flags, val->name, in_tbl))
1282             ret = 0;
1283     }
1284     sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1285     return ret;
1286 }
1287 
set_table_opts(unsigned long * flags,const char * arg,const NAME_EX_TBL * in_tbl)1288 static int set_table_opts(unsigned long *flags, const char *arg,
1289     const NAME_EX_TBL *in_tbl)
1290 {
1291     char c;
1292     const NAME_EX_TBL *ptbl;
1293 
1294     c = arg[0];
1295     if (c == '-') {
1296         c = 0;
1297         arg++;
1298     } else if (c == '+') {
1299         c = 1;
1300         arg++;
1301     } else {
1302         c = 1;
1303     }
1304 
1305     for (ptbl = in_tbl; ptbl->name; ptbl++) {
1306         if (OPENSSL_strcasecmp(arg, ptbl->name) == 0) {
1307             *flags &= ~ptbl->mask;
1308             if (c)
1309                 *flags |= ptbl->flag;
1310             else
1311                 *flags &= ~ptbl->flag;
1312             return 1;
1313         }
1314     }
1315     return 0;
1316 }
1317 
print_name(BIO * out,const char * title,const X509_NAME * nm)1318 void print_name(BIO *out, const char *title, const X509_NAME *nm)
1319 {
1320     char *buf;
1321     char mline = 0;
1322     int indent = 0;
1323     unsigned long lflags = get_nameopt();
1324 
1325     if (out == NULL)
1326         return;
1327     if (title != NULL)
1328         BIO_puts(out, title);
1329     if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1330         mline = 1;
1331         indent = 4;
1332     }
1333     if (lflags == XN_FLAG_COMPAT) {
1334         buf = X509_NAME_oneline(nm, 0, 0);
1335         BIO_puts(out, buf);
1336         BIO_puts(out, "\n");
1337         OPENSSL_free(buf);
1338     } else {
1339         if (mline)
1340             BIO_puts(out, "\n");
1341         X509_NAME_print_ex(out, nm, indent, lflags);
1342         BIO_puts(out, "\n");
1343     }
1344 }
1345 
print_bignum_var(BIO * out,const BIGNUM * in,const char * var,int len,unsigned char * buffer)1346 void print_bignum_var(BIO *out, const BIGNUM *in, const char *var,
1347     int len, unsigned char *buffer)
1348 {
1349     BIO_printf(out, "    static unsigned char %s_%d[] = {", var, len);
1350     if (BN_is_zero(in)) {
1351         BIO_printf(out, "\n        0x00");
1352     } else {
1353         int i, l;
1354 
1355         l = BN_bn2bin(in, buffer);
1356         for (i = 0; i < l; i++) {
1357             BIO_printf(out, (i % 10) == 0 ? "\n        " : " ");
1358             if (i < l - 1)
1359                 BIO_printf(out, "0x%02X,", buffer[i]);
1360             else
1361                 BIO_printf(out, "0x%02X", buffer[i]);
1362         }
1363     }
1364     BIO_printf(out, "\n    };\n");
1365 }
1366 
print_array(BIO * out,const char * title,int len,const unsigned char * d)1367 void print_array(BIO *out, const char *title, int len, const unsigned char *d)
1368 {
1369     int i;
1370 
1371     BIO_printf(out, "unsigned char %s[%d] = {", title, len);
1372     for (i = 0; i < len; i++) {
1373         if ((i % 10) == 0)
1374             BIO_printf(out, "\n    ");
1375         if (i < len - 1)
1376             BIO_printf(out, "0x%02X, ", d[i]);
1377         else
1378             BIO_printf(out, "0x%02X", d[i]);
1379     }
1380     BIO_printf(out, "\n};\n");
1381 }
1382 
setup_verify(const char * CAfile,int noCAfile,const char * CApath,int noCApath,const char * CAstore,int noCAstore)1383 X509_STORE *setup_verify(const char *CAfile, int noCAfile,
1384     const char *CApath, int noCApath,
1385     const char *CAstore, int noCAstore)
1386 {
1387     X509_STORE *store = X509_STORE_new();
1388     X509_LOOKUP *lookup;
1389     OSSL_LIB_CTX *libctx = app_get0_libctx();
1390     const char *propq = app_get0_propq();
1391 
1392     if (store == NULL)
1393         goto end;
1394 
1395     if (CAfile != NULL || !noCAfile) {
1396         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1397         if (lookup == NULL)
1398             goto end;
1399         if (CAfile != NULL) {
1400             if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM,
1401                     libctx, propq)
1402                 <= 0) {
1403                 ERR_clear_error();
1404                 if (X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_ASN1,
1405                         libctx, propq)
1406                     <= 0) {
1407                     BIO_printf(bio_err, "Error loading file %s\n", CAfile);
1408                     goto end;
1409                 }
1410             }
1411         } else {
1412             X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT,
1413                 libctx, propq);
1414         }
1415     }
1416 
1417     if (CApath != NULL || !noCApath) {
1418         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1419         if (lookup == NULL)
1420             goto end;
1421         if (CApath != NULL) {
1422             if (X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM) <= 0) {
1423                 BIO_printf(bio_err, "Error loading directory %s\n", CApath);
1424                 goto end;
1425             }
1426         } else {
1427             X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1428         }
1429     }
1430 
1431     if (CAstore != NULL || !noCAstore) {
1432         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store());
1433         if (lookup == NULL)
1434             goto end;
1435         if (!X509_LOOKUP_add_store_ex(lookup, CAstore, libctx, propq)) {
1436             if (CAstore != NULL)
1437                 BIO_printf(bio_err, "Error loading store URI %s\n", CAstore);
1438             goto end;
1439         }
1440     }
1441 
1442     ERR_clear_error();
1443     return store;
1444 end:
1445     ERR_print_errors(bio_err);
1446     X509_STORE_free(store);
1447     return NULL;
1448 }
1449 
index_serial_hash(const OPENSSL_CSTRING * a)1450 static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
1451 {
1452     const char *n;
1453 
1454     n = a[DB_serial];
1455     while (*n == '0')
1456         n++;
1457     return OPENSSL_LH_strhash(n);
1458 }
1459 
index_serial_cmp(const OPENSSL_CSTRING * a,const OPENSSL_CSTRING * b)1460 static int index_serial_cmp(const OPENSSL_CSTRING *a,
1461     const OPENSSL_CSTRING *b)
1462 {
1463     const char *aa, *bb;
1464 
1465     for (aa = a[DB_serial]; *aa == '0'; aa++)
1466         ;
1467     for (bb = b[DB_serial]; *bb == '0'; bb++)
1468         ;
1469     return strcmp(aa, bb);
1470 }
1471 
index_name_qual(char ** a)1472 static int index_name_qual(char **a)
1473 {
1474     return (a[0][0] == 'V');
1475 }
1476 
index_name_hash(const OPENSSL_CSTRING * a)1477 static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
1478 {
1479     return OPENSSL_LH_strhash(a[DB_name]);
1480 }
1481 
index_name_cmp(const OPENSSL_CSTRING * a,const OPENSSL_CSTRING * b)1482 int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1483 {
1484     return strcmp(a[DB_name], b[DB_name]);
1485 }
1486 
IMPLEMENT_LHASH_HASH_FN(index_serial,OPENSSL_CSTRING)1487 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1488 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1489 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1490 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1491 #undef BSIZE
1492 #define BSIZE 256
1493 BIGNUM *load_serial(const char *serialfile, int *exists, int create,
1494     ASN1_INTEGER **retai)
1495 {
1496     BIO *in = NULL;
1497     BIGNUM *ret = NULL;
1498     char buf[1024];
1499     ASN1_INTEGER *ai = NULL;
1500 
1501     ai = ASN1_INTEGER_new();
1502     if (ai == NULL)
1503         goto err;
1504 
1505     in = BIO_new_file(serialfile, "r");
1506     if (exists != NULL)
1507         *exists = in != NULL;
1508     if (in == NULL) {
1509         if (!create) {
1510             perror(serialfile);
1511             goto err;
1512         }
1513         ERR_clear_error();
1514         ret = BN_new();
1515         if (ret == NULL) {
1516             BIO_printf(bio_err, "Out of memory\n");
1517         } else if (!rand_serial(ret, ai)) {
1518             BIO_printf(bio_err, "Error creating random number to store in %s\n",
1519                 serialfile);
1520             BN_free(ret);
1521             ret = NULL;
1522         }
1523     } else {
1524         if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
1525             BIO_printf(bio_err, "Unable to load number from %s\n",
1526                 serialfile);
1527             goto err;
1528         }
1529         ret = ASN1_INTEGER_to_BN(ai, NULL);
1530         if (ret == NULL) {
1531             BIO_printf(bio_err, "Error converting number from bin to BIGNUM\n");
1532             goto err;
1533         }
1534     }
1535 
1536     if (ret != NULL && retai != NULL) {
1537         *retai = ai;
1538         ai = NULL;
1539     }
1540 err:
1541     if (ret == NULL)
1542         ERR_print_errors(bio_err);
1543     BIO_free(in);
1544     ASN1_INTEGER_free(ai);
1545     return ret;
1546 }
1547 
save_serial(const char * serialfile,const char * suffix,const BIGNUM * serial,ASN1_INTEGER ** retai)1548 int save_serial(const char *serialfile, const char *suffix,
1549     const BIGNUM *serial, ASN1_INTEGER **retai)
1550 {
1551     char buf[1][BSIZE];
1552     BIO *out = NULL;
1553     int ret = 0;
1554     ASN1_INTEGER *ai = NULL;
1555     int j;
1556 
1557     if (suffix == NULL)
1558         j = strlen(serialfile);
1559     else
1560         j = strlen(serialfile) + strlen(suffix) + 1;
1561     if (j >= BSIZE) {
1562         BIO_printf(bio_err, "File name too long\n");
1563         goto err;
1564     }
1565 
1566     if (suffix == NULL) {
1567         OPENSSL_strlcpy(buf[0], serialfile, BSIZE);
1568     } else {
1569 #ifndef OPENSSL_SYS_VMS
1570         BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, suffix);
1571 #else
1572         BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, suffix);
1573 #endif
1574     }
1575     out = BIO_new_file(buf[0], "w");
1576     if (out == NULL) {
1577         goto err;
1578     }
1579 
1580     if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1581         BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
1582         goto err;
1583     }
1584     i2a_ASN1_INTEGER(out, ai);
1585     BIO_puts(out, "\n");
1586     ret = 1;
1587     if (retai) {
1588         *retai = ai;
1589         ai = NULL;
1590     }
1591 err:
1592     if (!ret)
1593         ERR_print_errors(bio_err);
1594     BIO_free_all(out);
1595     ASN1_INTEGER_free(ai);
1596     return ret;
1597 }
1598 
rotate_serial(const char * serialfile,const char * new_suffix,const char * old_suffix)1599 int rotate_serial(const char *serialfile, const char *new_suffix,
1600     const char *old_suffix)
1601 {
1602     char buf[2][BSIZE];
1603     int i, j;
1604 
1605     i = strlen(serialfile) + strlen(old_suffix);
1606     j = strlen(serialfile) + strlen(new_suffix);
1607     if (i > j)
1608         j = i;
1609     if (j + 1 >= BSIZE) {
1610         BIO_printf(bio_err, "File name too long\n");
1611         goto err;
1612     }
1613 #ifndef OPENSSL_SYS_VMS
1614     BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, new_suffix);
1615     BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", serialfile, old_suffix);
1616 #else
1617     BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, new_suffix);
1618     BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", serialfile, old_suffix);
1619 #endif
1620     if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
1621 #ifdef ENOTDIR
1622         && errno != ENOTDIR
1623 #endif
1624     ) {
1625         BIO_printf(bio_err,
1626             "Unable to rename %s to %s\n", serialfile, buf[1]);
1627         perror("reason");
1628         goto err;
1629     }
1630     if (rename(buf[0], serialfile) < 0) {
1631         BIO_printf(bio_err,
1632             "Unable to rename %s to %s\n", buf[0], serialfile);
1633         perror("reason");
1634         rename(buf[1], serialfile);
1635         goto err;
1636     }
1637     return 1;
1638 err:
1639     ERR_print_errors(bio_err);
1640     return 0;
1641 }
1642 
rand_serial(BIGNUM * b,ASN1_INTEGER * ai)1643 int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1644 {
1645     BIGNUM *btmp;
1646     int ret = 0;
1647 
1648     btmp = b == NULL ? BN_new() : b;
1649     if (btmp == NULL)
1650         return 0;
1651 
1652     if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
1653         goto error;
1654     if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1655         goto error;
1656 
1657     ret = 1;
1658 
1659 error:
1660 
1661     if (btmp != b)
1662         BN_free(btmp);
1663 
1664     return ret;
1665 }
1666 
load_index(const char * dbfile,DB_ATTR * db_attr)1667 CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
1668 {
1669     CA_DB *retdb = NULL;
1670     TXT_DB *tmpdb = NULL;
1671     BIO *in;
1672     CONF *dbattr_conf = NULL;
1673     char buf[BSIZE];
1674 #ifndef OPENSSL_NO_POSIX_IO
1675     FILE *dbfp;
1676     struct stat dbst;
1677 #endif
1678 
1679     in = BIO_new_file(dbfile, "r");
1680     if (in == NULL)
1681         goto err;
1682 
1683 #ifndef OPENSSL_NO_POSIX_IO
1684     BIO_get_fp(in, &dbfp);
1685     if (fstat(fileno(dbfp), &dbst) == -1) {
1686         ERR_raise_data(ERR_LIB_SYS, errno,
1687             "calling fstat(%s)", dbfile);
1688         goto err;
1689     }
1690 #endif
1691 
1692     if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1693         goto err;
1694 
1695 #ifndef OPENSSL_SYS_VMS
1696     BIO_snprintf(buf, sizeof(buf), "%s.attr", dbfile);
1697 #else
1698     BIO_snprintf(buf, sizeof(buf), "%s-attr", dbfile);
1699 #endif
1700     dbattr_conf = app_load_config_quiet(buf);
1701 
1702     retdb = app_malloc(sizeof(*retdb), "new DB");
1703     retdb->db = tmpdb;
1704     tmpdb = NULL;
1705     if (db_attr)
1706         retdb->attributes = *db_attr;
1707     else
1708         retdb->attributes.unique_subject = 1;
1709 
1710     if (dbattr_conf != NULL) {
1711         char *p = app_conf_try_string(dbattr_conf, NULL, "unique_subject");
1712 
1713         if (p != NULL)
1714             retdb->attributes.unique_subject = parse_yesno(p, 1);
1715     }
1716 
1717     retdb->dbfname = OPENSSL_strdup(dbfile);
1718     if (retdb->dbfname == NULL)
1719         goto err;
1720 
1721 #ifndef OPENSSL_NO_POSIX_IO
1722     retdb->dbst = dbst;
1723 #endif
1724 
1725 err:
1726     ERR_print_errors(bio_err);
1727     NCONF_free(dbattr_conf);
1728     TXT_DB_free(tmpdb);
1729     BIO_free_all(in);
1730     return retdb;
1731 }
1732 
1733 /*
1734  * Returns > 0 on success, <= 0 on error
1735  */
index_index(CA_DB * db)1736 int index_index(CA_DB *db)
1737 {
1738     if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1739             LHASH_HASH_FN(index_serial),
1740             LHASH_COMP_FN(index_serial))) {
1741         BIO_printf(bio_err,
1742             "Error creating serial number index:(%ld,%ld,%ld)\n",
1743             db->db->error, db->db->arg1, db->db->arg2);
1744         goto err;
1745     }
1746 
1747     if (db->attributes.unique_subject
1748         && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1749             LHASH_HASH_FN(index_name),
1750             LHASH_COMP_FN(index_name))) {
1751         BIO_printf(bio_err, "Error creating name index:(%ld,%ld,%ld)\n",
1752             db->db->error, db->db->arg1, db->db->arg2);
1753         goto err;
1754     }
1755     return 1;
1756 err:
1757     ERR_print_errors(bio_err);
1758     return 0;
1759 }
1760 
save_index(const char * dbfile,const char * suffix,CA_DB * db)1761 int save_index(const char *dbfile, const char *suffix, CA_DB *db)
1762 {
1763     char buf[3][BSIZE];
1764     BIO *out;
1765     int j;
1766 
1767     j = strlen(dbfile) + strlen(suffix);
1768     if (j + 6 >= BSIZE) {
1769         BIO_printf(bio_err, "File name too long\n");
1770         goto err;
1771     }
1772 #ifndef OPENSSL_SYS_VMS
1773     BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr", dbfile);
1774     BIO_snprintf(buf[1], sizeof(buf[1]), "%s.attr.%s", dbfile, suffix);
1775     BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, suffix);
1776 #else
1777     BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr", dbfile);
1778     BIO_snprintf(buf[1], sizeof(buf[1]), "%s-attr-%s", dbfile, suffix);
1779     BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, suffix);
1780 #endif
1781     out = BIO_new_file(buf[0], "w");
1782     if (out == NULL) {
1783         perror(dbfile);
1784         BIO_printf(bio_err, "Unable to open '%s'\n", dbfile);
1785         goto err;
1786     }
1787     j = TXT_DB_write(out, db->db);
1788     BIO_free(out);
1789     if (j <= 0)
1790         goto err;
1791 
1792     out = BIO_new_file(buf[1], "w");
1793     if (out == NULL) {
1794         perror(buf[2]);
1795         BIO_printf(bio_err, "Unable to open '%s'\n", buf[2]);
1796         goto err;
1797     }
1798     BIO_printf(out, "unique_subject = %s\n",
1799         db->attributes.unique_subject ? "yes" : "no");
1800     BIO_free(out);
1801 
1802     return 1;
1803 err:
1804     ERR_print_errors(bio_err);
1805     return 0;
1806 }
1807 
rotate_index(const char * dbfile,const char * new_suffix,const char * old_suffix)1808 int rotate_index(const char *dbfile, const char *new_suffix,
1809     const char *old_suffix)
1810 {
1811     char buf[5][BSIZE];
1812     int i, j;
1813 
1814     i = strlen(dbfile) + strlen(old_suffix);
1815     j = strlen(dbfile) + strlen(new_suffix);
1816     if (i > j)
1817         j = i;
1818     if (j + 6 >= BSIZE) {
1819         BIO_printf(bio_err, "File name too long\n");
1820         goto err;
1821     }
1822 #ifndef OPENSSL_SYS_VMS
1823     BIO_snprintf(buf[4], sizeof(buf[4]), "%s.attr", dbfile);
1824     BIO_snprintf(buf[3], sizeof(buf[3]), "%s.attr.%s", dbfile, old_suffix);
1825     BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr.%s", dbfile, new_suffix);
1826     BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", dbfile, old_suffix);
1827     BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, new_suffix);
1828 #else
1829     BIO_snprintf(buf[4], sizeof(buf[4]), "%s-attr", dbfile);
1830     BIO_snprintf(buf[3], sizeof(buf[3]), "%s-attr-%s", dbfile, old_suffix);
1831     BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr-%s", dbfile, new_suffix);
1832     BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", dbfile, old_suffix);
1833     BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, new_suffix);
1834 #endif
1835     if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
1836 #ifdef ENOTDIR
1837         && errno != ENOTDIR
1838 #endif
1839     ) {
1840         BIO_printf(bio_err, "Unable to rename %s to %s\n", dbfile, buf[1]);
1841         perror("reason");
1842         goto err;
1843     }
1844     if (rename(buf[0], dbfile) < 0) {
1845         BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[0], dbfile);
1846         perror("reason");
1847         rename(buf[1], dbfile);
1848         goto err;
1849     }
1850     if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
1851 #ifdef ENOTDIR
1852         && errno != ENOTDIR
1853 #endif
1854     ) {
1855         BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[4], buf[3]);
1856         perror("reason");
1857         rename(dbfile, buf[0]);
1858         rename(buf[1], dbfile);
1859         goto err;
1860     }
1861     if (rename(buf[2], buf[4]) < 0) {
1862         BIO_printf(bio_err, "Unable to rename %s to %s\n", buf[2], buf[4]);
1863         perror("reason");
1864         rename(buf[3], buf[4]);
1865         rename(dbfile, buf[0]);
1866         rename(buf[1], dbfile);
1867         goto err;
1868     }
1869     return 1;
1870 err:
1871     ERR_print_errors(bio_err);
1872     return 0;
1873 }
1874 
free_index(CA_DB * db)1875 void free_index(CA_DB *db)
1876 {
1877     if (db) {
1878         TXT_DB_free(db->db);
1879         OPENSSL_free(db->dbfname);
1880         OPENSSL_free(db);
1881     }
1882 }
1883 
parse_yesno(const char * str,int def)1884 int parse_yesno(const char *str, int def)
1885 {
1886     if (str) {
1887         switch (*str) {
1888         case 'f': /* false */
1889         case 'F': /* FALSE */
1890         case 'n': /* no */
1891         case 'N': /* NO */
1892         case '0': /* 0 */
1893             return 0;
1894         case 't': /* true */
1895         case 'T': /* TRUE */
1896         case 'y': /* yes */
1897         case 'Y': /* YES */
1898         case '1': /* 1 */
1899             return 1;
1900         }
1901     }
1902     return def;
1903 }
1904 
1905 /*
1906  * name is expected to be in the format /type0=value0/type1=value1/type2=...
1907  * where + can be used instead of / to form multi-valued RDNs if canmulti
1908  * and characters may be escaped by \
1909  */
parse_name(const char * cp,int chtype,int canmulti,const char * desc)1910 X509_NAME *parse_name(const char *cp, int chtype, int canmulti,
1911     const char *desc)
1912 {
1913     int nextismulti = 0;
1914     char *work;
1915     X509_NAME *n;
1916 
1917     if (*cp++ != '/') {
1918         BIO_printf(bio_err,
1919             "%s: %s name is expected to be in the format "
1920             "/type0=value0/type1=value1/type2=... where characters may "
1921             "be escaped by \\. This name is not in that format: '%s'\n",
1922             opt_getprog(), desc, --cp);
1923         return NULL;
1924     }
1925 
1926     n = X509_NAME_new();
1927     if (n == NULL) {
1928         BIO_printf(bio_err, "%s: Out of memory\n", opt_getprog());
1929         return NULL;
1930     }
1931     work = OPENSSL_strdup(cp);
1932     if (work == NULL) {
1933         BIO_printf(bio_err, "%s: Error copying %s name input\n",
1934             opt_getprog(), desc);
1935         goto err;
1936     }
1937 
1938     while (*cp != '\0') {
1939         char *bp = work;
1940         char *typestr = bp;
1941         unsigned char *valstr;
1942         int nid;
1943         int ismulti = nextismulti;
1944 
1945         nextismulti = 0;
1946 
1947         /* Collect the type */
1948         while (*cp != '\0' && *cp != '=')
1949             *bp++ = *cp++;
1950         *bp++ = '\0';
1951         if (*cp == '\0') {
1952             BIO_printf(bio_err,
1953                 "%s: Missing '=' after RDN type string '%s' in %s name string\n",
1954                 opt_getprog(), typestr, desc);
1955             goto err;
1956         }
1957         ++cp;
1958 
1959         /* Collect the value. */
1960         valstr = (unsigned char *)bp;
1961         for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) {
1962             /* unescaped '+' symbol string signals further member of multiRDN */
1963             if (canmulti && *cp == '+') {
1964                 nextismulti = 1;
1965                 break;
1966             }
1967             if (*cp == '\\' && *++cp == '\0') {
1968                 BIO_printf(bio_err,
1969                     "%s: Escape character at end of %s name string\n",
1970                     opt_getprog(), desc);
1971                 goto err;
1972             }
1973         }
1974         *bp++ = '\0';
1975 
1976         /* If not at EOS (must be + or /), move forward. */
1977         if (*cp != '\0')
1978             ++cp;
1979 
1980         /* Parse */
1981         nid = OBJ_txt2nid(typestr);
1982         if (nid == NID_undef) {
1983             BIO_printf(bio_err,
1984                 "%s warning: Skipping unknown %s name attribute \"%s\"\n",
1985                 opt_getprog(), desc, typestr);
1986             if (ismulti)
1987                 BIO_printf(bio_err,
1988                     "%s hint: a '+' in a value string needs be escaped using '\\' else a new member of a multi-valued RDN is expected\n",
1989                     opt_getprog());
1990             continue;
1991         }
1992         if (*valstr == '\0') {
1993             BIO_printf(bio_err,
1994                 "%s warning: No value provided for %s name attribute \"%s\", skipped\n",
1995                 opt_getprog(), desc, typestr);
1996             continue;
1997         }
1998         if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1999                 valstr, strlen((char *)valstr),
2000                 -1, ismulti ? -1 : 0)) {
2001             ERR_print_errors(bio_err);
2002             BIO_printf(bio_err,
2003                 "%s: Error adding %s name attribute \"/%s=%s\"\n",
2004                 opt_getprog(), desc, typestr, valstr);
2005             goto err;
2006         }
2007     }
2008 
2009     OPENSSL_free(work);
2010     return n;
2011 
2012 err:
2013     X509_NAME_free(n);
2014     OPENSSL_free(work);
2015     return NULL;
2016 }
2017 
2018 /*
2019  * Read whole contents of a BIO into an allocated memory buffer.
2020  * The return value is one on success, zero on error.
2021  * If `maxlen` is non-zero, at most `maxlen` bytes are returned, or else, if
2022  * the input is longer than `maxlen`, an error is returned.
2023  * If `maxlen` is zero, the limit is effectively `SIZE_MAX`.
2024  */
bio_to_mem(unsigned char ** out,size_t * outlen,size_t maxlen,BIO * in)2025 int bio_to_mem(unsigned char **out, size_t *outlen, size_t maxlen, BIO *in)
2026 {
2027     unsigned char tbuf[4096];
2028     BIO *mem;
2029     BUF_MEM *bufm;
2030     size_t sz = 0;
2031     int len;
2032 
2033     mem = BIO_new(BIO_s_mem());
2034     if (mem == NULL)
2035         return 0;
2036     for (;;) {
2037         if ((len = BIO_read(in, tbuf, 4096)) == 0)
2038             break;
2039         if (len < 0
2040             || BIO_write(mem, tbuf, len) != len
2041             || sz > SIZE_MAX - len
2042             || ((sz += len) > maxlen && maxlen != 0)) {
2043             BIO_free(mem);
2044             return 0;
2045         }
2046     }
2047 
2048     /* So BIO_free orphans BUF_MEM */
2049     (void)BIO_set_close(mem, BIO_NOCLOSE);
2050     BIO_get_mem_ptr(mem, &bufm);
2051     BIO_free(mem);
2052     *out = (unsigned char *)bufm->data;
2053     *outlen = bufm->length;
2054     /* Tell BUF_MEM to orphan data */
2055     bufm->data = NULL;
2056     BUF_MEM_free(bufm);
2057     return 1;
2058 }
2059 
pkey_ctrl_string(EVP_PKEY_CTX * ctx,const char * value)2060 int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value)
2061 {
2062     int rv = 0;
2063     char *stmp, *vtmp = NULL;
2064 
2065     stmp = OPENSSL_strdup(value);
2066     if (stmp == NULL)
2067         return -1;
2068     vtmp = strchr(stmp, ':');
2069     if (vtmp == NULL)
2070         goto err;
2071 
2072     *vtmp = 0;
2073     vtmp++;
2074     rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
2075 
2076 err:
2077     OPENSSL_free(stmp);
2078     return rv;
2079 }
2080 
nodes_print(const char * name,STACK_OF (X509_POLICY_NODE)* nodes)2081 static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
2082 {
2083     X509_POLICY_NODE *node;
2084     int i;
2085 
2086     BIO_printf(bio_err, "%s Policies:", name);
2087     if (nodes) {
2088         BIO_puts(bio_err, "\n");
2089         for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
2090             node = sk_X509_POLICY_NODE_value(nodes, i);
2091             X509_POLICY_NODE_print(bio_err, node, 2);
2092         }
2093     } else {
2094         BIO_puts(bio_err, " <empty>\n");
2095     }
2096 }
2097 
policies_print(X509_STORE_CTX * ctx)2098 void policies_print(X509_STORE_CTX *ctx)
2099 {
2100     X509_POLICY_TREE *tree;
2101     int explicit_policy;
2102 
2103     tree = X509_STORE_CTX_get0_policy_tree(ctx);
2104     explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
2105 
2106     BIO_printf(bio_err, "Require explicit Policy: %s\n",
2107         explicit_policy ? "True" : "False");
2108 
2109     nodes_print("Authority", X509_policy_tree_get0_policies(tree));
2110     nodes_print("User", X509_policy_tree_get0_user_policies(tree));
2111 }
2112 
2113 /*-
2114  * next_protos_parse parses a comma separated list of strings into a string
2115  * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
2116  *   outlen: (output) set to the length of the resulting buffer on success.
2117  *   err: (maybe NULL) on failure, an error message line is written to this BIO.
2118  *   in: a NUL terminated string like "abc,def,ghi"
2119  *
2120  *   returns: a malloc'd buffer or NULL on failure.
2121  */
next_protos_parse(size_t * outlen,const char * in)2122 unsigned char *next_protos_parse(size_t *outlen, const char *in)
2123 {
2124     size_t len;
2125     unsigned char *out;
2126     size_t i, start = 0;
2127     size_t skipped = 0;
2128 
2129     len = strlen(in);
2130     if (len == 0 || len >= 65535)
2131         return NULL;
2132 
2133     out = app_malloc(len + 1, "NPN buffer");
2134     for (i = 0; i <= len; ++i) {
2135         if (i == len || in[i] == ',') {
2136             /*
2137              * Zero-length ALPN elements are invalid on the wire, we could be
2138              * strict and reject the entire string, but just ignoring extra
2139              * commas seems harmless and more friendly.
2140              *
2141              * Every comma we skip in this way puts the input buffer another
2142              * byte ahead of the output buffer, so all stores into the output
2143              * buffer need to be decremented by the number commas skipped.
2144              */
2145             if (i == start) {
2146                 ++start;
2147                 ++skipped;
2148                 continue;
2149             }
2150             if (i - start > 255) {
2151                 OPENSSL_free(out);
2152                 return NULL;
2153             }
2154             out[start - skipped] = (unsigned char)(i - start);
2155             start = i + 1;
2156         } else {
2157             out[i + 1 - skipped] = in[i];
2158         }
2159     }
2160 
2161     if (len <= skipped) {
2162         OPENSSL_free(out);
2163         return NULL;
2164     }
2165 
2166     *outlen = len + 1 - skipped;
2167     return out;
2168 }
2169 
check_cert_attributes(BIO * bio,X509 * x,const char * checkhost,const char * checkemail,const char * checkip,int print)2170 int check_cert_attributes(BIO *bio, X509 *x, const char *checkhost,
2171     const char *checkemail, const char *checkip,
2172     int print)
2173 {
2174     int valid_host = 0;
2175     int valid_mail = 0;
2176     int valid_ip = 0;
2177     int ret = 1;
2178 
2179     if (x == NULL)
2180         return 0;
2181 
2182     if (checkhost != NULL) {
2183         valid_host = X509_check_host(x, checkhost, 0, 0, NULL);
2184         if (print)
2185             BIO_printf(bio, "Hostname %s does%s match certificate\n",
2186                 checkhost, valid_host == 1 ? "" : " NOT");
2187         ret = ret && valid_host > 0;
2188     }
2189 
2190     if (checkemail != NULL) {
2191         valid_mail = X509_check_email(x, checkemail, 0, 0);
2192         if (print)
2193             BIO_printf(bio, "Email %s does%s match certificate\n",
2194                 checkemail, valid_mail ? "" : " NOT");
2195         ret = ret && valid_mail > 0;
2196     }
2197 
2198     if (checkip != NULL) {
2199         valid_ip = X509_check_ip_asc(x, checkip, 0);
2200         if (print)
2201             BIO_printf(bio, "IP %s does%s match certificate\n",
2202                 checkip, valid_ip ? "" : " NOT");
2203         ret = ret && valid_ip > 0;
2204     }
2205 
2206     return ret;
2207 }
2208 
do_pkey_ctx_init(EVP_PKEY_CTX * pkctx,STACK_OF (OPENSSL_STRING)* opts)2209 static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts)
2210 {
2211     int i;
2212 
2213     if (opts == NULL)
2214         return 1;
2215 
2216     for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
2217         char *opt = sk_OPENSSL_STRING_value(opts, i);
2218 
2219         if (pkey_ctrl_string(pkctx, opt) <= 0) {
2220             BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
2221             ERR_print_errors(bio_err);
2222             return 0;
2223         }
2224     }
2225 
2226     return 1;
2227 }
2228 
do_x509_init(X509 * x,STACK_OF (OPENSSL_STRING)* opts)2229 static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts)
2230 {
2231     int i;
2232 
2233     if (opts == NULL)
2234         return 1;
2235 
2236     for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
2237         char *opt = sk_OPENSSL_STRING_value(opts, i);
2238 
2239         if (x509_ctrl_string(x, opt) <= 0) {
2240             BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
2241             ERR_print_errors(bio_err);
2242             return 0;
2243         }
2244     }
2245 
2246     return 1;
2247 }
2248 
do_x509_req_init(X509_REQ * x,STACK_OF (OPENSSL_STRING)* opts)2249 static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
2250 {
2251     int i;
2252 
2253     if (opts == NULL)
2254         return 1;
2255 
2256     for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
2257         char *opt = sk_OPENSSL_STRING_value(opts, i);
2258 
2259         if (x509_req_ctrl_string(x, opt) <= 0) {
2260             BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
2261             ERR_print_errors(bio_err);
2262             return 0;
2263         }
2264     }
2265 
2266     return 1;
2267 }
2268 
do_sign_init(EVP_MD_CTX * ctx,EVP_PKEY * pkey,const char * md,STACK_OF (OPENSSL_STRING)* sigopts)2269 static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
2270     const char *md, STACK_OF(OPENSSL_STRING) *sigopts)
2271 {
2272     EVP_PKEY_CTX *pkctx = NULL;
2273     char def_md[80];
2274 
2275     if (ctx == NULL)
2276         return 0;
2277     /*
2278      * EVP_PKEY_get_default_digest_name() returns 2 if the digest is mandatory
2279      * for this algorithm.
2280      */
2281     if (EVP_PKEY_get_default_digest_name(pkey, def_md, sizeof(def_md)) == 2
2282         && strcmp(def_md, "UNDEF") == 0) {
2283         /* The signing algorithm requires there to be no digest */
2284         md = NULL;
2285     }
2286 
2287     return EVP_DigestSignInit_ex(ctx, &pkctx, md, app_get0_libctx(),
2288                app_get0_propq(), pkey, NULL)
2289         && do_pkey_ctx_init(pkctx, sigopts);
2290 }
2291 
adapt_keyid_ext(X509 * cert,X509V3_CTX * ext_ctx,const char * name,const char * value,int add_default)2292 static int adapt_keyid_ext(X509 *cert, X509V3_CTX *ext_ctx,
2293     const char *name, const char *value, int add_default)
2294 {
2295     const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert);
2296     X509_EXTENSION *new_ext = X509V3_EXT_nconf(NULL, ext_ctx, name, value);
2297     int idx, rv = 0;
2298 
2299     if (new_ext == NULL)
2300         return rv;
2301 
2302     idx = X509v3_get_ext_by_OBJ(exts, X509_EXTENSION_get_object(new_ext), -1);
2303     if (idx >= 0) {
2304         X509_EXTENSION *found_ext = X509v3_get_ext(exts, idx);
2305         ASN1_OCTET_STRING *encoded = X509_EXTENSION_get_data(found_ext);
2306         int disabled = ASN1_STRING_length(encoded) <= 2; /* indicating "none" */
2307 
2308         if (disabled) {
2309             X509_delete_ext(cert, idx);
2310             X509_EXTENSION_free(found_ext);
2311         } /* else keep existing key identifier, which might be outdated */
2312         rv = 1;
2313     } else {
2314         rv = !add_default || X509_add_ext(cert, new_ext, -1);
2315     }
2316     X509_EXTENSION_free(new_ext);
2317     return rv;
2318 }
2319 
cert_matches_key(const X509 * cert,const EVP_PKEY * pkey)2320 int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey)
2321 {
2322     int match;
2323 
2324     ERR_set_mark();
2325     match = X509_check_private_key(cert, pkey);
2326     ERR_pop_to_mark();
2327     return match;
2328 }
2329 
2330 /* Ensure RFC 5280 compliance, adapt keyIDs as needed, and sign the cert info */
do_X509_sign(X509 * cert,int force_v1,EVP_PKEY * pkey,const char * md,STACK_OF (OPENSSL_STRING)* sigopts,X509V3_CTX * ext_ctx)2331 int do_X509_sign(X509 *cert, int force_v1, EVP_PKEY *pkey, const char *md,
2332     STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx)
2333 {
2334     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
2335     int self_sign;
2336     int rv = 0;
2337 
2338     if (!force_v1) {
2339         if (!X509_set_version(cert, X509_VERSION_3))
2340             goto end;
2341 
2342         /*
2343          * Add default SKID before AKID such that AKID can make use of it
2344          * in case the certificate is self-signed
2345          */
2346         /* Prevent X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER */
2347         if (!adapt_keyid_ext(cert, ext_ctx, "subjectKeyIdentifier", "hash", 1))
2348             goto end;
2349         /* Prevent X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER */
2350         self_sign = cert_matches_key(cert, pkey);
2351         if (!adapt_keyid_ext(cert, ext_ctx, "authorityKeyIdentifier",
2352                 "keyid, issuer", !self_sign))
2353             goto end;
2354     }
2355     /* May add further measures for ensuring RFC 5280 compliance, see #19805 */
2356 
2357     if (mctx != NULL && do_sign_init(mctx, pkey, md, sigopts) > 0)
2358         rv = (X509_sign_ctx(cert, mctx) > 0);
2359 end:
2360     EVP_MD_CTX_free(mctx);
2361     return rv;
2362 }
2363 
2364 /* Sign the certificate request info */
do_X509_REQ_sign(X509_REQ * x,EVP_PKEY * pkey,const char * md,STACK_OF (OPENSSL_STRING)* sigopts)2365 int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md,
2366     STACK_OF(OPENSSL_STRING) *sigopts)
2367 {
2368     int rv = 0;
2369     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
2370 
2371     if (do_sign_init(mctx, pkey, md, sigopts) > 0)
2372         rv = (X509_REQ_sign_ctx(x, mctx) > 0);
2373     EVP_MD_CTX_free(mctx);
2374     return rv;
2375 }
2376 
2377 /* Sign the CRL info */
do_X509_CRL_sign(X509_CRL * x,EVP_PKEY * pkey,const char * md,STACK_OF (OPENSSL_STRING)* sigopts)2378 int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md,
2379     STACK_OF(OPENSSL_STRING) *sigopts)
2380 {
2381     int rv = 0;
2382     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
2383 
2384     if (do_sign_init(mctx, pkey, md, sigopts) > 0)
2385         rv = (X509_CRL_sign_ctx(x, mctx) > 0);
2386     EVP_MD_CTX_free(mctx);
2387     return rv;
2388 }
2389 
2390 /*
2391  * do_X509_verify returns 1 if the signature is valid,
2392  * 0 if the signature check fails, or -1 if error occurs.
2393  */
do_X509_verify(X509 * x,EVP_PKEY * pkey,STACK_OF (OPENSSL_STRING)* vfyopts)2394 int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts)
2395 {
2396     int rv = 0;
2397 
2398     if (do_x509_init(x, vfyopts) > 0)
2399         rv = X509_verify(x, pkey);
2400     else
2401         rv = -1;
2402     return rv;
2403 }
2404 
2405 /*
2406  * do_X509_REQ_verify returns 1 if the signature is valid,
2407  * 0 if the signature check fails, or -1 if error occurs.
2408  */
do_X509_REQ_verify(X509_REQ * x,EVP_PKEY * pkey,STACK_OF (OPENSSL_STRING)* vfyopts)2409 int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
2410     STACK_OF(OPENSSL_STRING) *vfyopts)
2411 {
2412     int rv = 0;
2413 
2414     if (do_x509_req_init(x, vfyopts) > 0)
2415         rv = X509_REQ_verify_ex(x, pkey, app_get0_libctx(), app_get0_propq());
2416     else
2417         rv = -1;
2418     return rv;
2419 }
2420 
2421 /* Get first http URL from a DIST_POINT structure */
2422 
get_dp_url(DIST_POINT * dp)2423 static const char *get_dp_url(DIST_POINT *dp)
2424 {
2425     GENERAL_NAMES *gens;
2426     GENERAL_NAME *gen;
2427     int i, gtype;
2428     ASN1_STRING *uri;
2429 
2430     if (!dp->distpoint || dp->distpoint->type != 0)
2431         return NULL;
2432     gens = dp->distpoint->name.fullname;
2433     for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
2434         gen = sk_GENERAL_NAME_value(gens, i);
2435         uri = GENERAL_NAME_get0_value(gen, &gtype);
2436         if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
2437             const char *uptr = (const char *)ASN1_STRING_get0_data(uri);
2438 
2439             if (IS_HTTP(uptr)) /* can/should not use HTTPS here */
2440                 return uptr;
2441         }
2442     }
2443     return NULL;
2444 }
2445 
2446 /*
2447  * Look through a CRLDP structure and attempt to find an http URL to
2448  * downloads a CRL from.
2449  */
2450 
load_crl_crldp(STACK_OF (DIST_POINT)* crldp)2451 static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
2452 {
2453     int i;
2454     const char *urlptr = NULL;
2455 
2456     for (i = 0; i < sk_DIST_POINT_num(crldp); i++) {
2457         DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
2458 
2459         urlptr = get_dp_url(dp);
2460         if (urlptr != NULL)
2461             return load_crl(urlptr, FORMAT_UNDEF, 0, "CRL via CDP");
2462     }
2463     return NULL;
2464 }
2465 
2466 /*
2467  * Example of downloading CRLs from CRLDP:
2468  * not usable for real world as it always downloads and doesn't cache anything.
2469  */
2470 
STACK_OF(X509_CRL)2471 static STACK_OF(X509_CRL) *crls_http_cb(const X509_STORE_CTX *ctx,
2472     const X509_NAME *nm)
2473 {
2474     X509 *x;
2475     STACK_OF(X509_CRL) *crls = NULL;
2476     X509_CRL *crl;
2477     STACK_OF(DIST_POINT) *crldp;
2478 
2479     crls = sk_X509_CRL_new_null();
2480     if (!crls)
2481         return NULL;
2482     x = X509_STORE_CTX_get_current_cert(ctx);
2483     crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
2484     crl = load_crl_crldp(crldp);
2485     sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
2486 
2487     if (crl == NULL || !sk_X509_CRL_push(crls, crl))
2488         goto error;
2489 
2490     /* Try to download delta CRL */
2491     crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL);
2492     crl = load_crl_crldp(crldp);
2493     sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
2494 
2495     if (crl != NULL && !sk_X509_CRL_push(crls, crl))
2496         goto error;
2497 
2498     return crls;
2499 
2500 error:
2501     X509_CRL_free(crl);
2502     sk_X509_CRL_pop_free(crls, X509_CRL_free);
2503     return NULL;
2504 }
2505 
store_setup_crl_download(X509_STORE * st)2506 void store_setup_crl_download(X509_STORE *st)
2507 {
2508     X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
2509 }
2510 
2511 #if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_HTTP)
tls_error_hint(void)2512 static const char *tls_error_hint(void)
2513 {
2514     unsigned long err = ERR_peek_error();
2515 
2516     if (ERR_GET_LIB(err) != ERR_LIB_SSL)
2517         err = ERR_peek_last_error();
2518     if (ERR_GET_LIB(err) != ERR_LIB_SSL)
2519         return NULL; /* likely no TLS error */
2520 
2521     switch (ERR_GET_REASON(err)) {
2522     case SSL_R_WRONG_VERSION_NUMBER:
2523         return "The server does not support (a suitable version of) TLS";
2524     case SSL_R_UNKNOWN_PROTOCOL:
2525         return "The server does not support HTTPS";
2526     case SSL_R_CERTIFICATE_VERIFY_FAILED:
2527         return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status";
2528     case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA:
2529         return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status";
2530     case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE:
2531         return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it";
2532     default:
2533         return NULL; /* no hint available for TLS error */
2534     }
2535 }
2536 
http_tls_shutdown(BIO * bio)2537 static BIO *http_tls_shutdown(BIO *bio)
2538 {
2539     if (bio != NULL) {
2540         BIO *cbio;
2541         const char *hint = tls_error_hint();
2542 
2543         if (hint != NULL)
2544             BIO_printf(bio_err, "%s\n", hint);
2545         (void)ERR_set_mark();
2546         BIO_ssl_shutdown(bio);
2547         cbio = BIO_pop(bio); /* connect+HTTP BIO */
2548         BIO_free(bio); /* SSL BIO */
2549         (void)ERR_pop_to_mark(); /* hide SSL_R_READ_BIO_NOT_SET etc. */
2550         bio = cbio;
2551     }
2552     return bio;
2553 }
2554 
2555 /* HTTP callback function that supports TLS connection also via HTTPS proxy */
app_http_tls_cb(BIO * bio,void * arg,int connect,int detail)2556 BIO *app_http_tls_cb(BIO *bio, void *arg, int connect, int detail)
2557 {
2558     APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
2559     SSL_CTX *ssl_ctx = info->ssl_ctx;
2560 
2561     if (ssl_ctx == NULL) /* not using TLS */
2562         return bio;
2563     if (connect) {
2564         SSL *ssl;
2565         BIO *sbio = NULL;
2566         X509_STORE *ts = SSL_CTX_get_cert_store(ssl_ctx);
2567         X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts);
2568         const char *host = vpm == NULL ? NULL : X509_VERIFY_PARAM_get0_host(vpm, 0 /* first hostname */);
2569 
2570         /* adapt after fixing callback design flaw, see #17088 */
2571         if ((info->use_proxy
2572                 && !OSSL_HTTP_proxy_connect(bio, info->server, info->port,
2573                     NULL, NULL, /* no proxy credentials */
2574                     info->timeout, bio_err, opt_getprog()))
2575             || (sbio = BIO_new(BIO_f_ssl())) == NULL) {
2576             return NULL;
2577         }
2578         if ((ssl = SSL_new(ssl_ctx)) == NULL) {
2579             BIO_free(sbio);
2580             return NULL;
2581         }
2582 
2583         if (vpm != NULL)
2584             SSL_set_tlsext_host_name(ssl, host /* may be NULL */);
2585 
2586         SSL_set_connect_state(ssl);
2587         BIO_set_ssl(sbio, ssl, BIO_CLOSE);
2588 
2589         bio = BIO_push(sbio, bio);
2590     } else { /* disconnect from TLS */
2591         bio = http_tls_shutdown(bio);
2592     }
2593     return bio;
2594 }
2595 
APP_HTTP_TLS_INFO_free(APP_HTTP_TLS_INFO * info)2596 void APP_HTTP_TLS_INFO_free(APP_HTTP_TLS_INFO *info)
2597 {
2598     if (info != NULL) {
2599         SSL_CTX_free(info->ssl_ctx);
2600         OPENSSL_free(info);
2601     }
2602 }
2603 
app_http_get_asn1(const char * url,const char * proxy,const char * no_proxy,SSL_CTX * ssl_ctx,const STACK_OF (CONF_VALUE)* headers,long timeout,const char * expected_content_type,const ASN1_ITEM * it)2604 ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
2605     const char *no_proxy, SSL_CTX *ssl_ctx,
2606     const STACK_OF(CONF_VALUE) *headers,
2607     long timeout, const char *expected_content_type,
2608     const ASN1_ITEM *it)
2609 {
2610     APP_HTTP_TLS_INFO info;
2611     char *server;
2612     char *port;
2613     int use_ssl;
2614     BIO *mem;
2615     ASN1_VALUE *resp = NULL;
2616 
2617     if (url == NULL || it == NULL) {
2618         ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
2619         return NULL;
2620     }
2621 
2622     if (!OSSL_HTTP_parse_url(url, &use_ssl, NULL /* userinfo */, &server, &port,
2623             NULL /* port_num, */, NULL, NULL, NULL))
2624         return NULL;
2625     if (use_ssl && ssl_ctx == NULL) {
2626         ERR_raise_data(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER,
2627             "missing SSL_CTX");
2628         goto end;
2629     }
2630     if (!use_ssl && ssl_ctx != NULL) {
2631         ERR_raise_data(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT,
2632             "SSL_CTX given but use_ssl == 0");
2633         goto end;
2634     }
2635 
2636     info.server = server;
2637     info.port = port;
2638     info.use_proxy = /* workaround for callback design flaw, see #17088 */
2639         OSSL_HTTP_adapt_proxy(proxy, no_proxy, server, use_ssl) != NULL;
2640     info.timeout = timeout;
2641     info.ssl_ctx = ssl_ctx;
2642     mem = OSSL_HTTP_get(url, proxy, no_proxy, NULL /* bio */, NULL /* rbio */,
2643         app_http_tls_cb, &info, 0 /* buf_size */, headers,
2644         expected_content_type, 1 /* expect_asn1 */,
2645         OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout);
2646     resp = ASN1_item_d2i_bio(it, mem, NULL);
2647     BIO_free(mem);
2648 
2649 end:
2650     OPENSSL_free(server);
2651     OPENSSL_free(port);
2652     return resp;
2653 }
2654 
app_http_post_asn1(const char * host,const char * port,const char * path,const char * proxy,const char * no_proxy,SSL_CTX * ssl_ctx,const STACK_OF (CONF_VALUE)* headers,const char * content_type,ASN1_VALUE * req,const ASN1_ITEM * req_it,const char * expected_content_type,long timeout,const ASN1_ITEM * rsp_it)2655 ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
2656     const char *path, const char *proxy,
2657     const char *no_proxy, SSL_CTX *ssl_ctx,
2658     const STACK_OF(CONF_VALUE) *headers,
2659     const char *content_type,
2660     ASN1_VALUE *req, const ASN1_ITEM *req_it,
2661     const char *expected_content_type,
2662     long timeout, const ASN1_ITEM *rsp_it)
2663 {
2664     int use_ssl = ssl_ctx != NULL;
2665     APP_HTTP_TLS_INFO info;
2666     BIO *rsp, *req_mem = ASN1_item_i2d_mem_bio(req_it, req);
2667     ASN1_VALUE *res;
2668 
2669     if (req_mem == NULL)
2670         return NULL;
2671 
2672     info.server = host;
2673     info.port = port;
2674     info.use_proxy = /* workaround for callback design flaw, see #17088 */
2675         OSSL_HTTP_adapt_proxy(proxy, no_proxy, host, use_ssl) != NULL;
2676     info.timeout = timeout;
2677     info.ssl_ctx = ssl_ctx;
2678     rsp = OSSL_HTTP_transfer(NULL, host, port, path, use_ssl,
2679         proxy, no_proxy, NULL /* bio */, NULL /* rbio */,
2680         app_http_tls_cb, &info,
2681         0 /* buf_size */, headers, content_type, req_mem,
2682         expected_content_type, 1 /* expect_asn1 */,
2683         OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout,
2684         0 /* keep_alive */);
2685     BIO_free(req_mem);
2686     res = ASN1_item_d2i_bio(rsp_it, rsp, NULL);
2687     BIO_free(rsp);
2688     return res;
2689 }
2690 
2691 #endif
2692 
2693 /*
2694  * Platform-specific sections
2695  */
2696 #if defined(_WIN32)
2697 #ifdef fileno
2698 #undef fileno
2699 #define fileno(a) (int)_fileno(a)
2700 #endif
2701 
2702 #include <windows.h>
2703 #include <tchar.h>
2704 
WIN32_rename(const char * from,const char * to)2705 static int WIN32_rename(const char *from, const char *to)
2706 {
2707     TCHAR *tfrom = NULL, *tto;
2708     DWORD err;
2709     int ret = 0;
2710 
2711     if (sizeof(TCHAR) == 1) {
2712         tfrom = (TCHAR *)from;
2713         tto = (TCHAR *)to;
2714     } else { /* UNICODE path */
2715         size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
2716 
2717         tfrom = malloc(sizeof(*tfrom) * (flen + tlen));
2718         if (tfrom == NULL)
2719             goto err;
2720         tto = tfrom + flen;
2721 #if !defined(_WIN32_WCE) || _WIN32_WCE >= 101
2722         if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
2723 #endif
2724             for (i = 0; i < flen; i++)
2725                 tfrom[i] = (TCHAR)from[i];
2726 #if !defined(_WIN32_WCE) || _WIN32_WCE >= 101
2727         if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
2728 #endif
2729             for (i = 0; i < tlen; i++)
2730                 tto[i] = (TCHAR)to[i];
2731     }
2732 
2733     if (MoveFile(tfrom, tto))
2734         goto ok;
2735     err = GetLastError();
2736     if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
2737         if (DeleteFile(tto) && MoveFile(tfrom, tto))
2738             goto ok;
2739         err = GetLastError();
2740     }
2741     if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
2742         errno = ENOENT;
2743     else if (err == ERROR_ACCESS_DENIED)
2744         errno = EACCES;
2745     else
2746         errno = EINVAL; /* we could map more codes... */
2747 err:
2748     ret = -1;
2749 ok:
2750     if (tfrom != NULL && tfrom != (TCHAR *)from)
2751         free(tfrom);
2752     return ret;
2753 }
2754 #endif
2755 
2756 /* app_tminterval section */
2757 #if defined(_WIN32)
app_tminterval(int stop,int usertime)2758 double app_tminterval(int stop, int usertime)
2759 {
2760     FILETIME now;
2761     double ret = 0;
2762     static ULARGE_INTEGER tmstart;
2763     static int warning = 1;
2764     int use_GetSystemTime = 1;
2765 #ifdef _WIN32_WINNT
2766     static HANDLE proc = NULL;
2767 
2768     if (proc == NULL) {
2769         if (check_winnt())
2770             proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
2771                 GetCurrentProcessId());
2772         if (proc == NULL)
2773             proc = (HANDLE)-1;
2774     }
2775 
2776     if (usertime && proc != (HANDLE)-1) {
2777         FILETIME junk;
2778 
2779         GetProcessTimes(proc, &junk, &junk, &junk, &now);
2780         use_GetSystemTime = 0;
2781     }
2782 #endif
2783     if (use_GetSystemTime) {
2784         SYSTEMTIME systime;
2785 
2786         if (usertime && warning) {
2787             BIO_printf(bio_err, "To get meaningful results, run "
2788                                 "this program on idle system.\n");
2789             warning = 0;
2790         }
2791         GetSystemTime(&systime);
2792         SystemTimeToFileTime(&systime, &now);
2793     }
2794 
2795     if (stop == TM_START) {
2796         tmstart.u.LowPart = now.dwLowDateTime;
2797         tmstart.u.HighPart = now.dwHighDateTime;
2798     } else {
2799         ULARGE_INTEGER tmstop;
2800 
2801         tmstop.u.LowPart = now.dwLowDateTime;
2802         tmstop.u.HighPart = now.dwHighDateTime;
2803 
2804         ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
2805     }
2806 
2807     return ret;
2808 }
2809 #elif defined(OPENSSL_SYS_VXWORKS)
2810 #include <time.h>
2811 
app_tminterval(int stop,int usertime)2812 double app_tminterval(int stop, int usertime)
2813 {
2814     double ret = 0;
2815 #ifdef CLOCK_REALTIME
2816     static struct timespec tmstart;
2817     struct timespec now;
2818 #else
2819     static unsigned long tmstart;
2820     unsigned long now;
2821 #endif
2822     static int warning = 1;
2823 
2824     if (usertime && warning) {
2825         BIO_printf(bio_err, "To get meaningful results, run "
2826                             "this program on idle system.\n");
2827         warning = 0;
2828     }
2829 #ifdef CLOCK_REALTIME
2830     clock_gettime(CLOCK_REALTIME, &now);
2831     if (stop == TM_START)
2832         tmstart = now;
2833     else
2834         ret = ((now.tv_sec + now.tv_nsec * 1e-9)
2835             - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
2836 #else
2837     now = tickGet();
2838     if (stop == TM_START)
2839         tmstart = now;
2840     else
2841         ret = (now - tmstart) / (double)sysClkRateGet();
2842 #endif
2843     return ret;
2844 }
2845 
2846 #elif defined(_SC_CLK_TCK) /* by means of unistd.h */
2847 #include <sys/times.h>
2848 
app_tminterval(int stop,int usertime)2849 double app_tminterval(int stop, int usertime)
2850 {
2851     double ret = 0;
2852     struct tms rus;
2853     clock_t now = times(&rus);
2854     static clock_t tmstart;
2855 
2856     if (usertime)
2857         now = rus.tms_utime;
2858 
2859     if (stop == TM_START) {
2860         tmstart = now;
2861     } else {
2862         long int tck = sysconf(_SC_CLK_TCK);
2863 
2864         ret = (now - tmstart) / (double)tck;
2865     }
2866 
2867     return ret;
2868 }
2869 
2870 #else
2871 #include <sys/time.h>
2872 #include <sys/resource.h>
2873 
app_tminterval(int stop,int usertime)2874 double app_tminterval(int stop, int usertime)
2875 {
2876     double ret = 0;
2877     struct rusage rus;
2878     struct timeval now;
2879     static struct timeval tmstart;
2880 
2881     if (usertime)
2882         getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
2883     else
2884         gettimeofday(&now, NULL);
2885 
2886     if (stop == TM_START)
2887         tmstart = now;
2888     else
2889         ret = ((now.tv_sec + now.tv_usec * 1e-6)
2890             - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
2891 
2892     return ret;
2893 }
2894 #endif
2895 
app_access(const char * name,int flag)2896 int app_access(const char *name, int flag)
2897 {
2898 #ifdef _WIN32
2899     return _access(name, flag);
2900 #else
2901     return access(name, flag);
2902 #endif
2903 }
2904 
app_isdir(const char * name)2905 int app_isdir(const char *name)
2906 {
2907     return opt_isdir(name);
2908 }
2909 
2910 /* raw_read|write section */
2911 #if defined(__VMS)
2912 #include "vms_term_sock.h"
2913 static int stdin_sock = -1;
2914 
close_stdin_sock(void)2915 static void close_stdin_sock(void)
2916 {
2917     TerminalSocket(TERM_SOCK_DELETE, &stdin_sock);
2918 }
2919 
fileno_stdin(void)2920 int fileno_stdin(void)
2921 {
2922     if (stdin_sock == -1) {
2923         TerminalSocket(TERM_SOCK_CREATE, &stdin_sock);
2924         atexit(close_stdin_sock);
2925     }
2926 
2927     return stdin_sock;
2928 }
2929 #else
fileno_stdin(void)2930 int fileno_stdin(void)
2931 {
2932     return fileno(stdin);
2933 }
2934 #endif
2935 
fileno_stdout(void)2936 int fileno_stdout(void)
2937 {
2938     return fileno(stdout);
2939 }
2940 
2941 #if defined(_WIN32) && defined(STD_INPUT_HANDLE)
raw_read_stdin(void * buf,int siz)2942 int raw_read_stdin(void *buf, int siz)
2943 {
2944     DWORD n;
2945 
2946     if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
2947         return n;
2948     else
2949         return -1;
2950 }
2951 #elif defined(__VMS)
2952 #include <sys/socket.h>
2953 
raw_read_stdin(void * buf,int siz)2954 int raw_read_stdin(void *buf, int siz)
2955 {
2956     return recv(fileno_stdin(), buf, siz, 0);
2957 }
2958 #else
raw_read_stdin(void * buf,int siz)2959 int raw_read_stdin(void *buf, int siz)
2960 {
2961     return read(fileno_stdin(), buf, siz);
2962 }
2963 #endif
2964 
2965 #if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
raw_write_stdout(const void * buf,int siz)2966 int raw_write_stdout(const void *buf, int siz)
2967 {
2968     DWORD n;
2969 
2970     if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
2971         return n;
2972     else
2973         return -1;
2974 }
2975 #elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) \
2976     && defined(_SPT_MODEL_)
raw_write_stdout(const void * buf,int siz)2977 int raw_write_stdout(const void *buf, int siz)
2978 {
2979     return write(fileno(stdout), (void *)buf, siz);
2980 }
2981 #else
raw_write_stdout(const void * buf,int siz)2982 int raw_write_stdout(const void *buf, int siz)
2983 {
2984     return write(fileno_stdout(), buf, siz);
2985 }
2986 #endif
2987 
2988 /*
2989  * Centralized handling of input and output files with format specification
2990  * The format is meant to show what the input and output is supposed to be,
2991  * and is therefore a show of intent more than anything else.  However, it
2992  * does impact behavior on some platforms, such as differentiating between
2993  * text and binary input/output on non-Unix platforms
2994  */
dup_bio_in(int format)2995 BIO *dup_bio_in(int format)
2996 {
2997     return BIO_new_fp(stdin,
2998         BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
2999 }
3000 
dup_bio_out(int format)3001 BIO *dup_bio_out(int format)
3002 {
3003     BIO *b = BIO_new_fp(stdout,
3004         BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
3005     void *prefix = NULL;
3006 
3007     if (b == NULL)
3008         return NULL;
3009 
3010 #ifdef OPENSSL_SYS_VMS
3011     if (FMT_istext(format))
3012         b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
3013 #endif
3014 
3015     if (FMT_istext(format)
3016         && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) {
3017         b = BIO_push(BIO_new(BIO_f_prefix()), b);
3018         BIO_set_prefix(b, prefix);
3019     }
3020 
3021     return b;
3022 }
3023 
dup_bio_err(int format)3024 BIO *dup_bio_err(int format)
3025 {
3026     BIO *b = BIO_new_fp(stderr,
3027         BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0));
3028 
3029 #ifdef OPENSSL_SYS_VMS
3030     if (b != NULL && FMT_istext(format))
3031         b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
3032 #endif
3033     return b;
3034 }
3035 
unbuffer(FILE * fp)3036 void unbuffer(FILE *fp)
3037 {
3038 /*
3039  * On VMS, setbuf() will only take 32-bit pointers, and a compilation
3040  * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here.
3041  * However, we trust that the C RTL will never give us a FILE pointer
3042  * above the first 4 GB of memory, so we simply turn off the warning
3043  * temporarily.
3044  */
3045 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
3046 #pragma environment save
3047 #pragma message disable maylosedata2
3048 #endif
3049     setbuf(fp, NULL);
3050 #if defined(OPENSSL_SYS_VMS) && defined(__DECC)
3051 #pragma environment restore
3052 #endif
3053 }
3054 
modestr(char mode,int format)3055 static const char *modestr(char mode, int format)
3056 {
3057     OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w');
3058 
3059     switch (mode) {
3060     case 'a':
3061         return FMT_istext(format) ? "a" : "ab";
3062     case 'r':
3063         return FMT_istext(format) ? "r" : "rb";
3064     case 'w':
3065         return FMT_istext(format) ? "w" : "wb";
3066     }
3067     /* The assert above should make sure we never reach this point */
3068     return NULL;
3069 }
3070 
modeverb(char mode)3071 static const char *modeverb(char mode)
3072 {
3073     switch (mode) {
3074     case 'a':
3075         return "appending";
3076     case 'r':
3077         return "reading";
3078     case 'w':
3079         return "writing";
3080     }
3081     return "(doing something)";
3082 }
3083 
3084 /*
3085  * Open a file for writing, owner-read-only.
3086  */
bio_open_owner(const char * filename,int format,int private)3087 BIO *bio_open_owner(const char *filename, int format, int private)
3088 {
3089     FILE *fp = NULL;
3090     BIO *b = NULL;
3091     int textmode, bflags;
3092 #ifndef OPENSSL_NO_POSIX_IO
3093     int fd = -1, mode;
3094 #endif
3095 
3096     if (!private || filename == NULL || strcmp(filename, "-") == 0)
3097         return bio_open_default(filename, 'w', format);
3098 
3099     textmode = FMT_istext(format);
3100 #ifndef OPENSSL_NO_POSIX_IO
3101     mode = O_WRONLY;
3102 #ifdef O_CREAT
3103     mode |= O_CREAT;
3104 #endif
3105 #ifdef O_TRUNC
3106     mode |= O_TRUNC;
3107 #endif
3108     if (!textmode) {
3109 #ifdef O_BINARY
3110         mode |= O_BINARY;
3111 #elif defined(_O_BINARY)
3112         mode |= _O_BINARY;
3113 #endif
3114     }
3115 
3116 #ifdef OPENSSL_SYS_VMS
3117     /*
3118      * VMS doesn't have O_BINARY, it just doesn't make sense.  But,
3119      * it still needs to know that we're going binary, or fdopen()
3120      * will fail with "invalid argument"...  so we tell VMS what the
3121      * context is.
3122      */
3123     if (!textmode)
3124         fd = open(filename, mode, 0600, "ctx=bin");
3125     else
3126 #endif
3127         fd = open(filename, mode, 0600);
3128     if (fd < 0)
3129         goto err;
3130     fp = fdopen(fd, modestr('w', format));
3131 #else /* OPENSSL_NO_POSIX_IO */
3132     /* Have stdio but not Posix IO, do the best we can */
3133     fp = fopen(filename, modestr('w', format));
3134 #endif /* OPENSSL_NO_POSIX_IO */
3135     if (fp == NULL)
3136         goto err;
3137     bflags = BIO_CLOSE;
3138     if (textmode)
3139         bflags |= BIO_FP_TEXT;
3140     b = BIO_new_fp(fp, bflags);
3141     if (b != NULL)
3142         return b;
3143 
3144 err:
3145     BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n",
3146         opt_getprog(), filename, strerror(errno));
3147     ERR_print_errors(bio_err);
3148     /* If we have fp, then fdopen took over fd, so don't close both. */
3149     if (fp != NULL)
3150         fclose(fp);
3151 #ifndef OPENSSL_NO_POSIX_IO
3152     else if (fd >= 0)
3153         close(fd);
3154 #endif
3155     return NULL;
3156 }
3157 
bio_open_default_(const char * filename,char mode,int format,int quiet)3158 static BIO *bio_open_default_(const char *filename, char mode, int format,
3159     int quiet)
3160 {
3161     BIO *ret;
3162 
3163     if (filename == NULL || strcmp(filename, "-") == 0) {
3164         ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format);
3165         if (quiet) {
3166             ERR_clear_error();
3167             return ret;
3168         }
3169         if (ret != NULL)
3170             return ret;
3171         BIO_printf(bio_err,
3172             "Can't open %s, %s\n",
3173             mode == 'r' ? "stdin" : "stdout", strerror(errno));
3174     } else {
3175         ret = BIO_new_file(filename, modestr(mode, format));
3176         if (quiet) {
3177             ERR_clear_error();
3178             return ret;
3179         }
3180         if (ret != NULL)
3181             return ret;
3182         BIO_printf(bio_err,
3183             "Can't open \"%s\" for %s, %s\n",
3184             filename, modeverb(mode), strerror(errno));
3185     }
3186     ERR_print_errors(bio_err);
3187     return NULL;
3188 }
3189 
bio_open_default(const char * filename,char mode,int format)3190 BIO *bio_open_default(const char *filename, char mode, int format)
3191 {
3192     return bio_open_default_(filename, mode, format, 0);
3193 }
3194 
bio_open_default_quiet(const char * filename,char mode,int format)3195 BIO *bio_open_default_quiet(const char *filename, char mode, int format)
3196 {
3197     return bio_open_default_(filename, mode, format, 1);
3198 }
3199 
mem_bio_to_file(BIO * in,const char * filename,int format,int private)3200 int mem_bio_to_file(BIO *in, const char *filename, int format, int private)
3201 {
3202     int rv = 0, ret = 0;
3203     BIO *out = NULL;
3204     BUF_MEM *mem_buffer = NULL;
3205 
3206     rv = BIO_get_mem_ptr(in, &mem_buffer);
3207     if (rv <= 0) {
3208         BIO_puts(bio_err, "Error reading mem buffer\n");
3209         goto end;
3210     }
3211     out = bio_open_owner(filename, format, private);
3212     if (out == NULL)
3213         goto end;
3214     rv = BIO_write(out, mem_buffer->data, mem_buffer->length);
3215     if (rv < 0 || (size_t)rv != mem_buffer->length)
3216         BIO_printf(bio_err, "Error writing to output file: '%s'\n", filename);
3217     else
3218         ret = 1;
3219 end:
3220     if (!ret)
3221         ERR_print_errors(bio_err);
3222     BIO_free_all(out);
3223     return ret;
3224 }
3225 
wait_for_async(SSL * s)3226 void wait_for_async(SSL *s)
3227 {
3228     /* On Windows select only works for sockets, so we simply don't wait  */
3229 #ifndef OPENSSL_SYS_WINDOWS
3230     int width = 0;
3231     fd_set asyncfds;
3232     OSSL_ASYNC_FD *fds;
3233     size_t numfds;
3234     size_t i;
3235 
3236     if (!SSL_get_all_async_fds(s, NULL, &numfds))
3237         return;
3238     if (numfds == 0)
3239         return;
3240     fds = app_malloc(sizeof(OSSL_ASYNC_FD) * numfds, "allocate async fds");
3241     if (!SSL_get_all_async_fds(s, fds, &numfds)) {
3242         OPENSSL_free(fds);
3243         return;
3244     }
3245 
3246     FD_ZERO(&asyncfds);
3247     for (i = 0; i < numfds; i++) {
3248         if (width <= (int)fds[i])
3249             width = (int)fds[i] + 1;
3250         openssl_fdset((int)fds[i], &asyncfds);
3251     }
3252     select(width, (void *)&asyncfds, NULL, NULL, NULL);
3253     OPENSSL_free(fds);
3254 #endif
3255 }
3256 
3257 /* if OPENSSL_SYS_WINDOWS is defined then so is OPENSSL_SYS_MSDOS */
3258 #if defined(OPENSSL_SYS_MSDOS)
has_stdin_waiting(void)3259 int has_stdin_waiting(void)
3260 {
3261 #if defined(OPENSSL_SYS_WINDOWS)
3262     HANDLE inhand = GetStdHandle(STD_INPUT_HANDLE);
3263     DWORD events = 0;
3264     INPUT_RECORD inputrec;
3265     DWORD insize = 1;
3266     BOOL peeked;
3267 
3268     if (inhand == INVALID_HANDLE_VALUE) {
3269         return 0;
3270     }
3271 
3272     peeked = PeekConsoleInput(inhand, &inputrec, insize, &events);
3273     if (!peeked) {
3274         /* Probably redirected input? _kbhit() does not work in this case */
3275         if (!feof(stdin)) {
3276             return 1;
3277         }
3278         return 0;
3279     }
3280 #endif
3281     return _kbhit();
3282 }
3283 #endif
3284 
3285 /* Corrupt a signature by modifying final byte */
corrupt_signature(const ASN1_STRING * signature)3286 void corrupt_signature(const ASN1_STRING *signature)
3287 {
3288     unsigned char *s = signature->data;
3289 
3290     s[signature->length - 1] ^= 0x1;
3291 }
3292 
check_cert_time_string(const char * time,const char * desc)3293 int check_cert_time_string(const char *time, const char *desc)
3294 {
3295     if (time == NULL || strcmp(time, "today") == 0
3296         || ASN1_TIME_set_string_X509(NULL, time))
3297         return 1;
3298     BIO_printf(bio_err,
3299         "%s is invalid, it should be \"today\" or have format [CC]YYMMDDHHMMSSZ\n",
3300         desc);
3301     return 0;
3302 }
3303 
set_cert_times(X509 * x,const char * startdate,const char * enddate,int days,int strict_compare_times)3304 int set_cert_times(X509 *x, const char *startdate, const char *enddate,
3305     int days, int strict_compare_times)
3306 {
3307     if (!check_cert_time_string(startdate, "start date"))
3308         return 0;
3309     if (!check_cert_time_string(enddate, "end date"))
3310         return 0;
3311     if (startdate == NULL || strcmp(startdate, "today") == 0) {
3312         if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL) {
3313             BIO_printf(bio_err, "Error setting notBefore certificate field\n");
3314             return 0;
3315         }
3316     } else {
3317         if (!ASN1_TIME_set_string_X509(X509_getm_notBefore(x), startdate)) {
3318             BIO_printf(bio_err, "Error setting notBefore certificate field\n");
3319             return 0;
3320         }
3321     }
3322     if (enddate != NULL && strcmp(enddate, "today") == 0) {
3323         enddate = NULL;
3324         days = 0;
3325     }
3326     if (enddate == NULL) {
3327         if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL) == NULL) {
3328             BIO_printf(bio_err, "Error setting notAfter certificate field\n");
3329             return 0;
3330         }
3331     } else if (!ASN1_TIME_set_string_X509(X509_getm_notAfter(x), enddate)) {
3332         BIO_printf(bio_err, "Error setting notAfter certificate field\n");
3333         return 0;
3334     }
3335     if (ASN1_TIME_compare(X509_get0_notAfter(x), X509_get0_notBefore(x)) < 0) {
3336         BIO_printf(bio_err, "%s: end date before start date\n",
3337             strict_compare_times ? "Error" : "Warning");
3338         if (strict_compare_times)
3339             return 0;
3340     }
3341     return 1;
3342 }
3343 
set_crl_lastupdate(X509_CRL * crl,const char * lastupdate)3344 int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate)
3345 {
3346     int ret = 0;
3347     ASN1_TIME *tm = ASN1_TIME_new();
3348 
3349     if (tm == NULL)
3350         goto end;
3351 
3352     if (lastupdate == NULL) {
3353         if (X509_gmtime_adj(tm, 0) == NULL)
3354             goto end;
3355     } else {
3356         if (!ASN1_TIME_set_string_X509(tm, lastupdate))
3357             goto end;
3358     }
3359 
3360     if (!X509_CRL_set1_lastUpdate(crl, tm))
3361         goto end;
3362 
3363     ret = 1;
3364 end:
3365     ASN1_TIME_free(tm);
3366     return ret;
3367 }
3368 
set_crl_nextupdate(X509_CRL * crl,const char * nextupdate,long days,long hours,long secs)3369 int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate,
3370     long days, long hours, long secs)
3371 {
3372     int ret = 0;
3373     ASN1_TIME *tm = ASN1_TIME_new();
3374 
3375     if (tm == NULL)
3376         goto end;
3377 
3378     if (nextupdate == NULL) {
3379         if (X509_time_adj_ex(tm, days, hours * 60 * 60 + secs, NULL) == NULL)
3380             goto end;
3381     } else {
3382         if (!ASN1_TIME_set_string_X509(tm, nextupdate))
3383             goto end;
3384     }
3385 
3386     if (!X509_CRL_set1_nextUpdate(crl, tm))
3387         goto end;
3388 
3389     ret = 1;
3390 end:
3391     ASN1_TIME_free(tm);
3392     return ret;
3393 }
3394 
make_uppercase(char * string)3395 void make_uppercase(char *string)
3396 {
3397     int i;
3398 
3399     for (i = 0; string[i] != '\0'; i++)
3400         string[i] = toupper((unsigned char)string[i]);
3401 }
3402 
app_params_new_from_opts(STACK_OF (OPENSSL_STRING)* opts,const OSSL_PARAM * paramdefs)3403 OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
3404     const OSSL_PARAM *paramdefs)
3405 {
3406     OSSL_PARAM *params = NULL;
3407     size_t sz = (size_t)sk_OPENSSL_STRING_num(opts);
3408     size_t params_n;
3409     char *opt = "", *stmp, *vtmp = NULL;
3410     int found = 1;
3411 
3412     if (opts == NULL)
3413         return NULL;
3414 
3415     params = OPENSSL_zalloc(sizeof(OSSL_PARAM) * (sz + 1));
3416     if (params == NULL)
3417         return NULL;
3418 
3419     for (params_n = 0; params_n < sz; params_n++) {
3420         opt = sk_OPENSSL_STRING_value(opts, (int)params_n);
3421         if ((stmp = OPENSSL_strdup(opt)) == NULL
3422             || (vtmp = strchr(stmp, ':')) == NULL)
3423             goto err;
3424         /* Replace ':' with 0 to terminate the string pointed to by stmp */
3425         *vtmp = 0;
3426         /* Skip over the separator so that vmtp points to the value */
3427         vtmp++;
3428         if (!OSSL_PARAM_allocate_from_text(&params[params_n], paramdefs,
3429                 stmp, vtmp, strlen(vtmp), &found))
3430             goto err;
3431         OPENSSL_free(stmp);
3432     }
3433     params[params_n] = OSSL_PARAM_construct_end();
3434     return params;
3435 err:
3436     OPENSSL_free(stmp);
3437     BIO_printf(bio_err, "Parameter %s '%s'\n", found ? "error" : "unknown",
3438         opt);
3439     ERR_print_errors(bio_err);
3440     app_params_free(params);
3441     return NULL;
3442 }
3443 
app_params_free(OSSL_PARAM * params)3444 void app_params_free(OSSL_PARAM *params)
3445 {
3446     int i;
3447 
3448     if (params != NULL) {
3449         for (i = 0; params[i].key != NULL; ++i)
3450             OPENSSL_free(params[i].data);
3451         OPENSSL_free(params);
3452     }
3453 }
3454 
app_keygen(EVP_PKEY_CTX * ctx,const char * alg,int bits,int verbose)3455 EVP_PKEY *app_keygen(EVP_PKEY_CTX *ctx, const char *alg, int bits, int verbose)
3456 {
3457     EVP_PKEY *res = NULL;
3458 
3459     if (verbose && alg != NULL) {
3460         BIO_printf(bio_err, "Generating %s key", alg);
3461         if (bits > 0)
3462             BIO_printf(bio_err, " with %d bits\n", bits);
3463         else
3464             BIO_printf(bio_err, "\n");
3465     }
3466     if (!RAND_status())
3467         BIO_printf(bio_err, "Warning: generating random key material may take a long time\n"
3468                             "if the system has a poor entropy source\n");
3469     if (EVP_PKEY_keygen(ctx, &res) <= 0)
3470         BIO_printf(bio_err, "%s: Error generating %s key\n", opt_getprog(),
3471             alg != NULL ? alg : "asymmetric");
3472     return res;
3473 }
3474 
app_paramgen(EVP_PKEY_CTX * ctx,const char * alg)3475 EVP_PKEY *app_paramgen(EVP_PKEY_CTX *ctx, const char *alg)
3476 {
3477     EVP_PKEY *res = NULL;
3478 
3479     if (!RAND_status())
3480         BIO_printf(bio_err, "Warning: generating random key parameters may take a long time\n"
3481                             "if the system has a poor entropy source\n");
3482     if (EVP_PKEY_paramgen(ctx, &res) <= 0)
3483         BIO_printf(bio_err, "%s: Generating %s key parameters failed\n",
3484             opt_getprog(), alg != NULL ? alg : "asymmetric");
3485     return res;
3486 }
3487 
3488 /*
3489  * Return non-zero if the legacy path is still an option.
3490  * This decision is based on the global command line operations and the
3491  * behaviour thus far.
3492  */
opt_legacy_okay(void)3493 int opt_legacy_okay(void)
3494 {
3495     int provider_options = opt_provider_option_given();
3496     int libctx = app_get0_libctx() != NULL || app_get0_propq() != NULL;
3497 
3498     /*
3499      * Having a provider option specified or a custom library context or
3500      * property query, is a sure sign we're not using legacy.
3501      */
3502     if (provider_options || libctx)
3503         return 0;
3504     return 1;
3505 }
3506