blob: 216bc797df5287c9cae26548e68fc7785148c3a8 [file] [log] [blame]
Rich Salz846e33c2016-05-17 14:18:30 -04001/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00003 *
Rich Salz846e33c2016-05-17 14:18:30 -04004 * Licensed under the OpenSSL license (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
Bodo Möllera661b652001-10-20 17:56:36 +00008 */
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00009
Dr. Stephen Hensonfc7dae52012-02-11 23:41:19 +000010#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
Matt Caswell0f113f32015-01-22 03:40:55 +000011/*
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.
Matt Caswell68d39f32015-01-21 19:18:47 +000014 */
Matt Caswell0f113f32015-01-22 03:40:55 +000015# define _POSIX_C_SOURCE 2
Dr. Stephen Henson83d8fa72009-05-13 11:32:46 +000016#endif
Matt Caswell75dd6c12016-05-20 11:53:26 +010017
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000018#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
Richard Levittea412b892015-09-06 10:51:04 +020021#ifndef NO_SYS_TYPES_H
22# include <sys/types.h>
23#endif
24#ifndef OPENSSL_NO_POSIX_IO
25# include <sys/stat.h>
26# include <fcntl.h>
27#endif
Richard Levitted652a092002-10-25 09:51:45 +000028#include <ctype.h>
Andy Polyakova1ad2532005-11-04 16:12:05 +000029#include <errno.h>
Richard Levitte90ae4672000-06-22 17:42:50 +000030#include <openssl/err.h>
31#include <openssl/x509.h>
Dr. Stephen Henson535d79d2001-03-15 19:13:40 +000032#include <openssl/x509v3.h>
Richard Levitte90ae4672000-06-22 17:42:50 +000033#include <openssl/pem.h>
34#include <openssl/pkcs12.h>
Richard Levitte2fe5adc2001-06-19 16:26:30 +000035#include <openssl/ui.h>
Richard Levitte90ae4672000-06-22 17:42:50 +000036#include <openssl/safestack.h>
Richard Levitte0b13e9f2003-01-30 17:39:26 +000037#ifndef OPENSSL_NO_ENGINE
Matt Caswell0f113f32015-01-22 03:40:55 +000038# include <openssl/engine.h>
Richard Levitte0b13e9f2003-01-30 17:39:26 +000039#endif
Nils Larsch3eeaab42005-07-16 12:37:36 +000040#ifndef OPENSSL_NO_RSA
Matt Caswell0f113f32015-01-22 03:40:55 +000041# include <openssl/rsa.h>
Nils Larsch3eeaab42005-07-16 12:37:36 +000042#endif
Geoff Thorpef0eae952004-05-17 19:05:32 +000043#include <openssl/bn.h>
Rich Salz7e1b7482015-04-24 15:26:15 -040044#include <openssl/ssl.h>
Matt Caswell75dd6c12016-05-20 11:53:26 +010045#include "s_apps.h"
Richard Levitted610d272002-10-24 10:03:55 +000046#include "apps.h"
Richard Levitted610d272002-10-24 10:03:55 +000047
Andy Polyakova1ad2532005-11-04 16:12:05 +000048#ifdef _WIN32
49static int WIN32_rename(const char *from, const char *to);
Matt Caswell0f113f32015-01-22 03:40:55 +000050# define rename(from,to) WIN32_rename((from),(to))
Andy Polyakova1ad2532005-11-04 16:12:05 +000051#endif
52
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +000053typedef struct {
Matt Caswell0f113f32015-01-22 03:40:55 +000054 const char *name;
55 unsigned long flag;
56 unsigned long mask;
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +000057} NAME_EX_TBL;
58
Ben Lauriee93836b2016-04-18 10:44:42 +010059#if !defined(OPENSSL_NO_UI) || !defined(OPENSSL_NO_ENGINE)
Richard Levitte2fe5adc2001-06-19 16:26:30 +000060static UI_METHOD *ui_method = NULL;
Ben Lauriee93836b2016-04-18 10:44:42 +010061#endif
Richard Levitte2fe5adc2001-06-19 16:26:30 +000062
Matt Caswell0f113f32015-01-22 03:40:55 +000063static int set_table_opts(unsigned long *flags, const char *arg,
64 const NAME_EX_TBL * in_tbl);
65static int set_multi_opts(unsigned long *flags, const char *arg,
66 const NAME_EX_TBL * in_tbl);
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +000067
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000068int app_init(long mesgwin);
Rich Salz7e1b7482015-04-24 15:26:15 -040069
70int chopup_args(ARGS *arg, char *buf)
Matt Caswell0f113f32015-01-22 03:40:55 +000071{
Rich Salz7e1b7482015-04-24 15:26:15 -040072 int quoted;
Gunnar Kudrjavets4c9b0a02015-05-06 10:16:55 +010073 char c = '\0', *p = NULL;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000074
Rich Salz7e1b7482015-04-24 15:26:15 -040075 arg->argc = 0;
76 if (arg->size == 0) {
77 arg->size = 20;
Rich Salzb4faea52015-05-01 23:10:31 -040078 arg->argv = app_malloc(sizeof(*arg->argv) * arg->size, "argv space");
Matt Caswell0f113f32015-01-22 03:40:55 +000079 }
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000080
Rich Salz7e1b7482015-04-24 15:26:15 -040081 for (p = buf;;) {
82 /* Skip whitespace. */
Richard Levitte18295f02016-02-14 13:02:15 +010083 while (*p && isspace(_UC(*p)))
Matt Caswell0f113f32015-01-22 03:40:55 +000084 p++;
85 if (!*p)
86 break;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000087
Matt Caswell0f113f32015-01-22 03:40:55 +000088 /* The start of something good :-) */
Rich Salz7e1b7482015-04-24 15:26:15 -040089 if (arg->argc >= arg->size) {
Dr. Stephen Henson7c0ef842016-05-11 21:14:57 +010090 char **tmp;
Rich Salz7e1b7482015-04-24 15:26:15 -040091 arg->size += 20;
Dr. Stephen Henson7c0ef842016-05-11 21:14:57 +010092 tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size);
93 if (tmp == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +000094 return 0;
Dr. Stephen Henson7c0ef842016-05-11 21:14:57 +010095 arg->argv = tmp;
Matt Caswell0f113f32015-01-22 03:40:55 +000096 }
Rich Salz7e1b7482015-04-24 15:26:15 -040097 quoted = *p == '\'' || *p == '"';
98 if (quoted)
99 c = *p++;
100 arg->argv[arg->argc++] = p;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000101
Matt Caswell0f113f32015-01-22 03:40:55 +0000102 /* now look for the end of this */
Rich Salz7e1b7482015-04-24 15:26:15 -0400103 if (quoted) {
104 while (*p && *p != c)
Matt Caswell0f113f32015-01-22 03:40:55 +0000105 p++;
Rich Salz7e1b7482015-04-24 15:26:15 -0400106 *p++ = '\0';
Matt Caswell0f113f32015-01-22 03:40:55 +0000107 } else {
Richard Levitte18295f02016-02-14 13:02:15 +0100108 while (*p && !isspace(_UC(*p)))
Matt Caswell0f113f32015-01-22 03:40:55 +0000109 p++;
Rich Salz7e1b7482015-04-24 15:26:15 -0400110 if (*p)
111 *p++ = '\0';
Matt Caswell0f113f32015-01-22 03:40:55 +0000112 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000113 }
Rich Salz7e1b7482015-04-24 15:26:15 -0400114 arg->argv[arg->argc] = NULL;
Matt Caswell0f113f32015-01-22 03:40:55 +0000115 return (1);
116}
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000117
118#ifndef APP_INIT
Ulf Möller6b691a51999-04-19 21:31:43 +0000119int app_init(long mesgwin)
Matt Caswell0f113f32015-01-22 03:40:55 +0000120{
121 return (1);
122}
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000123#endif
Dr. Stephen Henson53b18991999-11-11 13:58:41 +0000124
Matt Caswell2b6bcb72015-09-22 16:00:52 +0100125int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile,
126 const char *CApath, int noCAfile, int noCApath)
Rich Salz7e1b7482015-04-24 15:26:15 -0400127{
Matt Caswell2b6bcb72015-09-22 16:00:52 +0100128 if (CAfile == NULL && CApath == NULL) {
129 if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0)
130 return 0;
131 if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0)
132 return 0;
133
134 return 1;
135 }
Rich Salz7e1b7482015-04-24 15:26:15 -0400136 return SSL_CTX_load_verify_locations(ctx, CAfile, CApath);
137}
138
Rob Percivalb5369582016-03-10 23:10:02 +0000139#ifndef OPENSSL_NO_CT
140
Rob Percivaldd696a52016-03-02 13:34:05 +0000141int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
142{
143 if (path == NULL) {
Rob Percival328f36c2016-03-04 19:06:43 +0000144 return SSL_CTX_set_default_ctlog_list_file(ctx);
Rob Percivaldd696a52016-03-02 13:34:05 +0000145 }
146
147 return SSL_CTX_set_ctlog_list_file(ctx, path);
148}
149
Rob Percivalb5369582016-03-10 23:10:02 +0000150#endif
151
Matt Caswell0f113f32015-01-22 03:40:55 +0000152int dump_cert_text(BIO *out, X509 *x)
Dr. Stephen Henson954ef7e1999-11-12 01:42:25 +0000153{
Matt Caswell0f113f32015-01-22 03:40:55 +0000154 char *p;
Dr. Stephen Henson954ef7e1999-11-12 01:42:25 +0000155
Matt Caswell0f113f32015-01-22 03:40:55 +0000156 p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
157 BIO_puts(out, "subject=");
158 BIO_puts(out, p);
159 OPENSSL_free(p);
Ben Laurie54a656e2002-11-13 15:43:43 +0000160
Matt Caswell0f113f32015-01-22 03:40:55 +0000161 p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
162 BIO_puts(out, "\nissuer=");
163 BIO_puts(out, p);
164 BIO_puts(out, "\n");
165 OPENSSL_free(p);
Ben Laurie54a656e2002-11-13 15:43:43 +0000166
Matt Caswell0f113f32015-01-22 03:40:55 +0000167 return 0;
Dr. Stephen Henson954ef7e1999-11-12 01:42:25 +0000168}
Dr. Stephen Hensona3fe3822000-02-16 23:16:01 +0000169
Richard Levitte923b1852016-03-21 18:08:57 +0100170#ifndef OPENSSL_NO_UI
Richard Levitte2fe5adc2001-06-19 16:26:30 +0000171static int ui_open(UI *ui)
Matt Caswell0f113f32015-01-22 03:40:55 +0000172{
173 return UI_method_get_opener(UI_OpenSSL())(ui);
174}
175
Richard Levitte2fe5adc2001-06-19 16:26:30 +0000176static int ui_read(UI *ui, UI_STRING *uis)
Matt Caswell0f113f32015-01-22 03:40:55 +0000177{
178 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
179 && UI_get0_user_data(ui)) {
180 switch (UI_get_string_type(uis)) {
181 case UIT_PROMPT:
182 case UIT_VERIFY:
183 {
184 const char *password =
185 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
186 if (password && password[0] != '\0') {
187 UI_set_result(ui, uis, password);
188 return 1;
189 }
190 }
Rich Salzf3b3d7f2016-08-30 13:31:18 -0400191 break;
192 case UIT_NONE:
193 case UIT_BOOLEAN:
194 case UIT_INFO:
195 case UIT_ERROR:
Matt Caswell0f113f32015-01-22 03:40:55 +0000196 break;
197 }
198 }
199 return UI_method_get_reader(UI_OpenSSL())(ui, uis);
200}
201
Richard Levitte2fe5adc2001-06-19 16:26:30 +0000202static int ui_write(UI *ui, UI_STRING *uis)
Matt Caswell0f113f32015-01-22 03:40:55 +0000203{
204 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
205 && UI_get0_user_data(ui)) {
206 switch (UI_get_string_type(uis)) {
207 case UIT_PROMPT:
208 case UIT_VERIFY:
209 {
210 const char *password =
211 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
212 if (password && password[0] != '\0')
213 return 1;
214 }
Rich Salzf3b3d7f2016-08-30 13:31:18 -0400215 break;
216 case UIT_NONE:
217 case UIT_BOOLEAN:
218 case UIT_INFO:
219 case UIT_ERROR:
Matt Caswell0f113f32015-01-22 03:40:55 +0000220 break;
221 }
222 }
223 return UI_method_get_writer(UI_OpenSSL())(ui, uis);
224}
225
Richard Levitte2fe5adc2001-06-19 16:26:30 +0000226static int ui_close(UI *ui)
Matt Caswell0f113f32015-01-22 03:40:55 +0000227{
228 return UI_method_get_closer(UI_OpenSSL())(ui);
229}
230
Lutz Jänicke40889b92002-06-13 17:40:27 +0000231int setup_ui_method(void)
Matt Caswell0f113f32015-01-22 03:40:55 +0000232{
233 ui_method = UI_create_method("OpenSSL application user interface");
234 UI_method_set_opener(ui_method, ui_open);
235 UI_method_set_reader(ui_method, ui_read);
236 UI_method_set_writer(ui_method, ui_write);
237 UI_method_set_closer(ui_method, ui_close);
238 return 0;
239}
240
Lutz Jänicke40889b92002-06-13 17:40:27 +0000241void destroy_ui_method(void)
Matt Caswell0f113f32015-01-22 03:40:55 +0000242{
243 if (ui_method) {
244 UI_destroy_method(ui_method);
245 ui_method = NULL;
246 }
247}
Richard Levitte264b2d92016-12-06 04:17:18 +0100248
249const UI_METHOD *get_ui_method(void)
250{
251 return ui_method;
252}
Richard Levitte923b1852016-03-21 18:08:57 +0100253#endif
Richard Levitte30b4c272001-05-30 15:29:28 +0000254
Matt Caswell0f113f32015-01-22 03:40:55 +0000255int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
256{
Matt Caswell0f113f32015-01-22 03:40:55 +0000257 int res = 0;
Richard Levitte923b1852016-03-21 18:08:57 +0100258#ifndef OPENSSL_NO_UI
259 UI *ui = NULL;
Richard Levitte923b1852016-03-21 18:08:57 +0100260#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000261 PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
Richard Levitte30b4c272001-05-30 15:29:28 +0000262
Richard Levitte57c0f372016-12-08 01:27:31 +0100263#ifdef OPENSSL_NO_UI
264 if (cb_data != NULL && cb_data->password != NULL) {
265 res = strlen(cb_data->password);
Matt Caswell0f113f32015-01-22 03:40:55 +0000266 if (res > bufsiz)
267 res = bufsiz;
Richard Levitte57c0f372016-12-08 01:27:31 +0100268 memcpy(buf, cb_data->password, res);
Matt Caswell0f113f32015-01-22 03:40:55 +0000269 }
Richard Levitte57c0f372016-12-08 01:27:31 +0100270#else
Matt Caswell0f113f32015-01-22 03:40:55 +0000271 ui = UI_new_method(ui_method);
272 if (ui) {
273 int ok = 0;
274 char *buff = NULL;
275 int ui_flags = 0;
Richard Levitte57c0f372016-12-08 01:27:31 +0100276 const char *prompt_info = NULL;
Rich Salz7e1b7482015-04-24 15:26:15 -0400277 char *prompt;
Richard Levitte2fe5adc2001-06-19 16:26:30 +0000278
Richard Levitte57c0f372016-12-08 01:27:31 +0100279 if (cb_data != NULL && cb_data->prompt_info != NULL)
280 prompt_info = cb_data->prompt_info;
Matt Caswell0f113f32015-01-22 03:40:55 +0000281 prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
Viktor Dukhovni61986d32015-04-16 01:50:03 -0400282 if (!prompt) {
Matt Caswell918bb862015-03-04 17:49:51 +0000283 BIO_printf(bio_err, "Out of memory\n");
284 UI_free(ui);
285 return 0;
286 }
Richard Levitte2fe5adc2001-06-19 16:26:30 +0000287
Matt Caswell0f113f32015-01-22 03:40:55 +0000288 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
289 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
Richard Levitte4f272c12001-06-23 16:30:14 +0000290
Richard Levitte57c0f372016-12-08 01:27:31 +0100291 /* We know that there is no previous user data to return to us */
292 (void)UI_add_user_data(ui, cb_data);
293
Matt Caswell0f113f32015-01-22 03:40:55 +0000294 if (ok >= 0)
295 ok = UI_add_input_string(ui, prompt, ui_flags, buf,
296 PW_MIN_LENGTH, bufsiz - 1);
297 if (ok >= 0 && verify) {
Rich Salz68dc6822015-04-30 17:48:31 -0400298 buff = app_malloc(bufsiz, "password buffer");
Matt Caswell0f113f32015-01-22 03:40:55 +0000299 ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
300 PW_MIN_LENGTH, bufsiz - 1, buf);
301 }
302 if (ok >= 0)
303 do {
304 ok = UI_process(ui);
305 }
306 while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
Richard Levitte2fe5adc2001-06-19 16:26:30 +0000307
Rich Salz4b45c6e2015-04-30 17:57:32 -0400308 OPENSSL_clear_free(buff, (unsigned int)bufsiz);
Matt Caswell0f113f32015-01-22 03:40:55 +0000309
310 if (ok >= 0)
311 res = strlen(buf);
312 if (ok == -1) {
313 BIO_printf(bio_err, "User interface error\n");
314 ERR_print_errors(bio_err);
315 OPENSSL_cleanse(buf, (unsigned int)bufsiz);
316 res = 0;
317 }
318 if (ok == -2) {
319 BIO_printf(bio_err, "aborted!\n");
320 OPENSSL_cleanse(buf, (unsigned int)bufsiz);
321 res = 0;
322 }
323 UI_free(ui);
324 OPENSSL_free(prompt);
325 }
Richard Levitte923b1852016-03-21 18:08:57 +0100326#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000327 return res;
328}
Richard Levitte30b4c272001-05-30 15:29:28 +0000329
FdaSilvaYYcc696292016-08-04 23:52:22 +0200330static char *app_get_pass(const char *arg, int keepbio);
Dr. Stephen Hensona3fe3822000-02-16 23:16:01 +0000331
FdaSilvaYYcc696292016-08-04 23:52:22 +0200332int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2)
Dr. Stephen Hensona3fe3822000-02-16 23:16:01 +0000333{
Matt Caswell0f113f32015-01-22 03:40:55 +0000334 int same;
335 if (!arg2 || !arg1 || strcmp(arg1, arg2))
336 same = 0;
337 else
338 same = 1;
339 if (arg1) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400340 *pass1 = app_get_pass(arg1, same);
Matt Caswell0f113f32015-01-22 03:40:55 +0000341 if (!*pass1)
342 return 0;
343 } else if (pass1)
344 *pass1 = NULL;
345 if (arg2) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400346 *pass2 = app_get_pass(arg2, same ? 2 : 0);
Matt Caswell0f113f32015-01-22 03:40:55 +0000347 if (!*pass2)
348 return 0;
349 } else if (pass2)
350 *pass2 = NULL;
351 return 1;
Dr. Stephen Hensona3fe3822000-02-16 23:16:01 +0000352}
353
FdaSilvaYYcc696292016-08-04 23:52:22 +0200354static char *app_get_pass(const char *arg, int keepbio)
Dr. Stephen Hensona3fe3822000-02-16 23:16:01 +0000355{
Matt Caswell0f113f32015-01-22 03:40:55 +0000356 char *tmp, tpass[APP_PASS_LEN];
357 static BIO *pwdbio = NULL;
358 int i;
Rich Salz86885c22015-05-06 14:56:14 -0400359
360 if (strncmp(arg, "pass:", 5) == 0)
Rich Salz7644a9a2015-12-16 16:12:24 -0500361 return OPENSSL_strdup(arg + 5);
Rich Salz86885c22015-05-06 14:56:14 -0400362 if (strncmp(arg, "env:", 4) == 0) {
Matt Caswell0f113f32015-01-22 03:40:55 +0000363 tmp = getenv(arg + 4);
364 if (!tmp) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400365 BIO_printf(bio_err, "Can't read environment variable %s\n", arg + 4);
Matt Caswell0f113f32015-01-22 03:40:55 +0000366 return NULL;
367 }
Rich Salz7644a9a2015-12-16 16:12:24 -0500368 return OPENSSL_strdup(tmp);
Matt Caswell0f113f32015-01-22 03:40:55 +0000369 }
370 if (!keepbio || !pwdbio) {
Rich Salz86885c22015-05-06 14:56:14 -0400371 if (strncmp(arg, "file:", 5) == 0) {
Matt Caswell0f113f32015-01-22 03:40:55 +0000372 pwdbio = BIO_new_file(arg + 5, "r");
373 if (!pwdbio) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400374 BIO_printf(bio_err, "Can't open file %s\n", arg + 5);
Matt Caswell0f113f32015-01-22 03:40:55 +0000375 return NULL;
376 }
Andy Polyakoveff7cb42005-11-03 15:31:28 +0000377#if !defined(_WIN32)
Matt Caswell0f113f32015-01-22 03:40:55 +0000378 /*
379 * Under _WIN32, which covers even Win64 and CE, file
380 * descriptors referenced by BIO_s_fd are not inherited
381 * by child process and therefore below is not an option.
382 * It could have been an option if bss_fd.c was operating
383 * on real Windows descriptors, such as those obtained
384 * with CreateFile.
385 */
Rich Salz86885c22015-05-06 14:56:14 -0400386 } else if (strncmp(arg, "fd:", 3) == 0) {
Matt Caswell0f113f32015-01-22 03:40:55 +0000387 BIO *btmp;
388 i = atoi(arg + 3);
389 if (i >= 0)
390 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
391 if ((i < 0) || !pwdbio) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400392 BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3);
Matt Caswell0f113f32015-01-22 03:40:55 +0000393 return NULL;
394 }
395 /*
396 * Can't do BIO_gets on an fd BIO so add a buffering BIO
397 */
398 btmp = BIO_new(BIO_f_buffer());
399 pwdbio = BIO_push(btmp, pwdbio);
Andy Polyakoveff7cb42005-11-03 15:31:28 +0000400#endif
Rich Salz86885c22015-05-06 14:56:14 -0400401 } else if (strcmp(arg, "stdin") == 0) {
Richard Levittea60994d2015-09-06 12:20:12 +0200402 pwdbio = dup_bio_in(FORMAT_TEXT);
Matt Caswell0f113f32015-01-22 03:40:55 +0000403 if (!pwdbio) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400404 BIO_printf(bio_err, "Can't open BIO for stdin\n");
Matt Caswell0f113f32015-01-22 03:40:55 +0000405 return NULL;
406 }
407 } else {
Rich Salz7e1b7482015-04-24 15:26:15 -0400408 BIO_printf(bio_err, "Invalid password argument \"%s\"\n", arg);
Matt Caswell0f113f32015-01-22 03:40:55 +0000409 return NULL;
410 }
411 }
412 i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
413 if (keepbio != 1) {
414 BIO_free_all(pwdbio);
415 pwdbio = NULL;
416 }
417 if (i <= 0) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400418 BIO_printf(bio_err, "Error reading password from BIO\n");
Matt Caswell0f113f32015-01-22 03:40:55 +0000419 return NULL;
420 }
421 tmp = strchr(tpass, '\n');
422 if (tmp)
423 *tmp = 0;
Rich Salz7644a9a2015-12-16 16:12:24 -0500424 return OPENSSL_strdup(tpass);
Dr. Stephen Hensona3fe3822000-02-16 23:16:01 +0000425}
Richard Levitte90ae4672000-06-22 17:42:50 +0000426
Richard Levitte296f54e2015-05-29 08:07:10 +0200427static CONF *app_load_config_(BIO *in, const char *filename)
Rich Salzcc01d212015-05-28 13:52:55 -0400428{
429 long errorline = -1;
430 CONF *conf;
431 int i;
Rich Salzcc01d212015-05-28 13:52:55 -0400432
433 conf = NCONF_new(NULL);
434 i = NCONF_load_bio(conf, in, &errorline);
Rich Salzcc01d212015-05-28 13:52:55 -0400435 if (i > 0)
436 return conf;
437
438 if (errorline <= 0)
439 BIO_printf(bio_err, "%s: Can't load config file \"%s\"\n",
440 opt_getprog(), filename);
441 else
442 BIO_printf(bio_err, "%s: Error on line %ld of config file \"%s\"\n",
443 opt_getprog(), errorline, filename);
444 NCONF_free(conf);
445 return NULL;
446}
Richard Levitte296f54e2015-05-29 08:07:10 +0200447CONF *app_load_config(const char *filename)
448{
449 BIO *in;
450 CONF *conf;
451
Richard Levittebdd58d92015-09-04 12:49:06 +0200452 in = bio_open_default(filename, 'r', FORMAT_TEXT);
Richard Levitte296f54e2015-05-29 08:07:10 +0200453 if (in == NULL)
454 return NULL;
455
456 conf = app_load_config_(in, filename);
457 BIO_free(in);
458 return conf;
459}
460CONF *app_load_config_quiet(const char *filename)
461{
462 BIO *in;
463 CONF *conf;
464
Richard Levittebdd58d92015-09-04 12:49:06 +0200465 in = bio_open_default_quiet(filename, 'r', FORMAT_TEXT);
Richard Levitte296f54e2015-05-29 08:07:10 +0200466 if (in == NULL)
467 return NULL;
468
469 conf = app_load_config_(in, filename);
470 BIO_free(in);
471 return conf;
472}
473
474int app_load_modules(const CONF *config)
475{
476 CONF *to_free = NULL;
477
478 if (config == NULL)
FdaSilvaYYdccd20d2016-05-03 22:40:33 +0200479 config = to_free = app_load_config_quiet(default_config_file);
Richard Levitte296f54e2015-05-29 08:07:10 +0200480 if (config == NULL)
FdaSilvaYYdccd20d2016-05-03 22:40:33 +0200481 return 1;
Richard Levitte296f54e2015-05-29 08:07:10 +0200482
483 if (CONF_modules_load(config, NULL, 0) <= 0) {
484 BIO_printf(bio_err, "Error configuring OpenSSL modules\n");
485 ERR_print_errors(bio_err);
486 NCONF_free(to_free);
487 return 0;
488 }
489 NCONF_free(to_free);
490 return 1;
491}
Rich Salzcc01d212015-05-28 13:52:55 -0400492
Rich Salz7e1b7482015-04-24 15:26:15 -0400493int add_oid_section(CONF *conf)
Matt Caswell0f113f32015-01-22 03:40:55 +0000494{
495 char *p;
496 STACK_OF(CONF_VALUE) *sktmp;
497 CONF_VALUE *cnf;
498 int i;
Rich Salz75ebbd92015-05-06 13:43:59 -0400499
500 if ((p = NCONF_get_string(conf, NULL, "oid_section")) == NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +0000501 ERR_clear_error();
502 return 1;
503 }
Rich Salz75ebbd92015-05-06 13:43:59 -0400504 if ((sktmp = NCONF_get_section(conf, p)) == NULL) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400505 BIO_printf(bio_err, "problem loading oid section %s\n", p);
Matt Caswell0f113f32015-01-22 03:40:55 +0000506 return 0;
507 }
508 for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
509 cnf = sk_CONF_VALUE_value(sktmp, i);
510 if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400511 BIO_printf(bio_err, "problem creating object %s=%s\n",
Matt Caswell0f113f32015-01-22 03:40:55 +0000512 cnf->name, cnf->value);
513 return 0;
514 }
515 }
516 return 1;
Richard Levitte431b0cc2000-06-22 22:07:27 +0000517}
518
Rich Salz7e1b7482015-04-24 15:26:15 -0400519static int load_pkcs12(BIO *in, const char *desc,
Matt Caswell0f113f32015-01-22 03:40:55 +0000520 pem_password_cb *pem_cb, void *cb_data,
521 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
522{
523 const char *pass;
524 char tpass[PEM_BUFSIZE];
525 int len, ret = 0;
526 PKCS12 *p12;
527 p12 = d2i_PKCS12_bio(in, NULL);
528 if (p12 == NULL) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400529 BIO_printf(bio_err, "Error loading PKCS12 file for %s\n", desc);
Matt Caswell0f113f32015-01-22 03:40:55 +0000530 goto die;
531 }
532 /* See if an empty password will do */
533 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
534 pass = "";
535 else {
536 if (!pem_cb)
537 pem_cb = (pem_password_cb *)password_callback;
538 len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
539 if (len < 0) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400540 BIO_printf(bio_err, "Passphrase callback error for %s\n", desc);
Matt Caswell0f113f32015-01-22 03:40:55 +0000541 goto die;
542 }
543 if (len < PEM_BUFSIZE)
544 tpass[len] = 0;
545 if (!PKCS12_verify_mac(p12, tpass, len)) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400546 BIO_printf(bio_err,
Matt Caswell0f113f32015-01-22 03:40:55 +0000547 "Mac verify error (wrong password?) in PKCS12 file for %s\n",
548 desc);
549 goto die;
550 }
551 pass = tpass;
552 }
553 ret = PKCS12_parse(p12, pass, pkey, cert, ca);
554 die:
Rich Salze0e920b2015-04-11 16:32:54 -0400555 PKCS12_free(p12);
Matt Caswell0f113f32015-01-22 03:40:55 +0000556 return ret;
557}
Dr. Stephen Hensone90fadd2004-12-29 01:07:14 +0000558
Matt Caswellf9e55032016-03-21 15:32:40 +0000559#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
Rich Salz5d322282016-02-25 00:56:35 -0500560static int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl)
Matt Caswell0f113f32015-01-22 03:40:55 +0000561{
562 char *host = NULL, *port = NULL, *path = NULL;
563 BIO *bio = NULL;
564 OCSP_REQ_CTX *rctx = NULL;
565 int use_ssl, rv = 0;
566 if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl))
567 goto err;
568 if (use_ssl) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400569 BIO_puts(bio_err, "https not supported\n");
Matt Caswell0f113f32015-01-22 03:40:55 +0000570 goto err;
571 }
572 bio = BIO_new_connect(host);
573 if (!bio || !BIO_set_conn_port(bio, port))
574 goto err;
575 rctx = OCSP_REQ_CTX_new(bio, 1024);
Matt Caswell96487cd2015-10-30 11:18:04 +0000576 if (rctx == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000577 goto err;
578 if (!OCSP_REQ_CTX_http(rctx, "GET", path))
579 goto err;
580 if (!OCSP_REQ_CTX_add1_header(rctx, "Host", host))
581 goto err;
582 if (pcert) {
583 do {
584 rv = X509_http_nbio(rctx, pcert);
Rich Salz7e1b7482015-04-24 15:26:15 -0400585 } while (rv == -1);
Matt Caswell0f113f32015-01-22 03:40:55 +0000586 } else {
587 do {
588 rv = X509_CRL_http_nbio(rctx, pcrl);
589 } while (rv == -1);
590 }
Dr. Stephen Henson95ea5312012-12-02 14:00:22 +0000591
Matt Caswell0f113f32015-01-22 03:40:55 +0000592 err:
Rich Salz25aaa982015-05-01 14:37:16 -0400593 OPENSSL_free(host);
594 OPENSSL_free(path);
595 OPENSSL_free(port);
Matt Caswell0f113f32015-01-22 03:40:55 +0000596 if (bio)
597 BIO_free_all(bio);
Rich Salz895cba12015-04-30 18:10:52 -0400598 OCSP_REQ_CTX_free(rctx);
Matt Caswell0f113f32015-01-22 03:40:55 +0000599 if (rv != 1) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400600 BIO_printf(bio_err, "Error loading %s from %s\n",
601 pcert ? "certificate" : "CRL", url);
Matt Caswell0f113f32015-01-22 03:40:55 +0000602 ERR_print_errors(bio_err);
603 }
604 return rv;
605}
Rich Salz5d322282016-02-25 00:56:35 -0500606#endif
Dr. Stephen Henson95ea5312012-12-02 14:00:22 +0000607
Rich Salza773b522016-02-13 22:33:56 -0500608X509 *load_cert(const char *file, int format, const char *cert_descrip)
Matt Caswell0f113f32015-01-22 03:40:55 +0000609{
610 X509 *x = NULL;
611 BIO *cert;
Richard Levitte90ae4672000-06-22 17:42:50 +0000612
Matt Caswell0f113f32015-01-22 03:40:55 +0000613 if (format == FORMAT_HTTP) {
Matt Caswellf9e55032016-03-21 15:32:40 +0000614#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
Rich Salz7e1b7482015-04-24 15:26:15 -0400615 load_cert_crl_http(file, &x, NULL);
Rich Salz5d322282016-02-25 00:56:35 -0500616#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000617 return x;
618 }
Dr. Stephen Henson95ea5312012-12-02 14:00:22 +0000619
Matt Caswell0f113f32015-01-22 03:40:55 +0000620 if (file == NULL) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400621 unbuffer(stdin);
Richard Levittea60994d2015-09-06 12:20:12 +0200622 cert = dup_bio_in(format);
Rich Salz7e1b7482015-04-24 15:26:15 -0400623 } else
Richard Levittebdd58d92015-09-04 12:49:06 +0200624 cert = bio_open_default(file, 'r', format);
Rich Salz7e1b7482015-04-24 15:26:15 -0400625 if (cert == NULL)
626 goto end;
Richard Levitte90ae4672000-06-22 17:42:50 +0000627
Matt Caswell0f113f32015-01-22 03:40:55 +0000628 if (format == FORMAT_ASN1)
629 x = d2i_X509_bio(cert, NULL);
Rich Salz0bc2f362015-07-02 08:49:54 -0400630 else if (format == FORMAT_PEM)
Matt Caswell0f113f32015-01-22 03:40:55 +0000631 x = PEM_read_bio_X509_AUX(cert, NULL,
632 (pem_password_cb *)password_callback, NULL);
633 else if (format == FORMAT_PKCS12) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400634 if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL))
Matt Caswell0f113f32015-01-22 03:40:55 +0000635 goto end;
636 } else {
Rich Salz7e1b7482015-04-24 15:26:15 -0400637 BIO_printf(bio_err, "bad input format specified for %s\n", cert_descrip);
Matt Caswell0f113f32015-01-22 03:40:55 +0000638 goto end;
639 }
640 end:
641 if (x == NULL) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400642 BIO_printf(bio_err, "unable to load certificate\n");
643 ERR_print_errors(bio_err);
Matt Caswell0f113f32015-01-22 03:40:55 +0000644 }
Rich Salz25aaa982015-05-01 14:37:16 -0400645 BIO_free(cert);
Matt Caswell0f113f32015-01-22 03:40:55 +0000646 return (x);
647}
Richard Levitte90ae4672000-06-22 17:42:50 +0000648
Dr. Stephen Henson0090a682012-12-06 18:43:40 +0000649X509_CRL *load_crl(const char *infile, int format)
Matt Caswell0f113f32015-01-22 03:40:55 +0000650{
651 X509_CRL *x = NULL;
652 BIO *in = NULL;
Dr. Stephen Hensonfdb78f32012-12-02 16:16:28 +0000653
Matt Caswell0f113f32015-01-22 03:40:55 +0000654 if (format == FORMAT_HTTP) {
Matt Caswellf9e55032016-03-21 15:32:40 +0000655#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
Rich Salz7e1b7482015-04-24 15:26:15 -0400656 load_cert_crl_http(infile, NULL, &x);
Rich Salz5d322282016-02-25 00:56:35 -0500657#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000658 return x;
659 }
Dr. Stephen Hensonfdb78f32012-12-02 16:16:28 +0000660
Richard Levittebdd58d92015-09-04 12:49:06 +0200661 in = bio_open_default(infile, 'r', format);
Rich Salz7e1b7482015-04-24 15:26:15 -0400662 if (in == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000663 goto end;
Matt Caswell0f113f32015-01-22 03:40:55 +0000664 if (format == FORMAT_ASN1)
665 x = d2i_X509_CRL_bio(in, NULL);
666 else if (format == FORMAT_PEM)
667 x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
668 else {
669 BIO_printf(bio_err, "bad input format specified for input crl\n");
670 goto end;
671 }
672 if (x == NULL) {
673 BIO_printf(bio_err, "unable to load CRL\n");
674 ERR_print_errors(bio_err);
675 goto end;
676 }
Dr. Stephen Hensonfdb78f32012-12-02 16:16:28 +0000677
Matt Caswell0f113f32015-01-22 03:40:55 +0000678 end:
679 BIO_free(in);
680 return (x);
681}
Dr. Stephen Hensonfdb78f32012-12-02 16:16:28 +0000682
Rich Salz7e1b7482015-04-24 15:26:15 -0400683EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
Matt Caswell0f113f32015-01-22 03:40:55 +0000684 const char *pass, ENGINE *e, const char *key_descrip)
685{
686 BIO *key = NULL;
687 EVP_PKEY *pkey = NULL;
688 PW_CB_DATA cb_data;
Richard Levitte30b4c272001-05-30 15:29:28 +0000689
Matt Caswell0f113f32015-01-22 03:40:55 +0000690 cb_data.password = pass;
691 cb_data.prompt_info = file;
Richard Levitte90ae4672000-06-22 17:42:50 +0000692
Matt Caswell0f113f32015-01-22 03:40:55 +0000693 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400694 BIO_printf(bio_err, "no keyfile specified\n");
Matt Caswell0f113f32015-01-22 03:40:55 +0000695 goto end;
696 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000697 if (format == FORMAT_ENGINE) {
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500698 if (e == NULL)
Rich Salz7e1b7482015-04-24 15:26:15 -0400699 BIO_printf(bio_err, "no engine specified\n");
Matt Caswell0f113f32015-01-22 03:40:55 +0000700 else {
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500701#ifndef OPENSSL_NO_ENGINE
Richard Levitte49e476a2016-09-28 21:28:00 +0200702 if (ENGINE_init(e)) {
703 pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data);
704 ENGINE_finish(e);
705 }
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500706 if (pkey == NULL) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400707 BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip);
708 ERR_print_errors(bio_err);
Matt Caswell0f113f32015-01-22 03:40:55 +0000709 }
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500710#else
711 BIO_printf(bio_err, "engines not supported\n");
712#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000713 }
714 goto end;
715 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000716 if (file == NULL && maybe_stdin) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400717 unbuffer(stdin);
Richard Levittea60994d2015-09-06 12:20:12 +0200718 key = dup_bio_in(format);
Rich Salz7e1b7482015-04-24 15:26:15 -0400719 } else
Richard Levittebdd58d92015-09-04 12:49:06 +0200720 key = bio_open_default(file, 'r', format);
Rich Salz7e1b7482015-04-24 15:26:15 -0400721 if (key == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000722 goto end;
Matt Caswell0f113f32015-01-22 03:40:55 +0000723 if (format == FORMAT_ASN1) {
724 pkey = d2i_PrivateKey_bio(key, NULL);
725 } else if (format == FORMAT_PEM) {
726 pkey = PEM_read_bio_PrivateKey(key, NULL,
727 (pem_password_cb *)password_callback,
728 &cb_data);
729 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000730 else if (format == FORMAT_PKCS12) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400731 if (!load_pkcs12(key, key_descrip,
Matt Caswell0f113f32015-01-22 03:40:55 +0000732 (pem_password_cb *)password_callback, &cb_data,
733 &pkey, NULL, NULL))
734 goto end;
735 }
Dr. Stephen Henson00a37b52010-04-06 11:18:59 +0000736#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
Matt Caswell0f113f32015-01-22 03:40:55 +0000737 else if (format == FORMAT_MSBLOB)
738 pkey = b2i_PrivateKey_bio(key);
739 else if (format == FORMAT_PVK)
740 pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
741 &cb_data);
Dr. Stephen Hensond4f03392009-04-26 22:18:22 +0000742#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000743 else {
Rich Salz7e1b7482015-04-24 15:26:15 -0400744 BIO_printf(bio_err, "bad input format specified for key file\n");
Matt Caswell0f113f32015-01-22 03:40:55 +0000745 goto end;
746 }
Richard Levitte90ae4672000-06-22 17:42:50 +0000747 end:
Rich Salz25aaa982015-05-01 14:37:16 -0400748 BIO_free(key);
Matt Caswell0f113f32015-01-22 03:40:55 +0000749 if (pkey == NULL) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400750 BIO_printf(bio_err, "unable to load %s\n", key_descrip);
751 ERR_print_errors(bio_err);
Matt Caswell0f113f32015-01-22 03:40:55 +0000752 }
753 return (pkey);
754}
Richard Levitte90ae4672000-06-22 17:42:50 +0000755
Rich Salz7e1b7482015-04-24 15:26:15 -0400756EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
Matt Caswell0f113f32015-01-22 03:40:55 +0000757 const char *pass, ENGINE *e, const char *key_descrip)
758{
759 BIO *key = NULL;
760 EVP_PKEY *pkey = NULL;
761 PW_CB_DATA cb_data;
Richard Levitte30b4c272001-05-30 15:29:28 +0000762
Matt Caswell0f113f32015-01-22 03:40:55 +0000763 cb_data.password = pass;
764 cb_data.prompt_info = file;
Dr. Stephen Hensonbd08a2b2000-09-03 23:13:48 +0000765
Matt Caswell0f113f32015-01-22 03:40:55 +0000766 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400767 BIO_printf(bio_err, "no keyfile specified\n");
Matt Caswell0f113f32015-01-22 03:40:55 +0000768 goto end;
769 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000770 if (format == FORMAT_ENGINE) {
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500771 if (e == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000772 BIO_printf(bio_err, "no engine specified\n");
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500773 else {
774#ifndef OPENSSL_NO_ENGINE
Matt Caswell0f113f32015-01-22 03:40:55 +0000775 pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data);
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500776 if (pkey == NULL) {
777 BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip);
778 ERR_print_errors(bio_err);
779 }
780#else
781 BIO_printf(bio_err, "engines not supported\n");
782#endif
783 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000784 goto end;
785 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000786 if (file == NULL && maybe_stdin) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400787 unbuffer(stdin);
Richard Levittea60994d2015-09-06 12:20:12 +0200788 key = dup_bio_in(format);
Rich Salz7e1b7482015-04-24 15:26:15 -0400789 } else
Richard Levittebdd58d92015-09-04 12:49:06 +0200790 key = bio_open_default(file, 'r', format);
Rich Salz7e1b7482015-04-24 15:26:15 -0400791 if (key == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000792 goto end;
Matt Caswell0f113f32015-01-22 03:40:55 +0000793 if (format == FORMAT_ASN1) {
794 pkey = d2i_PUBKEY_bio(key, NULL);
795 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000796 else if (format == FORMAT_ASN1RSA) {
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500797#ifndef OPENSSL_NO_RSA
Matt Caswell0f113f32015-01-22 03:40:55 +0000798 RSA *rsa;
799 rsa = d2i_RSAPublicKey_bio(key, NULL);
800 if (rsa) {
801 pkey = EVP_PKEY_new();
Matt Caswell96487cd2015-10-30 11:18:04 +0000802 if (pkey != NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000803 EVP_PKEY_set1_RSA(pkey, rsa);
804 RSA_free(rsa);
805 } else
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500806#else
807 BIO_printf(bio_err, "RSA keys not supported\n");
808#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000809 pkey = NULL;
810 } else if (format == FORMAT_PEMRSA) {
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500811#ifndef OPENSSL_NO_RSA
Matt Caswell0f113f32015-01-22 03:40:55 +0000812 RSA *rsa;
813 rsa = PEM_read_bio_RSAPublicKey(key, NULL,
814 (pem_password_cb *)password_callback,
815 &cb_data);
Matt Caswell96487cd2015-10-30 11:18:04 +0000816 if (rsa != NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +0000817 pkey = EVP_PKEY_new();
Matt Caswell96487cd2015-10-30 11:18:04 +0000818 if (pkey != NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000819 EVP_PKEY_set1_RSA(pkey, rsa);
820 RSA_free(rsa);
821 } else
Viktor Dukhovni0c208022016-02-02 00:37:41 -0500822#else
823 BIO_printf(bio_err, "RSA keys not supported\n");
824#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000825 pkey = NULL;
826 }
Matt Caswell0f113f32015-01-22 03:40:55 +0000827 else if (format == FORMAT_PEM) {
828 pkey = PEM_read_bio_PUBKEY(key, NULL,
829 (pem_password_cb *)password_callback,
830 &cb_data);
831 }
Dr. Stephen Hensond4f03392009-04-26 22:18:22 +0000832#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
Matt Caswell0f113f32015-01-22 03:40:55 +0000833 else if (format == FORMAT_MSBLOB)
834 pkey = b2i_PublicKey_bio(key);
Dr. Stephen Hensond4f03392009-04-26 22:18:22 +0000835#endif
Dr. Stephen Hensonbd08a2b2000-09-03 23:13:48 +0000836 end:
Rich Salz25aaa982015-05-01 14:37:16 -0400837 BIO_free(key);
Matt Caswell0f113f32015-01-22 03:40:55 +0000838 if (pkey == NULL)
Rich Salz7e1b7482015-04-24 15:26:15 -0400839 BIO_printf(bio_err, "unable to load %s\n", key_descrip);
Matt Caswell0f113f32015-01-22 03:40:55 +0000840 return (pkey);
841}
Dr. Stephen Hensonbd08a2b2000-09-03 23:13:48 +0000842
Rich Salz7e1b7482015-04-24 15:26:15 -0400843static int load_certs_crls(const char *file, int format,
Rich Salza773b522016-02-13 22:33:56 -0500844 const char *pass, const char *desc,
Matt Caswell0f113f32015-01-22 03:40:55 +0000845 STACK_OF(X509) **pcerts,
846 STACK_OF(X509_CRL) **pcrls)
847{
848 int i;
849 BIO *bio;
850 STACK_OF(X509_INFO) *xis = NULL;
851 X509_INFO *xi;
852 PW_CB_DATA cb_data;
853 int rv = 0;
Richard Levitte30b4c272001-05-30 15:29:28 +0000854
Matt Caswell0f113f32015-01-22 03:40:55 +0000855 cb_data.password = pass;
856 cb_data.prompt_info = file;
Richard Levitte90ae4672000-06-22 17:42:50 +0000857
Matt Caswell0f113f32015-01-22 03:40:55 +0000858 if (format != FORMAT_PEM) {
Rich Salz7e1b7482015-04-24 15:26:15 -0400859 BIO_printf(bio_err, "bad input format specified for %s\n", desc);
Matt Caswell0f113f32015-01-22 03:40:55 +0000860 return 0;
861 }
Richard Levitte90ae4672000-06-22 17:42:50 +0000862
Richard Levittebdd58d92015-09-04 12:49:06 +0200863 bio = bio_open_default(file, 'r', FORMAT_PEM);
Rich Salz7e1b7482015-04-24 15:26:15 -0400864 if (bio == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +0000865 return 0;
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000866
Matt Caswell0f113f32015-01-22 03:40:55 +0000867 xis = PEM_X509_INFO_read_bio(bio, NULL,
868 (pem_password_cb *)password_callback,
869 &cb_data);
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000870
Matt Caswell0f113f32015-01-22 03:40:55 +0000871 BIO_free(bio);
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000872
Viktor Dukhovni0996dc52016-01-16 00:08:38 -0500873 if (pcerts && *pcerts == NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +0000874 *pcerts = sk_X509_new_null();
875 if (!*pcerts)
876 goto end;
877 }
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000878
Viktor Dukhovni0996dc52016-01-16 00:08:38 -0500879 if (pcrls && *pcrls == NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +0000880 *pcrls = sk_X509_CRL_new_null();
881 if (!*pcrls)
882 goto end;
883 }
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000884
Matt Caswell0f113f32015-01-22 03:40:55 +0000885 for (i = 0; i < sk_X509_INFO_num(xis); i++) {
886 xi = sk_X509_INFO_value(xis, i);
887 if (xi->x509 && pcerts) {
888 if (!sk_X509_push(*pcerts, xi->x509))
889 goto end;
890 xi->x509 = NULL;
891 }
892 if (xi->crl && pcrls) {
893 if (!sk_X509_CRL_push(*pcrls, xi->crl))
894 goto end;
895 xi->crl = NULL;
896 }
897 }
Richard Levitte90ae4672000-06-22 17:42:50 +0000898
Matt Caswell0f113f32015-01-22 03:40:55 +0000899 if (pcerts && sk_X509_num(*pcerts) > 0)
900 rv = 1;
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000901
Matt Caswell0f113f32015-01-22 03:40:55 +0000902 if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
903 rv = 1;
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000904
Matt Caswell0f113f32015-01-22 03:40:55 +0000905 end:
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000906
Rich Salz222561f2015-04-30 17:33:59 -0400907 sk_X509_INFO_pop_free(xis, X509_INFO_free);
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000908
Matt Caswell0f113f32015-01-22 03:40:55 +0000909 if (rv == 0) {
910 if (pcerts) {
911 sk_X509_pop_free(*pcerts, X509_free);
912 *pcerts = NULL;
913 }
914 if (pcrls) {
915 sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
916 *pcrls = NULL;
917 }
Rich Salz7e1b7482015-04-24 15:26:15 -0400918 BIO_printf(bio_err, "unable to load %s\n",
Matt Caswell0f113f32015-01-22 03:40:55 +0000919 pcerts ? "certificates" : "CRLs");
Rich Salz7e1b7482015-04-24 15:26:15 -0400920 ERR_print_errors(bio_err);
Matt Caswell0f113f32015-01-22 03:40:55 +0000921 }
922 return rv;
923}
Richard Levitte90ae4672000-06-22 17:42:50 +0000924
Rich Salz68dc6822015-04-30 17:48:31 -0400925void* app_malloc(int sz, const char *what)
926{
927 void *vp = OPENSSL_malloc(sz);
928
929 if (vp == NULL) {
930 BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n",
931 opt_getprog(), sz, what);
932 ERR_print_errors(bio_err);
933 exit(1);
934 }
935 return vp;
936}
937
Viktor Dukhovni0996dc52016-01-16 00:08:38 -0500938/*
FdaSilvaYY6b4a77f2016-06-28 22:51:51 +0200939 * Initialize or extend, if *certs != NULL, a certificate stack.
Viktor Dukhovni0996dc52016-01-16 00:08:38 -0500940 */
941int load_certs(const char *file, STACK_OF(X509) **certs, int format,
Rich Salza773b522016-02-13 22:33:56 -0500942 const char *pass, const char *desc)
Matt Caswell0f113f32015-01-22 03:40:55 +0000943{
Rich Salza773b522016-02-13 22:33:56 -0500944 return load_certs_crls(file, format, pass, desc, certs, NULL);
Matt Caswell0f113f32015-01-22 03:40:55 +0000945}
Dr. Stephen Henson245d2ee2009-10-31 13:33:57 +0000946
Viktor Dukhovni0996dc52016-01-16 00:08:38 -0500947/*
FdaSilvaYY6b4a77f2016-06-28 22:51:51 +0200948 * Initialize or extend, if *crls != NULL, a certificate stack.
Viktor Dukhovni0996dc52016-01-16 00:08:38 -0500949 */
950int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format,
Rich Salza773b522016-02-13 22:33:56 -0500951 const char *pass, const char *desc)
Matt Caswell0f113f32015-01-22 03:40:55 +0000952{
Rich Salza773b522016-02-13 22:33:56 -0500953 return load_certs_crls(file, format, pass, desc, NULL, crls);
Matt Caswell0f113f32015-01-22 03:40:55 +0000954}
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000955
Matt Caswell0f113f32015-01-22 03:40:55 +0000956#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000957/* Return error for unknown extensions */
Matt Caswell0f113f32015-01-22 03:40:55 +0000958#define X509V3_EXT_DEFAULT 0
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000959/* Print error for unknown extensions */
Matt Caswell0f113f32015-01-22 03:40:55 +0000960#define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000961/* ASN1 parse unknown extensions */
Matt Caswell0f113f32015-01-22 03:40:55 +0000962#define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000963/* BIO_dump unknown extensions */
Matt Caswell0f113f32015-01-22 03:40:55 +0000964#define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000965
Dr. Stephen Henson535d79d2001-03-15 19:13:40 +0000966#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
Matt Caswell0f113f32015-01-22 03:40:55 +0000967 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
Dr. Stephen Henson535d79d2001-03-15 19:13:40 +0000968
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000969int set_cert_ex(unsigned long *flags, const char *arg)
970{
Matt Caswell0f113f32015-01-22 03:40:55 +0000971 static const NAME_EX_TBL cert_tbl[] = {
972 {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
973 {"ca_default", X509_FLAG_CA, 0xffffffffl},
974 {"no_header", X509_FLAG_NO_HEADER, 0},
975 {"no_version", X509_FLAG_NO_VERSION, 0},
976 {"no_serial", X509_FLAG_NO_SERIAL, 0},
977 {"no_signame", X509_FLAG_NO_SIGNAME, 0},
978 {"no_validity", X509_FLAG_NO_VALIDITY, 0},
979 {"no_subject", X509_FLAG_NO_SUBJECT, 0},
980 {"no_issuer", X509_FLAG_NO_ISSUER, 0},
981 {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
982 {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
983 {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
984 {"no_aux", X509_FLAG_NO_AUX, 0},
985 {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
986 {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
987 {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
988 {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
989 {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
990 {NULL, 0, 0}
991 };
992 return set_multi_opts(flags, arg, cert_tbl);
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +0000993}
Dr. Stephen Hensona6575462000-07-28 01:58:15 +0000994
995int set_name_ex(unsigned long *flags, const char *arg)
996{
Matt Caswell0f113f32015-01-22 03:40:55 +0000997 static const NAME_EX_TBL ex_tbl[] = {
998 {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
Richard Levittebc776512016-05-18 17:14:19 +0200999 {"esc_2254", ASN1_STRFLGS_ESC_2254, 0},
Matt Caswell0f113f32015-01-22 03:40:55 +00001000 {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
1001 {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
1002 {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
1003 {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
1004 {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
1005 {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
1006 {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
1007 {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
1008 {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
1009 {"compat", XN_FLAG_COMPAT, 0xffffffffL},
1010 {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
1011 {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
1012 {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
1013 {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
1014 {"dn_rev", XN_FLAG_DN_REV, 0},
1015 {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
1016 {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
1017 {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
1018 {"align", XN_FLAG_FN_ALIGN, 0},
1019 {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
1020 {"space_eq", XN_FLAG_SPC_EQ, 0},
1021 {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
1022 {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
1023 {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
1024 {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
1025 {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
1026 {NULL, 0, 0}
1027 };
Dr. Stephen Henson03706af2015-09-11 16:13:52 +01001028 if (set_multi_opts(flags, arg, ex_tbl) == 0)
1029 return 0;
1030 if ((*flags & XN_FLAG_SEP_MASK) == 0)
1031 *flags |= XN_FLAG_SEP_CPLUS_SPC;
1032 return 1;
Dr. Stephen Henson535d79d2001-03-15 19:13:40 +00001033}
1034
Dr. Stephen Henson791bd0c2001-03-16 02:04:17 +00001035int set_ext_copy(int *copy_type, const char *arg)
1036{
Rich Salz86885c22015-05-06 14:56:14 -04001037 if (strcasecmp(arg, "none") == 0)
Matt Caswell0f113f32015-01-22 03:40:55 +00001038 *copy_type = EXT_COPY_NONE;
Rich Salz86885c22015-05-06 14:56:14 -04001039 else if (strcasecmp(arg, "copy") == 0)
Matt Caswell0f113f32015-01-22 03:40:55 +00001040 *copy_type = EXT_COPY_ADD;
Rich Salz86885c22015-05-06 14:56:14 -04001041 else if (strcasecmp(arg, "copyall") == 0)
Matt Caswell0f113f32015-01-22 03:40:55 +00001042 *copy_type = EXT_COPY_ALL;
1043 else
1044 return 0;
1045 return 1;
Dr. Stephen Henson791bd0c2001-03-16 02:04:17 +00001046}
1047
1048int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1049{
Matt Caswell0f113f32015-01-22 03:40:55 +00001050 STACK_OF(X509_EXTENSION) *exts = NULL;
1051 X509_EXTENSION *ext, *tmpext;
1052 ASN1_OBJECT *obj;
1053 int i, idx, ret = 0;
1054 if (!x || !req || (copy_type == EXT_COPY_NONE))
1055 return 1;
1056 exts = X509_REQ_get_extensions(req);
Dr. Stephen Henson791bd0c2001-03-16 02:04:17 +00001057
Matt Caswell0f113f32015-01-22 03:40:55 +00001058 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1059 ext = sk_X509_EXTENSION_value(exts, i);
1060 obj = X509_EXTENSION_get_object(ext);
1061 idx = X509_get_ext_by_OBJ(x, obj, -1);
1062 /* Does extension exist? */
1063 if (idx != -1) {
1064 /* If normal copy don't override existing extension */
1065 if (copy_type == EXT_COPY_ADD)
1066 continue;
1067 /* Delete all extensions of same type */
1068 do {
1069 tmpext = X509_get_ext(x, idx);
1070 X509_delete_ext(x, idx);
1071 X509_EXTENSION_free(tmpext);
1072 idx = X509_get_ext_by_OBJ(x, obj, -1);
1073 } while (idx != -1);
1074 }
1075 if (!X509_add_ext(x, ext, -1))
1076 goto end;
1077 }
Dr. Stephen Henson791bd0c2001-03-16 02:04:17 +00001078
Matt Caswell0f113f32015-01-22 03:40:55 +00001079 ret = 1;
Dr. Stephen Henson791bd0c2001-03-16 02:04:17 +00001080
Matt Caswell0f113f32015-01-22 03:40:55 +00001081 end:
Dr. Stephen Henson791bd0c2001-03-16 02:04:17 +00001082
Matt Caswell0f113f32015-01-22 03:40:55 +00001083 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
Dr. Stephen Henson791bd0c2001-03-16 02:04:17 +00001084
Matt Caswell0f113f32015-01-22 03:40:55 +00001085 return ret;
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +00001086}
Dr. Stephen Hensona6575462000-07-28 01:58:15 +00001087
Matt Caswell0f113f32015-01-22 03:40:55 +00001088static int set_multi_opts(unsigned long *flags, const char *arg,
1089 const NAME_EX_TBL * in_tbl)
Dr. Stephen Henson8ca533e2000-10-06 11:51:47 +00001090{
Matt Caswell0f113f32015-01-22 03:40:55 +00001091 STACK_OF(CONF_VALUE) *vals;
1092 CONF_VALUE *val;
1093 int i, ret = 1;
1094 if (!arg)
1095 return 0;
1096 vals = X509V3_parse_list(arg);
1097 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1098 val = sk_CONF_VALUE_value(vals, i);
1099 if (!set_table_opts(flags, val->name, in_tbl))
1100 ret = 0;
1101 }
1102 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1103 return ret;
Dr. Stephen Hensona6575462000-07-28 01:58:15 +00001104}
1105
Matt Caswell0f113f32015-01-22 03:40:55 +00001106static int set_table_opts(unsigned long *flags, const char *arg,
1107 const NAME_EX_TBL * in_tbl)
Dr. Stephen Hensona6575462000-07-28 01:58:15 +00001108{
Matt Caswell0f113f32015-01-22 03:40:55 +00001109 char c;
1110 const NAME_EX_TBL *ptbl;
1111 c = arg[0];
Ben Laurie54a656e2002-11-13 15:43:43 +00001112
Matt Caswell0f113f32015-01-22 03:40:55 +00001113 if (c == '-') {
1114 c = 0;
1115 arg++;
1116 } else if (c == '+') {
1117 c = 1;
1118 arg++;
1119 } else
1120 c = 1;
1121
1122 for (ptbl = in_tbl; ptbl->name; ptbl++) {
Rich Salz86885c22015-05-06 14:56:14 -04001123 if (strcasecmp(arg, ptbl->name) == 0) {
Matt Caswell0f113f32015-01-22 03:40:55 +00001124 *flags &= ~ptbl->mask;
1125 if (c)
1126 *flags |= ptbl->flag;
1127 else
1128 *flags &= ~ptbl->flag;
1129 return 1;
1130 }
1131 }
1132 return 0;
1133}
1134
1135void print_name(BIO *out, const char *title, X509_NAME *nm,
1136 unsigned long lflags)
1137{
1138 char *buf;
1139 char mline = 0;
1140 int indent = 0;
1141
1142 if (title)
1143 BIO_puts(out, title);
1144 if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1145 mline = 1;
1146 indent = 4;
1147 }
1148 if (lflags == XN_FLAG_COMPAT) {
1149 buf = X509_NAME_oneline(nm, 0, 0);
1150 BIO_puts(out, buf);
1151 BIO_puts(out, "\n");
1152 OPENSSL_free(buf);
1153 } else {
1154 if (mline)
1155 BIO_puts(out, "\n");
1156 X509_NAME_print_ex(out, nm, indent, lflags);
1157 BIO_puts(out, "\n");
1158 }
Dr. Stephen Hensona6575462000-07-28 01:58:15 +00001159}
1160
Richard Levitte2ac61152016-06-14 15:49:05 +02001161void print_bignum_var(BIO *out, const BIGNUM *in, const char *var,
Rich Salz7e1b7482015-04-24 15:26:15 -04001162 int len, unsigned char *buffer)
Dr. Stephen Henson81f169e2001-01-17 01:31:34 +00001163{
Rich Salz7e1b7482015-04-24 15:26:15 -04001164 BIO_printf(out, " static unsigned char %s_%d[] = {", var, len);
1165 if (BN_is_zero(in))
1166 BIO_printf(out, "\n\t0x00");
1167 else {
1168 int i, l;
1169
1170 l = BN_bn2bin(in, buffer);
1171 for (i = 0; i < l; i++) {
1172 if ((i % 10) == 0)
1173 BIO_printf(out, "\n\t");
1174 if (i < l - 1)
1175 BIO_printf(out, "0x%02X, ", buffer[i]);
1176 else
1177 BIO_printf(out, "0x%02X", buffer[i]);
1178 }
1179 }
1180 BIO_printf(out, "\n };\n");
1181}
1182void print_array(BIO *out, const char* title, int len, const unsigned char* d)
1183{
1184 int i;
1185
1186 BIO_printf(out, "unsigned char %s[%d] = {", title, len);
1187 for (i = 0; i < len; i++) {
1188 if ((i % 10) == 0)
1189 BIO_printf(out, "\n ");
1190 if (i < len - 1)
1191 BIO_printf(out, "0x%02X, ", d[i]);
1192 else
1193 BIO_printf(out, "0x%02X", d[i]);
1194 }
1195 BIO_printf(out, "\n};\n");
1196}
1197
FdaSilvaYYcc696292016-08-04 23:52:22 +02001198X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, int noCApath)
Rich Salz7e1b7482015-04-24 15:26:15 -04001199{
1200 X509_STORE *store = X509_STORE_new();
Matt Caswell0f113f32015-01-22 03:40:55 +00001201 X509_LOOKUP *lookup;
Rich Salz7e1b7482015-04-24 15:26:15 -04001202
Matt Caswell96487cd2015-10-30 11:18:04 +00001203 if (store == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +00001204 goto end;
Dr. Stephen Henson81f169e2001-01-17 01:31:34 +00001205
FdaSilvaYYe8aa8b62016-06-29 00:18:50 +02001206 if (CAfile != NULL || !noCAfile) {
Matt Caswell2b6bcb72015-09-22 16:00:52 +01001207 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1208 if (lookup == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +00001209 goto end;
Matt Caswell2b6bcb72015-09-22 16:00:52 +01001210 if (CAfile) {
1211 if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
1212 BIO_printf(bio_err, "Error loading file %s\n", CAfile);
1213 goto end;
1214 }
1215 } else
1216 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
1217 }
1218
FdaSilvaYYe8aa8b62016-06-29 00:18:50 +02001219 if (CApath != NULL || !noCApath) {
Matt Caswell2b6bcb72015-09-22 16:00:52 +01001220 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1221 if (lookup == NULL)
1222 goto end;
1223 if (CApath) {
1224 if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1225 BIO_printf(bio_err, "Error loading directory %s\n", CApath);
1226 goto end;
1227 }
1228 } else
1229 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1230 }
Matt Caswell0f113f32015-01-22 03:40:55 +00001231
1232 ERR_clear_error();
1233 return store;
1234 end:
1235 X509_STORE_free(store);
1236 return NULL;
Dr. Stephen Henson81f169e2001-01-17 01:31:34 +00001237}
Richard Levitte531d6302001-06-18 06:22:33 +00001238
Richard Levitte0b13e9f2003-01-30 17:39:26 +00001239#ifndef OPENSSL_NO_ENGINE
Richard Levittee1a00d72001-11-15 18:48:42 +00001240/* Try to load an engine in a shareable library */
Rich Salza773b522016-02-13 22:33:56 -05001241static ENGINE *try_load_engine(const char *engine)
Matt Caswell0f113f32015-01-22 03:40:55 +00001242{
1243 ENGINE *e = ENGINE_by_id("dynamic");
1244 if (e) {
1245 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
1246 || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
1247 ENGINE_free(e);
1248 e = NULL;
1249 }
1250 }
1251 return e;
1252}
Richard Levitte907c6c82016-10-19 19:49:22 +02001253#endif
Richard Levittee1a00d72001-11-15 18:48:42 +00001254
Rich Salz7e1b7482015-04-24 15:26:15 -04001255ENGINE *setup_engine(const char *engine, int debug)
Matt Caswell0f113f32015-01-22 03:40:55 +00001256{
1257 ENGINE *e = NULL;
Richard Levitte531d6302001-06-18 06:22:33 +00001258
Richard Levitte907c6c82016-10-19 19:49:22 +02001259#ifndef OPENSSL_NO_ENGINE
Matt Caswell0f113f32015-01-22 03:40:55 +00001260 if (engine) {
1261 if (strcmp(engine, "auto") == 0) {
Rich Salz7e1b7482015-04-24 15:26:15 -04001262 BIO_printf(bio_err, "enabling auto ENGINE support\n");
Matt Caswell0f113f32015-01-22 03:40:55 +00001263 ENGINE_register_all_complete();
1264 return NULL;
Richard Levitte531d6302001-06-18 06:22:33 +00001265 }
Matt Caswell0f113f32015-01-22 03:40:55 +00001266 if ((e = ENGINE_by_id(engine)) == NULL
Rich Salza773b522016-02-13 22:33:56 -05001267 && (e = try_load_engine(engine)) == NULL) {
Rich Salz7e1b7482015-04-24 15:26:15 -04001268 BIO_printf(bio_err, "invalid engine \"%s\"\n", engine);
1269 ERR_print_errors(bio_err);
Matt Caswell0f113f32015-01-22 03:40:55 +00001270 return NULL;
1271 }
1272 if (debug) {
Rich Salz7e1b7482015-04-24 15:26:15 -04001273 ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
Matt Caswell0f113f32015-01-22 03:40:55 +00001274 }
1275 ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
Rich Salz56e36bd2016-09-28 14:40:25 -04001276 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
Rich Salz7e1b7482015-04-24 15:26:15 -04001277 BIO_printf(bio_err, "can't use that engine\n");
1278 ERR_print_errors(bio_err);
Matt Caswell0f113f32015-01-22 03:40:55 +00001279 ENGINE_free(e);
1280 return NULL;
1281 }
1282
Rich Salz7e1b7482015-04-24 15:26:15 -04001283 BIO_printf(bio_err, "engine \"%s\" set.\n", ENGINE_get_id(e));
Matt Caswell0f113f32015-01-22 03:40:55 +00001284 }
Richard Levitte907c6c82016-10-19 19:49:22 +02001285#endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001286 return e;
1287}
Dr. Stephen Henson3647bee2002-02-22 14:01:21 +00001288
Richard Levittedd1abd42016-09-28 23:39:18 +02001289void release_engine(ENGINE *e)
1290{
1291#ifndef OPENSSL_NO_ENGINE
1292 if (e != NULL)
1293 /* Free our "structural" reference. */
1294 ENGINE_free(e);
1295#endif
1296}
1297
Dr. Stephen Hensonc869da82009-07-27 21:10:00 +00001298static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
Matt Caswell0f113f32015-01-22 03:40:55 +00001299{
1300 const char *n;
Richard Levittef85b68c2003-04-03 16:33:03 +00001301
Matt Caswell0f113f32015-01-22 03:40:55 +00001302 n = a[DB_serial];
1303 while (*n == '0')
1304 n++;
Rich Salz739a1eb2016-05-20 10:46:29 -04001305 return OPENSSL_LH_strhash(n);
Matt Caswell0f113f32015-01-22 03:40:55 +00001306}
Richard Levittef85b68c2003-04-03 16:33:03 +00001307
Matt Caswell0f113f32015-01-22 03:40:55 +00001308static int index_serial_cmp(const OPENSSL_CSTRING *a,
1309 const OPENSSL_CSTRING *b)
1310{
1311 const char *aa, *bb;
Richard Levittef85b68c2003-04-03 16:33:03 +00001312
Matt Caswell0f113f32015-01-22 03:40:55 +00001313 for (aa = a[DB_serial]; *aa == '0'; aa++) ;
1314 for (bb = b[DB_serial]; *bb == '0'; bb++) ;
1315 return (strcmp(aa, bb));
1316}
Richard Levittef85b68c2003-04-03 16:33:03 +00001317
1318static int index_name_qual(char **a)
Matt Caswell0f113f32015-01-22 03:40:55 +00001319{
1320 return (a[0][0] == 'V');
1321}
Richard Levittef85b68c2003-04-03 16:33:03 +00001322
Dr. Stephen Hensonc869da82009-07-27 21:10:00 +00001323static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
Matt Caswell0f113f32015-01-22 03:40:55 +00001324{
Rich Salz739a1eb2016-05-20 10:46:29 -04001325 return OPENSSL_LH_strhash(a[DB_name]);
Matt Caswell0f113f32015-01-22 03:40:55 +00001326}
Richard Levittef85b68c2003-04-03 16:33:03 +00001327
Dr. Stephen Hensonc869da82009-07-27 21:10:00 +00001328int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
Matt Caswell0f113f32015-01-22 03:40:55 +00001329{
1330 return (strcmp(a[DB_name], b[DB_name]));
1331}
Richard Levittef85b68c2003-04-03 16:33:03 +00001332
Dr. Stephen Hensonc869da82009-07-27 21:10:00 +00001333static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1334static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1335static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1336static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
Richard Levittef85b68c2003-04-03 16:33:03 +00001337#undef BSIZE
1338#define BSIZE 256
FdaSilvaYYcc696292016-08-04 23:52:22 +02001339BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai)
Matt Caswell0f113f32015-01-22 03:40:55 +00001340{
1341 BIO *in = NULL;
1342 BIGNUM *ret = NULL;
Rich Salz68b00c22015-01-23 11:58:26 -05001343 char buf[1024];
Matt Caswell0f113f32015-01-22 03:40:55 +00001344 ASN1_INTEGER *ai = NULL;
Richard Levittef85b68c2003-04-03 16:33:03 +00001345
Matt Caswell0f113f32015-01-22 03:40:55 +00001346 ai = ASN1_INTEGER_new();
1347 if (ai == NULL)
1348 goto err;
Richard Levittef85b68c2003-04-03 16:33:03 +00001349
Rich Salz7e1b7482015-04-24 15:26:15 -04001350 in = BIO_new_file(serialfile, "r");
1351 if (in == NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +00001352 if (!create) {
1353 perror(serialfile);
1354 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001355 }
Rich Salz7e1b7482015-04-24 15:26:15 -04001356 ERR_clear_error();
1357 ret = BN_new();
1358 if (ret == NULL || !rand_serial(ret, ai))
1359 BIO_printf(bio_err, "Out of memory\n");
Matt Caswell0f113f32015-01-22 03:40:55 +00001360 } else {
1361 if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
1362 BIO_printf(bio_err, "unable to load number from %s\n",
1363 serialfile);
1364 goto err;
1365 }
1366 ret = ASN1_INTEGER_to_BN(ai, NULL);
1367 if (ret == NULL) {
1368 BIO_printf(bio_err,
1369 "error converting number from bin to BIGNUM\n");
1370 goto err;
1371 }
1372 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001373
Matt Caswell0f113f32015-01-22 03:40:55 +00001374 if (ret && retai) {
1375 *retai = ai;
1376 ai = NULL;
1377 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001378 err:
Rich Salzca3a82c2015-03-25 11:31:18 -04001379 BIO_free(in);
Rich Salz2ace7452015-04-30 11:30:03 -04001380 ASN1_INTEGER_free(ai);
Matt Caswell0f113f32015-01-22 03:40:55 +00001381 return (ret);
1382}
Richard Levittef85b68c2003-04-03 16:33:03 +00001383
FdaSilvaYYcc696292016-08-04 23:52:22 +02001384int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial,
Matt Caswell0f113f32015-01-22 03:40:55 +00001385 ASN1_INTEGER **retai)
1386{
1387 char buf[1][BSIZE];
1388 BIO *out = NULL;
1389 int ret = 0;
1390 ASN1_INTEGER *ai = NULL;
1391 int j;
Richard Levittef85b68c2003-04-03 16:33:03 +00001392
Matt Caswell0f113f32015-01-22 03:40:55 +00001393 if (suffix == NULL)
1394 j = strlen(serialfile);
1395 else
1396 j = strlen(serialfile) + strlen(suffix) + 1;
1397 if (j >= BSIZE) {
1398 BIO_printf(bio_err, "file name too long\n");
1399 goto err;
1400 }
Richard Levitte4c771792003-04-04 15:10:35 +00001401
Matt Caswell0f113f32015-01-22 03:40:55 +00001402 if (suffix == NULL)
Rich Salz7644a9a2015-12-16 16:12:24 -05001403 OPENSSL_strlcpy(buf[0], serialfile, BSIZE);
Matt Caswell0f113f32015-01-22 03:40:55 +00001404 else {
Richard Levitte4c771792003-04-04 15:10:35 +00001405#ifndef OPENSSL_SYS_VMS
Matt Caswell0f113f32015-01-22 03:40:55 +00001406 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
Richard Levitte4c771792003-04-04 15:10:35 +00001407#else
Matt Caswell0f113f32015-01-22 03:40:55 +00001408 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
Richard Levitte4c771792003-04-04 15:10:35 +00001409#endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001410 }
Rich Salz7e1b7482015-04-24 15:26:15 -04001411 out = BIO_new_file(buf[0], "w");
Matt Caswell0f113f32015-01-22 03:40:55 +00001412 if (out == NULL) {
1413 ERR_print_errors(bio_err);
1414 goto err;
1415 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001416
Matt Caswell0f113f32015-01-22 03:40:55 +00001417 if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1418 BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
1419 goto err;
1420 }
1421 i2a_ASN1_INTEGER(out, ai);
1422 BIO_puts(out, "\n");
1423 ret = 1;
1424 if (retai) {
1425 *retai = ai;
1426 ai = NULL;
1427 }
1428 err:
Rich Salzca3a82c2015-03-25 11:31:18 -04001429 BIO_free_all(out);
Rich Salz2ace7452015-04-30 11:30:03 -04001430 ASN1_INTEGER_free(ai);
Matt Caswell0f113f32015-01-22 03:40:55 +00001431 return (ret);
1432}
Richard Levittef85b68c2003-04-03 16:33:03 +00001433
FdaSilvaYYcc696292016-08-04 23:52:22 +02001434int rotate_serial(const char *serialfile, const char *new_suffix,
1435 const char *old_suffix)
Matt Caswell0f113f32015-01-22 03:40:55 +00001436{
FdaSilvaYYbde136c2016-03-18 19:02:17 +01001437 char buf[2][BSIZE];
Matt Caswell0f113f32015-01-22 03:40:55 +00001438 int i, j;
Richard Levitte4c771792003-04-04 15:10:35 +00001439
Matt Caswell0f113f32015-01-22 03:40:55 +00001440 i = strlen(serialfile) + strlen(old_suffix);
1441 j = strlen(serialfile) + strlen(new_suffix);
1442 if (i > j)
1443 j = i;
1444 if (j + 1 >= BSIZE) {
1445 BIO_printf(bio_err, "file name too long\n");
1446 goto err;
1447 }
Richard Levitte4c771792003-04-04 15:10:35 +00001448#ifndef OPENSSL_SYS_VMS
Matt Caswell0f113f32015-01-22 03:40:55 +00001449 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix);
Matt Caswell0f113f32015-01-22 03:40:55 +00001450 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix);
Richard Levitte4c771792003-04-04 15:10:35 +00001451#else
Rich Salzd63a5e52016-02-18 11:33:21 -05001452 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, new_suffix);
Matt Caswell0f113f32015-01-22 03:40:55 +00001453 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix);
Richard Levitte4c771792003-04-04 15:10:35 +00001454#endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001455 if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
Richard Levitte4c771792003-04-04 15:10:35 +00001456#ifdef ENOTDIR
Matt Caswell0f113f32015-01-22 03:40:55 +00001457 && errno != ENOTDIR
Richard Levitte4c771792003-04-04 15:10:35 +00001458#endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001459 ) {
1460 BIO_printf(bio_err,
1461 "unable to rename %s to %s\n", serialfile, buf[1]);
1462 perror("reason");
1463 goto err;
1464 }
Matt Caswell0f113f32015-01-22 03:40:55 +00001465 if (rename(buf[0], serialfile) < 0) {
1466 BIO_printf(bio_err,
1467 "unable to rename %s to %s\n", buf[0], serialfile);
1468 perror("reason");
1469 rename(buf[1], serialfile);
1470 goto err;
1471 }
1472 return 1;
Richard Levitte4c771792003-04-04 15:10:35 +00001473 err:
Matt Caswell0f113f32015-01-22 03:40:55 +00001474 return 0;
1475}
Richard Levitte4c771792003-04-04 15:10:35 +00001476
Dr. Stephen Henson64674bc2004-04-20 12:05:26 +00001477int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
Matt Caswell0f113f32015-01-22 03:40:55 +00001478{
1479 BIGNUM *btmp;
1480 int ret = 0;
Rich Salz23a1d5e2015-04-30 21:37:06 -04001481
Matt Caswell0f113f32015-01-22 03:40:55 +00001482 if (b)
1483 btmp = b;
1484 else
1485 btmp = BN_new();
Dr. Stephen Henson64674bc2004-04-20 12:05:26 +00001486
Matt Caswell96487cd2015-10-30 11:18:04 +00001487 if (btmp == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +00001488 return 0;
Dr. Stephen Henson64674bc2004-04-20 12:05:26 +00001489
Matt Caswell0f113f32015-01-22 03:40:55 +00001490 if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1491 goto error;
1492 if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1493 goto error;
Dr. Stephen Henson64674bc2004-04-20 12:05:26 +00001494
Matt Caswell0f113f32015-01-22 03:40:55 +00001495 ret = 1;
Dr. Stephen Henson64674bc2004-04-20 12:05:26 +00001496
Matt Caswell0f113f32015-01-22 03:40:55 +00001497 error:
1498
Rich Salz23a1d5e2015-04-30 21:37:06 -04001499 if (btmp != b)
Matt Caswell0f113f32015-01-22 03:40:55 +00001500 BN_free(btmp);
1501
1502 return ret;
1503}
Dr. Stephen Henson64674bc2004-04-20 12:05:26 +00001504
FdaSilvaYYcc696292016-08-04 23:52:22 +02001505CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
Matt Caswell0f113f32015-01-22 03:40:55 +00001506{
1507 CA_DB *retdb = NULL;
1508 TXT_DB *tmpdb = NULL;
Rich Salz7e1b7482015-04-24 15:26:15 -04001509 BIO *in;
Matt Caswell0f113f32015-01-22 03:40:55 +00001510 CONF *dbattr_conf = NULL;
Rich Salzcc01d212015-05-28 13:52:55 -04001511 char buf[BSIZE];
Richard Levittef85b68c2003-04-03 16:33:03 +00001512
Rich Salz7e1b7482015-04-24 15:26:15 -04001513 in = BIO_new_file(dbfile, "r");
Matt Caswell0f113f32015-01-22 03:40:55 +00001514 if (in == NULL) {
1515 ERR_print_errors(bio_err);
1516 goto err;
1517 }
Matt Caswell0f113f32015-01-22 03:40:55 +00001518 if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1519 goto err;
Richard Levittef85b68c2003-04-03 16:33:03 +00001520
1521#ifndef OPENSSL_SYS_VMS
Rich Salzcc01d212015-05-28 13:52:55 -04001522 BIO_snprintf(buf, sizeof buf, "%s.attr", dbfile);
Richard Levittef85b68c2003-04-03 16:33:03 +00001523#else
Rich Salzcc01d212015-05-28 13:52:55 -04001524 BIO_snprintf(buf, sizeof buf, "%s-attr", dbfile);
Richard Levittef85b68c2003-04-03 16:33:03 +00001525#endif
Rich Salzcc01d212015-05-28 13:52:55 -04001526 dbattr_conf = app_load_config(buf);
Richard Levittef85b68c2003-04-03 16:33:03 +00001527
Rich Salzb4faea52015-05-01 23:10:31 -04001528 retdb = app_malloc(sizeof(*retdb), "new DB");
Matt Caswell0f113f32015-01-22 03:40:55 +00001529 retdb->db = tmpdb;
1530 tmpdb = NULL;
1531 if (db_attr)
1532 retdb->attributes = *db_attr;
1533 else {
1534 retdb->attributes.unique_subject = 1;
1535 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001536
Matt Caswell0f113f32015-01-22 03:40:55 +00001537 if (dbattr_conf) {
1538 char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1539 if (p) {
Matt Caswell0f113f32015-01-22 03:40:55 +00001540 retdb->attributes.unique_subject = parse_yesno(p, 1);
1541 }
1542 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001543
1544 err:
Rich Salzefa7dd62015-05-01 10:15:18 -04001545 NCONF_free(dbattr_conf);
Rich Salz895cba12015-04-30 18:10:52 -04001546 TXT_DB_free(tmpdb);
Rich Salzca3a82c2015-03-25 11:31:18 -04001547 BIO_free_all(in);
Matt Caswell0f113f32015-01-22 03:40:55 +00001548 return retdb;
1549}
Richard Levittef85b68c2003-04-03 16:33:03 +00001550
1551int index_index(CA_DB *db)
Matt Caswell0f113f32015-01-22 03:40:55 +00001552{
1553 if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1554 LHASH_HASH_FN(index_serial),
1555 LHASH_COMP_FN(index_serial))) {
1556 BIO_printf(bio_err,
1557 "error creating serial number index:(%ld,%ld,%ld)\n",
1558 db->db->error, db->db->arg1, db->db->arg2);
1559 return 0;
1560 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001561
Matt Caswell0f113f32015-01-22 03:40:55 +00001562 if (db->attributes.unique_subject
1563 && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1564 LHASH_HASH_FN(index_name),
1565 LHASH_COMP_FN(index_name))) {
1566 BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
1567 db->db->error, db->db->arg1, db->db->arg2);
1568 return 0;
1569 }
1570 return 1;
1571}
Richard Levittef85b68c2003-04-03 16:33:03 +00001572
Nils Larsch7d727232005-04-05 19:11:19 +00001573int save_index(const char *dbfile, const char *suffix, CA_DB *db)
Matt Caswell0f113f32015-01-22 03:40:55 +00001574{
1575 char buf[3][BSIZE];
Rich Salz7e1b7482015-04-24 15:26:15 -04001576 BIO *out;
Matt Caswell0f113f32015-01-22 03:40:55 +00001577 int j;
Richard Levittef85b68c2003-04-03 16:33:03 +00001578
Matt Caswell0f113f32015-01-22 03:40:55 +00001579 j = strlen(dbfile) + strlen(suffix);
1580 if (j + 6 >= BSIZE) {
1581 BIO_printf(bio_err, "file name too long\n");
1582 goto err;
1583 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001584#ifndef OPENSSL_SYS_VMS
Matt Caswell0f113f32015-01-22 03:40:55 +00001585 j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
Matt Caswell0f113f32015-01-22 03:40:55 +00001586 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
Matt Caswell0f113f32015-01-22 03:40:55 +00001587 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
Richard Levittef85b68c2003-04-03 16:33:03 +00001588#else
Rich Salzd63a5e52016-02-18 11:33:21 -05001589 j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
1590 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
Matt Caswell0f113f32015-01-22 03:40:55 +00001591 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
Richard Levittef85b68c2003-04-03 16:33:03 +00001592#endif
Rich Salz7e1b7482015-04-24 15:26:15 -04001593 out = BIO_new_file(buf[0], "w");
1594 if (out == NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +00001595 perror(dbfile);
1596 BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1597 goto err;
1598 }
1599 j = TXT_DB_write(out, db->db);
Rich Salz7e1b7482015-04-24 15:26:15 -04001600 BIO_free(out);
Matt Caswell0f113f32015-01-22 03:40:55 +00001601 if (j <= 0)
1602 goto err;
Richard Levittef85b68c2003-04-03 16:33:03 +00001603
Rich Salz7e1b7482015-04-24 15:26:15 -04001604 out = BIO_new_file(buf[1], "w");
Rich Salz7e1b7482015-04-24 15:26:15 -04001605 if (out == NULL) {
Matt Caswell0f113f32015-01-22 03:40:55 +00001606 perror(buf[2]);
1607 BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
1608 goto err;
1609 }
1610 BIO_printf(out, "unique_subject = %s\n",
1611 db->attributes.unique_subject ? "yes" : "no");
1612 BIO_free(out);
Richard Levittef85b68c2003-04-03 16:33:03 +00001613
Matt Caswell0f113f32015-01-22 03:40:55 +00001614 return 1;
Richard Levittef85b68c2003-04-03 16:33:03 +00001615 err:
Matt Caswell0f113f32015-01-22 03:40:55 +00001616 return 0;
1617}
Richard Levittef85b68c2003-04-03 16:33:03 +00001618
Matt Caswell0f113f32015-01-22 03:40:55 +00001619int rotate_index(const char *dbfile, const char *new_suffix,
1620 const char *old_suffix)
1621{
1622 char buf[5][BSIZE];
1623 int i, j;
Richard Levittef85b68c2003-04-03 16:33:03 +00001624
Matt Caswell0f113f32015-01-22 03:40:55 +00001625 i = strlen(dbfile) + strlen(old_suffix);
1626 j = strlen(dbfile) + strlen(new_suffix);
1627 if (i > j)
1628 j = i;
1629 if (j + 6 >= BSIZE) {
1630 BIO_printf(bio_err, "file name too long\n");
1631 goto err;
1632 }
Richard Levittef85b68c2003-04-03 16:33:03 +00001633#ifndef OPENSSL_SYS_VMS
Matt Caswell0f113f32015-01-22 03:40:55 +00001634 j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
Rich Salzd63a5e52016-02-18 11:33:21 -05001635 j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix);
Matt Caswell0f113f32015-01-22 03:40:55 +00001636 j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix);
Rich Salzd63a5e52016-02-18 11:33:21 -05001637 j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix);
Matt Caswell0f113f32015-01-22 03:40:55 +00001638 j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix);
Richard Levittef85b68c2003-04-03 16:33:03 +00001639#else
Rich Salzd63a5e52016-02-18 11:33:21 -05001640 j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
Matt Caswell0f113f32015-01-22 03:40:55 +00001641 j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix);
Rich Salzd63a5e52016-02-18 11:33:21 -05001642 j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", dbfile, new_suffix);
1643 j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", dbfile, old_suffix);
1644 j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, new_suffix);
Richard Levitte63b6fe22003-04-03 18:07:39 +00001645#endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001646 if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
Andy Polyakova1ad2532005-11-04 16:12:05 +00001647#ifdef ENOTDIR
Matt Caswell0f113f32015-01-22 03:40:55 +00001648 && errno != ENOTDIR
Andy Polyakova1ad2532005-11-04 16:12:05 +00001649#endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001650 ) {
1651 BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]);
1652 perror("reason");
1653 goto err;
1654 }
Matt Caswell0f113f32015-01-22 03:40:55 +00001655 if (rename(buf[0], dbfile) < 0) {
1656 BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile);
1657 perror("reason");
1658 rename(buf[1], dbfile);
1659 goto err;
1660 }
Matt Caswell0f113f32015-01-22 03:40:55 +00001661 if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
Andy Polyakova1ad2532005-11-04 16:12:05 +00001662#ifdef ENOTDIR
Matt Caswell0f113f32015-01-22 03:40:55 +00001663 && errno != ENOTDIR
Andy Polyakova1ad2532005-11-04 16:12:05 +00001664#endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001665 ) {
1666 BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]);
1667 perror("reason");
1668 rename(dbfile, buf[0]);
1669 rename(buf[1], dbfile);
1670 goto err;
1671 }
Matt Caswell0f113f32015-01-22 03:40:55 +00001672 if (rename(buf[2], buf[4]) < 0) {
1673 BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]);
1674 perror("reason");
1675 rename(buf[3], buf[4]);
1676 rename(dbfile, buf[0]);
1677 rename(buf[1], dbfile);
1678 goto err;
1679 }
1680 return 1;
Richard Levittef85b68c2003-04-03 16:33:03 +00001681 err:
Matt Caswell0f113f32015-01-22 03:40:55 +00001682 return 0;
1683}
Richard Levittef85b68c2003-04-03 16:33:03 +00001684
1685void free_index(CA_DB *db)
Matt Caswell0f113f32015-01-22 03:40:55 +00001686{
1687 if (db) {
Rich Salz895cba12015-04-30 18:10:52 -04001688 TXT_DB_free(db->db);
Matt Caswell0f113f32015-01-22 03:40:55 +00001689 OPENSSL_free(db);
1690 }
1691}
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001692
Nils Larschff990442005-04-15 18:29:33 +00001693int parse_yesno(const char *str, int def)
Matt Caswell0f113f32015-01-22 03:40:55 +00001694{
Matt Caswell0f113f32015-01-22 03:40:55 +00001695 if (str) {
1696 switch (*str) {
1697 case 'f': /* false */
1698 case 'F': /* FALSE */
1699 case 'n': /* no */
1700 case 'N': /* NO */
1701 case '0': /* 0 */
Rich Salz1bb2dae2015-04-26 21:28:38 -04001702 return 0;
Matt Caswell0f113f32015-01-22 03:40:55 +00001703 case 't': /* true */
1704 case 'T': /* TRUE */
1705 case 'y': /* yes */
1706 case 'Y': /* YES */
1707 case '1': /* 1 */
Rich Salz1bb2dae2015-04-26 21:28:38 -04001708 return 1;
Matt Caswell0f113f32015-01-22 03:40:55 +00001709 }
1710 }
Rich Salz1bb2dae2015-04-26 21:28:38 -04001711 return def;
Matt Caswell0f113f32015-01-22 03:40:55 +00001712}
Richard Levitte03ddbdd2003-11-28 14:45:09 +00001713
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001714/*
Rich Salzdb4c08f2015-04-29 14:50:00 -04001715 * name is expected to be in the format /type0=value0/type1=value1/type2=...
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001716 * where characters may be escaped by \
1717 */
Rich Salzdb4c08f2015-04-29 14:50:00 -04001718X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
Matt Caswell0f113f32015-01-22 03:40:55 +00001719{
Rich Salzdb4c08f2015-04-29 14:50:00 -04001720 int nextismulti = 0;
1721 char *work;
1722 X509_NAME *n;
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001723
Rich Salzdb4c08f2015-04-29 14:50:00 -04001724 if (*cp++ != '/')
1725 return NULL;
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001726
Rich Salzdb4c08f2015-04-29 14:50:00 -04001727 n = X509_NAME_new();
1728 if (n == NULL)
1729 return NULL;
Matt Caswella3ed4922015-04-30 09:43:11 +01001730 work = OPENSSL_strdup(cp);
Rich Salzdb4c08f2015-04-29 14:50:00 -04001731 if (work == NULL)
1732 goto err;
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001733
Rich Salzdb4c08f2015-04-29 14:50:00 -04001734 while (*cp) {
1735 char *bp = work;
1736 char *typestr = bp;
1737 unsigned char *valstr;
1738 int nid;
1739 int ismulti = nextismulti;
1740 nextismulti = 0;
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001741
Rich Salzdb4c08f2015-04-29 14:50:00 -04001742 /* Collect the type */
1743 while (*cp && *cp != '=')
1744 *bp++ = *cp++;
1745 if (*cp == '\0') {
Matt Caswell0f113f32015-01-22 03:40:55 +00001746 BIO_printf(bio_err,
Rich Salzdb4c08f2015-04-29 14:50:00 -04001747 "%s: Hit end of string before finding the equals.\n",
1748 opt_getprog());
1749 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001750 }
1751 *bp++ = '\0';
Rich Salzdb4c08f2015-04-29 14:50:00 -04001752 ++cp;
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001753
Rich Salzdb4c08f2015-04-29 14:50:00 -04001754 /* Collect the value. */
1755 valstr = (unsigned char *)bp;
1756 for (; *cp && *cp != '/'; *bp++ = *cp++) {
1757 if (canmulti && *cp == '+') {
1758 nextismulti = 1;
1759 break;
1760 }
1761 if (*cp == '\\' && *++cp == '\0') {
1762 BIO_printf(bio_err,
1763 "%s: escape character at end of string\n",
1764 opt_getprog());
1765 goto err;
1766 }
1767 }
1768 *bp++ = '\0';
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001769
Rich Salzdb4c08f2015-04-29 14:50:00 -04001770 /* If not at EOS (must be + or /), move forward. */
1771 if (*cp)
1772 ++cp;
1773
1774 /* Parse */
1775 nid = OBJ_txt2nid(typestr);
1776 if (nid == NID_undef) {
1777 BIO_printf(bio_err, "%s: Skipping unknown attribute \"%s\"\n",
1778 opt_getprog(), typestr);
Matt Caswell0f113f32015-01-22 03:40:55 +00001779 continue;
1780 }
Rich Salzdb4c08f2015-04-29 14:50:00 -04001781 if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1782 valstr, strlen((char *)valstr),
1783 -1, ismulti ? -1 : 0))
1784 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001785 }
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001786
Matt Caswella3ed4922015-04-30 09:43:11 +01001787 OPENSSL_free(work);
Matt Caswell0f113f32015-01-22 03:40:55 +00001788 return n;
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001789
Rich Salzdb4c08f2015-04-29 14:50:00 -04001790 err:
Matt Caswell0f113f32015-01-22 03:40:55 +00001791 X509_NAME_free(n);
Matt Caswella3ed4922015-04-30 09:43:11 +01001792 OPENSSL_free(work);
Matt Caswell0f113f32015-01-22 03:40:55 +00001793 return NULL;
Richard Levitte6d5ffb52003-11-28 14:07:14 +00001794}
1795
Matt Caswell0f113f32015-01-22 03:40:55 +00001796/*
1797 * Read whole contents of a BIO into an allocated memory buffer and return
1798 * it.
Dr. Stephen Hensona9164152006-04-08 22:25:47 +00001799 */
1800
1801int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
Matt Caswell0f113f32015-01-22 03:40:55 +00001802{
1803 BIO *mem;
1804 int len, ret;
1805 unsigned char tbuf[1024];
FdaSilvaYYbde136c2016-03-18 19:02:17 +01001806
Matt Caswell0f113f32015-01-22 03:40:55 +00001807 mem = BIO_new(BIO_s_mem());
Matt Caswell96487cd2015-10-30 11:18:04 +00001808 if (mem == NULL)
Matt Caswell0f113f32015-01-22 03:40:55 +00001809 return -1;
1810 for (;;) {
1811 if ((maxlen != -1) && maxlen < 1024)
1812 len = maxlen;
1813 else
1814 len = 1024;
1815 len = BIO_read(in, tbuf, len);
Viktor Dukhovni0c208022016-02-02 00:37:41 -05001816 if (len < 0) {
1817 BIO_free(mem);
1818 return -1;
1819 }
1820 if (len == 0)
Matt Caswell0f113f32015-01-22 03:40:55 +00001821 break;
1822 if (BIO_write(mem, tbuf, len) != len) {
1823 BIO_free(mem);
1824 return -1;
1825 }
1826 maxlen -= len;
Dr. Stephen Hensona9164152006-04-08 22:25:47 +00001827
Matt Caswell0f113f32015-01-22 03:40:55 +00001828 if (maxlen == 0)
1829 break;
1830 }
1831 ret = BIO_get_mem_data(mem, (char **)out);
1832 BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
1833 BIO_free(mem);
1834 return ret;
1835}
Dr. Stephen Hensona9164152006-04-08 22:25:47 +00001836
Viktor Dukhovni0c208022016-02-02 00:37:41 -05001837int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value)
Matt Caswell0f113f32015-01-22 03:40:55 +00001838{
1839 int rv;
1840 char *stmp, *vtmp = NULL;
Rich Salz7644a9a2015-12-16 16:12:24 -05001841 stmp = OPENSSL_strdup(value);
Matt Caswell0f113f32015-01-22 03:40:55 +00001842 if (!stmp)
1843 return -1;
1844 vtmp = strchr(stmp, ':');
1845 if (vtmp) {
1846 *vtmp = 0;
1847 vtmp++;
1848 }
1849 rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
1850 OPENSSL_free(stmp);
1851 return rv;
1852}
Dr. Stephen Hensona2318e82006-04-09 00:34:00 +00001853
Rich Salzecf3a1f2015-04-29 11:27:08 -04001854static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
Matt Caswell0f113f32015-01-22 03:40:55 +00001855{
1856 X509_POLICY_NODE *node;
1857 int i;
Rich Salzecf3a1f2015-04-29 11:27:08 -04001858
1859 BIO_printf(bio_err, "%s Policies:", name);
Matt Caswell0f113f32015-01-22 03:40:55 +00001860 if (nodes) {
Rich Salzecf3a1f2015-04-29 11:27:08 -04001861 BIO_puts(bio_err, "\n");
Matt Caswell0f113f32015-01-22 03:40:55 +00001862 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
1863 node = sk_X509_POLICY_NODE_value(nodes, i);
Rich Salzecf3a1f2015-04-29 11:27:08 -04001864 X509_POLICY_NODE_print(bio_err, node, 2);
Matt Caswell0f113f32015-01-22 03:40:55 +00001865 }
1866 } else
Rich Salzecf3a1f2015-04-29 11:27:08 -04001867 BIO_puts(bio_err, " <empty>\n");
Matt Caswell0f113f32015-01-22 03:40:55 +00001868}
Dr. Stephen Hensonc4317982004-09-07 18:38:46 +00001869
Rich Salzecf3a1f2015-04-29 11:27:08 -04001870void policies_print(X509_STORE_CTX *ctx)
Matt Caswell0f113f32015-01-22 03:40:55 +00001871{
1872 X509_POLICY_TREE *tree;
1873 int explicit_policy;
Matt Caswell0f113f32015-01-22 03:40:55 +00001874 tree = X509_STORE_CTX_get0_policy_tree(ctx);
1875 explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
Dr. Stephen Hensonc4317982004-09-07 18:38:46 +00001876
Rich Salzecf3a1f2015-04-29 11:27:08 -04001877 BIO_printf(bio_err, "Require explicit Policy: %s\n",
Matt Caswell0f113f32015-01-22 03:40:55 +00001878 explicit_policy ? "True" : "False");
Dr. Stephen Hensonc4317982004-09-07 18:38:46 +00001879
Rich Salzecf3a1f2015-04-29 11:27:08 -04001880 nodes_print("Authority", X509_policy_tree_get0_policies(tree));
1881 nodes_print("User", X509_policy_tree_get0_user_policies(tree));
Matt Caswell0f113f32015-01-22 03:40:55 +00001882}
Andy Polyakovffa10182005-11-04 09:30:55 +00001883
Matt Caswell3a834622015-01-05 00:34:00 +00001884/*-
1885 * next_protos_parse parses a comma separated list of strings into a string
Ben Laurie71fa4512012-06-03 22:00:21 +00001886 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
1887 * outlen: (output) set to the length of the resulting buffer on success.
1888 * err: (maybe NULL) on failure, an error message line is written to this BIO.
FdaSilvaYY8483a002016-03-10 21:34:48 +01001889 * in: a NUL terminated string like "abc,def,ghi"
Ben Laurie71fa4512012-06-03 22:00:21 +00001890 *
FdaSilvaYY8483a002016-03-10 21:34:48 +01001891 * returns: a malloc'd buffer or NULL on failure.
Ben Laurie71fa4512012-06-03 22:00:21 +00001892 */
Todd Short817cd0d2016-03-05 08:47:55 -05001893unsigned char *next_protos_parse(size_t *outlen, const char *in)
Matt Caswell0f113f32015-01-22 03:40:55 +00001894{
1895 size_t len;
1896 unsigned char *out;
1897 size_t i, start = 0;
Ben Laurie71fa4512012-06-03 22:00:21 +00001898
Matt Caswell0f113f32015-01-22 03:40:55 +00001899 len = strlen(in);
1900 if (len >= 65535)
1901 return NULL;
Ben Laurie71fa4512012-06-03 22:00:21 +00001902
Rich Salz68dc6822015-04-30 17:48:31 -04001903 out = app_malloc(strlen(in) + 1, "NPN buffer");
Matt Caswell0f113f32015-01-22 03:40:55 +00001904 for (i = 0; i <= len; ++i) {
1905 if (i == len || in[i] == ',') {
1906 if (i - start > 255) {
1907 OPENSSL_free(out);
1908 return NULL;
1909 }
1910 out[start] = i - start;
1911 start = i + 1;
1912 } else
1913 out[i + 1] = in[i];
1914 }
Ben Laurie71fa4512012-06-03 22:00:21 +00001915
Matt Caswell0f113f32015-01-22 03:40:55 +00001916 *outlen = len + 1;
1917 return out;
1918}
Ben Laurie71fa4512012-06-03 22:00:21 +00001919
Dr. Stephen Hensona70da5b2012-10-08 15:10:07 +00001920void print_cert_checks(BIO *bio, X509 *x,
Matt Caswell0f113f32015-01-22 03:40:55 +00001921 const char *checkhost,
1922 const char *checkemail, const char *checkip)
1923{
1924 if (x == NULL)
1925 return;
1926 if (checkhost) {
1927 BIO_printf(bio, "Hostname %s does%s match certificate\n",
Rich Salz7e1b7482015-04-24 15:26:15 -04001928 checkhost,
1929 X509_check_host(x, checkhost, 0, 0, NULL) == 1
1930 ? "" : " NOT");
Matt Caswell0f113f32015-01-22 03:40:55 +00001931 }
Dr. Stephen Hensona70da5b2012-10-08 15:10:07 +00001932
Matt Caswell0f113f32015-01-22 03:40:55 +00001933 if (checkemail) {
1934 BIO_printf(bio, "Email %s does%s match certificate\n",
Rich Salz7e1b7482015-04-24 15:26:15 -04001935 checkemail, X509_check_email(x, checkemail, 0, 0)
1936 ? "" : " NOT");
Matt Caswell0f113f32015-01-22 03:40:55 +00001937 }
Dr. Stephen Hensona70da5b2012-10-08 15:10:07 +00001938
Matt Caswell0f113f32015-01-22 03:40:55 +00001939 if (checkip) {
1940 BIO_printf(bio, "IP %s does%s match certificate\n",
1941 checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT");
1942 }
1943}
Dr. Stephen Hensona70da5b2012-10-08 15:10:07 +00001944
Dr. Stephen Henson0090a682012-12-06 18:43:40 +00001945/* Get first http URL from a DIST_POINT structure */
1946
1947static const char *get_dp_url(DIST_POINT *dp)
Matt Caswell0f113f32015-01-22 03:40:55 +00001948{
1949 GENERAL_NAMES *gens;
1950 GENERAL_NAME *gen;
1951 int i, gtype;
1952 ASN1_STRING *uri;
1953 if (!dp->distpoint || dp->distpoint->type != 0)
1954 return NULL;
1955 gens = dp->distpoint->name.fullname;
1956 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1957 gen = sk_GENERAL_NAME_value(gens, i);
1958 uri = GENERAL_NAME_get0_value(gen, &gtype);
1959 if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
Dr. Stephen Henson17ebf852016-08-16 14:06:48 +01001960 const char *uptr = (const char *)ASN1_STRING_get0_data(uri);
Rich Salz86885c22015-05-06 14:56:14 -04001961 if (strncmp(uptr, "http://", 7) == 0)
Matt Caswell0f113f32015-01-22 03:40:55 +00001962 return uptr;
1963 }
1964 }
1965 return NULL;
1966}
Dr. Stephen Henson0090a682012-12-06 18:43:40 +00001967
Matt Caswell0f113f32015-01-22 03:40:55 +00001968/*
1969 * Look through a CRLDP structure and attempt to find an http URL to
1970 * downloads a CRL from.
Dr. Stephen Henson0090a682012-12-06 18:43:40 +00001971 */
1972
1973static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
Matt Caswell0f113f32015-01-22 03:40:55 +00001974{
1975 int i;
1976 const char *urlptr = NULL;
1977 for (i = 0; i < sk_DIST_POINT_num(crldp); i++) {
1978 DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
1979 urlptr = get_dp_url(dp);
1980 if (urlptr)
1981 return load_crl(urlptr, FORMAT_HTTP);
1982 }
1983 return NULL;
1984}
Dr. Stephen Henson0090a682012-12-06 18:43:40 +00001985
Matt Caswell0f113f32015-01-22 03:40:55 +00001986/*
1987 * Example of downloading CRLs from CRLDP: not usable for real world as it
1988 * always downloads, doesn't support non-blocking I/O and doesn't cache
1989 * anything.
Dr. Stephen Henson0090a682012-12-06 18:43:40 +00001990 */
1991
1992static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
Matt Caswell0f113f32015-01-22 03:40:55 +00001993{
1994 X509 *x;
1995 STACK_OF(X509_CRL) *crls = NULL;
1996 X509_CRL *crl;
1997 STACK_OF(DIST_POINT) *crldp;
Rich Salz7e1b7482015-04-24 15:26:15 -04001998
1999 crls = sk_X509_CRL_new_null();
2000 if (!crls)
2001 return NULL;
Matt Caswell0f113f32015-01-22 03:40:55 +00002002 x = X509_STORE_CTX_get_current_cert(ctx);
2003 crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
2004 crl = load_crl_crldp(crldp);
2005 sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
Matt Caswellfe2b7df2016-04-26 18:28:03 +01002006 if (!crl) {
2007 sk_X509_CRL_free(crls);
Matt Caswell0f113f32015-01-22 03:40:55 +00002008 return NULL;
Matt Caswellfe2b7df2016-04-26 18:28:03 +01002009 }
Matt Caswell0f113f32015-01-22 03:40:55 +00002010 sk_X509_CRL_push(crls, crl);
2011 /* Try to download delta CRL */
2012 crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL);
2013 crl = load_crl_crldp(crldp);
2014 sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
2015 if (crl)
2016 sk_X509_CRL_push(crls, crl);
2017 return crls;
2018}
Dr. Stephen Henson0090a682012-12-06 18:43:40 +00002019
2020void store_setup_crl_download(X509_STORE *st)
Matt Caswell0f113f32015-01-22 03:40:55 +00002021{
2022 X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
2023}
Dr. Stephen Henson0090a682012-12-06 18:43:40 +00002024
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002025/*
2026 * Platform-specific sections
2027 */
Andy Polyakovffa10182005-11-04 09:30:55 +00002028#if defined(_WIN32)
Andy Polyakova1ad2532005-11-04 16:12:05 +00002029# ifdef fileno
2030# undef fileno
2031# define fileno(a) (int)_fileno(a)
2032# endif
2033
2034# include <windows.h>
2035# include <tchar.h>
2036
2037static int WIN32_rename(const char *from, const char *to)
Matt Caswell0f113f32015-01-22 03:40:55 +00002038{
2039 TCHAR *tfrom = NULL, *tto;
2040 DWORD err;
2041 int ret = 0;
Andy Polyakova1ad2532005-11-04 16:12:05 +00002042
Matt Caswell0f113f32015-01-22 03:40:55 +00002043 if (sizeof(TCHAR) == 1) {
2044 tfrom = (TCHAR *)from;
2045 tto = (TCHAR *)to;
2046 } else { /* UNICODE path */
Andy Polyakova1ad2532005-11-04 16:12:05 +00002047
Matt Caswell0f113f32015-01-22 03:40:55 +00002048 size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
Matt Caswellb1ad95e2015-05-05 22:09:01 +01002049 tfrom = malloc(sizeof(*tfrom) * (flen + tlen));
Matt Caswell0f113f32015-01-22 03:40:55 +00002050 if (tfrom == NULL)
2051 goto err;
2052 tto = tfrom + flen;
2053# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2054 if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
2055# endif
2056 for (i = 0; i < flen; i++)
2057 tfrom[i] = (TCHAR)from[i];
2058# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2059 if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
2060# endif
2061 for (i = 0; i < tlen; i++)
2062 tto[i] = (TCHAR)to[i];
2063 }
2064
2065 if (MoveFile(tfrom, tto))
2066 goto ok;
2067 err = GetLastError();
2068 if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
2069 if (DeleteFile(tto) && MoveFile(tfrom, tto))
2070 goto ok;
2071 err = GetLastError();
2072 }
2073 if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
2074 errno = ENOENT;
2075 else if (err == ERROR_ACCESS_DENIED)
2076 errno = EACCES;
2077 else
2078 errno = EINVAL; /* we could map more codes... */
2079 err:
2080 ret = -1;
2081 ok:
2082 if (tfrom != NULL && tfrom != (TCHAR *)from)
2083 free(tfrom);
2084 return ret;
2085}
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002086#endif
Andy Polyakova1ad2532005-11-04 16:12:05 +00002087
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002088/* app_tminterval section */
2089#if defined(_WIN32)
Matt Caswell0f113f32015-01-22 03:40:55 +00002090double app_tminterval(int stop, int usertime)
2091{
2092 FILETIME now;
2093 double ret = 0;
2094 static ULARGE_INTEGER tmstart;
2095 static int warning = 1;
2096# ifdef _WIN32_WINNT
2097 static HANDLE proc = NULL;
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002098
Matt Caswell0f113f32015-01-22 03:40:55 +00002099 if (proc == NULL) {
2100 if (check_winnt())
2101 proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
2102 GetCurrentProcessId());
2103 if (proc == NULL)
2104 proc = (HANDLE) - 1;
2105 }
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002106
Matt Caswell0f113f32015-01-22 03:40:55 +00002107 if (usertime && proc != (HANDLE) - 1) {
2108 FILETIME junk;
2109 GetProcessTimes(proc, &junk, &junk, &junk, &now);
2110 } else
2111# endif
2112 {
2113 SYSTEMTIME systime;
Andy Polyakove22f63f2005-11-06 12:15:12 +00002114
Matt Caswell0f113f32015-01-22 03:40:55 +00002115 if (usertime && warning) {
2116 BIO_printf(bio_err, "To get meaningful results, run "
2117 "this program on idle system.\n");
2118 warning = 0;
2119 }
2120 GetSystemTime(&systime);
2121 SystemTimeToFileTime(&systime, &now);
2122 }
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002123
Matt Caswell0f113f32015-01-22 03:40:55 +00002124 if (stop == TM_START) {
2125 tmstart.u.LowPart = now.dwLowDateTime;
2126 tmstart.u.HighPart = now.dwHighDateTime;
2127 } else {
2128 ULARGE_INTEGER tmstop;
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002129
Matt Caswell0f113f32015-01-22 03:40:55 +00002130 tmstop.u.LowPart = now.dwLowDateTime;
2131 tmstop.u.HighPart = now.dwHighDateTime;
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002132
Matt Caswell0f113f32015-01-22 03:40:55 +00002133 ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
2134 }
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002135
Matt Caswell0f113f32015-01-22 03:40:55 +00002136 return (ret);
2137}
Andy Polyakovd88fcf72005-11-06 16:55:44 +00002138#elif defined(OPENSSL_SYSTEM_VXWORKS)
Matt Caswell0f113f32015-01-22 03:40:55 +00002139# include <time.h>
Andy Polyakovd88fcf72005-11-06 16:55:44 +00002140
Matt Caswell0f113f32015-01-22 03:40:55 +00002141double app_tminterval(int stop, int usertime)
2142{
2143 double ret = 0;
2144# ifdef CLOCK_REALTIME
2145 static struct timespec tmstart;
2146 struct timespec now;
2147# else
2148 static unsigned long tmstart;
2149 unsigned long now;
2150# endif
2151 static int warning = 1;
Andy Polyakovd88fcf72005-11-06 16:55:44 +00002152
Matt Caswell0f113f32015-01-22 03:40:55 +00002153 if (usertime && warning) {
2154 BIO_printf(bio_err, "To get meaningful results, run "
2155 "this program on idle system.\n");
2156 warning = 0;
2157 }
2158# ifdef CLOCK_REALTIME
2159 clock_gettime(CLOCK_REALTIME, &now);
2160 if (stop == TM_START)
2161 tmstart = now;
2162 else
2163 ret = ((now.tv_sec + now.tv_nsec * 1e-9)
2164 - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
2165# else
2166 now = tickGet();
2167 if (stop == TM_START)
2168 tmstart = now;
2169 else
2170 ret = (now - tmstart) / (double)sysClkRateGet();
2171# endif
2172 return (ret);
2173}
Andy Polyakovd88fcf72005-11-06 16:55:44 +00002174
Andy Polyakova950f282005-11-06 16:16:38 +00002175#elif defined(OPENSSL_SYSTEM_VMS)
Matt Caswell0f113f32015-01-22 03:40:55 +00002176# include <time.h>
2177# include <times.h>
Andy Polyakova950f282005-11-06 16:16:38 +00002178
Matt Caswell0f113f32015-01-22 03:40:55 +00002179double app_tminterval(int stop, int usertime)
2180{
2181 static clock_t tmstart;
2182 double ret = 0;
2183 clock_t now;
2184# ifdef __TMS
2185 struct tms rus;
Andy Polyakova950f282005-11-06 16:16:38 +00002186
Matt Caswell0f113f32015-01-22 03:40:55 +00002187 now = times(&rus);
2188 if (usertime)
2189 now = rus.tms_utime;
2190# else
2191 if (usertime)
2192 now = clock(); /* sum of user and kernel times */
2193 else {
2194 struct timeval tv;
2195 gettimeofday(&tv, NULL);
2196 now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
2197 (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
2198 );
2199 }
2200# endif
2201 if (stop == TM_START)
2202 tmstart = now;
2203 else
2204 ret = (now - tmstart) / (double)(CLK_TCK);
Andy Polyakova950f282005-11-06 16:16:38 +00002205
Matt Caswell0f113f32015-01-22 03:40:55 +00002206 return (ret);
2207}
Andy Polyakova950f282005-11-06 16:16:38 +00002208
Matt Caswell0f113f32015-01-22 03:40:55 +00002209#elif defined(_SC_CLK_TCK) /* by means of unistd.h */
2210# include <sys/times.h>
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002211
Matt Caswell0f113f32015-01-22 03:40:55 +00002212double app_tminterval(int stop, int usertime)
2213{
2214 double ret = 0;
2215 struct tms rus;
2216 clock_t now = times(&rus);
2217 static clock_t tmstart;
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002218
Matt Caswell0f113f32015-01-22 03:40:55 +00002219 if (usertime)
2220 now = rus.tms_utime;
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002221
Matt Caswell0f113f32015-01-22 03:40:55 +00002222 if (stop == TM_START)
2223 tmstart = now;
2224 else {
2225 long int tck = sysconf(_SC_CLK_TCK);
2226 ret = (now - tmstart) / (double)tck;
2227 }
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002228
Matt Caswell0f113f32015-01-22 03:40:55 +00002229 return (ret);
2230}
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002231
2232#else
Matt Caswell0f113f32015-01-22 03:40:55 +00002233# include <sys/time.h>
2234# include <sys/resource.h>
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002235
Matt Caswell0f113f32015-01-22 03:40:55 +00002236double app_tminterval(int stop, int usertime)
2237{
2238 double ret = 0;
2239 struct rusage rus;
2240 struct timeval now;
2241 static struct timeval tmstart;
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002242
Matt Caswell0f113f32015-01-22 03:40:55 +00002243 if (usertime)
2244 getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
2245 else
2246 gettimeofday(&now, NULL);
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002247
Matt Caswell0f113f32015-01-22 03:40:55 +00002248 if (stop == TM_START)
2249 tmstart = now;
2250 else
2251 ret = ((now.tv_sec + now.tv_usec * 1e-6)
2252 - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002253
Matt Caswell0f113f32015-01-22 03:40:55 +00002254 return ret;
2255}
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002256#endif
2257
Rich Salz7e1b7482015-04-24 15:26:15 -04002258int app_access(const char* name, int flag)
2259{
2260#ifdef _WIN32
2261 return _access(name, flag);
2262#else
2263 return access(name, flag);
2264#endif
2265}
2266
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002267/* app_isdir section */
2268#ifdef _WIN32
Andy Polyakovffa10182005-11-04 09:30:55 +00002269int app_isdir(const char *name)
Matt Caswell0f113f32015-01-22 03:40:55 +00002270{
2271 HANDLE hList;
2272 WIN32_FIND_DATA FileData;
2273# if defined(UNICODE) || defined(_UNICODE)
2274 size_t i, len_0 = strlen(name) + 1;
Andy Polyakovffa10182005-11-04 09:30:55 +00002275
Dr. Stephen Hensonbdcb1a22015-05-03 17:32:05 +01002276 if (len_0 > OSSL_NELEM(FileData.cFileName))
Matt Caswell0f113f32015-01-22 03:40:55 +00002277 return -1;
Andy Polyakovffa10182005-11-04 09:30:55 +00002278
Matt Caswell0f113f32015-01-22 03:40:55 +00002279# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2280 if (!MultiByteToWideChar
2281 (CP_ACP, 0, name, len_0, FileData.cFileName, len_0))
2282# endif
2283 for (i = 0; i < len_0; i++)
2284 FileData.cFileName[i] = (WCHAR)name[i];
Andy Polyakovffa10182005-11-04 09:30:55 +00002285
Matt Caswell0f113f32015-01-22 03:40:55 +00002286 hList = FindFirstFile(FileData.cFileName, &FileData);
2287# else
2288 hList = FindFirstFile(name, &FileData);
2289# endif
2290 if (hList == INVALID_HANDLE_VALUE)
2291 return -1;
2292 FindClose(hList);
2293 return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
2294}
Andy Polyakovffa10182005-11-04 09:30:55 +00002295#else
Matt Caswell0f113f32015-01-22 03:40:55 +00002296# include <sys/stat.h>
2297# ifndef S_ISDIR
2298# if defined(_S_IFMT) && defined(_S_IFDIR)
2299# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)
2300# else
2301# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
2302# endif
2303# endif
Andy Polyakovffa10182005-11-04 09:30:55 +00002304
2305int app_isdir(const char *name)
Matt Caswell0f113f32015-01-22 03:40:55 +00002306{
2307# if defined(S_ISDIR)
2308 struct stat st;
Andy Polyakovffa10182005-11-04 09:30:55 +00002309
Matt Caswell0f113f32015-01-22 03:40:55 +00002310 if (stat(name, &st) == 0)
2311 return S_ISDIR(st.st_mode);
2312 else
2313 return -1;
2314# else
2315 return -1;
2316# endif
2317}
Andy Polyakovffa10182005-11-04 09:30:55 +00002318#endif
2319
Andy Polyakov0a39d8f2005-11-06 11:40:59 +00002320/* raw_read|write section */
Richard Levitte51e51332016-09-15 11:20:18 +02002321#if defined(__VMS)
2322# include "vms_term_sock.h"
2323static int stdin_sock = -1;
2324
2325static void close_stdin_sock(void)
2326{
2327 TerminalSocket (TERM_SOCK_DELETE, &stdin_sock);
2328}
2329
2330int fileno_stdin(void)
2331{
2332 if (stdin_sock == -1) {
2333 TerminalSocket(TERM_SOCK_CREATE, &stdin_sock);
2334 atexit(close_stdin_sock);
2335 }
2336
2337 return stdin_sock;
2338}
2339#else
2340int fileno_stdin(void)
2341{
2342 return fileno(stdin);
2343}
2344#endif
2345
2346int fileno_stdout(void)
2347{
2348 return fileno(stdout);
2349}
2350
Andy Polyakovffa10182005-11-04 09:30:55 +00002351#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
Matt Caswell0f113f32015-01-22 03:40:55 +00002352int raw_read_stdin(void *buf, int siz)
2353{
2354 DWORD n;
2355 if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
2356 return (n);
2357 else
2358 return (-1);
2359}
Richard Levitte51e51332016-09-15 11:20:18 +02002360#elif defined(__VMS)
Richard Levittea19228b2016-09-20 18:43:24 +02002361#include <sys/socket.h>
2362
Richard Levitte51e51332016-09-15 11:20:18 +02002363int raw_read_stdin(void *buf, int siz)
2364{
2365 return recv(fileno_stdin(), buf, siz, 0);
2366}
Andy Polyakovffa10182005-11-04 09:30:55 +00002367#else
Matt Caswell0f113f32015-01-22 03:40:55 +00002368int raw_read_stdin(void *buf, int siz)
2369{
Richard Levitte51e51332016-09-15 11:20:18 +02002370 return read(fileno_stdin(), buf, siz);
Matt Caswell0f113f32015-01-22 03:40:55 +00002371}
Andy Polyakovffa10182005-11-04 09:30:55 +00002372#endif
2373
2374#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
Matt Caswell0f113f32015-01-22 03:40:55 +00002375int raw_write_stdout(const void *buf, int siz)
2376{
2377 DWORD n;
2378 if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
2379 return (n);
2380 else
2381 return (-1);
2382}
Andy Polyakovffa10182005-11-04 09:30:55 +00002383#else
Matt Caswell0f113f32015-01-22 03:40:55 +00002384int raw_write_stdout(const void *buf, int siz)
2385{
Richard Levitte51e51332016-09-15 11:20:18 +02002386 return write(fileno_stdout(), buf, siz);
Matt Caswell0f113f32015-01-22 03:40:55 +00002387}
Andy Polyakovffa10182005-11-04 09:30:55 +00002388#endif
Richard Levittea412b892015-09-06 10:51:04 +02002389
2390/*
2391 * Centralized handling if input and output files with format specification
2392 * The format is meant to show what the input and output is supposed to be,
2393 * and is therefore a show of intent more than anything else. However, it
2394 * does impact behavior on some platform, such as differentiating between
2395 * text and binary input/output on non-Unix platforms
2396 */
Richard Levitte496f4f92015-09-06 22:43:25 +02002397static int istext(int format)
Richard Levittea412b892015-09-06 10:51:04 +02002398{
Richard Levittea60994d2015-09-06 12:20:12 +02002399 return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT;
Richard Levittea412b892015-09-06 10:51:04 +02002400}
2401
Richard Levittea60994d2015-09-06 12:20:12 +02002402BIO *dup_bio_in(int format)
Richard Levittea412b892015-09-06 10:51:04 +02002403{
Richard Levittea60994d2015-09-06 12:20:12 +02002404 return BIO_new_fp(stdin,
2405 BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
2406}
2407
2408BIO *dup_bio_out(int format)
2409{
2410 BIO *b = BIO_new_fp(stdout,
2411 BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
Richard Levittea412b892015-09-06 10:51:04 +02002412#ifdef OPENSSL_SYS_VMS
Richard Levittea60994d2015-09-06 12:20:12 +02002413 if (istext(format))
2414 b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
Richard Levittea412b892015-09-06 10:51:04 +02002415#endif
2416 return b;
2417}
2418
Richard Levitte149bd5d2016-03-21 18:30:30 +01002419BIO *dup_bio_err(int format)
2420{
2421 BIO *b = BIO_new_fp(stderr,
2422 BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
2423#ifdef OPENSSL_SYS_VMS
2424 if (istext(format))
2425 b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
2426#endif
2427 return b;
2428}
2429
Richard Levittea412b892015-09-06 10:51:04 +02002430void unbuffer(FILE *fp)
2431{
Richard Levitte90dbd252016-03-30 08:32:19 +02002432/*
2433 * On VMS, setbuf() will only take 32-bit pointers, and a compilation
2434 * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here.
2435 * However, we trust that the C RTL will never give us a FILE pointer
2436 * above the first 4 GB of memory, so we simply turn off the warning
2437 * temporarily.
2438 */
2439#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
2440# pragma environment save
2441# pragma message disable maylosedata2
2442#endif
Richard Levittea412b892015-09-06 10:51:04 +02002443 setbuf(fp, NULL);
Richard Levitte90dbd252016-03-30 08:32:19 +02002444#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
2445# pragma environment restore
2446#endif
Richard Levittea412b892015-09-06 10:51:04 +02002447}
2448
2449static const char *modestr(char mode, int format)
2450{
2451 OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w');
2452
2453 switch (mode) {
2454 case 'a':
Richard Levittea60994d2015-09-06 12:20:12 +02002455 return istext(format) ? "a" : "ab";
Richard Levittea412b892015-09-06 10:51:04 +02002456 case 'r':
Richard Levittea60994d2015-09-06 12:20:12 +02002457 return istext(format) ? "r" : "rb";
Richard Levittea412b892015-09-06 10:51:04 +02002458 case 'w':
Richard Levittea60994d2015-09-06 12:20:12 +02002459 return istext(format) ? "w" : "wb";
Richard Levittea412b892015-09-06 10:51:04 +02002460 }
2461 /* The assert above should make sure we never reach this point */
2462 return NULL;
2463}
2464
2465static const char *modeverb(char mode)
2466{
2467 switch (mode) {
2468 case 'a':
2469 return "appending";
2470 case 'r':
2471 return "reading";
2472 case 'w':
2473 return "writing";
2474 }
2475 return "(doing something)";
2476}
2477
2478/*
2479 * Open a file for writing, owner-read-only.
2480 */
2481BIO *bio_open_owner(const char *filename, int format, int private)
2482{
2483 FILE *fp = NULL;
2484 BIO *b = NULL;
Richard Levitte1cd5cc32016-01-14 14:07:57 +01002485 int fd = -1, bflags, mode, textmode;
Richard Levittea412b892015-09-06 10:51:04 +02002486
2487 if (!private || filename == NULL || strcmp(filename, "-") == 0)
2488 return bio_open_default(filename, 'w', format);
2489
2490 mode = O_WRONLY;
2491#ifdef O_CREAT
2492 mode |= O_CREAT;
2493#endif
2494#ifdef O_TRUNC
2495 mode |= O_TRUNC;
2496#endif
Richard Levitte1cd5cc32016-01-14 14:07:57 +01002497 textmode = istext(format);
2498 if (!textmode) {
Richard Levittea412b892015-09-06 10:51:04 +02002499#ifdef O_BINARY
2500 mode |= O_BINARY;
2501#elif defined(_O_BINARY)
2502 mode |= _O_BINARY;
2503#endif
2504 }
2505
Richard Levittefbd03b02016-01-14 14:08:49 +01002506#ifdef OPENSSL_SYS_VMS
2507 /* VMS doesn't have O_BINARY, it just doesn't make sense. But,
2508 * it still needs to know that we're going binary, or fdopen()
2509 * will fail with "invalid argument"... so we tell VMS what the
2510 * context is.
2511 */
2512 if (!textmode)
2513 fd = open(filename, mode, 0600, "ctx=bin");
2514 else
2515#endif
2516 fd = open(filename, mode, 0600);
Richard Levittea412b892015-09-06 10:51:04 +02002517 if (fd < 0)
2518 goto err;
2519 fp = fdopen(fd, modestr('w', format));
2520 if (fp == NULL)
2521 goto err;
2522 bflags = BIO_CLOSE;
Richard Levitte1cd5cc32016-01-14 14:07:57 +01002523 if (textmode)
Richard Levittea412b892015-09-06 10:51:04 +02002524 bflags |= BIO_FP_TEXT;
2525 b = BIO_new_fp(fp, bflags);
2526 if (b)
2527 return b;
2528
2529 err:
2530 BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n",
2531 opt_getprog(), filename, strerror(errno));
2532 ERR_print_errors(bio_err);
2533 /* If we have fp, then fdopen took over fd, so don't close both. */
2534 if (fp)
2535 fclose(fp);
2536 else if (fd >= 0)
2537 close(fd);
2538 return NULL;
2539}
2540
2541static BIO *bio_open_default_(const char *filename, char mode, int format,
2542 int quiet)
2543{
2544 BIO *ret;
2545
2546 if (filename == NULL || strcmp(filename, "-") == 0) {
Richard Levittea60994d2015-09-06 12:20:12 +02002547 ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format);
Richard Levittea412b892015-09-06 10:51:04 +02002548 if (quiet) {
2549 ERR_clear_error();
2550 return ret;
2551 }
2552 if (ret != NULL)
2553 return ret;
2554 BIO_printf(bio_err,
2555 "Can't open %s, %s\n",
2556 mode == 'r' ? "stdin" : "stdout", strerror(errno));
2557 } else {
2558 ret = BIO_new_file(filename, modestr(mode, format));
2559 if (quiet) {
2560 ERR_clear_error();
2561 return ret;
2562 }
2563 if (ret != NULL)
2564 return ret;
2565 BIO_printf(bio_err,
2566 "Can't open %s for %s, %s\n",
2567 filename, modeverb(mode), strerror(errno));
2568 }
2569 ERR_print_errors(bio_err);
2570 return NULL;
2571}
2572
2573BIO *bio_open_default(const char *filename, char mode, int format)
2574{
2575 return bio_open_default_(filename, mode, format, 0);
2576}
2577
2578BIO *bio_open_default_quiet(const char *filename, char mode, int format)
2579{
2580 return bio_open_default_(filename, mode, format, 1);
2581}
2582
Matt Caswelle1b98402015-10-06 14:04:11 +01002583void wait_for_async(SSL *s)
2584{
Matt Caswelld6e03b72016-04-20 12:56:54 +01002585 /* On Windows select only works for sockets, so we simply don't wait */
2586#ifndef OPENSSL_SYS_WINDOWS
Matt Caswellff75a252016-01-25 15:28:57 +00002587 int width = 0;
Matt Caswelle1b98402015-10-06 14:04:11 +01002588 fd_set asyncfds;
Matt Caswellff75a252016-01-25 15:28:57 +00002589 OSSL_ASYNC_FD *fds;
2590 size_t numfds;
Matt Caswelle1b98402015-10-06 14:04:11 +01002591
Matt Caswellff75a252016-01-25 15:28:57 +00002592 if (!SSL_get_all_async_fds(s, NULL, &numfds))
Matt Caswelle1b98402015-10-06 14:04:11 +01002593 return;
Matt Caswellff75a252016-01-25 15:28:57 +00002594 if (numfds == 0)
2595 return;
Rich Salz589902b2016-05-16 14:58:00 -04002596 fds = app_malloc(sizeof(OSSL_ASYNC_FD) * numfds, "allocate async fds");
Matt Caswellff75a252016-01-25 15:28:57 +00002597 if (!SSL_get_all_async_fds(s, fds, &numfds)) {
2598 OPENSSL_free(fds);
2599 }
Matt Caswelle1b98402015-10-06 14:04:11 +01002600
Matt Caswelle1b98402015-10-06 14:04:11 +01002601 FD_ZERO(&asyncfds);
Matt Caswellff75a252016-01-25 15:28:57 +00002602 while (numfds > 0) {
2603 if (width <= (int)*fds)
2604 width = (int)*fds + 1;
2605 openssl_fdset((int)*fds, &asyncfds);
2606 numfds--;
2607 fds++;
2608 }
Matt Caswelle1b98402015-10-06 14:04:11 +01002609 select(width, (void *)&asyncfds, NULL, NULL, NULL);
Matt Caswelld6e03b72016-04-20 12:56:54 +01002610#endif
Matt Caswelle1b98402015-10-06 14:04:11 +01002611}
Matt Caswell75dd6c12016-05-20 11:53:26 +01002612
2613/* if OPENSSL_SYS_WINDOWS is defined then so is OPENSSL_SYS_MSDOS */
2614#if defined(OPENSSL_SYS_MSDOS)
2615int has_stdin_waiting(void)
2616{
2617# if defined(OPENSSL_SYS_WINDOWS)
2618 HANDLE inhand = GetStdHandle(STD_INPUT_HANDLE);
2619 DWORD events = 0;
2620 INPUT_RECORD inputrec;
2621 DWORD insize = 1;
2622 BOOL peeked;
2623
2624 if (inhand == INVALID_HANDLE_VALUE) {
2625 return 0;
2626 }
2627
2628 peeked = PeekConsoleInput(inhand, &inputrec, insize, &events);
2629 if (!peeked) {
2630 /* Probably redirected input? _kbhit() does not work in this case */
2631 if (!feof(stdin)) {
2632 return 1;
2633 }
2634 return 0;
2635 }
2636# endif
2637 return _kbhit();
2638}
2639#endif
Dr. Stephen Henson17ebf852016-08-16 14:06:48 +01002640
2641/* Corrupt a signature by modifying final byte */
Dr. Stephen Hensona0754082016-08-17 12:34:22 +01002642void corrupt_signature(const ASN1_STRING *signature)
Dr. Stephen Henson17ebf852016-08-16 14:06:48 +01002643{
Dr. Stephen Hensona0754082016-08-17 12:34:22 +01002644 unsigned char *s = signature->data;
2645 s[signature->length - 1] ^= 0x1;
Dr. Stephen Henson17ebf852016-08-16 14:06:48 +01002646}
Dr. Stephen Hensondc047d32016-08-19 16:21:21 +01002647
2648int set_cert_times(X509 *x, const char *startdate, const char *enddate,
2649 int days)
2650{
Dr. Stephen Hensondc047d32016-08-19 16:21:21 +01002651 if (startdate == NULL || strcmp(startdate, "today") == 0) {
Dr. Stephen Henson0b7347e2016-08-20 13:02:09 +01002652 if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL)
2653 return 0;
2654 } else {
2655 if (!ASN1_TIME_set_string(X509_getm_notBefore(x), startdate))
2656 return 0;
Dr. Stephen Hensondc047d32016-08-19 16:21:21 +01002657 }
Dr. Stephen Hensondc047d32016-08-19 16:21:21 +01002658 if (enddate == NULL) {
Dr. Stephen Henson0b7347e2016-08-20 13:02:09 +01002659 if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL)
2660 == NULL)
2661 return 0;
2662 } else if (!ASN1_TIME_set_string(X509_getm_notAfter(x), enddate)) {
2663 return 0;
Dr. Stephen Hensondc047d32016-08-19 16:21:21 +01002664 }
Dr. Stephen Henson0b7347e2016-08-20 13:02:09 +01002665 return 1;
Dr. Stephen Hensondc047d32016-08-19 16:21:21 +01002666}
Robert Scheck20967af2017-02-09 22:20:59 +01002667
2668void make_uppercase(char *string)
2669{
2670 int i;
2671
2672 for (i = 0; string[i] != '\0'; i++)
2673 string[i] = toupper((unsigned char)string[i]);
2674}