1/* apps/apps.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 *    notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 *    notice, this list of conditions and the following disclaimer in
70 *    the documentation and/or other materials provided with the
71 *    distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 *    software must display the following acknowledgment:
75 *    "This product includes software developed by the OpenSSL Project
76 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 *    endorse or promote products derived from this software without
80 *    prior written permission. For written permission, please contact
81 *    openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 *    nor may "OpenSSL" appear in their names without prior written
85 *    permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 *    acknowledgment:
89 *    "This product includes software developed by the OpenSSL Project
90 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com).  This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
113/*
114 * On VMS, you need to define this to get the declaration of fileno().  The
115 * value 2 is to make sure no function defined in POSIX-2 is left undefined.
116 */
117# define _POSIX_C_SOURCE 2
118#endif
119#include <stdio.h>
120#include <stdlib.h>
121#include <string.h>
122#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(OPENSSL_SYSNAME_WINCE) && !defined(NETWARE_CLIB)
123# include <strings.h>
124#endif
125#include <sys/types.h>
126#include <ctype.h>
127#include <errno.h>
128#include <assert.h>
129#include <openssl/err.h>
130#include <openssl/x509.h>
131#include <openssl/x509v3.h>
132#include <openssl/pem.h>
133#include <openssl/pkcs12.h>
134#include <openssl/ui.h>
135#include <openssl/safestack.h>
136#ifndef OPENSSL_NO_ENGINE
137# include <openssl/engine.h>
138#endif
139#ifndef OPENSSL_NO_RSA
140# include <openssl/rsa.h>
141#endif
142#include <openssl/bn.h>
143#ifndef OPENSSL_NO_JPAKE
144# include <openssl/jpake.h>
145#endif
146
147#define NON_MAIN
148#include "apps.h"
149#undef NON_MAIN
150
151#ifdef _WIN32
152static int WIN32_rename(const char *from, const char *to);
153# define rename(from,to) WIN32_rename((from),(to))
154#endif
155
156typedef struct {
157    const char *name;
158    unsigned long flag;
159    unsigned long mask;
160} NAME_EX_TBL;
161
162static UI_METHOD *ui_method = NULL;
163
164static int set_table_opts(unsigned long *flags, const char *arg,
165                          const NAME_EX_TBL * in_tbl);
166static int set_multi_opts(unsigned long *flags, const char *arg,
167                          const NAME_EX_TBL * in_tbl);
168
169#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
170/* Looks like this stuff is worth moving into separate function */
171static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
172                                   const char *key_descrip, int format);
173#endif
174
175int app_init(long mesgwin);
176#ifdef undef                    /* never finished - probably never will be
177                                 * :-) */
178int args_from_file(char *file, int *argc, char **argv[])
179{
180    FILE *fp;
181    int num, i;
182    unsigned int len;
183    static char *buf = NULL;
184    static char **arg = NULL;
185    char *p;
186
187    fp = fopen(file, "r");
188    if (fp == NULL)
189        return (0);
190
191    if (fseek(fp, 0, SEEK_END) == 0)
192        len = ftell(fp), rewind(fp);
193    else
194        len = -1;
195    if (len <= 0) {
196        fclose(fp);
197        return (0);
198    }
199
200    *argc = 0;
201    *argv = NULL;
202
203    if (buf != NULL)
204        OPENSSL_free(buf);
205    buf = (char *)OPENSSL_malloc(len + 1);
206    if (buf == NULL)
207        return (0);
208
209    len = fread(buf, 1, len, fp);
210    if (len <= 1)
211        return (0);
212    buf[len] = '\0';
213
214    i = 0;
215    for (p = buf; *p; p++)
216        if (*p == '\n')
217            i++;
218    if (arg != NULL)
219        OPENSSL_free(arg);
220    arg = (char **)OPENSSL_malloc(sizeof(char *) * (i * 2));
221
222    *argv = arg;
223    num = 0;
224    p = buf;
225    for (;;) {
226        if (!*p)
227            break;
228        if (*p == '#') {        /* comment line */
229            while (*p && (*p != '\n'))
230                p++;
231            continue;
232        }
233        /* else we have a line */
234        *(arg++) = p;
235        num++;
236        while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
237            p++;
238        if (!*p)
239            break;
240        if (*p == '\n') {
241            *(p++) = '\0';
242            continue;
243        }
244        /* else it is a tab or space */
245        p++;
246        while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
247            p++;
248        if (!*p)
249            break;
250        if (*p == '\n') {
251            p++;
252            continue;
253        }
254        *(arg++) = p++;
255        num++;
256        while (*p && (*p != '\n'))
257            p++;
258        if (!*p)
259            break;
260        /* else *p == '\n' */
261        *(p++) = '\0';
262    }
263    *argc = num;
264    return (1);
265}
266#endif
267
268int str2fmt(char *s)
269{
270    if (s == NULL)
271        return FORMAT_UNDEF;
272    if ((*s == 'D') || (*s == 'd'))
273        return (FORMAT_ASN1);
274    else if ((*s == 'T') || (*s == 't'))
275        return (FORMAT_TEXT);
276    else if ((*s == 'N') || (*s == 'n'))
277        return (FORMAT_NETSCAPE);
278    else if ((*s == 'S') || (*s == 's'))
279        return (FORMAT_SMIME);
280    else if ((*s == 'M') || (*s == 'm'))
281        return (FORMAT_MSBLOB);
282    else if ((*s == '1')
283             || (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0)
284             || (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0))
285        return (FORMAT_PKCS12);
286    else if ((*s == 'E') || (*s == 'e'))
287        return (FORMAT_ENGINE);
288    else if ((*s == 'H') || (*s == 'h'))
289        return FORMAT_HTTP;
290    else if ((*s == 'P') || (*s == 'p')) {
291        if (s[1] == 'V' || s[1] == 'v')
292            return FORMAT_PVK;
293        else
294            return (FORMAT_PEM);
295    } else
296        return (FORMAT_UNDEF);
297}
298
299#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
300void program_name(char *in, char *out, int size)
301{
302    int i, n;
303    char *p = NULL;
304
305    n = strlen(in);
306    /* find the last '/', '\' or ':' */
307    for (i = n - 1; i > 0; i--) {
308        if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':')) {
309            p = &(in[i + 1]);
310            break;
311        }
312    }
313    if (p == NULL)
314        p = in;
315    n = strlen(p);
316
317# if defined(OPENSSL_SYS_NETWARE)
318    /* strip off trailing .nlm if present. */
319    if ((n > 4) && (p[n - 4] == '.') &&
320        ((p[n - 3] == 'n') || (p[n - 3] == 'N')) &&
321        ((p[n - 2] == 'l') || (p[n - 2] == 'L')) &&
322        ((p[n - 1] == 'm') || (p[n - 1] == 'M')))
323        n -= 4;
324# else
325    /* strip off trailing .exe if present. */
326    if ((n > 4) && (p[n - 4] == '.') &&
327        ((p[n - 3] == 'e') || (p[n - 3] == 'E')) &&
328        ((p[n - 2] == 'x') || (p[n - 2] == 'X')) &&
329        ((p[n - 1] == 'e') || (p[n - 1] == 'E')))
330        n -= 4;
331# endif
332
333    if (n > size - 1)
334        n = size - 1;
335
336    for (i = 0; i < n; i++) {
337        if ((p[i] >= 'A') && (p[i] <= 'Z'))
338            out[i] = p[i] - 'A' + 'a';
339        else
340            out[i] = p[i];
341    }
342    out[n] = '\0';
343}
344#else
345# ifdef OPENSSL_SYS_VMS
346void program_name(char *in, char *out, int size)
347{
348    char *p = in, *q;
349    char *chars = ":]>";
350
351    while (*chars != '\0') {
352        q = strrchr(p, *chars);
353        if (q > p)
354            p = q + 1;
355        chars++;
356    }
357
358    q = strrchr(p, '.');
359    if (q == NULL)
360        q = p + strlen(p);
361    strncpy(out, p, size - 1);
362    if (q - p >= size) {
363        out[size - 1] = '\0';
364    } else {
365        out[q - p] = '\0';
366    }
367}
368# else
369void program_name(char *in, char *out, int size)
370{
371    char *p;
372
373    p = strrchr(in, '/');
374    if (p != NULL)
375        p++;
376    else
377        p = in;
378    BUF_strlcpy(out, p, size);
379}
380# endif
381#endif
382
383int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
384{
385    int num, i;
386    char *p;
387
388    *argc = 0;
389    *argv = NULL;
390
391    i = 0;
392    if (arg->count == 0) {
393        arg->count = 20;
394        arg->data = (char **)OPENSSL_malloc(sizeof(char *) * arg->count);
395        if (arg->data == NULL)
396            return 0;
397    }
398    for (i = 0; i < arg->count; i++)
399        arg->data[i] = NULL;
400
401    num = 0;
402    p = buf;
403    for (;;) {
404        /* first scan over white space */
405        if (!*p)
406            break;
407        while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
408            p++;
409        if (!*p)
410            break;
411
412        /* The start of something good :-) */
413        if (num >= arg->count) {
414            char **tmp_p;
415            int tlen = arg->count + 20;
416            tmp_p = (char **)OPENSSL_realloc(arg->data,
417                                             sizeof(char *) * tlen);
418            if (tmp_p == NULL)
419                return 0;
420            arg->data = tmp_p;
421            arg->count = tlen;
422            /* initialize newly allocated data */
423            for (i = num; i < arg->count; i++)
424                arg->data[i] = NULL;
425        }
426        arg->data[num++] = p;
427
428        /* now look for the end of this */
429        if ((*p == '\'') || (*p == '\"')) { /* scan for closing quote */
430            i = *(p++);
431            arg->data[num - 1]++; /* jump over quote */
432            while (*p && (*p != i))
433                p++;
434            *p = '\0';
435        } else {
436            while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
437                p++;
438
439            if (*p == '\0')
440                p--;
441            else
442                *p = '\0';
443        }
444        p++;
445    }
446    *argc = num;
447    *argv = arg->data;
448    return (1);
449}
450
451#ifndef APP_INIT
452int app_init(long mesgwin)
453{
454    return (1);
455}
456#endif
457
458int dump_cert_text(BIO *out, X509 *x)
459{
460    char *p;
461
462    p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
463    BIO_puts(out, "subject=");
464    BIO_puts(out, p);
465    OPENSSL_free(p);
466
467    p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
468    BIO_puts(out, "\nissuer=");
469    BIO_puts(out, p);
470    BIO_puts(out, "\n");
471    OPENSSL_free(p);
472
473    return 0;
474}
475
476static int ui_open(UI *ui)
477{
478    return UI_method_get_opener(UI_OpenSSL())(ui);
479}
480
481static int ui_read(UI *ui, UI_STRING *uis)
482{
483    if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
484        && UI_get0_user_data(ui)) {
485        switch (UI_get_string_type(uis)) {
486        case UIT_PROMPT:
487        case UIT_VERIFY:
488            {
489                const char *password =
490                    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
491                if (password && password[0] != '\0') {
492                    UI_set_result(ui, uis, password);
493                    return 1;
494                }
495            }
496        default:
497            break;
498        }
499    }
500    return UI_method_get_reader(UI_OpenSSL())(ui, uis);
501}
502
503static int ui_write(UI *ui, UI_STRING *uis)
504{
505    if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
506        && UI_get0_user_data(ui)) {
507        switch (UI_get_string_type(uis)) {
508        case UIT_PROMPT:
509        case UIT_VERIFY:
510            {
511                const char *password =
512                    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
513                if (password && password[0] != '\0')
514                    return 1;
515            }
516        default:
517            break;
518        }
519    }
520    return UI_method_get_writer(UI_OpenSSL())(ui, uis);
521}
522
523static int ui_close(UI *ui)
524{
525    return UI_method_get_closer(UI_OpenSSL())(ui);
526}
527
528int setup_ui_method(void)
529{
530    ui_method = UI_create_method("OpenSSL application user interface");
531    UI_method_set_opener(ui_method, ui_open);
532    UI_method_set_reader(ui_method, ui_read);
533    UI_method_set_writer(ui_method, ui_write);
534    UI_method_set_closer(ui_method, ui_close);
535    return 0;
536}
537
538void destroy_ui_method(void)
539{
540    if (ui_method) {
541        UI_destroy_method(ui_method);
542        ui_method = NULL;
543    }
544}
545
546int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
547{
548    UI *ui = NULL;
549    int res = 0;
550    const char *prompt_info = NULL;
551    const char *password = NULL;
552    PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
553
554    if (cb_data) {
555        if (cb_data->password)
556            password = cb_data->password;
557        if (cb_data->prompt_info)
558            prompt_info = cb_data->prompt_info;
559    }
560
561    if (password) {
562        res = strlen(password);
563        if (res > bufsiz)
564            res = bufsiz;
565        memcpy(buf, password, res);
566        return res;
567    }
568
569    ui = UI_new_method(ui_method);
570    if (ui) {
571        int ok = 0;
572        char *buff = NULL;
573        int ui_flags = 0;
574        char *prompt = NULL;
575
576        prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
577        if (!prompt) {
578            BIO_printf(bio_err, "Out of memory\n");
579            UI_free(ui);
580            return 0;
581        }
582
583        ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
584        UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
585
586        if (ok >= 0)
587            ok = UI_add_input_string(ui, prompt, ui_flags, buf,
588                                     PW_MIN_LENGTH, bufsiz - 1);
589        if (ok >= 0 && verify) {
590            buff = (char *)OPENSSL_malloc(bufsiz);
591            if (!buff) {
592                BIO_printf(bio_err, "Out of memory\n");
593                UI_free(ui);
594                OPENSSL_free(prompt);
595                return 0;
596            }
597            ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
598                                      PW_MIN_LENGTH, bufsiz - 1, buf);
599        }
600        if (ok >= 0)
601            do {
602                ok = UI_process(ui);
603            }
604            while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
605
606        if (buff) {
607            OPENSSL_cleanse(buff, (unsigned int)bufsiz);
608            OPENSSL_free(buff);
609        }
610
611        if (ok >= 0)
612            res = strlen(buf);
613        if (ok == -1) {
614            BIO_printf(bio_err, "User interface error\n");
615            ERR_print_errors(bio_err);
616            OPENSSL_cleanse(buf, (unsigned int)bufsiz);
617            res = 0;
618        }
619        if (ok == -2) {
620            BIO_printf(bio_err, "aborted!\n");
621            OPENSSL_cleanse(buf, (unsigned int)bufsiz);
622            res = 0;
623        }
624        UI_free(ui);
625        OPENSSL_free(prompt);
626    }
627    return res;
628}
629
630static char *app_get_pass(BIO *err, char *arg, int keepbio);
631
632int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
633{
634    int same;
635    if (!arg2 || !arg1 || strcmp(arg1, arg2))
636        same = 0;
637    else
638        same = 1;
639    if (arg1) {
640        *pass1 = app_get_pass(err, arg1, same);
641        if (!*pass1)
642            return 0;
643    } else if (pass1)
644        *pass1 = NULL;
645    if (arg2) {
646        *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
647        if (!*pass2)
648            return 0;
649    } else if (pass2)
650        *pass2 = NULL;
651    return 1;
652}
653
654static char *app_get_pass(BIO *err, char *arg, int keepbio)
655{
656    char *tmp, tpass[APP_PASS_LEN];
657    static BIO *pwdbio = NULL;
658    int i;
659    if (!strncmp(arg, "pass:", 5))
660        return BUF_strdup(arg + 5);
661    if (!strncmp(arg, "env:", 4)) {
662        tmp = getenv(arg + 4);
663        if (!tmp) {
664            BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
665            return NULL;
666        }
667        return BUF_strdup(tmp);
668    }
669    if (!keepbio || !pwdbio) {
670        if (!strncmp(arg, "file:", 5)) {
671            pwdbio = BIO_new_file(arg + 5, "r");
672            if (!pwdbio) {
673                BIO_printf(err, "Can't open file %s\n", arg + 5);
674                return NULL;
675            }
676#if !defined(_WIN32)
677            /*
678             * Under _WIN32, which covers even Win64 and CE, file
679             * descriptors referenced by BIO_s_fd are not inherited
680             * by child process and therefore below is not an option.
681             * It could have been an option if bss_fd.c was operating
682             * on real Windows descriptors, such as those obtained
683             * with CreateFile.
684             */
685        } else if (!strncmp(arg, "fd:", 3)) {
686            BIO *btmp;
687            i = atoi(arg + 3);
688            if (i >= 0)
689                pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
690            if ((i < 0) || !pwdbio) {
691                BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
692                return NULL;
693            }
694            /*
695             * Can't do BIO_gets on an fd BIO so add a buffering BIO
696             */
697            btmp = BIO_new(BIO_f_buffer());
698            pwdbio = BIO_push(btmp, pwdbio);
699#endif
700        } else if (!strcmp(arg, "stdin")) {
701            pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
702            if (!pwdbio) {
703                BIO_printf(err, "Can't open BIO for stdin\n");
704                return NULL;
705            }
706        } else {
707            BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
708            return NULL;
709        }
710    }
711    i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
712    if (keepbio != 1) {
713        BIO_free_all(pwdbio);
714        pwdbio = NULL;
715    }
716    if (i <= 0) {
717        BIO_printf(err, "Error reading password from BIO\n");
718        return NULL;
719    }
720    tmp = strchr(tpass, '\n');
721    if (tmp)
722        *tmp = 0;
723    return BUF_strdup(tpass);
724}
725
726int add_oid_section(BIO *err, CONF *conf)
727{
728    char *p;
729    STACK_OF(CONF_VALUE) *sktmp;
730    CONF_VALUE *cnf;
731    int i;
732    if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) {
733        ERR_clear_error();
734        return 1;
735    }
736    if (!(sktmp = NCONF_get_section(conf, p))) {
737        BIO_printf(err, "problem loading oid section %s\n", p);
738        return 0;
739    }
740    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
741        cnf = sk_CONF_VALUE_value(sktmp, i);
742        if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
743            BIO_printf(err, "problem creating object %s=%s\n",
744                       cnf->name, cnf->value);
745            return 0;
746        }
747    }
748    return 1;
749}
750
751static int load_pkcs12(BIO *err, BIO *in, const char *desc,
752                       pem_password_cb *pem_cb, void *cb_data,
753                       EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
754{
755    const char *pass;
756    char tpass[PEM_BUFSIZE];
757    int len, ret = 0;
758    PKCS12 *p12;
759    p12 = d2i_PKCS12_bio(in, NULL);
760    if (p12 == NULL) {
761        BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
762        goto die;
763    }
764    /* See if an empty password will do */
765    if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
766        pass = "";
767    else {
768        if (!pem_cb)
769            pem_cb = (pem_password_cb *)password_callback;
770        len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
771        if (len < 0) {
772            BIO_printf(err, "Passpharse callback error for %s\n", desc);
773            goto die;
774        }
775        if (len < PEM_BUFSIZE)
776            tpass[len] = 0;
777        if (!PKCS12_verify_mac(p12, tpass, len)) {
778            BIO_printf(err,
779                       "Mac verify error (wrong password?) in PKCS12 file for %s\n",
780                       desc);
781            goto die;
782        }
783        pass = tpass;
784    }
785    ret = PKCS12_parse(p12, pass, pkey, cert, ca);
786 die:
787    if (p12)
788        PKCS12_free(p12);
789    return ret;
790}
791
792int load_cert_crl_http(const char *url, BIO *err,
793                       X509 **pcert, X509_CRL **pcrl)
794{
795    char *host = NULL, *port = NULL, *path = NULL;
796    BIO *bio = NULL;
797    OCSP_REQ_CTX *rctx = NULL;
798    int use_ssl, rv = 0;
799    if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl))
800        goto err;
801    if (use_ssl) {
802        if (err)
803            BIO_puts(err, "https not supported\n");
804        goto err;
805    }
806    bio = BIO_new_connect(host);
807    if (!bio || !BIO_set_conn_port(bio, port))
808        goto err;
809    rctx = OCSP_REQ_CTX_new(bio, 1024);
810    if (!rctx)
811        goto err;
812    if (!OCSP_REQ_CTX_http(rctx, "GET", path))
813        goto err;
814    if (!OCSP_REQ_CTX_add1_header(rctx, "Host", host))
815        goto err;
816    if (pcert) {
817        do {
818            rv = X509_http_nbio(rctx, pcert);
819        }
820        while (rv == -1);
821    } else {
822        do {
823            rv = X509_CRL_http_nbio(rctx, pcrl);
824        } while (rv == -1);
825    }
826
827 err:
828    if (host)
829        OPENSSL_free(host);
830    if (path)
831        OPENSSL_free(path);
832    if (port)
833        OPENSSL_free(port);
834    if (bio)
835        BIO_free_all(bio);
836    if (rctx)
837        OCSP_REQ_CTX_free(rctx);
838    if (rv != 1) {
839        if (bio && err)
840            BIO_printf(bio_err, "Error loading %s from %s\n",
841                       pcert ? "certificate" : "CRL", url);
842        ERR_print_errors(bio_err);
843    }
844    return rv;
845}
846
847X509 *load_cert(BIO *err, const char *file, int format,
848                const char *pass, ENGINE *e, const char *cert_descrip)
849{
850    X509 *x = NULL;
851    BIO *cert;
852
853    if (format == FORMAT_HTTP) {
854        load_cert_crl_http(file, err, &x, NULL);
855        return x;
856    }
857
858    if ((cert = BIO_new(BIO_s_file())) == NULL) {
859        ERR_print_errors(err);
860        goto end;
861    }
862
863    if (file == NULL) {
864#ifdef _IONBF
865# ifndef OPENSSL_NO_SETVBUF_IONBF
866        setvbuf(stdin, NULL, _IONBF, 0);
867# endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
868#endif
869        BIO_set_fp(cert, stdin, BIO_NOCLOSE);
870    } else {
871        if (BIO_read_filename(cert, file) <= 0) {
872            BIO_printf(err, "Error opening %s %s\n", cert_descrip, file);
873            ERR_print_errors(err);
874            goto end;
875        }
876    }
877
878    if (format == FORMAT_ASN1)
879        x = d2i_X509_bio(cert, NULL);
880    else if (format == FORMAT_NETSCAPE) {
881        NETSCAPE_X509 *nx;
882        nx = ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509), cert, NULL);
883        if (nx == NULL)
884            goto end;
885
886        if ((strncmp(NETSCAPE_CERT_HDR, (char *)nx->header->data,
887                     nx->header->length) != 0)) {
888            NETSCAPE_X509_free(nx);
889            BIO_printf(err, "Error reading header on certificate\n");
890            goto end;
891        }
892        x = nx->cert;
893        nx->cert = NULL;
894        NETSCAPE_X509_free(nx);
895    } else if (format == FORMAT_PEM)
896        x = PEM_read_bio_X509_AUX(cert, NULL,
897                                  (pem_password_cb *)password_callback, NULL);
898    else if (format == FORMAT_PKCS12) {
899        if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL, NULL, &x, NULL))
900            goto end;
901    } else {
902        BIO_printf(err, "bad input format specified for %s\n", cert_descrip);
903        goto end;
904    }
905 end:
906    if (x == NULL) {
907        BIO_printf(err, "unable to load certificate\n");
908        ERR_print_errors(err);
909    }
910    if (cert != NULL)
911        BIO_free(cert);
912    return (x);
913}
914
915X509_CRL *load_crl(const char *infile, int format)
916{
917    X509_CRL *x = NULL;
918    BIO *in = NULL;
919
920    if (format == FORMAT_HTTP) {
921        load_cert_crl_http(infile, bio_err, NULL, &x);
922        return x;
923    }
924
925    in = BIO_new(BIO_s_file());
926    if (in == NULL) {
927        ERR_print_errors(bio_err);
928        goto end;
929    }
930
931    if (infile == NULL)
932        BIO_set_fp(in, stdin, BIO_NOCLOSE);
933    else {
934        if (BIO_read_filename(in, infile) <= 0) {
935            perror(infile);
936            goto end;
937        }
938    }
939    if (format == FORMAT_ASN1)
940        x = d2i_X509_CRL_bio(in, NULL);
941    else if (format == FORMAT_PEM)
942        x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
943    else {
944        BIO_printf(bio_err, "bad input format specified for input crl\n");
945        goto end;
946    }
947    if (x == NULL) {
948        BIO_printf(bio_err, "unable to load CRL\n");
949        ERR_print_errors(bio_err);
950        goto end;
951    }
952
953 end:
954    BIO_free(in);
955    return (x);
956}
957
958EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
959                   const char *pass, ENGINE *e, const char *key_descrip)
960{
961    BIO *key = NULL;
962    EVP_PKEY *pkey = NULL;
963    PW_CB_DATA cb_data;
964
965    cb_data.password = pass;
966    cb_data.prompt_info = file;
967
968    if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
969        BIO_printf(err, "no keyfile specified\n");
970        goto end;
971    }
972#ifndef OPENSSL_NO_ENGINE
973    if (format == FORMAT_ENGINE) {
974        if (!e)
975            BIO_printf(err, "no engine specified\n");
976        else {
977            pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data);
978            if (!pkey) {
979                BIO_printf(err, "cannot load %s from engine\n", key_descrip);
980                ERR_print_errors(err);
981            }
982        }
983        goto end;
984    }
985#endif
986    key = BIO_new(BIO_s_file());
987    if (key == NULL) {
988        ERR_print_errors(err);
989        goto end;
990    }
991    if (file == NULL && maybe_stdin) {
992#ifdef _IONBF
993# ifndef OPENSSL_NO_SETVBUF_IONBF
994        setvbuf(stdin, NULL, _IONBF, 0);
995# endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
996#endif
997        BIO_set_fp(key, stdin, BIO_NOCLOSE);
998    } else if (BIO_read_filename(key, file) <= 0) {
999        BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
1000        ERR_print_errors(err);
1001        goto end;
1002    }
1003    if (format == FORMAT_ASN1) {
1004        pkey = d2i_PrivateKey_bio(key, NULL);
1005    } else if (format == FORMAT_PEM) {
1006        pkey = PEM_read_bio_PrivateKey(key, NULL,
1007                                       (pem_password_cb *)password_callback,
1008                                       &cb_data);
1009    }
1010#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
1011    else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
1012        pkey = load_netscape_key(err, key, file, key_descrip, format);
1013#endif
1014    else if (format == FORMAT_PKCS12) {
1015        if (!load_pkcs12(err, key, key_descrip,
1016                         (pem_password_cb *)password_callback, &cb_data,
1017                         &pkey, NULL, NULL))
1018            goto end;
1019    }
1020#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
1021    else if (format == FORMAT_MSBLOB)
1022        pkey = b2i_PrivateKey_bio(key);
1023    else if (format == FORMAT_PVK)
1024        pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
1025                           &cb_data);
1026#endif
1027    else {
1028        BIO_printf(err, "bad input format specified for key file\n");
1029        goto end;
1030    }
1031 end:
1032    if (key != NULL)
1033        BIO_free(key);
1034    if (pkey == NULL) {
1035        BIO_printf(err, "unable to load %s\n", key_descrip);
1036        ERR_print_errors(err);
1037    }
1038    return (pkey);
1039}
1040
1041EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
1042                      const char *pass, ENGINE *e, const char *key_descrip)
1043{
1044    BIO *key = NULL;
1045    EVP_PKEY *pkey = NULL;
1046    PW_CB_DATA cb_data;
1047
1048    cb_data.password = pass;
1049    cb_data.prompt_info = file;
1050
1051    if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
1052        BIO_printf(err, "no keyfile specified\n");
1053        goto end;
1054    }
1055#ifndef OPENSSL_NO_ENGINE
1056    if (format == FORMAT_ENGINE) {
1057        if (!e)
1058            BIO_printf(bio_err, "no engine specified\n");
1059        else
1060            pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data);
1061        goto end;
1062    }
1063#endif
1064    key = BIO_new(BIO_s_file());
1065    if (key == NULL) {
1066        ERR_print_errors(err);
1067        goto end;
1068    }
1069    if (file == NULL && maybe_stdin) {
1070#ifdef _IONBF
1071# ifndef OPENSSL_NO_SETVBUF_IONBF
1072        setvbuf(stdin, NULL, _IONBF, 0);
1073# endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
1074#endif
1075        BIO_set_fp(key, stdin, BIO_NOCLOSE);
1076    } else if (BIO_read_filename(key, file) <= 0) {
1077        BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
1078        ERR_print_errors(err);
1079        goto end;
1080    }
1081    if (format == FORMAT_ASN1) {
1082        pkey = d2i_PUBKEY_bio(key, NULL);
1083    }
1084#ifndef OPENSSL_NO_RSA
1085    else if (format == FORMAT_ASN1RSA) {
1086        RSA *rsa;
1087        rsa = d2i_RSAPublicKey_bio(key, NULL);
1088        if (rsa) {
1089            pkey = EVP_PKEY_new();
1090            if (pkey)
1091                EVP_PKEY_set1_RSA(pkey, rsa);
1092            RSA_free(rsa);
1093        } else
1094            pkey = NULL;
1095    } else if (format == FORMAT_PEMRSA) {
1096        RSA *rsa;
1097        rsa = PEM_read_bio_RSAPublicKey(key, NULL,
1098                                        (pem_password_cb *)password_callback,
1099                                        &cb_data);
1100        if (rsa) {
1101            pkey = EVP_PKEY_new();
1102            if (pkey)
1103                EVP_PKEY_set1_RSA(pkey, rsa);
1104            RSA_free(rsa);
1105        } else
1106            pkey = NULL;
1107    }
1108#endif
1109    else if (format == FORMAT_PEM) {
1110        pkey = PEM_read_bio_PUBKEY(key, NULL,
1111                                   (pem_password_cb *)password_callback,
1112                                   &cb_data);
1113    }
1114#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
1115    else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
1116        pkey = load_netscape_key(err, key, file, key_descrip, format);
1117#endif
1118#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
1119    else if (format == FORMAT_MSBLOB)
1120        pkey = b2i_PublicKey_bio(key);
1121#endif
1122    else {
1123        BIO_printf(err, "bad input format specified for key file\n");
1124        goto end;
1125    }
1126 end:
1127    if (key != NULL)
1128        BIO_free(key);
1129    if (pkey == NULL)
1130        BIO_printf(err, "unable to load %s\n", key_descrip);
1131    return (pkey);
1132}
1133
1134#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
1135static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
1136                                   const char *key_descrip, int format)
1137{
1138    EVP_PKEY *pkey;
1139    BUF_MEM *buf;
1140    RSA *rsa;
1141    const unsigned char *p;
1142    int size, i;
1143
1144    buf = BUF_MEM_new();
1145    pkey = EVP_PKEY_new();
1146    size = 0;
1147    if (buf == NULL || pkey == NULL)
1148        goto error;
1149    for (;;) {
1150        if (!BUF_MEM_grow_clean(buf, size + 1024 * 10))
1151            goto error;
1152        i = BIO_read(key, &(buf->data[size]), 1024 * 10);
1153        size += i;
1154        if (i == 0)
1155            break;
1156        if (i < 0) {
1157            BIO_printf(err, "Error reading %s %s", key_descrip, file);
1158            goto error;
1159        }
1160    }
1161    p = (unsigned char *)buf->data;
1162    rsa = d2i_RSA_NET(NULL, &p, (long)size, NULL,
1163                      (format == FORMAT_IISSGC ? 1 : 0));
1164    if (rsa == NULL)
1165        goto error;
1166    BUF_MEM_free(buf);
1167    EVP_PKEY_set1_RSA(pkey, rsa);
1168    return pkey;
1169 error:
1170    BUF_MEM_free(buf);
1171    EVP_PKEY_free(pkey);
1172    return NULL;
1173}
1174#endif                          /* ndef OPENSSL_NO_RC4 */
1175
1176static int load_certs_crls(BIO *err, const char *file, int format,
1177                           const char *pass, ENGINE *e, const char *desc,
1178                           STACK_OF(X509) **pcerts,
1179                           STACK_OF(X509_CRL) **pcrls)
1180{
1181    int i;
1182    BIO *bio;
1183    STACK_OF(X509_INFO) *xis = NULL;
1184    X509_INFO *xi;
1185    PW_CB_DATA cb_data;
1186    int rv = 0;
1187
1188    cb_data.password = pass;
1189    cb_data.prompt_info = file;
1190
1191    if (format != FORMAT_PEM) {
1192        BIO_printf(err, "bad input format specified for %s\n", desc);
1193        return 0;
1194    }
1195
1196    if (file == NULL)
1197        bio = BIO_new_fp(stdin, BIO_NOCLOSE);
1198    else
1199        bio = BIO_new_file(file, "r");
1200
1201    if (bio == NULL) {
1202        BIO_printf(err, "Error opening %s %s\n", desc, file ? file : "stdin");
1203        ERR_print_errors(err);
1204        return 0;
1205    }
1206
1207    xis = PEM_X509_INFO_read_bio(bio, NULL,
1208                                 (pem_password_cb *)password_callback,
1209                                 &cb_data);
1210
1211    BIO_free(bio);
1212
1213    if (pcerts) {
1214        *pcerts = sk_X509_new_null();
1215        if (!*pcerts)
1216            goto end;
1217    }
1218
1219    if (pcrls) {
1220        *pcrls = sk_X509_CRL_new_null();
1221        if (!*pcrls)
1222            goto end;
1223    }
1224
1225    for (i = 0; i < sk_X509_INFO_num(xis); i++) {
1226        xi = sk_X509_INFO_value(xis, i);
1227        if (xi->x509 && pcerts) {
1228            if (!sk_X509_push(*pcerts, xi->x509))
1229                goto end;
1230            xi->x509 = NULL;
1231        }
1232        if (xi->crl && pcrls) {
1233            if (!sk_X509_CRL_push(*pcrls, xi->crl))
1234                goto end;
1235            xi->crl = NULL;
1236        }
1237    }
1238
1239    if (pcerts && sk_X509_num(*pcerts) > 0)
1240        rv = 1;
1241
1242    if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
1243        rv = 1;
1244
1245 end:
1246
1247    if (xis)
1248        sk_X509_INFO_pop_free(xis, X509_INFO_free);
1249
1250    if (rv == 0) {
1251        if (pcerts) {
1252            sk_X509_pop_free(*pcerts, X509_free);
1253            *pcerts = NULL;
1254        }
1255        if (pcrls) {
1256            sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
1257            *pcrls = NULL;
1258        }
1259        BIO_printf(err, "unable to load %s\n",
1260                   pcerts ? "certificates" : "CRLs");
1261        ERR_print_errors(err);
1262    }
1263    return rv;
1264}
1265
1266STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
1267                           const char *pass, ENGINE *e, const char *desc)
1268{
1269    STACK_OF(X509) *certs;
1270    if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
1271        return NULL;
1272    return certs;
1273}
1274
1275STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
1276                              const char *pass, ENGINE *e, const char *desc)
1277{
1278    STACK_OF(X509_CRL) *crls;
1279    if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
1280        return NULL;
1281    return crls;
1282}
1283
1284#define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
1285/* Return error for unknown extensions */
1286#define X509V3_EXT_DEFAULT              0
1287/* Print error for unknown extensions */
1288#define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
1289/* ASN1 parse unknown extensions */
1290#define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
1291/* BIO_dump unknown extensions */
1292#define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)
1293
1294#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
1295                         X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
1296
1297int set_cert_ex(unsigned long *flags, const char *arg)
1298{
1299    static const NAME_EX_TBL cert_tbl[] = {
1300        {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
1301        {"ca_default", X509_FLAG_CA, 0xffffffffl},
1302        {"no_header", X509_FLAG_NO_HEADER, 0},
1303        {"no_version", X509_FLAG_NO_VERSION, 0},
1304        {"no_serial", X509_FLAG_NO_SERIAL, 0},
1305        {"no_signame", X509_FLAG_NO_SIGNAME, 0},
1306        {"no_validity", X509_FLAG_NO_VALIDITY, 0},
1307        {"no_subject", X509_FLAG_NO_SUBJECT, 0},
1308        {"no_issuer", X509_FLAG_NO_ISSUER, 0},
1309        {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
1310        {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
1311        {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
1312        {"no_aux", X509_FLAG_NO_AUX, 0},
1313        {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
1314        {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
1315        {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1316        {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1317        {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1318        {NULL, 0, 0}
1319    };
1320    return set_multi_opts(flags, arg, cert_tbl);
1321}
1322
1323int set_name_ex(unsigned long *flags, const char *arg)
1324{
1325    static const NAME_EX_TBL ex_tbl[] = {
1326        {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
1327        {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
1328        {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
1329        {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
1330        {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
1331        {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
1332        {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
1333        {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
1334        {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
1335        {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
1336        {"compat", XN_FLAG_COMPAT, 0xffffffffL},
1337        {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
1338        {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
1339        {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
1340        {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
1341        {"dn_rev", XN_FLAG_DN_REV, 0},
1342        {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
1343        {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
1344        {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
1345        {"align", XN_FLAG_FN_ALIGN, 0},
1346        {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
1347        {"space_eq", XN_FLAG_SPC_EQ, 0},
1348        {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
1349        {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
1350        {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
1351        {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
1352        {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
1353        {NULL, 0, 0}
1354    };
1355    return set_multi_opts(flags, arg, ex_tbl);
1356}
1357
1358int set_ext_copy(int *copy_type, const char *arg)
1359{
1360    if (!strcasecmp(arg, "none"))
1361        *copy_type = EXT_COPY_NONE;
1362    else if (!strcasecmp(arg, "copy"))
1363        *copy_type = EXT_COPY_ADD;
1364    else if (!strcasecmp(arg, "copyall"))
1365        *copy_type = EXT_COPY_ALL;
1366    else
1367        return 0;
1368    return 1;
1369}
1370
1371int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1372{
1373    STACK_OF(X509_EXTENSION) *exts = NULL;
1374    X509_EXTENSION *ext, *tmpext;
1375    ASN1_OBJECT *obj;
1376    int i, idx, ret = 0;
1377    if (!x || !req || (copy_type == EXT_COPY_NONE))
1378        return 1;
1379    exts = X509_REQ_get_extensions(req);
1380
1381    for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1382        ext = sk_X509_EXTENSION_value(exts, i);
1383        obj = X509_EXTENSION_get_object(ext);
1384        idx = X509_get_ext_by_OBJ(x, obj, -1);
1385        /* Does extension exist? */
1386        if (idx != -1) {
1387            /* If normal copy don't override existing extension */
1388            if (copy_type == EXT_COPY_ADD)
1389                continue;
1390            /* Delete all extensions of same type */
1391            do {
1392                tmpext = X509_get_ext(x, idx);
1393                X509_delete_ext(x, idx);
1394                X509_EXTENSION_free(tmpext);
1395                idx = X509_get_ext_by_OBJ(x, obj, -1);
1396            } while (idx != -1);
1397        }
1398        if (!X509_add_ext(x, ext, -1))
1399            goto end;
1400    }
1401
1402    ret = 1;
1403
1404 end:
1405
1406    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
1407
1408    return ret;
1409}
1410
1411static int set_multi_opts(unsigned long *flags, const char *arg,
1412                          const NAME_EX_TBL * in_tbl)
1413{
1414    STACK_OF(CONF_VALUE) *vals;
1415    CONF_VALUE *val;
1416    int i, ret = 1;
1417    if (!arg)
1418        return 0;
1419    vals = X509V3_parse_list(arg);
1420    for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1421        val = sk_CONF_VALUE_value(vals, i);
1422        if (!set_table_opts(flags, val->name, in_tbl))
1423            ret = 0;
1424    }
1425    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1426    return ret;
1427}
1428
1429static int set_table_opts(unsigned long *flags, const char *arg,
1430                          const NAME_EX_TBL * in_tbl)
1431{
1432    char c;
1433    const NAME_EX_TBL *ptbl;
1434    c = arg[0];
1435
1436    if (c == '-') {
1437        c = 0;
1438        arg++;
1439    } else if (c == '+') {
1440        c = 1;
1441        arg++;
1442    } else
1443        c = 1;
1444
1445    for (ptbl = in_tbl; ptbl->name; ptbl++) {
1446        if (!strcasecmp(arg, ptbl->name)) {
1447            *flags &= ~ptbl->mask;
1448            if (c)
1449                *flags |= ptbl->flag;
1450            else
1451                *flags &= ~ptbl->flag;
1452            return 1;
1453        }
1454    }
1455    return 0;
1456}
1457
1458void print_name(BIO *out, const char *title, X509_NAME *nm,
1459                unsigned long lflags)
1460{
1461    char *buf;
1462    char mline = 0;
1463    int indent = 0;
1464
1465    if (title)
1466        BIO_puts(out, title);
1467    if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1468        mline = 1;
1469        indent = 4;
1470    }
1471    if (lflags == XN_FLAG_COMPAT) {
1472        buf = X509_NAME_oneline(nm, 0, 0);
1473        BIO_puts(out, buf);
1474        BIO_puts(out, "\n");
1475        OPENSSL_free(buf);
1476    } else {
1477        if (mline)
1478            BIO_puts(out, "\n");
1479        X509_NAME_print_ex(out, nm, indent, lflags);
1480        BIO_puts(out, "\n");
1481    }
1482}
1483
1484X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
1485{
1486    X509_STORE *store;
1487    X509_LOOKUP *lookup;
1488    if (!(store = X509_STORE_new()))
1489        goto end;
1490    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1491    if (lookup == NULL)
1492        goto end;
1493    if (CAfile) {
1494        if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
1495            BIO_printf(bp, "Error loading file %s\n", CAfile);
1496            goto end;
1497        }
1498    } else
1499        X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
1500
1501    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1502    if (lookup == NULL)
1503        goto end;
1504    if (CApath) {
1505        if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1506            BIO_printf(bp, "Error loading directory %s\n", CApath);
1507            goto end;
1508        }
1509    } else
1510        X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1511
1512    ERR_clear_error();
1513    return store;
1514 end:
1515    X509_STORE_free(store);
1516    return NULL;
1517}
1518
1519#ifndef OPENSSL_NO_ENGINE
1520/* Try to load an engine in a shareable library */
1521static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
1522{
1523    ENGINE *e = ENGINE_by_id("dynamic");
1524    if (e) {
1525        if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
1526            || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
1527            ENGINE_free(e);
1528            e = NULL;
1529        }
1530    }
1531    return e;
1532}
1533
1534ENGINE *setup_engine(BIO *err, const char *engine, int debug)
1535{
1536    ENGINE *e = NULL;
1537
1538    if (engine) {
1539        if (strcmp(engine, "auto") == 0) {
1540            BIO_printf(err, "enabling auto ENGINE support\n");
1541            ENGINE_register_all_complete();
1542            return NULL;
1543        }
1544        if ((e = ENGINE_by_id(engine)) == NULL
1545            && (e = try_load_engine(err, engine, debug)) == NULL) {
1546            BIO_printf(err, "invalid engine \"%s\"\n", engine);
1547            ERR_print_errors(err);
1548            return NULL;
1549        }
1550        if (debug) {
1551            ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, err, 0);
1552        }
1553        ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
1554        if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
1555            BIO_printf(err, "can't use that engine\n");
1556            ERR_print_errors(err);
1557            ENGINE_free(e);
1558            return NULL;
1559        }
1560
1561        BIO_printf(err, "engine \"%s\" set.\n", ENGINE_get_id(e));
1562
1563        /* Free our "structural" reference. */
1564        ENGINE_free(e);
1565    }
1566    return e;
1567}
1568#endif
1569
1570int load_config(BIO *err, CONF *cnf)
1571{
1572    static int load_config_called = 0;
1573    if (load_config_called)
1574        return 1;
1575    load_config_called = 1;
1576    if (!cnf)
1577        cnf = config;
1578    if (!cnf)
1579        return 1;
1580
1581    OPENSSL_load_builtin_modules();
1582
1583    if (CONF_modules_load(cnf, NULL, 0) <= 0) {
1584        BIO_printf(err, "Error configuring OpenSSL\n");
1585        ERR_print_errors(err);
1586        return 0;
1587    }
1588    return 1;
1589}
1590
1591char *make_config_name()
1592{
1593    const char *t = X509_get_default_cert_area();
1594    size_t len;
1595    char *p;
1596
1597    len = strlen(t) + strlen(OPENSSL_CONF) + 2;
1598    p = OPENSSL_malloc(len);
1599    if (p == NULL)
1600        return NULL;
1601    BUF_strlcpy(p, t, len);
1602#ifndef OPENSSL_SYS_VMS
1603    BUF_strlcat(p, "/", len);
1604#endif
1605    BUF_strlcat(p, OPENSSL_CONF, len);
1606
1607    return p;
1608}
1609
1610static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
1611{
1612    const char *n;
1613
1614    n = a[DB_serial];
1615    while (*n == '0')
1616        n++;
1617    return (lh_strhash(n));
1618}
1619
1620static int index_serial_cmp(const OPENSSL_CSTRING *a,
1621                            const OPENSSL_CSTRING *b)
1622{
1623    const char *aa, *bb;
1624
1625    for (aa = a[DB_serial]; *aa == '0'; aa++) ;
1626    for (bb = b[DB_serial]; *bb == '0'; bb++) ;
1627    return (strcmp(aa, bb));
1628}
1629
1630static int index_name_qual(char **a)
1631{
1632    return (a[0][0] == 'V');
1633}
1634
1635static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
1636{
1637    return (lh_strhash(a[DB_name]));
1638}
1639
1640int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1641{
1642    return (strcmp(a[DB_name], b[DB_name]));
1643}
1644
1645static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1646static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1647static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1648static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1649#undef BSIZE
1650#define BSIZE 256
1651BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
1652{
1653    BIO *in = NULL;
1654    BIGNUM *ret = NULL;
1655    MS_STATIC char buf[1024];
1656    ASN1_INTEGER *ai = NULL;
1657
1658    ai = ASN1_INTEGER_new();
1659    if (ai == NULL)
1660        goto err;
1661
1662    if ((in = BIO_new(BIO_s_file())) == NULL) {
1663        ERR_print_errors(bio_err);
1664        goto err;
1665    }
1666
1667    if (BIO_read_filename(in, serialfile) <= 0) {
1668        if (!create) {
1669            perror(serialfile);
1670            goto err;
1671        } else {
1672            ret = BN_new();
1673            if (ret == NULL || !rand_serial(ret, ai))
1674                BIO_printf(bio_err, "Out of memory\n");
1675        }
1676    } else {
1677        if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
1678            BIO_printf(bio_err, "unable to load number from %s\n",
1679                       serialfile);
1680            goto err;
1681        }
1682        ret = ASN1_INTEGER_to_BN(ai, NULL);
1683        if (ret == NULL) {
1684            BIO_printf(bio_err,
1685                       "error converting number from bin to BIGNUM\n");
1686            goto err;
1687        }
1688    }
1689
1690    if (ret && retai) {
1691        *retai = ai;
1692        ai = NULL;
1693    }
1694 err:
1695    if (in != NULL)
1696        BIO_free(in);
1697    if (ai != NULL)
1698        ASN1_INTEGER_free(ai);
1699    return (ret);
1700}
1701
1702int save_serial(char *serialfile, char *suffix, BIGNUM *serial,
1703                ASN1_INTEGER **retai)
1704{
1705    char buf[1][BSIZE];
1706    BIO *out = NULL;
1707    int ret = 0;
1708    ASN1_INTEGER *ai = NULL;
1709    int j;
1710
1711    if (suffix == NULL)
1712        j = strlen(serialfile);
1713    else
1714        j = strlen(serialfile) + strlen(suffix) + 1;
1715    if (j >= BSIZE) {
1716        BIO_printf(bio_err, "file name too long\n");
1717        goto err;
1718    }
1719
1720    if (suffix == NULL)
1721        BUF_strlcpy(buf[0], serialfile, BSIZE);
1722    else {
1723#ifndef OPENSSL_SYS_VMS
1724        j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
1725#else
1726        j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
1727#endif
1728    }
1729#ifdef RL_DEBUG
1730    BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
1731#endif
1732    out = BIO_new(BIO_s_file());
1733    if (out == NULL) {
1734        ERR_print_errors(bio_err);
1735        goto err;
1736    }
1737    if (BIO_write_filename(out, buf[0]) <= 0) {
1738        perror(serialfile);
1739        goto err;
1740    }
1741
1742    if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1743        BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
1744        goto err;
1745    }
1746    i2a_ASN1_INTEGER(out, ai);
1747    BIO_puts(out, "\n");
1748    ret = 1;
1749    if (retai) {
1750        *retai = ai;
1751        ai = NULL;
1752    }
1753 err:
1754    if (out != NULL)
1755        BIO_free_all(out);
1756    if (ai != NULL)
1757        ASN1_INTEGER_free(ai);
1758    return (ret);
1759}
1760
1761int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
1762{
1763    char buf[5][BSIZE];
1764    int i, j;
1765
1766    i = strlen(serialfile) + strlen(old_suffix);
1767    j = strlen(serialfile) + strlen(new_suffix);
1768    if (i > j)
1769        j = i;
1770    if (j + 1 >= BSIZE) {
1771        BIO_printf(bio_err, "file name too long\n");
1772        goto err;
1773    }
1774#ifndef OPENSSL_SYS_VMS
1775    j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix);
1776#else
1777    j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, new_suffix);
1778#endif
1779#ifndef OPENSSL_SYS_VMS
1780    j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix);
1781#else
1782    j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix);
1783#endif
1784#ifdef RL_DEBUG
1785    BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
1786               serialfile, buf[1]);
1787#endif
1788    if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
1789#ifdef ENOTDIR
1790        && errno != ENOTDIR
1791#endif
1792        ) {
1793        BIO_printf(bio_err,
1794                   "unable to rename %s to %s\n", serialfile, buf[1]);
1795        perror("reason");
1796        goto err;
1797    }
1798#ifdef RL_DEBUG
1799    BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
1800               buf[0], serialfile);
1801#endif
1802    if (rename(buf[0], serialfile) < 0) {
1803        BIO_printf(bio_err,
1804                   "unable to rename %s to %s\n", buf[0], serialfile);
1805        perror("reason");
1806        rename(buf[1], serialfile);
1807        goto err;
1808    }
1809    return 1;
1810 err:
1811    return 0;
1812}
1813
1814int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1815{
1816    BIGNUM *btmp;
1817    int ret = 0;
1818    if (b)
1819        btmp = b;
1820    else
1821        btmp = BN_new();
1822
1823    if (!btmp)
1824        return 0;
1825
1826    if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1827        goto error;
1828    if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1829        goto error;
1830
1831    ret = 1;
1832
1833 error:
1834
1835    if (!b)
1836        BN_free(btmp);
1837
1838    return ret;
1839}
1840
1841CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
1842{
1843    CA_DB *retdb = NULL;
1844    TXT_DB *tmpdb = NULL;
1845    BIO *in = BIO_new(BIO_s_file());
1846    CONF *dbattr_conf = NULL;
1847    char buf[1][BSIZE];
1848    long errorline = -1;
1849
1850    if (in == NULL) {
1851        ERR_print_errors(bio_err);
1852        goto err;
1853    }
1854    if (BIO_read_filename(in, dbfile) <= 0) {
1855        perror(dbfile);
1856        BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1857        goto err;
1858    }
1859    if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1860        goto err;
1861
1862#ifndef OPENSSL_SYS_VMS
1863    BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
1864#else
1865    BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
1866#endif
1867    dbattr_conf = NCONF_new(NULL);
1868    if (NCONF_load(dbattr_conf, buf[0], &errorline) <= 0) {
1869        if (errorline > 0) {
1870            BIO_printf(bio_err,
1871                       "error on line %ld of db attribute file '%s'\n",
1872                       errorline, buf[0]);
1873            goto err;
1874        } else {
1875            NCONF_free(dbattr_conf);
1876            dbattr_conf = NULL;
1877        }
1878    }
1879
1880    if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) {
1881        fprintf(stderr, "Out of memory\n");
1882        goto err;
1883    }
1884
1885    retdb->db = tmpdb;
1886    tmpdb = NULL;
1887    if (db_attr)
1888        retdb->attributes = *db_attr;
1889    else {
1890        retdb->attributes.unique_subject = 1;
1891    }
1892
1893    if (dbattr_conf) {
1894        char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1895        if (p) {
1896#ifdef RL_DEBUG
1897            BIO_printf(bio_err,
1898                       "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
1899#endif
1900            retdb->attributes.unique_subject = parse_yesno(p, 1);
1901        }
1902    }
1903
1904 err:
1905    if (dbattr_conf)
1906        NCONF_free(dbattr_conf);
1907    if (tmpdb)
1908        TXT_DB_free(tmpdb);
1909    if (in)
1910        BIO_free_all(in);
1911    return retdb;
1912}
1913
1914int index_index(CA_DB *db)
1915{
1916    if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1917                             LHASH_HASH_FN(index_serial),
1918                             LHASH_COMP_FN(index_serial))) {
1919        BIO_printf(bio_err,
1920                   "error creating serial number index:(%ld,%ld,%ld)\n",
1921                   db->db->error, db->db->arg1, db->db->arg2);
1922        return 0;
1923    }
1924
1925    if (db->attributes.unique_subject
1926        && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1927                                LHASH_HASH_FN(index_name),
1928                                LHASH_COMP_FN(index_name))) {
1929        BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
1930                   db->db->error, db->db->arg1, db->db->arg2);
1931        return 0;
1932    }
1933    return 1;
1934}
1935
1936int save_index(const char *dbfile, const char *suffix, CA_DB *db)
1937{
1938    char buf[3][BSIZE];
1939    BIO *out = BIO_new(BIO_s_file());
1940    int j;
1941
1942    if (out == NULL) {
1943        ERR_print_errors(bio_err);
1944        goto err;
1945    }
1946
1947    j = strlen(dbfile) + strlen(suffix);
1948    if (j + 6 >= BSIZE) {
1949        BIO_printf(bio_err, "file name too long\n");
1950        goto err;
1951    }
1952#ifndef OPENSSL_SYS_VMS
1953    j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
1954#else
1955    j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
1956#endif
1957#ifndef OPENSSL_SYS_VMS
1958    j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
1959#else
1960    j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
1961#endif
1962#ifndef OPENSSL_SYS_VMS
1963    j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
1964#else
1965    j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
1966#endif
1967#ifdef RL_DEBUG
1968    BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
1969#endif
1970    if (BIO_write_filename(out, buf[0]) <= 0) {
1971        perror(dbfile);
1972        BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1973        goto err;
1974    }
1975    j = TXT_DB_write(out, db->db);
1976    if (j <= 0)
1977        goto err;
1978
1979    BIO_free(out);
1980
1981    out = BIO_new(BIO_s_file());
1982#ifdef RL_DEBUG
1983    BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
1984#endif
1985    if (BIO_write_filename(out, buf[1]) <= 0) {
1986        perror(buf[2]);
1987        BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
1988        goto err;
1989    }
1990    BIO_printf(out, "unique_subject = %s\n",
1991               db->attributes.unique_subject ? "yes" : "no");
1992    BIO_free(out);
1993
1994    return 1;
1995 err:
1996    return 0;
1997}
1998
1999int rotate_index(const char *dbfile, const char *new_suffix,
2000                 const char *old_suffix)
2001{
2002    char buf[5][BSIZE];
2003    int i, j;
2004
2005    i = strlen(dbfile) + strlen(old_suffix);
2006    j = strlen(dbfile) + strlen(new_suffix);
2007    if (i > j)
2008        j = i;
2009    if (j + 6 >= BSIZE) {
2010        BIO_printf(bio_err, "file name too long\n");
2011        goto err;
2012    }
2013#ifndef OPENSSL_SYS_VMS
2014    j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
2015#else
2016    j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
2017#endif
2018#ifndef OPENSSL_SYS_VMS
2019    j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix);
2020#else
2021    j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", dbfile, new_suffix);
2022#endif
2023#ifndef OPENSSL_SYS_VMS
2024    j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix);
2025#else
2026    j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, new_suffix);
2027#endif
2028#ifndef OPENSSL_SYS_VMS
2029    j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix);
2030#else
2031    j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", dbfile, old_suffix);
2032#endif
2033#ifndef OPENSSL_SYS_VMS
2034    j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix);
2035#else
2036    j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix);
2037#endif
2038#ifdef RL_DEBUG
2039    BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", dbfile, buf[1]);
2040#endif
2041    if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
2042#ifdef ENOTDIR
2043        && errno != ENOTDIR
2044#endif
2045        ) {
2046        BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]);
2047        perror("reason");
2048        goto err;
2049    }
2050#ifdef RL_DEBUG
2051    BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[0], dbfile);
2052#endif
2053    if (rename(buf[0], dbfile) < 0) {
2054        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile);
2055        perror("reason");
2056        rename(buf[1], dbfile);
2057        goto err;
2058    }
2059#ifdef RL_DEBUG
2060    BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[4], buf[3]);
2061#endif
2062    if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
2063#ifdef ENOTDIR
2064        && errno != ENOTDIR
2065#endif
2066        ) {
2067        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]);
2068        perror("reason");
2069        rename(dbfile, buf[0]);
2070        rename(buf[1], dbfile);
2071        goto err;
2072    }
2073#ifdef RL_DEBUG
2074    BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[2], buf[4]);
2075#endif
2076    if (rename(buf[2], buf[4]) < 0) {
2077        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]);
2078        perror("reason");
2079        rename(buf[3], buf[4]);
2080        rename(dbfile, buf[0]);
2081        rename(buf[1], dbfile);
2082        goto err;
2083    }
2084    return 1;
2085 err:
2086    return 0;
2087}
2088
2089void free_index(CA_DB *db)
2090{
2091    if (db) {
2092        if (db->db)
2093            TXT_DB_free(db->db);
2094        OPENSSL_free(db);
2095    }
2096}
2097
2098int parse_yesno(const char *str, int def)
2099{
2100    int ret = def;
2101    if (str) {
2102        switch (*str) {
2103        case 'f':              /* false */
2104        case 'F':              /* FALSE */
2105        case 'n':              /* no */
2106        case 'N':              /* NO */
2107        case '0':              /* 0 */
2108            ret = 0;
2109            break;
2110        case 't':              /* true */
2111        case 'T':              /* TRUE */
2112        case 'y':              /* yes */
2113        case 'Y':              /* YES */
2114        case '1':              /* 1 */
2115            ret = 1;
2116            break;
2117        default:
2118            ret = def;
2119            break;
2120        }
2121    }
2122    return ret;
2123}
2124
2125/*
2126 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2127 * where characters may be escaped by \
2128 */
2129X509_NAME *parse_name(char *subject, long chtype, int multirdn)
2130{
2131    size_t buflen = strlen(subject) + 1; /* to copy the types and values
2132                                          * into. due to escaping, the copy
2133                                          * can only become shorter */
2134    char *buf = OPENSSL_malloc(buflen);
2135    size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2136    char **ne_types = OPENSSL_malloc(max_ne * sizeof(char *));
2137    char **ne_values = OPENSSL_malloc(max_ne * sizeof(char *));
2138    int *mval = OPENSSL_malloc(max_ne * sizeof(int));
2139
2140    char *sp = subject, *bp = buf;
2141    int i, ne_num = 0;
2142
2143    X509_NAME *n = NULL;
2144    int nid;
2145
2146    if (!buf || !ne_types || !ne_values || !mval) {
2147        BIO_printf(bio_err, "malloc error\n");
2148        goto error;
2149    }
2150
2151    if (*subject != '/') {
2152        BIO_printf(bio_err, "Subject does not start with '/'.\n");
2153        goto error;
2154    }
2155    sp++;                       /* skip leading / */
2156
2157    /* no multivalued RDN by default */
2158    mval[ne_num] = 0;
2159
2160    while (*sp) {
2161        /* collect type */
2162        ne_types[ne_num] = bp;
2163        while (*sp) {
2164            if (*sp == '\\') {  /* is there anything to escape in the
2165                                 * type...? */
2166                if (*++sp)
2167                    *bp++ = *sp++;
2168                else {
2169                    BIO_printf(bio_err,
2170                               "escape character at end of string\n");
2171                    goto error;
2172                }
2173            } else if (*sp == '=') {
2174                sp++;
2175                *bp++ = '\0';
2176                break;
2177            } else
2178                *bp++ = *sp++;
2179        }
2180        if (!*sp) {
2181            BIO_printf(bio_err,
2182                       "end of string encountered while processing type of subject name element #%d\n",
2183                       ne_num);
2184            goto error;
2185        }
2186        ne_values[ne_num] = bp;
2187        while (*sp) {
2188            if (*sp == '\\') {
2189                if (*++sp)
2190                    *bp++ = *sp++;
2191                else {
2192                    BIO_printf(bio_err,
2193                               "escape character at end of string\n");
2194                    goto error;
2195                }
2196            } else if (*sp == '/') {
2197                sp++;
2198                /* no multivalued RDN by default */
2199                mval[ne_num + 1] = 0;
2200                break;
2201            } else if (*sp == '+' && multirdn) {
2202                /*
2203                 * a not escaped + signals a mutlivalued RDN
2204                 */
2205                sp++;
2206                mval[ne_num + 1] = -1;
2207                break;
2208            } else
2209                *bp++ = *sp++;
2210        }
2211        *bp++ = '\0';
2212        ne_num++;
2213    }
2214
2215    if (!(n = X509_NAME_new()))
2216        goto error;
2217
2218    for (i = 0; i < ne_num; i++) {
2219        if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
2220            BIO_printf(bio_err,
2221                       "Subject Attribute %s has no known NID, skipped\n",
2222                       ne_types[i]);
2223            continue;
2224        }
2225
2226        if (!*ne_values[i]) {
2227            BIO_printf(bio_err,
2228                       "No value provided for Subject Attribute %s, skipped\n",
2229                       ne_types[i]);
2230            continue;
2231        }
2232
2233        if (!X509_NAME_add_entry_by_NID
2234            (n, nid, chtype, (unsigned char *)ne_values[i], -1, -1, mval[i]))
2235            goto error;
2236    }
2237
2238    OPENSSL_free(ne_values);
2239    OPENSSL_free(ne_types);
2240    OPENSSL_free(buf);
2241    OPENSSL_free(mval);
2242    return n;
2243
2244 error:
2245    X509_NAME_free(n);
2246    if (ne_values)
2247        OPENSSL_free(ne_values);
2248    if (ne_types)
2249        OPENSSL_free(ne_types);
2250    if (mval)
2251        OPENSSL_free(mval);
2252    if (buf)
2253        OPENSSL_free(buf);
2254    return NULL;
2255}
2256
2257int args_verify(char ***pargs, int *pargc,
2258                int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
2259{
2260    ASN1_OBJECT *otmp = NULL;
2261    unsigned long flags = 0;
2262    int i;
2263    int purpose = 0, depth = -1;
2264    char **oldargs = *pargs;
2265    char *arg = **pargs, *argn = (*pargs)[1];
2266    time_t at_time = 0;
2267    char *hostname = NULL;
2268    char *email = NULL;
2269    char *ipasc = NULL;
2270    if (!strcmp(arg, "-policy")) {
2271        if (!argn)
2272            *badarg = 1;
2273        else {
2274            otmp = OBJ_txt2obj(argn, 0);
2275            if (!otmp) {
2276                BIO_printf(err, "Invalid Policy \"%s\"\n", argn);
2277                *badarg = 1;
2278            }
2279        }
2280        (*pargs)++;
2281    } else if (strcmp(arg, "-purpose") == 0) {
2282        X509_PURPOSE *xptmp;
2283        if (!argn)
2284            *badarg = 1;
2285        else {
2286            i = X509_PURPOSE_get_by_sname(argn);
2287            if (i < 0) {
2288                BIO_printf(err, "unrecognized purpose\n");
2289                *badarg = 1;
2290            } else {
2291                xptmp = X509_PURPOSE_get0(i);
2292                purpose = X509_PURPOSE_get_id(xptmp);
2293            }
2294        }
2295        (*pargs)++;
2296    } else if (strcmp(arg, "-verify_depth") == 0) {
2297        if (!argn)
2298            *badarg = 1;
2299        else {
2300            depth = atoi(argn);
2301            if (depth < 0) {
2302                BIO_printf(err, "invalid depth\n");
2303                *badarg = 1;
2304            }
2305        }
2306        (*pargs)++;
2307    } else if (strcmp(arg, "-attime") == 0) {
2308        if (!argn)
2309            *badarg = 1;
2310        else {
2311            long timestamp;
2312            /*
2313             * interpret the -attime argument as seconds since Epoch
2314             */
2315            if (sscanf(argn, "%li", &timestamp) != 1) {
2316                BIO_printf(bio_err, "Error parsing timestamp %s\n", argn);
2317                *badarg = 1;
2318            }
2319            /* on some platforms time_t may be a float */
2320            at_time = (time_t)timestamp;
2321        }
2322        (*pargs)++;
2323    } else if (strcmp(arg, "-verify_hostname") == 0) {
2324        if (!argn)
2325            *badarg = 1;
2326        hostname = argn;
2327        (*pargs)++;
2328    } else if (strcmp(arg, "-verify_email") == 0) {
2329        if (!argn)
2330            *badarg = 1;
2331        email = argn;
2332        (*pargs)++;
2333    } else if (strcmp(arg, "-verify_ip") == 0) {
2334        if (!argn)
2335            *badarg = 1;
2336        ipasc = argn;
2337        (*pargs)++;
2338    } else if (!strcmp(arg, "-ignore_critical"))
2339        flags |= X509_V_FLAG_IGNORE_CRITICAL;
2340    else if (!strcmp(arg, "-issuer_checks"))
2341        flags |= X509_V_FLAG_CB_ISSUER_CHECK;
2342    else if (!strcmp(arg, "-crl_check"))
2343        flags |= X509_V_FLAG_CRL_CHECK;
2344    else if (!strcmp(arg, "-crl_check_all"))
2345        flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
2346    else if (!strcmp(arg, "-policy_check"))
2347        flags |= X509_V_FLAG_POLICY_CHECK;
2348    else if (!strcmp(arg, "-explicit_policy"))
2349        flags |= X509_V_FLAG_EXPLICIT_POLICY;
2350    else if (!strcmp(arg, "-inhibit_any"))
2351        flags |= X509_V_FLAG_INHIBIT_ANY;
2352    else if (!strcmp(arg, "-inhibit_map"))
2353        flags |= X509_V_FLAG_INHIBIT_MAP;
2354    else if (!strcmp(arg, "-x509_strict"))
2355        flags |= X509_V_FLAG_X509_STRICT;
2356    else if (!strcmp(arg, "-extended_crl"))
2357        flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
2358    else if (!strcmp(arg, "-use_deltas"))
2359        flags |= X509_V_FLAG_USE_DELTAS;
2360    else if (!strcmp(arg, "-policy_print"))
2361        flags |= X509_V_FLAG_NOTIFY_POLICY;
2362    else if (!strcmp(arg, "-check_ss_sig"))
2363        flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
2364    else if (!strcmp(arg, "-trusted_first"))
2365        flags |= X509_V_FLAG_TRUSTED_FIRST;
2366    else if (!strcmp(arg, "-suiteB_128_only"))
2367        flags |= X509_V_FLAG_SUITEB_128_LOS_ONLY;
2368    else if (!strcmp(arg, "-suiteB_128"))
2369        flags |= X509_V_FLAG_SUITEB_128_LOS;
2370    else if (!strcmp(arg, "-suiteB_192"))
2371        flags |= X509_V_FLAG_SUITEB_192_LOS;
2372    else if (!strcmp(arg, "-partial_chain"))
2373        flags |= X509_V_FLAG_PARTIAL_CHAIN;
2374    else if (!strcmp(arg, "-no_alt_chains"))
2375        flags |= X509_V_FLAG_NO_ALT_CHAINS;
2376    else
2377        return 0;
2378
2379    if (*badarg) {
2380        if (*pm)
2381            X509_VERIFY_PARAM_free(*pm);
2382        *pm = NULL;
2383        goto end;
2384    }
2385
2386    if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) {
2387        *badarg = 1;
2388        goto end;
2389    }
2390
2391    if (otmp)
2392        X509_VERIFY_PARAM_add0_policy(*pm, otmp);
2393    if (flags)
2394        X509_VERIFY_PARAM_set_flags(*pm, flags);
2395
2396    if (purpose)
2397        X509_VERIFY_PARAM_set_purpose(*pm, purpose);
2398
2399    if (depth >= 0)
2400        X509_VERIFY_PARAM_set_depth(*pm, depth);
2401
2402    if (at_time)
2403        X509_VERIFY_PARAM_set_time(*pm, at_time);
2404
2405    if (hostname && !X509_VERIFY_PARAM_set1_host(*pm, hostname, 0))
2406        *badarg = 1;
2407
2408    if (email && !X509_VERIFY_PARAM_set1_email(*pm, email, 0))
2409        *badarg = 1;
2410
2411    if (ipasc && !X509_VERIFY_PARAM_set1_ip_asc(*pm, ipasc))
2412        *badarg = 1;
2413
2414 end:
2415
2416    (*pargs)++;
2417
2418    if (pargc)
2419        *pargc -= *pargs - oldargs;
2420
2421    return 1;
2422
2423}
2424
2425/*
2426 * Read whole contents of a BIO into an allocated memory buffer and return
2427 * it.
2428 */
2429
2430int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
2431{
2432    BIO *mem;
2433    int len, ret;
2434    unsigned char tbuf[1024];
2435    mem = BIO_new(BIO_s_mem());
2436    if (!mem)
2437        return -1;
2438    for (;;) {
2439        if ((maxlen != -1) && maxlen < 1024)
2440            len = maxlen;
2441        else
2442            len = 1024;
2443        len = BIO_read(in, tbuf, len);
2444        if (len <= 0)
2445            break;
2446        if (BIO_write(mem, tbuf, len) != len) {
2447            BIO_free(mem);
2448            return -1;
2449        }
2450        maxlen -= len;
2451
2452        if (maxlen == 0)
2453            break;
2454    }
2455    ret = BIO_get_mem_data(mem, (char **)out);
2456    BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
2457    BIO_free(mem);
2458    return ret;
2459}
2460
2461int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
2462{
2463    int rv;
2464    char *stmp, *vtmp = NULL;
2465    stmp = BUF_strdup(value);
2466    if (!stmp)
2467        return -1;
2468    vtmp = strchr(stmp, ':');
2469    if (vtmp) {
2470        *vtmp = 0;
2471        vtmp++;
2472    }
2473    rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
2474    OPENSSL_free(stmp);
2475    return rv;
2476}
2477
2478static void nodes_print(BIO *out, const char *name,
2479                        STACK_OF(X509_POLICY_NODE) *nodes)
2480{
2481    X509_POLICY_NODE *node;
2482    int i;
2483    BIO_printf(out, "%s Policies:", name);
2484    if (nodes) {
2485        BIO_puts(out, "\n");
2486        for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
2487            node = sk_X509_POLICY_NODE_value(nodes, i);
2488            X509_POLICY_NODE_print(out, node, 2);
2489        }
2490    } else
2491        BIO_puts(out, " <empty>\n");
2492}
2493
2494void policies_print(BIO *out, X509_STORE_CTX *ctx)
2495{
2496    X509_POLICY_TREE *tree;
2497    int explicit_policy;
2498    int free_out = 0;
2499    if (out == NULL) {
2500        out = BIO_new_fp(stderr, BIO_NOCLOSE);
2501        free_out = 1;
2502    }
2503    tree = X509_STORE_CTX_get0_policy_tree(ctx);
2504    explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
2505
2506    BIO_printf(out, "Require explicit Policy: %s\n",
2507               explicit_policy ? "True" : "False");
2508
2509    nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
2510    nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
2511    if (free_out)
2512        BIO_free(out);
2513}
2514
2515#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
2516
2517static JPAKE_CTX *jpake_init(const char *us, const char *them,
2518                             const char *secret)
2519{
2520    BIGNUM *p = NULL;
2521    BIGNUM *g = NULL;
2522    BIGNUM *q = NULL;
2523    BIGNUM *bnsecret = BN_new();
2524    JPAKE_CTX *ctx;
2525
2526    /* Use a safe prime for p (that we found earlier) */
2527    BN_hex2bn(&p,
2528              "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
2529    g = BN_new();
2530    BN_set_word(g, 2);
2531    q = BN_new();
2532    BN_rshift1(q, p);
2533
2534    BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
2535
2536    ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
2537    BN_free(bnsecret);
2538    BN_free(q);
2539    BN_free(g);
2540    BN_free(p);
2541
2542    return ctx;
2543}
2544
2545static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
2546{
2547    BN_print(conn, p->gx);
2548    BIO_puts(conn, "\n");
2549    BN_print(conn, p->zkpx.gr);
2550    BIO_puts(conn, "\n");
2551    BN_print(conn, p->zkpx.b);
2552    BIO_puts(conn, "\n");
2553}
2554
2555static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
2556{
2557    JPAKE_STEP1 s1;
2558
2559    JPAKE_STEP1_init(&s1);
2560    JPAKE_STEP1_generate(&s1, ctx);
2561    jpake_send_part(bconn, &s1.p1);
2562    jpake_send_part(bconn, &s1.p2);
2563    (void)BIO_flush(bconn);
2564    JPAKE_STEP1_release(&s1);
2565}
2566
2567static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
2568{
2569    JPAKE_STEP2 s2;
2570
2571    JPAKE_STEP2_init(&s2);
2572    JPAKE_STEP2_generate(&s2, ctx);
2573    jpake_send_part(bconn, &s2);
2574    (void)BIO_flush(bconn);
2575    JPAKE_STEP2_release(&s2);
2576}
2577
2578static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
2579{
2580    JPAKE_STEP3A s3a;
2581
2582    JPAKE_STEP3A_init(&s3a);
2583    JPAKE_STEP3A_generate(&s3a, ctx);
2584    BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
2585    (void)BIO_flush(bconn);
2586    JPAKE_STEP3A_release(&s3a);
2587}
2588
2589static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
2590{
2591    JPAKE_STEP3B s3b;
2592
2593    JPAKE_STEP3B_init(&s3b);
2594    JPAKE_STEP3B_generate(&s3b, ctx);
2595    BIO_write(bconn, s3b.hk, sizeof s3b.hk);
2596    (void)BIO_flush(bconn);
2597    JPAKE_STEP3B_release(&s3b);
2598}
2599
2600static void readbn(BIGNUM **bn, BIO *bconn)
2601{
2602    char buf[10240];
2603    int l;
2604
2605    l = BIO_gets(bconn, buf, sizeof buf);
2606    assert(l > 0);
2607    assert(buf[l - 1] == '\n');
2608    buf[l - 1] = '\0';
2609    BN_hex2bn(bn, buf);
2610}
2611
2612static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
2613{
2614    readbn(&p->gx, bconn);
2615    readbn(&p->zkpx.gr, bconn);
2616    readbn(&p->zkpx.b, bconn);
2617}
2618
2619static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
2620{
2621    JPAKE_STEP1 s1;
2622
2623    JPAKE_STEP1_init(&s1);
2624    jpake_receive_part(&s1.p1, bconn);
2625    jpake_receive_part(&s1.p2, bconn);
2626    if (!JPAKE_STEP1_process(ctx, &s1)) {
2627        ERR_print_errors(bio_err);
2628        exit(1);
2629    }
2630    JPAKE_STEP1_release(&s1);
2631}
2632
2633static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
2634{
2635    JPAKE_STEP2 s2;
2636
2637    JPAKE_STEP2_init(&s2);
2638    jpake_receive_part(&s2, bconn);
2639    if (!JPAKE_STEP2_process(ctx, &s2)) {
2640        ERR_print_errors(bio_err);
2641        exit(1);
2642    }
2643    JPAKE_STEP2_release(&s2);
2644}
2645
2646static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
2647{
2648    JPAKE_STEP3A s3a;
2649    int l;
2650
2651    JPAKE_STEP3A_init(&s3a);
2652    l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
2653    assert(l == sizeof s3a.hhk);
2654    if (!JPAKE_STEP3A_process(ctx, &s3a)) {
2655        ERR_print_errors(bio_err);
2656        exit(1);
2657    }
2658    JPAKE_STEP3A_release(&s3a);
2659}
2660
2661static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
2662{
2663    JPAKE_STEP3B s3b;
2664    int l;
2665
2666    JPAKE_STEP3B_init(&s3b);
2667    l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
2668    assert(l == sizeof s3b.hk);
2669    if (!JPAKE_STEP3B_process(ctx, &s3b)) {
2670        ERR_print_errors(bio_err);
2671        exit(1);
2672    }
2673    JPAKE_STEP3B_release(&s3b);
2674}
2675
2676void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
2677{
2678    JPAKE_CTX *ctx;
2679    BIO *bconn;
2680
2681    BIO_puts(out, "Authenticating with JPAKE\n");
2682
2683    ctx = jpake_init("client", "server", secret);
2684
2685    bconn = BIO_new(BIO_f_buffer());
2686    BIO_push(bconn, conn);
2687
2688    jpake_send_step1(bconn, ctx);
2689    jpake_receive_step1(ctx, bconn);
2690    jpake_send_step2(bconn, ctx);
2691    jpake_receive_step2(ctx, bconn);
2692    jpake_send_step3a(bconn, ctx);
2693    jpake_receive_step3b(ctx, bconn);
2694
2695    BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
2696
2697    if (psk_key)
2698        OPENSSL_free(psk_key);
2699
2700    psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
2701
2702    BIO_pop(bconn);
2703    BIO_free(bconn);
2704
2705    JPAKE_CTX_free(ctx);
2706}
2707
2708void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
2709{
2710    JPAKE_CTX *ctx;
2711    BIO *bconn;
2712
2713    BIO_puts(out, "Authenticating with JPAKE\n");
2714
2715    ctx = jpake_init("server", "client", secret);
2716
2717    bconn = BIO_new(BIO_f_buffer());
2718    BIO_push(bconn, conn);
2719
2720    jpake_receive_step1(ctx, bconn);
2721    jpake_send_step1(bconn, ctx);
2722    jpake_receive_step2(ctx, bconn);
2723    jpake_send_step2(bconn, ctx);
2724    jpake_receive_step3a(ctx, bconn);
2725    jpake_send_step3b(bconn, ctx);
2726
2727    BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
2728
2729    if (psk_key)
2730        OPENSSL_free(psk_key);
2731
2732    psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
2733
2734    BIO_pop(bconn);
2735    BIO_free(bconn);
2736
2737    JPAKE_CTX_free(ctx);
2738}
2739
2740#endif
2741
2742#ifndef OPENSSL_NO_TLSEXT
2743/*-
2744 * next_protos_parse parses a comma separated list of strings into a string
2745 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
2746 *   outlen: (output) set to the length of the resulting buffer on success.
2747 *   err: (maybe NULL) on failure, an error message line is written to this BIO.
2748 *   in: a NUL termianted string like "abc,def,ghi"
2749 *
2750 *   returns: a malloced buffer or NULL on failure.
2751 */
2752unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
2753{
2754    size_t len;
2755    unsigned char *out;
2756    size_t i, start = 0;
2757
2758    len = strlen(in);
2759    if (len >= 65535)
2760        return NULL;
2761
2762    out = OPENSSL_malloc(strlen(in) + 1);
2763    if (!out)
2764        return NULL;
2765
2766    for (i = 0; i <= len; ++i) {
2767        if (i == len || in[i] == ',') {
2768            if (i - start > 255) {
2769                OPENSSL_free(out);
2770                return NULL;
2771            }
2772            out[start] = i - start;
2773            start = i + 1;
2774        } else
2775            out[i + 1] = in[i];
2776    }
2777
2778    *outlen = len + 1;
2779    return out;
2780}
2781#endif                          /* ndef OPENSSL_NO_TLSEXT */
2782
2783void print_cert_checks(BIO *bio, X509 *x,
2784                       const char *checkhost,
2785                       const char *checkemail, const char *checkip)
2786{
2787    if (x == NULL)
2788        return;
2789    if (checkhost) {
2790        BIO_printf(bio, "Hostname %s does%s match certificate\n",
2791                   checkhost, X509_check_host(x, checkhost, 0, 0, NULL) == 1
2792                   ? "" : " NOT");
2793    }
2794
2795    if (checkemail) {
2796        BIO_printf(bio, "Email %s does%s match certificate\n",
2797                   checkemail, X509_check_email(x, checkemail, 0,
2798                                                0) ? "" : " NOT");
2799    }
2800
2801    if (checkip) {
2802        BIO_printf(bio, "IP %s does%s match certificate\n",
2803                   checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT");
2804    }
2805}
2806
2807/* Get first http URL from a DIST_POINT structure */
2808
2809static const char *get_dp_url(DIST_POINT *dp)
2810{
2811    GENERAL_NAMES *gens;
2812    GENERAL_NAME *gen;
2813    int i, gtype;
2814    ASN1_STRING *uri;
2815    if (!dp->distpoint || dp->distpoint->type != 0)
2816        return NULL;
2817    gens = dp->distpoint->name.fullname;
2818    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
2819        gen = sk_GENERAL_NAME_value(gens, i);
2820        uri = GENERAL_NAME_get0_value(gen, &gtype);
2821        if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
2822            char *uptr = (char *)ASN1_STRING_data(uri);
2823            if (!strncmp(uptr, "http://", 7))
2824                return uptr;
2825        }
2826    }
2827    return NULL;
2828}
2829
2830/*
2831 * Look through a CRLDP structure and attempt to find an http URL to
2832 * downloads a CRL from.
2833 */
2834
2835static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
2836{
2837    int i;
2838    const char *urlptr = NULL;
2839    for (i = 0; i < sk_DIST_POINT_num(crldp); i++) {
2840        DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
2841        urlptr = get_dp_url(dp);
2842        if (urlptr)
2843            return load_crl(urlptr, FORMAT_HTTP);
2844    }
2845    return NULL;
2846}
2847
2848/*
2849 * Example of downloading CRLs from CRLDP: not usable for real world as it
2850 * always downloads, doesn't support non-blocking I/O and doesn't cache
2851 * anything.
2852 */
2853
2854static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
2855{
2856    X509 *x;
2857    STACK_OF(X509_CRL) *crls = NULL;
2858    X509_CRL *crl;
2859    STACK_OF(DIST_POINT) *crldp;
2860    x = X509_STORE_CTX_get_current_cert(ctx);
2861    crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
2862    crl = load_crl_crldp(crldp);
2863    sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
2864    if (!crl)
2865        return NULL;
2866    crls = sk_X509_CRL_new_null();
2867    sk_X509_CRL_push(crls, crl);
2868    /* Try to download delta CRL */
2869    crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL);
2870    crl = load_crl_crldp(crldp);
2871    sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
2872    if (crl)
2873        sk_X509_CRL_push(crls, crl);
2874    return crls;
2875}
2876
2877void store_setup_crl_download(X509_STORE *st)
2878{
2879    X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
2880}
2881
2882/*
2883 * Platform-specific sections
2884 */
2885#if defined(_WIN32)
2886# ifdef fileno
2887#  undef fileno
2888#  define fileno(a) (int)_fileno(a)
2889# endif
2890
2891# include <windows.h>
2892# include <tchar.h>
2893
2894static int WIN32_rename(const char *from, const char *to)
2895{
2896    TCHAR *tfrom = NULL, *tto;
2897    DWORD err;
2898    int ret = 0;
2899
2900    if (sizeof(TCHAR) == 1) {
2901        tfrom = (TCHAR *)from;
2902        tto = (TCHAR *)to;
2903    } else {                    /* UNICODE path */
2904
2905        size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
2906        tfrom = (TCHAR *)malloc(sizeof(TCHAR) * (flen + tlen));
2907        if (tfrom == NULL)
2908            goto err;
2909        tto = tfrom + flen;
2910# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2911        if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
2912# endif
2913            for (i = 0; i < flen; i++)
2914                tfrom[i] = (TCHAR)from[i];
2915# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2916        if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
2917# endif
2918            for (i = 0; i < tlen; i++)
2919                tto[i] = (TCHAR)to[i];
2920    }
2921
2922    if (MoveFile(tfrom, tto))
2923        goto ok;
2924    err = GetLastError();
2925    if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
2926        if (DeleteFile(tto) && MoveFile(tfrom, tto))
2927            goto ok;
2928        err = GetLastError();
2929    }
2930    if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
2931        errno = ENOENT;
2932    else if (err == ERROR_ACCESS_DENIED)
2933        errno = EACCES;
2934    else
2935        errno = EINVAL;         /* we could map more codes... */
2936 err:
2937    ret = -1;
2938 ok:
2939    if (tfrom != NULL && tfrom != (TCHAR *)from)
2940        free(tfrom);
2941    return ret;
2942}
2943#endif
2944
2945/* app_tminterval section */
2946#if defined(_WIN32)
2947double app_tminterval(int stop, int usertime)
2948{
2949    FILETIME now;
2950    double ret = 0;
2951    static ULARGE_INTEGER tmstart;
2952    static int warning = 1;
2953# ifdef _WIN32_WINNT
2954    static HANDLE proc = NULL;
2955
2956    if (proc == NULL) {
2957        if (check_winnt())
2958            proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
2959                               GetCurrentProcessId());
2960        if (proc == NULL)
2961            proc = (HANDLE) - 1;
2962    }
2963
2964    if (usertime && proc != (HANDLE) - 1) {
2965        FILETIME junk;
2966        GetProcessTimes(proc, &junk, &junk, &junk, &now);
2967    } else
2968# endif
2969    {
2970        SYSTEMTIME systime;
2971
2972        if (usertime && warning) {
2973            BIO_printf(bio_err, "To get meaningful results, run "
2974                       "this program on idle system.\n");
2975            warning = 0;
2976        }
2977        GetSystemTime(&systime);
2978        SystemTimeToFileTime(&systime, &now);
2979    }
2980
2981    if (stop == TM_START) {
2982        tmstart.u.LowPart = now.dwLowDateTime;
2983        tmstart.u.HighPart = now.dwHighDateTime;
2984    } else {
2985        ULARGE_INTEGER tmstop;
2986
2987        tmstop.u.LowPart = now.dwLowDateTime;
2988        tmstop.u.HighPart = now.dwHighDateTime;
2989
2990        ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
2991    }
2992
2993    return (ret);
2994}
2995
2996#elif defined(OPENSSL_SYS_NETWARE)
2997# include <time.h>
2998
2999double app_tminterval(int stop, int usertime)
3000{
3001    double ret = 0;
3002    static clock_t tmstart;
3003    static int warning = 1;
3004
3005    if (usertime && warning) {
3006        BIO_printf(bio_err, "To get meaningful results, run "
3007                   "this program on idle system.\n");
3008        warning = 0;
3009    }
3010
3011    if (stop == TM_START)
3012        tmstart = clock();
3013    else
3014        ret = (clock() - tmstart) / (double)CLOCKS_PER_SEC;
3015
3016    return (ret);
3017}
3018
3019#elif defined(OPENSSL_SYSTEM_VXWORKS)
3020# include <time.h>
3021
3022double app_tminterval(int stop, int usertime)
3023{
3024    double ret = 0;
3025# ifdef CLOCK_REALTIME
3026    static struct timespec tmstart;
3027    struct timespec now;
3028# else
3029    static unsigned long tmstart;
3030    unsigned long now;
3031# endif
3032    static int warning = 1;
3033
3034    if (usertime && warning) {
3035        BIO_printf(bio_err, "To get meaningful results, run "
3036                   "this program on idle system.\n");
3037        warning = 0;
3038    }
3039# ifdef CLOCK_REALTIME
3040    clock_gettime(CLOCK_REALTIME, &now);
3041    if (stop == TM_START)
3042        tmstart = now;
3043    else
3044        ret = ((now.tv_sec + now.tv_nsec * 1e-9)
3045               - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
3046# else
3047    now = tickGet();
3048    if (stop == TM_START)
3049        tmstart = now;
3050    else
3051        ret = (now - tmstart) / (double)sysClkRateGet();
3052# endif
3053    return (ret);
3054}
3055
3056#elif defined(OPENSSL_SYSTEM_VMS)
3057# include <time.h>
3058# include <times.h>
3059
3060double app_tminterval(int stop, int usertime)
3061{
3062    static clock_t tmstart;
3063    double ret = 0;
3064    clock_t now;
3065# ifdef __TMS
3066    struct tms rus;
3067
3068    now = times(&rus);
3069    if (usertime)
3070        now = rus.tms_utime;
3071# else
3072    if (usertime)
3073        now = clock();          /* sum of user and kernel times */
3074    else {
3075        struct timeval tv;
3076        gettimeofday(&tv, NULL);
3077        now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
3078                        (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
3079            );
3080    }
3081# endif
3082    if (stop == TM_START)
3083        tmstart = now;
3084    else
3085        ret = (now - tmstart) / (double)(CLK_TCK);
3086
3087    return (ret);
3088}
3089
3090#elif defined(_SC_CLK_TCK)      /* by means of unistd.h */
3091# include <sys/times.h>
3092
3093double app_tminterval(int stop, int usertime)
3094{
3095    double ret = 0;
3096    struct tms rus;
3097    clock_t now = times(&rus);
3098    static clock_t tmstart;
3099
3100    if (usertime)
3101        now = rus.tms_utime;
3102
3103    if (stop == TM_START)
3104        tmstart = now;
3105    else {
3106        long int tck = sysconf(_SC_CLK_TCK);
3107        ret = (now - tmstart) / (double)tck;
3108    }
3109
3110    return (ret);
3111}
3112
3113#else
3114# include <sys/time.h>
3115# include <sys/resource.h>
3116
3117double app_tminterval(int stop, int usertime)
3118{
3119    double ret = 0;
3120    struct rusage rus;
3121    struct timeval now;
3122    static struct timeval tmstart;
3123
3124    if (usertime)
3125        getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
3126    else
3127        gettimeofday(&now, NULL);
3128
3129    if (stop == TM_START)
3130        tmstart = now;
3131    else
3132        ret = ((now.tv_sec + now.tv_usec * 1e-6)
3133               - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
3134
3135    return ret;
3136}
3137#endif
3138
3139/* app_isdir section */
3140#ifdef _WIN32
3141int app_isdir(const char *name)
3142{
3143    HANDLE hList;
3144    WIN32_FIND_DATA FileData;
3145# if defined(UNICODE) || defined(_UNICODE)
3146    size_t i, len_0 = strlen(name) + 1;
3147
3148    if (len_0 > sizeof(FileData.cFileName) / sizeof(FileData.cFileName[0]))
3149        return -1;
3150
3151#  if !defined(_WIN32_WCE) || _WIN32_WCE>=101
3152    if (!MultiByteToWideChar
3153        (CP_ACP, 0, name, len_0, FileData.cFileName, len_0))
3154#  endif
3155        for (i = 0; i < len_0; i++)
3156            FileData.cFileName[i] = (WCHAR)name[i];
3157
3158    hList = FindFirstFile(FileData.cFileName, &FileData);
3159# else
3160    hList = FindFirstFile(name, &FileData);
3161# endif
3162    if (hList == INVALID_HANDLE_VALUE)
3163        return -1;
3164    FindClose(hList);
3165    return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
3166}
3167#else
3168# include <sys/stat.h>
3169# ifndef S_ISDIR
3170#  if defined(_S_IFMT) && defined(_S_IFDIR)
3171#   define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
3172#  else
3173#   define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
3174#  endif
3175# endif
3176
3177int app_isdir(const char *name)
3178{
3179# if defined(S_ISDIR)
3180    struct stat st;
3181
3182    if (stat(name, &st) == 0)
3183        return S_ISDIR(st.st_mode);
3184    else
3185        return -1;
3186# else
3187    return -1;
3188# endif
3189}
3190#endif
3191
3192/* raw_read|write section */
3193#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
3194int raw_read_stdin(void *buf, int siz)
3195{
3196    DWORD n;
3197    if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
3198        return (n);
3199    else
3200        return (-1);
3201}
3202#else
3203int raw_read_stdin(void *buf, int siz)
3204{
3205    return read(fileno(stdin), buf, siz);
3206}
3207#endif
3208
3209#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
3210int raw_write_stdout(const void *buf, int siz)
3211{
3212    DWORD n;
3213    if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
3214        return (n);
3215    else
3216        return (-1);
3217}
3218#else
3219int raw_write_stdout(const void *buf, int siz)
3220{
3221    return write(fileno(stdout), buf, siz);
3222}
3223#endif
3224