summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl/apps.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr.bin/openssl/apps.c')
-rw-r--r--src/usr.bin/openssl/apps.c2220
1 files changed, 2220 insertions, 0 deletions
diff --git a/src/usr.bin/openssl/apps.c b/src/usr.bin/openssl/apps.c
new file mode 100644
index 0000000000..ac1c5107f1
--- /dev/null
+++ b/src/usr.bin/openssl/apps.c
@@ -0,0 +1,2220 @@
1/* $OpenBSD: apps.c,v 1.1 2014/08/26 17:47:24 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <sys/types.h>
113#include <sys/stat.h>
114#include <sys/times.h>
115
116#include <ctype.h>
117#include <errno.h>
118#include <stdio.h>
119#include <stdlib.h>
120#include <limits.h>
121#include <string.h>
122#include <strings.h>
123#include <unistd.h>
124
125#include "apps.h"
126
127#include <openssl/bn.h>
128#include <openssl/err.h>
129#include <openssl/pem.h>
130#include <openssl/pkcs12.h>
131#include <openssl/safestack.h>
132#include <openssl/ui.h>
133#include <openssl/x509.h>
134#include <openssl/x509v3.h>
135
136#ifndef OPENSSL_NO_ENGINE
137#include <openssl/engine.h>
138#endif
139
140#include <openssl/rsa.h>
141
142typedef struct {
143 const char *name;
144 unsigned long flag;
145 unsigned long mask;
146} NAME_EX_TBL;
147
148static UI_METHOD *ui_method = NULL;
149
150static int set_table_opts(unsigned long *flags, const char *arg,
151 const NAME_EX_TBL *in_tbl);
152static int set_multi_opts(unsigned long *flags, const char *arg,
153 const NAME_EX_TBL *in_tbl);
154
155#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
156/* Looks like this stuff is worth moving into separate function */
157static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
158 const char *key_descrip, int format);
159#endif
160
161int
162str2fmt(char *s)
163{
164 if (s == NULL)
165 return FORMAT_UNDEF;
166 if ((*s == 'D') || (*s == 'd'))
167 return (FORMAT_ASN1);
168 else if ((*s == 'T') || (*s == 't'))
169 return (FORMAT_TEXT);
170 else if ((*s == 'N') || (*s == 'n'))
171 return (FORMAT_NETSCAPE);
172 else if ((*s == 'S') || (*s == 's'))
173 return (FORMAT_SMIME);
174 else if ((*s == 'M') || (*s == 'm'))
175 return (FORMAT_MSBLOB);
176 else if ((*s == '1') ||
177 (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0) ||
178 (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0))
179 return (FORMAT_PKCS12);
180 else if ((*s == 'E') || (*s == 'e'))
181 return (FORMAT_ENGINE);
182 else if ((*s == 'P') || (*s == 'p')) {
183 if (s[1] == 'V' || s[1] == 'v')
184 return FORMAT_PVK;
185 else
186 return (FORMAT_PEM);
187 } else
188 return (FORMAT_UNDEF);
189}
190
191void
192program_name(char *in, char *out, int size)
193{
194 char *p;
195
196 p = strrchr(in, '/');
197 if (p != NULL)
198 p++;
199 else
200 p = in;
201 strlcpy(out, p, size);
202}
203
204int
205chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
206{
207 int num, i;
208 char *p;
209
210 *argc = 0;
211 *argv = NULL;
212
213 i = 0;
214 if (arg->count == 0) {
215 arg->count = 20;
216 arg->data = reallocarray(NULL, arg->count, sizeof(char *));
217 }
218 for (i = 0; i < arg->count; i++)
219 arg->data[i] = NULL;
220
221 num = 0;
222 p = buf;
223 for (;;) {
224 /* first scan over white space */
225 if (!*p)
226 break;
227 while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
228 p++;
229 if (!*p)
230 break;
231
232 /* The start of something good :-) */
233 if (num >= arg->count) {
234 char **tmp_p;
235 int tlen = arg->count + 20;
236 tmp_p = reallocarray(arg->data, tlen, sizeof(char *));
237 if (tmp_p == NULL)
238 return 0;
239 arg->data = tmp_p;
240 arg->count = tlen;
241 /* initialize newly allocated data */
242 for (i = num; i < arg->count; i++)
243 arg->data[i] = NULL;
244 }
245 arg->data[num++] = p;
246
247 /* now look for the end of this */
248 if ((*p == '\'') || (*p == '\"')) { /* scan for closing
249 * quote */
250 i = *(p++);
251 arg->data[num - 1]++; /* jump over quote */
252 while (*p && (*p != i))
253 p++;
254 *p = '\0';
255 } else {
256 while (*p && ((*p != ' ') &&
257 (*p != '\t') && (*p != '\n')))
258 p++;
259
260 if (*p == '\0')
261 p--;
262 else
263 *p = '\0';
264 }
265 p++;
266 }
267 *argc = num;
268 *argv = arg->data;
269 return (1);
270}
271
272int
273dump_cert_text(BIO *out, X509 *x)
274{
275 char *p;
276
277 p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
278 BIO_puts(out, "subject=");
279 BIO_puts(out, p);
280 free(p);
281
282 p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
283 BIO_puts(out, "\nissuer=");
284 BIO_puts(out, p);
285 BIO_puts(out, "\n");
286 free(p);
287
288 return 0;
289}
290
291static int
292ui_open(UI *ui)
293{
294 return UI_method_get_opener(UI_OpenSSL()) (ui);
295}
296
297static int
298ui_read(UI *ui, UI_STRING *uis)
299{
300 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
301 UI_get0_user_data(ui)) {
302 switch (UI_get_string_type(uis)) {
303 case UIT_PROMPT:
304 case UIT_VERIFY:
305 {
306 const char *password =
307 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
308 if (password && password[0] != '\0') {
309 UI_set_result(ui, uis, password);
310 return 1;
311 }
312 }
313 break;
314 default:
315 break;
316 }
317 }
318 return UI_method_get_reader(UI_OpenSSL()) (ui, uis);
319}
320
321static int
322ui_write(UI *ui, UI_STRING *uis)
323{
324 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
325 UI_get0_user_data(ui)) {
326 switch (UI_get_string_type(uis)) {
327 case UIT_PROMPT:
328 case UIT_VERIFY:
329 {
330 const char *password =
331 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
332 if (password && password[0] != '\0')
333 return 1;
334 }
335 break;
336 default:
337 break;
338 }
339 }
340 return UI_method_get_writer(UI_OpenSSL()) (ui, uis);
341}
342
343static int
344ui_close(UI *ui)
345{
346 return UI_method_get_closer(UI_OpenSSL()) (ui);
347}
348
349int
350setup_ui_method(void)
351{
352 ui_method = UI_create_method("OpenSSL application user interface");
353 UI_method_set_opener(ui_method, ui_open);
354 UI_method_set_reader(ui_method, ui_read);
355 UI_method_set_writer(ui_method, ui_write);
356 UI_method_set_closer(ui_method, ui_close);
357 return 0;
358}
359
360void
361destroy_ui_method(void)
362{
363 if (ui_method) {
364 UI_destroy_method(ui_method);
365 ui_method = NULL;
366 }
367}
368
369int
370password_callback(char *buf, int bufsiz, int verify, void *arg)
371{
372 PW_CB_DATA *cb_tmp = arg;
373 UI *ui = NULL;
374 int res = 0;
375 const char *prompt_info = NULL;
376 const char *password = NULL;
377 PW_CB_DATA *cb_data = (PW_CB_DATA *) cb_tmp;
378
379 if (cb_data) {
380 if (cb_data->password)
381 password = cb_data->password;
382 if (cb_data->prompt_info)
383 prompt_info = cb_data->prompt_info;
384 }
385 if (password) {
386 res = strlen(password);
387 if (res > bufsiz)
388 res = bufsiz;
389 memcpy(buf, password, res);
390 return res;
391 }
392 ui = UI_new_method(ui_method);
393 if (ui) {
394 int ok = 0;
395 char *buff = NULL;
396 int ui_flags = 0;
397 char *prompt = NULL;
398
399 prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
400
401 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
402 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
403
404 if (ok >= 0)
405 ok = UI_add_input_string(ui, prompt, ui_flags, buf,
406 PW_MIN_LENGTH, bufsiz - 1);
407 if (ok >= 0 && verify) {
408 buff = malloc(bufsiz);
409 ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
410 PW_MIN_LENGTH, bufsiz - 1, buf);
411 }
412 if (ok >= 0)
413 do {
414 ok = UI_process(ui);
415 } while (ok < 0 &&
416 UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
417
418 if (buff) {
419 OPENSSL_cleanse(buff, (unsigned int) bufsiz);
420 free(buff);
421 }
422 if (ok >= 0)
423 res = strlen(buf);
424 if (ok == -1) {
425 BIO_printf(bio_err, "User interface error\n");
426 ERR_print_errors(bio_err);
427 OPENSSL_cleanse(buf, (unsigned int) bufsiz);
428 res = 0;
429 }
430 if (ok == -2) {
431 BIO_printf(bio_err, "aborted!\n");
432 OPENSSL_cleanse(buf, (unsigned int) bufsiz);
433 res = 0;
434 }
435 UI_free(ui);
436 free(prompt);
437 }
438 return res;
439}
440
441static char *app_get_pass(BIO *err, char *arg, int keepbio);
442
443int
444app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
445{
446 int same;
447
448 if (!arg2 || !arg1 || strcmp(arg1, arg2))
449 same = 0;
450 else
451 same = 1;
452 if (arg1) {
453 *pass1 = app_get_pass(err, arg1, same);
454 if (!*pass1)
455 return 0;
456 } else if (pass1)
457 *pass1 = NULL;
458 if (arg2) {
459 *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
460 if (!*pass2)
461 return 0;
462 } else if (pass2)
463 *pass2 = NULL;
464 return 1;
465}
466
467static char *
468app_get_pass(BIO *err, char *arg, int keepbio)
469{
470 char *tmp, tpass[APP_PASS_LEN];
471 static BIO *pwdbio = NULL;
472 const char *errstr = NULL;
473 int i;
474
475 if (!strncmp(arg, "pass:", 5))
476 return strdup(arg + 5);
477 if (!strncmp(arg, "env:", 4)) {
478 tmp = getenv(arg + 4);
479 if (!tmp) {
480 BIO_printf(err, "Can't read environment variable %s\n",
481 arg + 4);
482 return NULL;
483 }
484 return strdup(tmp);
485 }
486 if (!keepbio || !pwdbio) {
487 if (!strncmp(arg, "file:", 5)) {
488 pwdbio = BIO_new_file(arg + 5, "r");
489 if (!pwdbio) {
490 BIO_printf(err, "Can't open file %s\n",
491 arg + 5);
492 return NULL;
493 }
494 } else if (!strncmp(arg, "fd:", 3)) {
495 BIO *btmp;
496 i = strtonum(arg + 3, 0, INT_MAX, &errstr);
497 if (errstr) {
498 BIO_printf(err,
499 "Invalid file descriptor %s: %s\n",
500 arg, errstr);
501 return NULL;
502 }
503 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
504 if (!pwdbio) {
505 BIO_printf(err,
506 "Can't access file descriptor %s\n",
507 arg + 3);
508 return NULL;
509 }
510 /*
511 * Can't do BIO_gets on an fd BIO so add a buffering
512 * BIO
513 */
514 btmp = BIO_new(BIO_f_buffer());
515 pwdbio = BIO_push(btmp, pwdbio);
516 } else if (!strcmp(arg, "stdin")) {
517 pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
518 if (!pwdbio) {
519 BIO_printf(err, "Can't open BIO for stdin\n");
520 return NULL;
521 }
522 } else {
523 BIO_printf(err, "Invalid password argument \"%s\"\n",
524 arg);
525 return NULL;
526 }
527 }
528 i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
529 if (keepbio != 1) {
530 BIO_free_all(pwdbio);
531 pwdbio = NULL;
532 }
533 if (i <= 0) {
534 BIO_printf(err, "Error reading password from BIO\n");
535 return NULL;
536 }
537 tmp = strchr(tpass, '\n');
538 if (tmp)
539 *tmp = 0;
540 return strdup(tpass);
541}
542
543int
544add_oid_section(BIO *err, CONF *conf)
545{
546 char *p;
547 STACK_OF(CONF_VALUE) *sktmp;
548 CONF_VALUE *cnf;
549 int i;
550
551 if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) {
552 ERR_clear_error();
553 return 1;
554 }
555 if (!(sktmp = NCONF_get_section(conf, p))) {
556 BIO_printf(err, "problem loading oid section %s\n", p);
557 return 0;
558 }
559 for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
560 cnf = sk_CONF_VALUE_value(sktmp, i);
561 if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
562 BIO_printf(err, "problem creating object %s=%s\n",
563 cnf->name, cnf->value);
564 return 0;
565 }
566 }
567 return 1;
568}
569
570static int
571load_pkcs12(BIO *err, BIO *in, const char *desc, pem_password_cb *pem_cb,
572 void *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
573{
574 const char *pass;
575 char tpass[PEM_BUFSIZE];
576 int len, ret = 0;
577 PKCS12 *p12;
578
579 p12 = d2i_PKCS12_bio(in, NULL);
580 if (p12 == NULL) {
581 BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
582 goto die;
583 }
584 /* See if an empty password will do */
585 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
586 pass = "";
587 else {
588 if (!pem_cb)
589 pem_cb = password_callback;
590 len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
591 if (len < 0) {
592 BIO_printf(err, "Passpharse callback error for %s\n",
593 desc);
594 goto die;
595 }
596 if (len < PEM_BUFSIZE)
597 tpass[len] = 0;
598 if (!PKCS12_verify_mac(p12, tpass, len)) {
599 BIO_printf(err,
600 "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
601 goto die;
602 }
603 pass = tpass;
604 }
605 ret = PKCS12_parse(p12, pass, pkey, cert, ca);
606
607die:
608 if (p12)
609 PKCS12_free(p12);
610 return ret;
611}
612
613X509 *
614load_cert(BIO *err, const char *file, int format, const char *pass, ENGINE *e,
615 const char *cert_descrip)
616{
617 X509 *x = NULL;
618 BIO *cert;
619
620 if ((cert = BIO_new(BIO_s_file())) == NULL) {
621 ERR_print_errors(err);
622 goto end;
623 }
624 if (file == NULL) {
625 setvbuf(stdin, NULL, _IONBF, 0);
626 BIO_set_fp(cert, stdin, BIO_NOCLOSE);
627 } else {
628 if (BIO_read_filename(cert, file) <= 0) {
629 BIO_printf(err, "Error opening %s %s\n",
630 cert_descrip, file);
631 ERR_print_errors(err);
632 goto end;
633 }
634 }
635
636 if (format == FORMAT_ASN1)
637 x = d2i_X509_bio(cert, NULL);
638 else if (format == FORMAT_NETSCAPE) {
639 NETSCAPE_X509 *nx;
640 nx = ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),
641 cert, NULL);
642 if (nx == NULL)
643 goto end;
644
645 if ((strncmp(NETSCAPE_CERT_HDR, (char *) nx->header->data,
646 nx->header->length) != 0)) {
647 NETSCAPE_X509_free(nx);
648 BIO_printf(err,
649 "Error reading header on certificate\n");
650 goto end;
651 }
652 x = nx->cert;
653 nx->cert = NULL;
654 NETSCAPE_X509_free(nx);
655 } else if (format == FORMAT_PEM)
656 x = PEM_read_bio_X509_AUX(cert, NULL, password_callback, NULL);
657 else if (format == FORMAT_PKCS12) {
658 if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL,
659 NULL, &x, NULL))
660 goto end;
661 } else {
662 BIO_printf(err, "bad input format specified for %s\n",
663 cert_descrip);
664 goto end;
665 }
666
667end:
668 if (x == NULL) {
669 BIO_printf(err, "unable to load certificate\n");
670 ERR_print_errors(err);
671 }
672 BIO_free(cert);
673 return (x);
674}
675
676EVP_PKEY *
677load_key(BIO *err, const char *file, int format, int maybe_stdin,
678 const char *pass, ENGINE *e, const char *key_descrip)
679{
680 BIO *key = NULL;
681 EVP_PKEY *pkey = NULL;
682 PW_CB_DATA cb_data;
683
684 cb_data.password = pass;
685 cb_data.prompt_info = file;
686
687 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
688 BIO_printf(err, "no keyfile specified\n");
689 goto end;
690 }
691#ifndef OPENSSL_NO_ENGINE
692 if (format == FORMAT_ENGINE) {
693 if (!e)
694 BIO_printf(err, "no engine specified\n");
695 else {
696 pkey = ENGINE_load_private_key(e, file,
697 ui_method, &cb_data);
698 if (!pkey) {
699 BIO_printf(err, "cannot load %s from engine\n",
700 key_descrip);
701 ERR_print_errors(err);
702 }
703 }
704 goto end;
705 }
706#endif
707 key = BIO_new(BIO_s_file());
708 if (key == NULL) {
709 ERR_print_errors(err);
710 goto end;
711 }
712 if (file == NULL && maybe_stdin) {
713 setvbuf(stdin, NULL, _IONBF, 0);
714 BIO_set_fp(key, stdin, BIO_NOCLOSE);
715 } else if (BIO_read_filename(key, file) <= 0) {
716 BIO_printf(err, "Error opening %s %s\n",
717 key_descrip, file);
718 ERR_print_errors(err);
719 goto end;
720 }
721 if (format == FORMAT_ASN1) {
722 pkey = d2i_PrivateKey_bio(key, NULL);
723 } else if (format == FORMAT_PEM) {
724 pkey = PEM_read_bio_PrivateKey(key, NULL, password_callback, &cb_data);
725 }
726#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
727 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
728 pkey = load_netscape_key(err, key, file, key_descrip, format);
729#endif
730 else if (format == FORMAT_PKCS12) {
731 if (!load_pkcs12(err, key, key_descrip, password_callback, &cb_data,
732 &pkey, NULL, NULL))
733 goto end;
734 }
735#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
736 else if (format == FORMAT_MSBLOB)
737 pkey = b2i_PrivateKey_bio(key);
738 else if (format == FORMAT_PVK)
739 pkey = b2i_PVK_bio(key, password_callback,
740 &cb_data);
741#endif
742 else {
743 BIO_printf(err, "bad input format specified for key file\n");
744 goto end;
745 }
746end:
747 BIO_free(key);
748 if (pkey == NULL) {
749 BIO_printf(err, "unable to load %s\n", key_descrip);
750 ERR_print_errors(err);
751 }
752 return (pkey);
753}
754
755EVP_PKEY *
756load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
757 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;
762
763 cb_data.password = pass;
764 cb_data.prompt_info = file;
765
766 if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
767 BIO_printf(err, "no keyfile specified\n");
768 goto end;
769 }
770#ifndef OPENSSL_NO_ENGINE
771 if (format == FORMAT_ENGINE) {
772 if (!e)
773 BIO_printf(bio_err, "no engine specified\n");
774 else
775 pkey = ENGINE_load_public_key(e, file,
776 ui_method, &cb_data);
777 goto end;
778 }
779#endif
780 key = BIO_new(BIO_s_file());
781 if (key == NULL) {
782 ERR_print_errors(err);
783 goto end;
784 }
785 if (file == NULL && maybe_stdin) {
786 setvbuf(stdin, NULL, _IONBF, 0);
787 BIO_set_fp(key, stdin, BIO_NOCLOSE);
788 } else if (BIO_read_filename(key, file) <= 0) {
789 BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
790 ERR_print_errors(err);
791 goto end;
792 }
793 if (format == FORMAT_ASN1) {
794 pkey = d2i_PUBKEY_bio(key, NULL);
795 }
796 else if (format == FORMAT_ASN1RSA) {
797 RSA *rsa;
798 rsa = d2i_RSAPublicKey_bio(key, NULL);
799 if (rsa) {
800 pkey = EVP_PKEY_new();
801 if (pkey)
802 EVP_PKEY_set1_RSA(pkey, rsa);
803 RSA_free(rsa);
804 } else
805 pkey = NULL;
806 } else if (format == FORMAT_PEMRSA) {
807 RSA *rsa;
808 rsa = PEM_read_bio_RSAPublicKey(key, NULL, password_callback, &cb_data);
809 if (rsa) {
810 pkey = EVP_PKEY_new();
811 if (pkey)
812 EVP_PKEY_set1_RSA(pkey, rsa);
813 RSA_free(rsa);
814 } else
815 pkey = NULL;
816 }
817 else if (format == FORMAT_PEM) {
818 pkey = PEM_read_bio_PUBKEY(key, NULL, password_callback, &cb_data);
819 }
820#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
821 else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
822 pkey = load_netscape_key(err, key, file, key_descrip, format);
823#endif
824#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
825 else if (format == FORMAT_MSBLOB)
826 pkey = b2i_PublicKey_bio(key);
827#endif
828 else {
829 BIO_printf(err, "bad input format specified for key file\n");
830 goto end;
831 }
832
833end:
834 BIO_free(key);
835 if (pkey == NULL)
836 BIO_printf(err, "unable to load %s\n", key_descrip);
837 return (pkey);
838}
839
840#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
841static EVP_PKEY *
842load_netscape_key(BIO *err, BIO *key, const char *file,
843 const char *key_descrip, int format)
844{
845 EVP_PKEY *pkey;
846 BUF_MEM *buf;
847 RSA *rsa;
848 const unsigned char *p;
849 int size, i;
850
851 buf = BUF_MEM_new();
852 pkey = EVP_PKEY_new();
853 size = 0;
854 if (buf == NULL || pkey == NULL)
855 goto error;
856 for (;;) {
857 if (!BUF_MEM_grow_clean(buf, size + 1024 * 10))
858 goto error;
859 i = BIO_read(key, &(buf->data[size]), 1024 * 10);
860 size += i;
861 if (i == 0)
862 break;
863 if (i < 0) {
864 BIO_printf(err, "Error reading %s %s",
865 key_descrip, file);
866 goto error;
867 }
868 }
869 p = (unsigned char *) buf->data;
870 rsa = d2i_RSA_NET(NULL, &p, (long) size, NULL,
871 (format == FORMAT_IISSGC ? 1 : 0));
872 if (rsa == NULL)
873 goto error;
874 BUF_MEM_free(buf);
875 EVP_PKEY_set1_RSA(pkey, rsa);
876 return pkey;
877
878error:
879 BUF_MEM_free(buf);
880 EVP_PKEY_free(pkey);
881 return NULL;
882}
883#endif /* ndef OPENSSL_NO_RC4 */
884
885static int
886load_certs_crls(BIO *err, const char *file, int format, const char *pass,
887 ENGINE *e, const char *desc, STACK_OF(X509) **pcerts,
888 STACK_OF(X509_CRL) **pcrls)
889{
890 int i;
891 BIO *bio;
892 STACK_OF(X509_INFO) *xis = NULL;
893 X509_INFO *xi;
894 PW_CB_DATA cb_data;
895 int rv = 0;
896
897 cb_data.password = pass;
898 cb_data.prompt_info = file;
899
900 if (format != FORMAT_PEM) {
901 BIO_printf(err, "bad input format specified for %s\n", desc);
902 return 0;
903 }
904 if (file == NULL)
905 bio = BIO_new_fp(stdin, BIO_NOCLOSE);
906 else
907 bio = BIO_new_file(file, "r");
908
909 if (bio == NULL) {
910 BIO_printf(err, "Error opening %s %s\n",
911 desc, file ? file : "stdin");
912 ERR_print_errors(err);
913 return 0;
914 }
915 xis = PEM_X509_INFO_read_bio(bio, NULL, password_callback, &cb_data);
916
917 BIO_free(bio);
918
919 if (pcerts) {
920 *pcerts = sk_X509_new_null();
921 if (!*pcerts)
922 goto end;
923 }
924 if (pcrls) {
925 *pcrls = sk_X509_CRL_new_null();
926 if (!*pcrls)
927 goto end;
928 }
929 for (i = 0; i < sk_X509_INFO_num(xis); i++) {
930 xi = sk_X509_INFO_value(xis, i);
931 if (xi->x509 && pcerts) {
932 if (!sk_X509_push(*pcerts, xi->x509))
933 goto end;
934 xi->x509 = NULL;
935 }
936 if (xi->crl && pcrls) {
937 if (!sk_X509_CRL_push(*pcrls, xi->crl))
938 goto end;
939 xi->crl = NULL;
940 }
941 }
942
943 if (pcerts && sk_X509_num(*pcerts) > 0)
944 rv = 1;
945
946 if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
947 rv = 1;
948
949end:
950 if (xis)
951 sk_X509_INFO_pop_free(xis, X509_INFO_free);
952
953 if (rv == 0) {
954 if (pcerts) {
955 sk_X509_pop_free(*pcerts, X509_free);
956 *pcerts = NULL;
957 }
958 if (pcrls) {
959 sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
960 *pcrls = NULL;
961 }
962 BIO_printf(err, "unable to load %s\n",
963 pcerts ? "certificates" : "CRLs");
964 ERR_print_errors(err);
965 }
966 return rv;
967}
968
969STACK_OF(X509) *
970load_certs(BIO *err, const char *file, int format, const char *pass,
971 ENGINE *e, const char *desc)
972{
973 STACK_OF(X509) *certs;
974
975 if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
976 return NULL;
977 return certs;
978}
979
980STACK_OF(X509_CRL) *
981load_crls(BIO *err, const char *file, int format, const char *pass, ENGINE *e,
982 const char *desc)
983{
984 STACK_OF(X509_CRL) *crls;
985
986 if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
987 return NULL;
988 return crls;
989}
990
991#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
992/* Return error for unknown extensions */
993#define X509V3_EXT_DEFAULT 0
994/* Print error for unknown extensions */
995#define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
996/* ASN1 parse unknown extensions */
997#define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
998/* BIO_dump unknown extensions */
999#define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
1000
1001#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
1002 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
1003
1004int
1005set_cert_ex(unsigned long *flags, const char *arg)
1006{
1007 static const NAME_EX_TBL cert_tbl[] = {
1008 {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
1009 {"ca_default", X509_FLAG_CA, 0xffffffffl},
1010 {"no_header", X509_FLAG_NO_HEADER, 0},
1011 {"no_version", X509_FLAG_NO_VERSION, 0},
1012 {"no_serial", X509_FLAG_NO_SERIAL, 0},
1013 {"no_signame", X509_FLAG_NO_SIGNAME, 0},
1014 {"no_validity", X509_FLAG_NO_VALIDITY, 0},
1015 {"no_subject", X509_FLAG_NO_SUBJECT, 0},
1016 {"no_issuer", X509_FLAG_NO_ISSUER, 0},
1017 {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
1018 {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
1019 {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
1020 {"no_aux", X509_FLAG_NO_AUX, 0},
1021 {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
1022 {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
1023 {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1024 {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1025 {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1026 {NULL, 0, 0}
1027 };
1028 return set_multi_opts(flags, arg, cert_tbl);
1029}
1030
1031int
1032set_name_ex(unsigned long *flags, const char *arg)
1033{
1034 static const NAME_EX_TBL ex_tbl[] = {
1035 {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
1036 {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
1037 {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
1038 {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
1039 {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
1040 {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
1041 {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
1042 {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
1043 {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
1044 {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
1045 {"compat", XN_FLAG_COMPAT, 0xffffffffL},
1046 {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
1047 {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
1048 {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
1049 {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
1050 {"dn_rev", XN_FLAG_DN_REV, 0},
1051 {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
1052 {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
1053 {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
1054 {"align", XN_FLAG_FN_ALIGN, 0},
1055 {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
1056 {"space_eq", XN_FLAG_SPC_EQ, 0},
1057 {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
1058 {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
1059 {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
1060 {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
1061 {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
1062 {NULL, 0, 0}
1063 };
1064 return set_multi_opts(flags, arg, ex_tbl);
1065}
1066
1067int
1068set_ext_copy(int *copy_type, const char *arg)
1069{
1070 if (!strcasecmp(arg, "none"))
1071 *copy_type = EXT_COPY_NONE;
1072 else if (!strcasecmp(arg, "copy"))
1073 *copy_type = EXT_COPY_ADD;
1074 else if (!strcasecmp(arg, "copyall"))
1075 *copy_type = EXT_COPY_ALL;
1076 else
1077 return 0;
1078 return 1;
1079}
1080
1081int
1082copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1083{
1084 STACK_OF(X509_EXTENSION) *exts = NULL;
1085 X509_EXTENSION *ext, *tmpext;
1086 ASN1_OBJECT *obj;
1087 int i, idx, ret = 0;
1088
1089 if (!x || !req || (copy_type == EXT_COPY_NONE))
1090 return 1;
1091 exts = X509_REQ_get_extensions(req);
1092
1093 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1094 ext = sk_X509_EXTENSION_value(exts, i);
1095 obj = X509_EXTENSION_get_object(ext);
1096 idx = X509_get_ext_by_OBJ(x, obj, -1);
1097 /* Does extension exist? */
1098 if (idx != -1) {
1099 /* If normal copy don't override existing extension */
1100 if (copy_type == EXT_COPY_ADD)
1101 continue;
1102 /* Delete all extensions of same type */
1103 do {
1104 tmpext = X509_get_ext(x, idx);
1105 X509_delete_ext(x, idx);
1106 X509_EXTENSION_free(tmpext);
1107 idx = X509_get_ext_by_OBJ(x, obj, -1);
1108 } while (idx != -1);
1109 }
1110 if (!X509_add_ext(x, ext, -1))
1111 goto end;
1112 }
1113
1114 ret = 1;
1115
1116end:
1117 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
1118
1119 return ret;
1120}
1121
1122static int
1123set_multi_opts(unsigned long *flags, const char *arg,
1124 const NAME_EX_TBL *in_tbl)
1125{
1126 STACK_OF(CONF_VALUE) *vals;
1127 CONF_VALUE *val;
1128 int i, ret = 1;
1129
1130 if (!arg)
1131 return 0;
1132 vals = X509V3_parse_list(arg);
1133 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1134 val = sk_CONF_VALUE_value(vals, i);
1135 if (!set_table_opts(flags, val->name, in_tbl))
1136 ret = 0;
1137 }
1138 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1139 return ret;
1140}
1141
1142static int
1143set_table_opts(unsigned long *flags, const char *arg,
1144 const NAME_EX_TBL *in_tbl)
1145{
1146 char c;
1147 const NAME_EX_TBL *ptbl;
1148
1149 c = arg[0];
1150 if (c == '-') {
1151 c = 0;
1152 arg++;
1153 } else if (c == '+') {
1154 c = 1;
1155 arg++;
1156 } else
1157 c = 1;
1158
1159 for (ptbl = in_tbl; ptbl->name; ptbl++) {
1160 if (!strcasecmp(arg, ptbl->name)) {
1161 *flags &= ~ptbl->mask;
1162 if (c)
1163 *flags |= ptbl->flag;
1164 else
1165 *flags &= ~ptbl->flag;
1166 return 1;
1167 }
1168 }
1169 return 0;
1170}
1171
1172void
1173print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
1174{
1175 char *buf;
1176 char mline = 0;
1177 int indent = 0;
1178
1179 if (title)
1180 BIO_puts(out, title);
1181 if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1182 mline = 1;
1183 indent = 4;
1184 }
1185 if (lflags == XN_FLAG_COMPAT) {
1186 buf = X509_NAME_oneline(nm, 0, 0);
1187 BIO_puts(out, buf);
1188 BIO_puts(out, "\n");
1189 free(buf);
1190 } else {
1191 if (mline)
1192 BIO_puts(out, "\n");
1193 X509_NAME_print_ex(out, nm, indent, lflags);
1194 BIO_puts(out, "\n");
1195 }
1196}
1197
1198X509_STORE *
1199setup_verify(BIO *bp, char *CAfile, char *CApath)
1200{
1201 X509_STORE *store;
1202 X509_LOOKUP *lookup;
1203
1204 if (!(store = X509_STORE_new()))
1205 goto end;
1206 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1207 if (lookup == NULL)
1208 goto end;
1209 if (CAfile) {
1210 if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
1211 BIO_printf(bp, "Error loading file %s\n", CAfile);
1212 goto end;
1213 }
1214 } else
1215 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
1216
1217 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1218 if (lookup == NULL)
1219 goto end;
1220 if (CApath) {
1221 if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1222 BIO_printf(bp, "Error loading directory %s\n", CApath);
1223 goto end;
1224 }
1225 } else
1226 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1227
1228 ERR_clear_error();
1229 return store;
1230
1231end:
1232 X509_STORE_free(store);
1233 return NULL;
1234}
1235
1236#ifndef OPENSSL_NO_ENGINE
1237/* Try to load an engine in a shareable library */
1238static ENGINE *
1239try_load_engine(BIO *err, const char *engine, int debug)
1240{
1241 ENGINE *e = ENGINE_by_id("dynamic");
1242
1243 if (e) {
1244 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) ||
1245 !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
1246 ENGINE_free(e);
1247 e = NULL;
1248 }
1249 }
1250 return e;
1251}
1252
1253ENGINE *
1254setup_engine(BIO *err, const char *engine, int debug)
1255{
1256 ENGINE *e = NULL;
1257
1258 if (engine) {
1259 if (strcmp(engine, "auto") == 0) {
1260 BIO_printf(err, "enabling auto ENGINE support\n");
1261 ENGINE_register_all_complete();
1262 return NULL;
1263 }
1264 if ((e = ENGINE_by_id(engine)) == NULL &&
1265 (e = try_load_engine(err, engine, debug)) == NULL) {
1266 BIO_printf(err, "invalid engine \"%s\"\n", engine);
1267 ERR_print_errors(err);
1268 return NULL;
1269 }
1270 if (debug) {
1271 ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
1272 0, err, 0);
1273 }
1274 ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
1275 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
1276 BIO_printf(err, "can't use that engine\n");
1277 ERR_print_errors(err);
1278 ENGINE_free(e);
1279 return NULL;
1280 }
1281 BIO_printf(err, "engine \"%s\" set.\n", ENGINE_get_id(e));
1282
1283 /* Free our "structural" reference. */
1284 ENGINE_free(e);
1285 }
1286 return e;
1287}
1288#endif
1289
1290int
1291load_config(BIO *err, CONF *cnf)
1292{
1293 static int load_config_called = 0;
1294
1295 if (load_config_called)
1296 return 1;
1297 load_config_called = 1;
1298 if (cnf == NULL)
1299 cnf = config;
1300 if (cnf == NULL)
1301 return 1;
1302
1303 OPENSSL_load_builtin_modules();
1304
1305 if (CONF_modules_load(cnf, NULL, 0) <= 0) {
1306 BIO_printf(err, "Error configuring OpenSSL\n");
1307 ERR_print_errors(err);
1308 return 0;
1309 }
1310 return 1;
1311}
1312
1313char *
1314make_config_name()
1315{
1316 const char *t = X509_get_default_cert_area();
1317 char *p;
1318
1319 if (asprintf(&p, "%s/openssl.cnf", t) == -1)
1320 return NULL;
1321 return p;
1322}
1323
1324static unsigned long
1325index_serial_hash(const OPENSSL_CSTRING *a)
1326{
1327 const char *n;
1328
1329 n = a[DB_serial];
1330 while (*n == '0')
1331 n++;
1332 return (lh_strhash(n));
1333}
1334
1335static int
1336index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1337{
1338 const char *aa, *bb;
1339
1340 for (aa = a[DB_serial]; *aa == '0'; aa++)
1341 ;
1342 for (bb = b[DB_serial]; *bb == '0'; bb++)
1343 ;
1344 return (strcmp(aa, bb));
1345}
1346
1347static int
1348index_name_qual(char **a)
1349{
1350 return (a[0][0] == 'V');
1351}
1352
1353static unsigned long
1354index_name_hash(const OPENSSL_CSTRING *a)
1355{
1356 return (lh_strhash(a[DB_name]));
1357}
1358
1359int
1360index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1361{
1362 return (strcmp(a[DB_name], b[DB_name]));
1363}
1364
1365static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1366static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1367static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1368static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1369
1370#define BSIZE 256
1371
1372BIGNUM *
1373load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
1374{
1375 BIO *in = NULL;
1376 BIGNUM *ret = NULL;
1377 char buf[1024];
1378 ASN1_INTEGER *ai = NULL;
1379
1380 ai = ASN1_INTEGER_new();
1381 if (ai == NULL)
1382 goto err;
1383
1384 if ((in = BIO_new(BIO_s_file())) == NULL) {
1385 ERR_print_errors(bio_err);
1386 goto err;
1387 }
1388 if (BIO_read_filename(in, serialfile) <= 0) {
1389 if (!create) {
1390 perror(serialfile);
1391 goto err;
1392 } else {
1393 ret = BN_new();
1394 if (ret == NULL || !rand_serial(ret, ai))
1395 BIO_printf(bio_err, "Out of memory\n");
1396 }
1397 } else {
1398 if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
1399 BIO_printf(bio_err, "unable to load number from %s\n",
1400 serialfile);
1401 goto err;
1402 }
1403 ret = ASN1_INTEGER_to_BN(ai, NULL);
1404 if (ret == NULL) {
1405 BIO_printf(bio_err,
1406 "error converting number from bin to BIGNUM\n");
1407 goto err;
1408 }
1409 }
1410
1411 if (ret && retai) {
1412 *retai = ai;
1413 ai = NULL;
1414 }
1415
1416err:
1417 if (in != NULL)
1418 BIO_free(in);
1419 if (ai != NULL)
1420 ASN1_INTEGER_free(ai);
1421 return (ret);
1422}
1423
1424int
1425save_serial(char *serialfile, char *suffix, BIGNUM *serial,
1426 ASN1_INTEGER **retai)
1427{
1428 char buf[1][BSIZE];
1429 BIO *out = NULL;
1430 int ret = 0, n;
1431 ASN1_INTEGER *ai = NULL;
1432 int j;
1433
1434 if (suffix == NULL)
1435 j = strlen(serialfile);
1436 else
1437 j = strlen(serialfile) + strlen(suffix) + 1;
1438 if (j >= BSIZE) {
1439 BIO_printf(bio_err, "file name too long\n");
1440 goto err;
1441 }
1442 if (suffix == NULL)
1443 n = strlcpy(buf[0], serialfile, BSIZE);
1444 else
1445 n = snprintf(buf[0], sizeof buf[0], "%s.%s",
1446 serialfile, suffix);
1447 if (n == -1 || n >= sizeof(buf[0])) {
1448 BIO_printf(bio_err, "serial too long\n");
1449 goto err;
1450 }
1451 out = BIO_new(BIO_s_file());
1452 if (out == NULL) {
1453 ERR_print_errors(bio_err);
1454 goto err;
1455 }
1456 if (BIO_write_filename(out, buf[0]) <= 0) {
1457 perror(serialfile);
1458 goto err;
1459 }
1460 if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1461 BIO_printf(bio_err,
1462 "error converting serial to ASN.1 format\n");
1463 goto err;
1464 }
1465 i2a_ASN1_INTEGER(out, ai);
1466 BIO_puts(out, "\n");
1467 ret = 1;
1468 if (retai) {
1469 *retai = ai;
1470 ai = NULL;
1471 }
1472
1473err:
1474 if (out != NULL)
1475 BIO_free_all(out);
1476 if (ai != NULL)
1477 ASN1_INTEGER_free(ai);
1478 return (ret);
1479}
1480
1481int
1482rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
1483{
1484 char buf[5][BSIZE];
1485 int i, j;
1486
1487 i = strlen(serialfile) + strlen(old_suffix);
1488 j = strlen(serialfile) + strlen(new_suffix);
1489 if (i > j)
1490 j = i;
1491 if (j + 1 >= BSIZE) {
1492 BIO_printf(bio_err, "file name too long\n");
1493 goto err;
1494 }
1495 snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix);
1496 snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix);
1497
1498
1499 if (rename(serialfile, buf[1]) < 0 &&
1500 errno != ENOENT && errno != ENOTDIR) {
1501 BIO_printf(bio_err, "unable to rename %s to %s\n",
1502 serialfile, buf[1]);
1503 perror("reason");
1504 goto err;
1505 }
1506
1507
1508 if (rename(buf[0], serialfile) < 0) {
1509 BIO_printf(bio_err, "unable to rename %s to %s\n",
1510 buf[0], serialfile);
1511 perror("reason");
1512 rename(buf[1], serialfile);
1513 goto err;
1514 }
1515 return 1;
1516
1517err:
1518 return 0;
1519}
1520
1521int
1522rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1523{
1524 BIGNUM *btmp;
1525 int ret = 0;
1526
1527 if (b)
1528 btmp = b;
1529 else
1530 btmp = BN_new();
1531
1532 if (!btmp)
1533 return 0;
1534
1535 if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1536 goto error;
1537 if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1538 goto error;
1539
1540 ret = 1;
1541
1542error:
1543 if (!b)
1544 BN_free(btmp);
1545
1546 return ret;
1547}
1548
1549CA_DB *
1550load_index(char *dbfile, DB_ATTR *db_attr)
1551{
1552 CA_DB *retdb = NULL;
1553 TXT_DB *tmpdb = NULL;
1554 BIO *in = BIO_new(BIO_s_file());
1555 CONF *dbattr_conf = NULL;
1556 char buf[1][BSIZE];
1557 long errorline = -1;
1558
1559 if (in == NULL) {
1560 ERR_print_errors(bio_err);
1561 goto err;
1562 }
1563 if (BIO_read_filename(in, dbfile) <= 0) {
1564 perror(dbfile);
1565 BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1566 goto err;
1567 }
1568 if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1569 goto err;
1570
1571 snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
1572 dbattr_conf = NCONF_new(NULL);
1573 if (NCONF_load(dbattr_conf, buf[0], &errorline) <= 0) {
1574 if (errorline > 0) {
1575 BIO_printf(bio_err,
1576 "error on line %ld of db attribute file '%s'\n",
1577 errorline, buf[0]);
1578 goto err;
1579 } else {
1580 NCONF_free(dbattr_conf);
1581 dbattr_conf = NULL;
1582 }
1583 }
1584 if ((retdb = malloc(sizeof(CA_DB))) == NULL) {
1585 fprintf(stderr, "Out of memory\n");
1586 goto err;
1587 }
1588 retdb->db = tmpdb;
1589 tmpdb = NULL;
1590 if (db_attr)
1591 retdb->attributes = *db_attr;
1592 else {
1593 retdb->attributes.unique_subject = 1;
1594 }
1595
1596 if (dbattr_conf) {
1597 char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1598 if (p) {
1599 retdb->attributes.unique_subject = parse_yesno(p, 1);
1600 }
1601 }
1602
1603err:
1604 if (dbattr_conf)
1605 NCONF_free(dbattr_conf);
1606 if (tmpdb)
1607 TXT_DB_free(tmpdb);
1608 if (in)
1609 BIO_free_all(in);
1610 return retdb;
1611}
1612
1613int
1614index_index(CA_DB *db)
1615{
1616 if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1617 LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) {
1618 BIO_printf(bio_err,
1619 "error creating serial number index:(%ld,%ld,%ld)\n",
1620 db->db->error, db->db->arg1, db->db->arg2);
1621 return 0;
1622 }
1623 if (db->attributes.unique_subject &&
1624 !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1625 LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) {
1626 BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
1627 db->db->error, db->db->arg1, db->db->arg2);
1628 return 0;
1629 }
1630 return 1;
1631}
1632
1633int
1634save_index(const char *dbfile, const char *suffix, CA_DB *db)
1635{
1636 char buf[3][BSIZE];
1637 BIO *out = BIO_new(BIO_s_file());
1638 int j;
1639
1640 if (out == NULL) {
1641 ERR_print_errors(bio_err);
1642 goto err;
1643 }
1644 j = strlen(dbfile) + strlen(suffix);
1645 if (j + 6 >= BSIZE) {
1646 BIO_printf(bio_err, "file name too long\n");
1647 goto err;
1648 }
1649 snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
1650 snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
1651 snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
1652
1653
1654 if (BIO_write_filename(out, buf[0]) <= 0) {
1655 perror(dbfile);
1656 BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1657 goto err;
1658 }
1659 j = TXT_DB_write(out, db->db);
1660 if (j <= 0)
1661 goto err;
1662
1663 BIO_free(out);
1664
1665 out = BIO_new(BIO_s_file());
1666
1667
1668 if (BIO_write_filename(out, buf[1]) <= 0) {
1669 perror(buf[2]);
1670 BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
1671 goto err;
1672 }
1673 BIO_printf(out, "unique_subject = %s\n",
1674 db->attributes.unique_subject ? "yes" : "no");
1675 BIO_free(out);
1676
1677 return 1;
1678
1679err:
1680 return 0;
1681}
1682
1683int
1684rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
1685{
1686 char buf[5][BSIZE];
1687 int i, j;
1688
1689 i = strlen(dbfile) + strlen(old_suffix);
1690 j = strlen(dbfile) + strlen(new_suffix);
1691 if (i > j)
1692 j = i;
1693 if (j + 6 >= BSIZE) {
1694 BIO_printf(bio_err, "file name too long\n");
1695 goto err;
1696 }
1697 snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
1698 snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix);
1699 snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix);
1700 snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix);
1701 snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix);
1702
1703
1704 if (rename(dbfile, buf[1]) < 0 && errno != ENOENT && errno != ENOTDIR) {
1705 BIO_printf(bio_err, "unable to rename %s to %s\n",
1706 dbfile, buf[1]);
1707 perror("reason");
1708 goto err;
1709 }
1710
1711
1712 if (rename(buf[0], dbfile) < 0) {
1713 BIO_printf(bio_err, "unable to rename %s to %s\n",
1714 buf[0], dbfile);
1715 perror("reason");
1716 rename(buf[1], dbfile);
1717 goto err;
1718 }
1719
1720
1721 if (rename(buf[4], buf[3]) < 0 && errno != ENOENT && errno != ENOTDIR) {
1722 BIO_printf(bio_err, "unable to rename %s to %s\n",
1723 buf[4], buf[3]);
1724 perror("reason");
1725 rename(dbfile, buf[0]);
1726 rename(buf[1], dbfile);
1727 goto err;
1728 }
1729
1730
1731 if (rename(buf[2], buf[4]) < 0) {
1732 BIO_printf(bio_err, "unable to rename %s to %s\n",
1733 buf[2], buf[4]);
1734 perror("reason");
1735 rename(buf[3], buf[4]);
1736 rename(dbfile, buf[0]);
1737 rename(buf[1], dbfile);
1738 goto err;
1739 }
1740 return 1;
1741
1742err:
1743 return 0;
1744}
1745
1746void
1747free_index(CA_DB *db)
1748{
1749 if (db) {
1750 if (db->db)
1751 TXT_DB_free(db->db);
1752 free(db);
1753 }
1754}
1755
1756int
1757parse_yesno(const char *str, int def)
1758{
1759 int ret = def;
1760
1761 if (str) {
1762 switch (*str) {
1763 case 'f': /* false */
1764 case 'F': /* FALSE */
1765 case 'n': /* no */
1766 case 'N': /* NO */
1767 case '0': /* 0 */
1768 ret = 0;
1769 break;
1770 case 't': /* true */
1771 case 'T': /* TRUE */
1772 case 'y': /* yes */
1773 case 'Y': /* YES */
1774 case '1': /* 1 */
1775 ret = 1;
1776 break;
1777 default:
1778 ret = def;
1779 break;
1780 }
1781 }
1782 return ret;
1783}
1784
1785/*
1786 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1787 * where characters may be escaped by \
1788 */
1789X509_NAME *
1790parse_name(char *subject, long chtype, int multirdn)
1791{
1792 X509_NAME *name = NULL;
1793 size_t buflen, max_ne;
1794 char **ne_types, **ne_values;
1795 char *buf, *bp, *sp;
1796 int i, nid, ne_num = 0;
1797 int *mval;
1798
1799 /*
1800 * Buffer to copy the types and values into. Due to escaping the
1801 * copy can only become shorter.
1802 */
1803 buflen = strlen(subject) + 1;
1804 buf = malloc(buflen);
1805
1806 /* Maximum number of name elements. */
1807 max_ne = buflen / 2 + 1;
1808 ne_types = reallocarray(NULL, max_ne, sizeof(char *));
1809 ne_values = reallocarray(NULL, max_ne, sizeof(char *));
1810 mval = reallocarray(NULL, max_ne, sizeof(int));
1811
1812 if (buf == NULL || ne_types == NULL || ne_values == NULL ||
1813 mval == NULL) {
1814 BIO_printf(bio_err, "malloc error\n");
1815 goto error;
1816 }
1817
1818 bp = buf;
1819 sp = subject;
1820
1821 if (*subject != '/') {
1822 BIO_printf(bio_err, "Subject does not start with '/'.\n");
1823 goto error;
1824 }
1825
1826 /* Skip leading '/'. */
1827 sp++;
1828
1829 /* No multivalued RDN by default. */
1830 mval[ne_num] = 0;
1831
1832 while (*sp) {
1833 /* Collect type. */
1834 ne_types[ne_num] = bp;
1835 while (*sp) {
1836 /* is there anything to escape in the type...? */
1837 if (*sp == '\\') {
1838 if (*++sp)
1839 *bp++ = *sp++;
1840 else {
1841 BIO_printf(bio_err, "escape character "
1842 "at end of string\n");
1843 goto error;
1844 }
1845 } else if (*sp == '=') {
1846 sp++;
1847 *bp++ = '\0';
1848 break;
1849 } else
1850 *bp++ = *sp++;
1851 }
1852 if (!*sp) {
1853 BIO_printf(bio_err, "end of string encountered while "
1854 "processing type of subject name element #%d\n",
1855 ne_num);
1856 goto error;
1857 }
1858 ne_values[ne_num] = bp;
1859 while (*sp) {
1860 if (*sp == '\\') {
1861 if (*++sp)
1862 *bp++ = *sp++;
1863 else {
1864 BIO_printf(bio_err, "escape character "
1865 "at end of string\n");
1866 goto error;
1867 }
1868 } else if (*sp == '/') {
1869 sp++;
1870 /* no multivalued RDN by default */
1871 mval[ne_num + 1] = 0;
1872 break;
1873 } else if (*sp == '+' && multirdn) {
1874 /* a not escaped + signals a mutlivalued RDN */
1875 sp++;
1876 mval[ne_num + 1] = -1;
1877 break;
1878 } else
1879 *bp++ = *sp++;
1880 }
1881 *bp++ = '\0';
1882 ne_num++;
1883 }
1884
1885 if ((name = X509_NAME_new()) == NULL)
1886 goto error;
1887
1888 for (i = 0; i < ne_num; i++) {
1889 if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
1890 BIO_printf(bio_err,
1891 "Subject Attribute %s has no known NID, skipped\n",
1892 ne_types[i]);
1893 continue;
1894 }
1895 if (!*ne_values[i]) {
1896 BIO_printf(bio_err, "No value provided for Subject "
1897 "Attribute %s, skipped\n", ne_types[i]);
1898 continue;
1899 }
1900 if (!X509_NAME_add_entry_by_NID(name, nid, chtype,
1901 (unsigned char *) ne_values[i], -1, -1, mval[i]))
1902 goto error;
1903 }
1904 goto done;
1905
1906error:
1907 X509_NAME_free(name);
1908 name = NULL;
1909
1910done:
1911 free(ne_values);
1912 free(ne_types);
1913 free(mval);
1914 free(buf);
1915
1916 return name;
1917}
1918
1919int
1920args_verify(char ***pargs, int *pargc, int *badarg, BIO *err,
1921 X509_VERIFY_PARAM **pm)
1922{
1923 ASN1_OBJECT *otmp = NULL;
1924 unsigned long flags = 0;
1925 int i;
1926 int purpose = 0, depth = -1;
1927 char **oldargs = *pargs;
1928 char *arg = **pargs, *argn = (*pargs)[1];
1929 time_t at_time = 0;
1930 const char *errstr = NULL;
1931
1932 if (!strcmp(arg, "-policy")) {
1933 if (!argn)
1934 *badarg = 1;
1935 else {
1936 otmp = OBJ_txt2obj(argn, 0);
1937 if (!otmp) {
1938 BIO_printf(err, "Invalid Policy \"%s\"\n",
1939 argn);
1940 *badarg = 1;
1941 }
1942 }
1943 (*pargs)++;
1944 } else if (strcmp(arg, "-purpose") == 0) {
1945 X509_PURPOSE *xptmp;
1946 if (!argn)
1947 *badarg = 1;
1948 else {
1949 i = X509_PURPOSE_get_by_sname(argn);
1950 if (i < 0) {
1951 BIO_printf(err, "unrecognized purpose\n");
1952 *badarg = 1;
1953 } else {
1954 xptmp = X509_PURPOSE_get0(i);
1955 purpose = X509_PURPOSE_get_id(xptmp);
1956 }
1957 }
1958 (*pargs)++;
1959 } else if (strcmp(arg, "-verify_depth") == 0) {
1960 if (!argn)
1961 *badarg = 1;
1962 else {
1963 depth = strtonum(argn, 1, INT_MAX, &errstr);
1964 if (errstr) {
1965 BIO_printf(err, "invalid depth %s: %s\n",
1966 argn, errstr);
1967 *badarg = 1;
1968 }
1969 }
1970 (*pargs)++;
1971 } else if (strcmp(arg, "-attime") == 0) {
1972 if (!argn)
1973 *badarg = 1;
1974 else {
1975 long long timestamp;
1976 /*
1977 * interpret the -attime argument as seconds since
1978 * Epoch
1979 */
1980 if (sscanf(argn, "%lli", &timestamp) != 1) {
1981 BIO_printf(bio_err,
1982 "Error parsing timestamp %s\n",
1983 argn);
1984 *badarg = 1;
1985 }
1986 /* XXX 2038 truncation */
1987 at_time = (time_t) timestamp;
1988 }
1989 (*pargs)++;
1990 } else if (!strcmp(arg, "-ignore_critical"))
1991 flags |= X509_V_FLAG_IGNORE_CRITICAL;
1992 else if (!strcmp(arg, "-issuer_checks"))
1993 flags |= X509_V_FLAG_CB_ISSUER_CHECK;
1994 else if (!strcmp(arg, "-crl_check"))
1995 flags |= X509_V_FLAG_CRL_CHECK;
1996 else if (!strcmp(arg, "-crl_check_all"))
1997 flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
1998 else if (!strcmp(arg, "-policy_check"))
1999 flags |= X509_V_FLAG_POLICY_CHECK;
2000 else if (!strcmp(arg, "-explicit_policy"))
2001 flags |= X509_V_FLAG_EXPLICIT_POLICY;
2002 else if (!strcmp(arg, "-inhibit_any"))
2003 flags |= X509_V_FLAG_INHIBIT_ANY;
2004 else if (!strcmp(arg, "-inhibit_map"))
2005 flags |= X509_V_FLAG_INHIBIT_MAP;
2006 else if (!strcmp(arg, "-x509_strict"))
2007 flags |= X509_V_FLAG_X509_STRICT;
2008 else if (!strcmp(arg, "-extended_crl"))
2009 flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
2010 else if (!strcmp(arg, "-use_deltas"))
2011 flags |= X509_V_FLAG_USE_DELTAS;
2012 else if (!strcmp(arg, "-policy_print"))
2013 flags |= X509_V_FLAG_NOTIFY_POLICY;
2014 else if (!strcmp(arg, "-check_ss_sig"))
2015 flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
2016 else
2017 return 0;
2018
2019 if (*badarg) {
2020 if (*pm)
2021 X509_VERIFY_PARAM_free(*pm);
2022 *pm = NULL;
2023 goto end;
2024 }
2025 if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) {
2026 *badarg = 1;
2027 goto end;
2028 }
2029 if (otmp)
2030 X509_VERIFY_PARAM_add0_policy(*pm, otmp);
2031 if (flags)
2032 X509_VERIFY_PARAM_set_flags(*pm, flags);
2033
2034 if (purpose)
2035 X509_VERIFY_PARAM_set_purpose(*pm, purpose);
2036
2037 if (depth >= 0)
2038 X509_VERIFY_PARAM_set_depth(*pm, depth);
2039
2040 if (at_time)
2041 X509_VERIFY_PARAM_set_time(*pm, at_time);
2042
2043end:
2044 (*pargs)++;
2045
2046 if (pargc)
2047 *pargc -= *pargs - oldargs;
2048
2049 return 1;
2050}
2051
2052/* Read whole contents of a BIO into an allocated memory buffer and
2053 * return it.
2054 */
2055
2056int
2057bio_to_mem(unsigned char **out, int maxlen, BIO *in)
2058{
2059 BIO *mem;
2060 int len, ret;
2061 unsigned char tbuf[1024];
2062
2063 mem = BIO_new(BIO_s_mem());
2064 if (!mem)
2065 return -1;
2066 for (;;) {
2067 if ((maxlen != -1) && maxlen < 1024)
2068 len = maxlen;
2069 else
2070 len = 1024;
2071 len = BIO_read(in, tbuf, len);
2072 if (len <= 0)
2073 break;
2074 if (BIO_write(mem, tbuf, len) != len) {
2075 BIO_free(mem);
2076 return -1;
2077 }
2078 maxlen -= len;
2079
2080 if (maxlen == 0)
2081 break;
2082 }
2083 ret = BIO_get_mem_data(mem, (char **) out);
2084 BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
2085 BIO_free(mem);
2086 return ret;
2087}
2088
2089int
2090pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
2091{
2092 int rv;
2093 char *stmp, *vtmp = NULL;
2094
2095 stmp = BUF_strdup(value);
2096 if (!stmp)
2097 return -1;
2098 vtmp = strchr(stmp, ':');
2099 if (vtmp) {
2100 *vtmp = 0;
2101 vtmp++;
2102 }
2103 rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
2104 free(stmp);
2105
2106 return rv;
2107}
2108
2109static void
2110nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
2111{
2112 X509_POLICY_NODE *node;
2113 int i;
2114
2115 BIO_printf(out, "%s Policies:", name);
2116 if (nodes) {
2117 BIO_puts(out, "\n");
2118 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
2119 node = sk_X509_POLICY_NODE_value(nodes, i);
2120 X509_POLICY_NODE_print(out, node, 2);
2121 }
2122 } else
2123 BIO_puts(out, " <empty>\n");
2124}
2125
2126void
2127policies_print(BIO *out, X509_STORE_CTX *ctx)
2128{
2129 X509_POLICY_TREE *tree;
2130 int explicit_policy;
2131 int free_out = 0;
2132
2133 if (out == NULL) {
2134 out = BIO_new_fp(stderr, BIO_NOCLOSE);
2135 free_out = 1;
2136 }
2137 tree = X509_STORE_CTX_get0_policy_tree(ctx);
2138 explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
2139
2140 BIO_printf(out, "Require explicit Policy: %s\n",
2141 explicit_policy ? "True" : "False");
2142
2143 nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
2144 nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
2145 if (free_out)
2146 BIO_free(out);
2147}
2148
2149#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
2150/* next_protos_parse parses a comma separated list of strings into a string
2151 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
2152 * outlen: (output) set to the length of the resulting buffer on success.
2153 * err: (maybe NULL) on failure, an error message line is written to this BIO.
2154 * in: a NUL termianted string like "abc,def,ghi"
2155 *
2156 * returns: a malloced buffer or NULL on failure.
2157 */
2158unsigned char *
2159next_protos_parse(unsigned short *outlen, const char *in)
2160{
2161 size_t len;
2162 unsigned char *out;
2163 size_t i, start = 0;
2164
2165 len = strlen(in);
2166 if (len >= 65535)
2167 return NULL;
2168
2169 out = malloc(strlen(in) + 1);
2170 if (!out)
2171 return NULL;
2172
2173 for (i = 0; i <= len; ++i) {
2174 if (i == len || in[i] == ',') {
2175 if (i - start > 255) {
2176 free(out);
2177 return NULL;
2178 }
2179 out[start] = i - start;
2180 start = i + 1;
2181 } else
2182 out[i + 1] = in[i];
2183 }
2184
2185 *outlen = len + 1;
2186 return out;
2187}
2188#endif
2189/* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
2190
2191double
2192app_tminterval(int stop, int usertime)
2193{
2194 double ret = 0;
2195 struct tms rus;
2196 clock_t now = times(&rus);
2197 static clock_t tmstart;
2198
2199 if (usertime)
2200 now = rus.tms_utime;
2201
2202 if (stop == TM_START)
2203 tmstart = now;
2204 else {
2205 long int tck = sysconf(_SC_CLK_TCK);
2206 ret = (now - tmstart) / (double) tck;
2207 }
2208
2209 return (ret);
2210}
2211
2212int
2213app_isdir(const char *name)
2214{
2215 struct stat st;
2216
2217 if (stat(name, &st) == 0)
2218 return S_ISDIR(st.st_mode);
2219 return -1;
2220}