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