Fix the update target and remove duplicate file updates
[openssl.git] / apps / apps.c
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(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
152 static int WIN32_rename(const char *from, const char *to);
153 # define rename(from,to) WIN32_rename((from),(to))
154 #endif
155
156 typedef struct {
157     const char *name;
158     unsigned long flag;
159     unsigned long mask;
160 } NAME_EX_TBL;
161
162 static UI_METHOD *ui_method = NULL;
163
164 static int set_table_opts(unsigned long *flags, const char *arg,
165                           const NAME_EX_TBL * in_tbl);
166 static 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 */
171 static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
172                                    const char *key_descrip, int format);
173 #endif
174
175 int app_init(long mesgwin);
176 #ifdef undef                    /* never finished - probably never will be
177                                  * :-) */
178 int 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
268 int 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 == 'P') || (*s == 'p')) {
289         if (s[1] == 'V' || s[1] == 'v')
290             return FORMAT_PVK;
291         else
292             return (FORMAT_PEM);
293     } else
294         return (FORMAT_UNDEF);
295 }
296
297 #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
298 void program_name(char *in, char *out, int size)
299 {
300     int i, n;
301     char *p = NULL;
302
303     n = strlen(in);
304     /* find the last '/', '\' or ':' */
305     for (i = n - 1; i > 0; i--) {
306         if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':')) {
307             p = &(in[i + 1]);
308             break;
309         }
310     }
311     if (p == NULL)
312         p = in;
313     n = strlen(p);
314
315 # if defined(OPENSSL_SYS_NETWARE)
316     /* strip off trailing .nlm if present. */
317     if ((n > 4) && (p[n - 4] == '.') &&
318         ((p[n - 3] == 'n') || (p[n - 3] == 'N')) &&
319         ((p[n - 2] == 'l') || (p[n - 2] == 'L')) &&
320         ((p[n - 1] == 'm') || (p[n - 1] == 'M')))
321         n -= 4;
322 # else
323     /* strip off trailing .exe if present. */
324     if ((n > 4) && (p[n - 4] == '.') &&
325         ((p[n - 3] == 'e') || (p[n - 3] == 'E')) &&
326         ((p[n - 2] == 'x') || (p[n - 2] == 'X')) &&
327         ((p[n - 1] == 'e') || (p[n - 1] == 'E')))
328         n -= 4;
329 # endif
330
331     if (n > size - 1)
332         n = size - 1;
333
334     for (i = 0; i < n; i++) {
335         if ((p[i] >= 'A') && (p[i] <= 'Z'))
336             out[i] = p[i] - 'A' + 'a';
337         else
338             out[i] = p[i];
339     }
340     out[n] = '\0';
341 }
342 #else
343 # ifdef OPENSSL_SYS_VMS
344 void program_name(char *in, char *out, int size)
345 {
346     char *p = in, *q;
347     char *chars = ":]>";
348
349     while (*chars != '\0') {
350         q = strrchr(p, *chars);
351         if (q > p)
352             p = q + 1;
353         chars++;
354     }
355
356     q = strrchr(p, '.');
357     if (q == NULL)
358         q = p + strlen(p);
359     strncpy(out, p, size - 1);
360     if (q - p >= size) {
361         out[size - 1] = '\0';
362     } else {
363         out[q - p] = '\0';
364     }
365 }
366 # else
367 void program_name(char *in, char *out, int size)
368 {
369     char *p;
370
371     p = strrchr(in, '/');
372     if (p != NULL)
373         p++;
374     else
375         p = in;
376     BUF_strlcpy(out, p, size);
377 }
378 # endif
379 #endif
380
381 int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
382 {
383     int num, i;
384     char *p;
385
386     *argc = 0;
387     *argv = NULL;
388
389     i = 0;
390     if (arg->count == 0) {
391         arg->count = 20;
392         arg->data = (char **)OPENSSL_malloc(sizeof(char *) * arg->count);
393         if (arg->data == NULL)
394             return 0;
395     }
396     for (i = 0; i < arg->count; i++)
397         arg->data[i] = NULL;
398
399     num = 0;
400     p = buf;
401     for (;;) {
402         /* first scan over white space */
403         if (!*p)
404             break;
405         while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
406             p++;
407         if (!*p)
408             break;
409
410         /* The start of something good :-) */
411         if (num >= arg->count) {
412             char **tmp_p;
413             int tlen = arg->count + 20;
414             tmp_p = (char **)OPENSSL_realloc(arg->data,
415                                              sizeof(char *) * tlen);
416             if (tmp_p == NULL)
417                 return 0;
418             arg->data = tmp_p;
419             arg->count = tlen;
420             /* initialize newly allocated data */
421             for (i = num; i < arg->count; i++)
422                 arg->data[i] = NULL;
423         }
424         arg->data[num++] = p;
425
426         /* now look for the end of this */
427         if ((*p == '\'') || (*p == '\"')) { /* scan for closing quote */
428             i = *(p++);
429             arg->data[num - 1]++; /* jump over quote */
430             while (*p && (*p != i))
431                 p++;
432             *p = '\0';
433         } else {
434             while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
435                 p++;
436
437             if (*p == '\0')
438                 p--;
439             else
440                 *p = '\0';
441         }
442         p++;
443     }
444     *argc = num;
445     *argv = arg->data;
446     return (1);
447 }
448
449 #ifndef APP_INIT
450 int app_init(long mesgwin)
451 {
452     return (1);
453 }
454 #endif
455
456 int dump_cert_text(BIO *out, X509 *x)
457 {
458     char *p;
459
460     p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
461     BIO_puts(out, "subject=");
462     BIO_puts(out, p);
463     OPENSSL_free(p);
464
465     p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
466     BIO_puts(out, "\nissuer=");
467     BIO_puts(out, p);
468     BIO_puts(out, "\n");
469     OPENSSL_free(p);
470
471     return 0;
472 }
473
474 static int ui_open(UI *ui)
475 {
476     return UI_method_get_opener(UI_OpenSSL())(ui);
477 }
478
479 static int ui_read(UI *ui, UI_STRING *uis)
480 {
481     if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
482         && UI_get0_user_data(ui)) {
483         switch (UI_get_string_type(uis)) {
484         case UIT_PROMPT:
485         case UIT_VERIFY:
486             {
487                 const char *password =
488                     ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
489                 if (password && password[0] != '\0') {
490                     UI_set_result(ui, uis, password);
491                     return 1;
492                 }
493             }
494         default:
495             break;
496         }
497     }
498     return UI_method_get_reader(UI_OpenSSL())(ui, uis);
499 }
500
501 static int ui_write(UI *ui, UI_STRING *uis)
502 {
503     if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
504         && UI_get0_user_data(ui)) {
505         switch (UI_get_string_type(uis)) {
506         case UIT_PROMPT:
507         case UIT_VERIFY:
508             {
509                 const char *password =
510                     ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
511                 if (password && password[0] != '\0')
512                     return 1;
513             }
514         default:
515             break;
516         }
517     }
518     return UI_method_get_writer(UI_OpenSSL())(ui, uis);
519 }
520
521 static int ui_close(UI *ui)
522 {
523     return UI_method_get_closer(UI_OpenSSL())(ui);
524 }
525
526 int setup_ui_method(void)
527 {
528     ui_method = UI_create_method("OpenSSL application user interface");
529     UI_method_set_opener(ui_method, ui_open);
530     UI_method_set_reader(ui_method, ui_read);
531     UI_method_set_writer(ui_method, ui_write);
532     UI_method_set_closer(ui_method, ui_close);
533     return 0;
534 }
535
536 void destroy_ui_method(void)
537 {
538     if (ui_method) {
539         UI_destroy_method(ui_method);
540         ui_method = NULL;
541     }
542 }
543
544 int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
545 {
546     UI *ui = NULL;
547     int res = 0;
548     const char *prompt_info = NULL;
549     const char *password = NULL;
550     PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
551
552     if (cb_data) {
553         if (cb_data->password)
554             password = cb_data->password;
555         if (cb_data->prompt_info)
556             prompt_info = cb_data->prompt_info;
557     }
558
559     if (password) {
560         res = strlen(password);
561         if (res > bufsiz)
562             res = bufsiz;
563         memcpy(buf, password, res);
564         return res;
565     }
566
567     ui = UI_new_method(ui_method);
568     if (ui) {
569         int ok = 0;
570         char *buff = NULL;
571         int ui_flags = 0;
572         char *prompt = NULL;
573
574         prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
575
576         ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
577         UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
578
579         if (ok >= 0)
580             ok = UI_add_input_string(ui, prompt, ui_flags, buf,
581                                      PW_MIN_LENGTH, bufsiz - 1);
582         if (ok >= 0 && verify) {
583             buff = (char *)OPENSSL_malloc(bufsiz);
584             ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
585                                       PW_MIN_LENGTH, bufsiz - 1, buf);
586         }
587         if (ok >= 0)
588             do {
589                 ok = UI_process(ui);
590             }
591             while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
592
593         if (buff) {
594             OPENSSL_cleanse(buff, (unsigned int)bufsiz);
595             OPENSSL_free(buff);
596         }
597
598         if (ok >= 0)
599             res = strlen(buf);
600         if (ok == -1) {
601             BIO_printf(bio_err, "User interface error\n");
602             ERR_print_errors(bio_err);
603             OPENSSL_cleanse(buf, (unsigned int)bufsiz);
604             res = 0;
605         }
606         if (ok == -2) {
607             BIO_printf(bio_err, "aborted!\n");
608             OPENSSL_cleanse(buf, (unsigned int)bufsiz);
609             res = 0;
610         }
611         UI_free(ui);
612         OPENSSL_free(prompt);
613     }
614     return res;
615 }
616
617 static char *app_get_pass(BIO *err, char *arg, int keepbio);
618
619 int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
620 {
621     int same;
622     if (!arg2 || !arg1 || strcmp(arg1, arg2))
623         same = 0;
624     else
625         same = 1;
626     if (arg1) {
627         *pass1 = app_get_pass(err, arg1, same);
628         if (!*pass1)
629             return 0;
630     } else if (pass1)
631         *pass1 = NULL;
632     if (arg2) {
633         *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
634         if (!*pass2)
635             return 0;
636     } else if (pass2)
637         *pass2 = NULL;
638     return 1;
639 }
640
641 static char *app_get_pass(BIO *err, char *arg, int keepbio)
642 {
643     char *tmp, tpass[APP_PASS_LEN];
644     static BIO *pwdbio = NULL;
645     int i;
646     if (!strncmp(arg, "pass:", 5))
647         return BUF_strdup(arg + 5);
648     if (!strncmp(arg, "env:", 4)) {
649         tmp = getenv(arg + 4);
650         if (!tmp) {
651             BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
652             return NULL;
653         }
654         return BUF_strdup(tmp);
655     }
656     if (!keepbio || !pwdbio) {
657         if (!strncmp(arg, "file:", 5)) {
658             pwdbio = BIO_new_file(arg + 5, "r");
659             if (!pwdbio) {
660                 BIO_printf(err, "Can't open file %s\n", arg + 5);
661                 return NULL;
662             }
663 #if !defined(_WIN32)
664             /*
665              * Under _WIN32, which covers even Win64 and CE, file
666              * descriptors referenced by BIO_s_fd are not inherited
667              * by child process and therefore below is not an option.
668              * It could have been an option if bss_fd.c was operating
669              * on real Windows descriptors, such as those obtained
670              * with CreateFile.
671              */
672         } else if (!strncmp(arg, "fd:", 3)) {
673             BIO *btmp;
674             i = atoi(arg + 3);
675             if (i >= 0)
676                 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
677             if ((i < 0) || !pwdbio) {
678                 BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
679                 return NULL;
680             }
681             /*
682              * Can't do BIO_gets on an fd BIO so add a buffering BIO
683              */
684             btmp = BIO_new(BIO_f_buffer());
685             pwdbio = BIO_push(btmp, pwdbio);
686 #endif
687         } else if (!strcmp(arg, "stdin")) {
688             pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
689             if (!pwdbio) {
690                 BIO_printf(err, "Can't open BIO for stdin\n");
691                 return NULL;
692             }
693         } else {
694             BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
695             return NULL;
696         }
697     }
698     i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
699     if (keepbio != 1) {
700         BIO_free_all(pwdbio);
701         pwdbio = NULL;
702     }
703     if (i <= 0) {
704         BIO_printf(err, "Error reading password from BIO\n");
705         return NULL;
706     }
707     tmp = strchr(tpass, '\n');
708     if (tmp)
709         *tmp = 0;
710     return BUF_strdup(tpass);
711 }
712
713 int add_oid_section(BIO *err, CONF *conf)
714 {
715     char *p;
716     STACK_OF(CONF_VALUE) *sktmp;
717     CONF_VALUE *cnf;
718     int i;
719     if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) {
720         ERR_clear_error();
721         return 1;
722     }
723     if (!(sktmp = NCONF_get_section(conf, p))) {
724         BIO_printf(err, "problem loading oid section %s\n", p);
725         return 0;
726     }
727     for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
728         cnf = sk_CONF_VALUE_value(sktmp, i);
729         if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
730             BIO_printf(err, "problem creating object %s=%s\n",
731                        cnf->name, cnf->value);
732             return 0;
733         }
734     }
735     return 1;
736 }
737
738 static int load_pkcs12(BIO *err, BIO *in, const char *desc,
739                        pem_password_cb *pem_cb, void *cb_data,
740                        EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
741 {
742     const char *pass;
743     char tpass[PEM_BUFSIZE];
744     int len, ret = 0;
745     PKCS12 *p12;
746     p12 = d2i_PKCS12_bio(in, NULL);
747     if (p12 == NULL) {
748         BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
749         goto die;
750     }
751     /* See if an empty password will do */
752     if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
753         pass = "";
754     else {
755         if (!pem_cb)
756             pem_cb = (pem_password_cb *)password_callback;
757         len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
758         if (len < 0) {
759             BIO_printf(err, "Passpharse callback error for %s\n", desc);
760             goto die;
761         }
762         if (len < PEM_BUFSIZE)
763             tpass[len] = 0;
764         if (!PKCS12_verify_mac(p12, tpass, len)) {
765             BIO_printf(err,
766                        "Mac verify error (wrong password?) in PKCS12 file for %s\n",
767                        desc);
768             goto die;
769         }
770         pass = tpass;
771     }
772     ret = PKCS12_parse(p12, pass, pkey, cert, ca);
773  die:
774     if (p12)
775         PKCS12_free(p12);
776     return ret;
777 }
778
779 X509 *load_cert(BIO *err, const char *file, int format,
780                 const char *pass, ENGINE *e, const char *cert_descrip)
781 {
782     X509 *x = NULL;
783     BIO *cert;
784
785     if ((cert = BIO_new(BIO_s_file())) == NULL) {
786         ERR_print_errors(err);
787         goto end;
788     }
789
790     if (file == NULL) {
791 #ifdef _IONBF
792 # ifndef OPENSSL_NO_SETVBUF_IONBF
793         setvbuf(stdin, NULL, _IONBF, 0);
794 # endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
795 #endif
796         BIO_set_fp(cert, stdin, BIO_NOCLOSE);
797     } else {
798         if (BIO_read_filename(cert, file) <= 0) {
799             BIO_printf(err, "Error opening %s %s\n", cert_descrip, file);
800             ERR_print_errors(err);
801             goto end;
802         }
803     }
804
805     if (format == FORMAT_ASN1)
806         x = d2i_X509_bio(cert, NULL);
807     else if (format == FORMAT_NETSCAPE) {
808         NETSCAPE_X509 *nx;
809         nx = ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509), cert, NULL);
810         if (nx == NULL)
811             goto end;
812
813         if ((strncmp(NETSCAPE_CERT_HDR, (char *)nx->header->data,
814                      nx->header->length) != 0)) {
815             NETSCAPE_X509_free(nx);
816             BIO_printf(err, "Error reading header on certificate\n");
817             goto end;
818         }
819         x = nx->cert;
820         nx->cert = NULL;
821         NETSCAPE_X509_free(nx);
822     } else if (format == FORMAT_PEM)
823         x = PEM_read_bio_X509_AUX(cert, NULL,
824                                   (pem_password_cb *)password_callback, NULL);
825     else if (format == FORMAT_PKCS12) {
826         if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL, NULL, &x, NULL))
827             goto end;
828     } else {
829         BIO_printf(err, "bad input format specified for %s\n", cert_descrip);
830         goto end;
831     }
832  end:
833     if (x == NULL) {
834         BIO_printf(err, "unable to load certificate\n");
835         ERR_print_errors(err);
836     }
837     if (cert != NULL)
838         BIO_free(cert);
839     return (x);
840 }
841
842 EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
843                    const char *pass, ENGINE *e, const char *key_descrip)
844 {
845     BIO *key = NULL;
846     EVP_PKEY *pkey = NULL;
847     PW_CB_DATA cb_data;
848
849     cb_data.password = pass;
850     cb_data.prompt_info = file;
851
852     if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
853         BIO_printf(err, "no keyfile specified\n");
854         goto end;
855     }
856 #ifndef OPENSSL_NO_ENGINE
857     if (format == FORMAT_ENGINE) {
858         if (!e)
859             BIO_printf(err, "no engine specified\n");
860         else {
861             pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data);
862             if (!pkey) {
863                 BIO_printf(err, "cannot load %s from engine\n", key_descrip);
864                 ERR_print_errors(err);
865             }
866         }
867         goto end;
868     }
869 #endif
870     key = BIO_new(BIO_s_file());
871     if (key == NULL) {
872         ERR_print_errors(err);
873         goto end;
874     }
875     if (file == NULL && maybe_stdin) {
876 #ifdef _IONBF
877 # ifndef OPENSSL_NO_SETVBUF_IONBF
878         setvbuf(stdin, NULL, _IONBF, 0);
879 # endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
880 #endif
881         BIO_set_fp(key, stdin, BIO_NOCLOSE);
882     } else if (BIO_read_filename(key, file) <= 0) {
883         BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
884         ERR_print_errors(err);
885         goto end;
886     }
887     if (format == FORMAT_ASN1) {
888         pkey = d2i_PrivateKey_bio(key, NULL);
889     } else if (format == FORMAT_PEM) {
890         pkey = PEM_read_bio_PrivateKey(key, NULL,
891                                        (pem_password_cb *)password_callback,
892                                        &cb_data);
893     }
894 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
895     else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
896         pkey = load_netscape_key(err, key, file, key_descrip, format);
897 #endif
898     else if (format == FORMAT_PKCS12) {
899         if (!load_pkcs12(err, key, key_descrip,
900                          (pem_password_cb *)password_callback, &cb_data,
901                          &pkey, NULL, NULL))
902             goto end;
903     }
904 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
905     else if (format == FORMAT_MSBLOB)
906         pkey = b2i_PrivateKey_bio(key);
907     else if (format == FORMAT_PVK)
908         pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
909                            &cb_data);
910 #endif
911     else {
912         BIO_printf(err, "bad input format specified for key file\n");
913         goto end;
914     }
915  end:
916     if (key != NULL)
917         BIO_free(key);
918     if (pkey == NULL) {
919         BIO_printf(err, "unable to load %s\n", key_descrip);
920         ERR_print_errors(err);
921     }
922     return (pkey);
923 }
924
925 EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
926                       const char *pass, ENGINE *e, const char *key_descrip)
927 {
928     BIO *key = NULL;
929     EVP_PKEY *pkey = NULL;
930     PW_CB_DATA cb_data;
931
932     cb_data.password = pass;
933     cb_data.prompt_info = file;
934
935     if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
936         BIO_printf(err, "no keyfile specified\n");
937         goto end;
938     }
939 #ifndef OPENSSL_NO_ENGINE
940     if (format == FORMAT_ENGINE) {
941         if (!e)
942             BIO_printf(bio_err, "no engine specified\n");
943         else
944             pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data);
945         goto end;
946     }
947 #endif
948     key = BIO_new(BIO_s_file());
949     if (key == NULL) {
950         ERR_print_errors(err);
951         goto end;
952     }
953     if (file == NULL && maybe_stdin) {
954 #ifdef _IONBF
955 # ifndef OPENSSL_NO_SETVBUF_IONBF
956         setvbuf(stdin, NULL, _IONBF, 0);
957 # endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
958 #endif
959         BIO_set_fp(key, stdin, BIO_NOCLOSE);
960     } else if (BIO_read_filename(key, file) <= 0) {
961         BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
962         ERR_print_errors(err);
963         goto end;
964     }
965     if (format == FORMAT_ASN1) {
966         pkey = d2i_PUBKEY_bio(key, NULL);
967     }
968 #ifndef OPENSSL_NO_RSA
969     else if (format == FORMAT_ASN1RSA) {
970         RSA *rsa;
971         rsa = d2i_RSAPublicKey_bio(key, NULL);
972         if (rsa) {
973             pkey = EVP_PKEY_new();
974             if (pkey)
975                 EVP_PKEY_set1_RSA(pkey, rsa);
976             RSA_free(rsa);
977         } else
978             pkey = NULL;
979     } else if (format == FORMAT_PEMRSA) {
980         RSA *rsa;
981         rsa = PEM_read_bio_RSAPublicKey(key, NULL,
982                                         (pem_password_cb *)password_callback,
983                                         &cb_data);
984         if (rsa) {
985             pkey = EVP_PKEY_new();
986             if (pkey)
987                 EVP_PKEY_set1_RSA(pkey, rsa);
988             RSA_free(rsa);
989         } else
990             pkey = NULL;
991     }
992 #endif
993     else if (format == FORMAT_PEM) {
994         pkey = PEM_read_bio_PUBKEY(key, NULL,
995                                    (pem_password_cb *)password_callback,
996                                    &cb_data);
997     }
998 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
999     else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
1000         pkey = load_netscape_key(err, key, file, key_descrip, format);
1001 #endif
1002 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
1003     else if (format == FORMAT_MSBLOB)
1004         pkey = b2i_PublicKey_bio(key);
1005 #endif
1006     else {
1007         BIO_printf(err, "bad input format specified for key file\n");
1008         goto end;
1009     }
1010  end:
1011     if (key != NULL)
1012         BIO_free(key);
1013     if (pkey == NULL)
1014         BIO_printf(err, "unable to load %s\n", key_descrip);
1015     return (pkey);
1016 }
1017
1018 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
1019 static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
1020                                    const char *key_descrip, int format)
1021 {
1022     EVP_PKEY *pkey;
1023     BUF_MEM *buf;
1024     RSA *rsa;
1025     const unsigned char *p;
1026     int size, i;
1027
1028     buf = BUF_MEM_new();
1029     pkey = EVP_PKEY_new();
1030     size = 0;
1031     if (buf == NULL || pkey == NULL)
1032         goto error;
1033     for (;;) {
1034         if (!BUF_MEM_grow_clean(buf, size + 1024 * 10))
1035             goto error;
1036         i = BIO_read(key, &(buf->data[size]), 1024 * 10);
1037         size += i;
1038         if (i == 0)
1039             break;
1040         if (i < 0) {
1041             BIO_printf(err, "Error reading %s %s", key_descrip, file);
1042             goto error;
1043         }
1044     }
1045     p = (unsigned char *)buf->data;
1046     rsa = d2i_RSA_NET(NULL, &p, (long)size, NULL,
1047                       (format == FORMAT_IISSGC ? 1 : 0));
1048     if (rsa == NULL)
1049         goto error;
1050     BUF_MEM_free(buf);
1051     EVP_PKEY_set1_RSA(pkey, rsa);
1052     return pkey;
1053  error:
1054     BUF_MEM_free(buf);
1055     EVP_PKEY_free(pkey);
1056     return NULL;
1057 }
1058 #endif                          /* ndef OPENSSL_NO_RC4 */
1059
1060 static int load_certs_crls(BIO *err, const char *file, int format,
1061                            const char *pass, ENGINE *e, const char *desc,
1062                            STACK_OF(X509) **pcerts,
1063                            STACK_OF(X509_CRL) **pcrls)
1064 {
1065     int i;
1066     BIO *bio;
1067     STACK_OF(X509_INFO) *xis = NULL;
1068     X509_INFO *xi;
1069     PW_CB_DATA cb_data;
1070     int rv = 0;
1071
1072     cb_data.password = pass;
1073     cb_data.prompt_info = file;
1074
1075     if (format != FORMAT_PEM) {
1076         BIO_printf(err, "bad input format specified for %s\n", desc);
1077         return 0;
1078     }
1079
1080     if (file == NULL)
1081         bio = BIO_new_fp(stdin, BIO_NOCLOSE);
1082     else
1083         bio = BIO_new_file(file, "r");
1084
1085     if (bio == NULL) {
1086         BIO_printf(err, "Error opening %s %s\n", desc, file ? file : "stdin");
1087         ERR_print_errors(err);
1088         return 0;
1089     }
1090
1091     xis = PEM_X509_INFO_read_bio(bio, NULL,
1092                                  (pem_password_cb *)password_callback,
1093                                  &cb_data);
1094
1095     BIO_free(bio);
1096
1097     if (pcerts) {
1098         *pcerts = sk_X509_new_null();
1099         if (!*pcerts)
1100             goto end;
1101     }
1102
1103     if (pcrls) {
1104         *pcrls = sk_X509_CRL_new_null();
1105         if (!*pcrls)
1106             goto end;
1107     }
1108
1109     for (i = 0; i < sk_X509_INFO_num(xis); i++) {
1110         xi = sk_X509_INFO_value(xis, i);
1111         if (xi->x509 && pcerts) {
1112             if (!sk_X509_push(*pcerts, xi->x509))
1113                 goto end;
1114             xi->x509 = NULL;
1115         }
1116         if (xi->crl && pcrls) {
1117             if (!sk_X509_CRL_push(*pcrls, xi->crl))
1118                 goto end;
1119             xi->crl = NULL;
1120         }
1121     }
1122
1123     if (pcerts && sk_X509_num(*pcerts) > 0)
1124         rv = 1;
1125
1126     if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
1127         rv = 1;
1128
1129  end:
1130
1131     if (xis)
1132         sk_X509_INFO_pop_free(xis, X509_INFO_free);
1133
1134     if (rv == 0) {
1135         if (pcerts) {
1136             sk_X509_pop_free(*pcerts, X509_free);
1137             *pcerts = NULL;
1138         }
1139         if (pcrls) {
1140             sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
1141             *pcrls = NULL;
1142         }
1143         BIO_printf(err, "unable to load %s\n",
1144                    pcerts ? "certificates" : "CRLs");
1145         ERR_print_errors(err);
1146     }
1147     return rv;
1148 }
1149
1150 STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
1151                            const char *pass, ENGINE *e, const char *desc)
1152 {
1153     STACK_OF(X509) *certs;
1154     if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
1155         return NULL;
1156     return certs;
1157 }
1158
1159 STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
1160                               const char *pass, ENGINE *e, const char *desc)
1161 {
1162     STACK_OF(X509_CRL) *crls;
1163     if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
1164         return NULL;
1165     return crls;
1166 }
1167
1168 #define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
1169 /* Return error for unknown extensions */
1170 #define X509V3_EXT_DEFAULT              0
1171 /* Print error for unknown extensions */
1172 #define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
1173 /* ASN1 parse unknown extensions */
1174 #define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
1175 /* BIO_dump unknown extensions */
1176 #define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)
1177
1178 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
1179                          X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
1180
1181 int set_cert_ex(unsigned long *flags, const char *arg)
1182 {
1183     static const NAME_EX_TBL cert_tbl[] = {
1184         {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
1185         {"ca_default", X509_FLAG_CA, 0xffffffffl},
1186         {"no_header", X509_FLAG_NO_HEADER, 0},
1187         {"no_version", X509_FLAG_NO_VERSION, 0},
1188         {"no_serial", X509_FLAG_NO_SERIAL, 0},
1189         {"no_signame", X509_FLAG_NO_SIGNAME, 0},
1190         {"no_validity", X509_FLAG_NO_VALIDITY, 0},
1191         {"no_subject", X509_FLAG_NO_SUBJECT, 0},
1192         {"no_issuer", X509_FLAG_NO_ISSUER, 0},
1193         {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
1194         {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
1195         {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
1196         {"no_aux", X509_FLAG_NO_AUX, 0},
1197         {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
1198         {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
1199         {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1200         {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1201         {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
1202         {NULL, 0, 0}
1203     };
1204     return set_multi_opts(flags, arg, cert_tbl);
1205 }
1206
1207 int set_name_ex(unsigned long *flags, const char *arg)
1208 {
1209     static const NAME_EX_TBL ex_tbl[] = {
1210         {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
1211         {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
1212         {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
1213         {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
1214         {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
1215         {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
1216         {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
1217         {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
1218         {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
1219         {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
1220         {"compat", XN_FLAG_COMPAT, 0xffffffffL},
1221         {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
1222         {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
1223         {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
1224         {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
1225         {"dn_rev", XN_FLAG_DN_REV, 0},
1226         {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
1227         {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
1228         {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
1229         {"align", XN_FLAG_FN_ALIGN, 0},
1230         {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
1231         {"space_eq", XN_FLAG_SPC_EQ, 0},
1232         {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
1233         {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
1234         {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
1235         {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
1236         {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
1237         {NULL, 0, 0}
1238     };
1239     return set_multi_opts(flags, arg, ex_tbl);
1240 }
1241
1242 int set_ext_copy(int *copy_type, const char *arg)
1243 {
1244     if (!strcasecmp(arg, "none"))
1245         *copy_type = EXT_COPY_NONE;
1246     else if (!strcasecmp(arg, "copy"))
1247         *copy_type = EXT_COPY_ADD;
1248     else if (!strcasecmp(arg, "copyall"))
1249         *copy_type = EXT_COPY_ALL;
1250     else
1251         return 0;
1252     return 1;
1253 }
1254
1255 int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
1256 {
1257     STACK_OF(X509_EXTENSION) *exts = NULL;
1258     X509_EXTENSION *ext, *tmpext;
1259     ASN1_OBJECT *obj;
1260     int i, idx, ret = 0;
1261     if (!x || !req || (copy_type == EXT_COPY_NONE))
1262         return 1;
1263     exts = X509_REQ_get_extensions(req);
1264
1265     for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1266         ext = sk_X509_EXTENSION_value(exts, i);
1267         obj = X509_EXTENSION_get_object(ext);
1268         idx = X509_get_ext_by_OBJ(x, obj, -1);
1269         /* Does extension exist? */
1270         if (idx != -1) {
1271             /* If normal copy don't override existing extension */
1272             if (copy_type == EXT_COPY_ADD)
1273                 continue;
1274             /* Delete all extensions of same type */
1275             do {
1276                 tmpext = X509_get_ext(x, idx);
1277                 X509_delete_ext(x, idx);
1278                 X509_EXTENSION_free(tmpext);
1279                 idx = X509_get_ext_by_OBJ(x, obj, -1);
1280             } while (idx != -1);
1281         }
1282         if (!X509_add_ext(x, ext, -1))
1283             goto end;
1284     }
1285
1286     ret = 1;
1287
1288  end:
1289
1290     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
1291
1292     return ret;
1293 }
1294
1295 static int set_multi_opts(unsigned long *flags, const char *arg,
1296                           const NAME_EX_TBL * in_tbl)
1297 {
1298     STACK_OF(CONF_VALUE) *vals;
1299     CONF_VALUE *val;
1300     int i, ret = 1;
1301     if (!arg)
1302         return 0;
1303     vals = X509V3_parse_list(arg);
1304     for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
1305         val = sk_CONF_VALUE_value(vals, i);
1306         if (!set_table_opts(flags, val->name, in_tbl))
1307             ret = 0;
1308     }
1309     sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
1310     return ret;
1311 }
1312
1313 static int set_table_opts(unsigned long *flags, const char *arg,
1314                           const NAME_EX_TBL * in_tbl)
1315 {
1316     char c;
1317     const NAME_EX_TBL *ptbl;
1318     c = arg[0];
1319
1320     if (c == '-') {
1321         c = 0;
1322         arg++;
1323     } else if (c == '+') {
1324         c = 1;
1325         arg++;
1326     } else
1327         c = 1;
1328
1329     for (ptbl = in_tbl; ptbl->name; ptbl++) {
1330         if (!strcasecmp(arg, ptbl->name)) {
1331             *flags &= ~ptbl->mask;
1332             if (c)
1333                 *flags |= ptbl->flag;
1334             else
1335                 *flags &= ~ptbl->flag;
1336             return 1;
1337         }
1338     }
1339     return 0;
1340 }
1341
1342 void print_name(BIO *out, const char *title, X509_NAME *nm,
1343                 unsigned long lflags)
1344 {
1345     char *buf;
1346     char mline = 0;
1347     int indent = 0;
1348
1349     if (title)
1350         BIO_puts(out, title);
1351     if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
1352         mline = 1;
1353         indent = 4;
1354     }
1355     if (lflags == XN_FLAG_COMPAT) {
1356         buf = X509_NAME_oneline(nm, 0, 0);
1357         BIO_puts(out, buf);
1358         BIO_puts(out, "\n");
1359         OPENSSL_free(buf);
1360     } else {
1361         if (mline)
1362             BIO_puts(out, "\n");
1363         X509_NAME_print_ex(out, nm, indent, lflags);
1364         BIO_puts(out, "\n");
1365     }
1366 }
1367
1368 X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
1369 {
1370     X509_STORE *store;
1371     X509_LOOKUP *lookup;
1372     if (!(store = X509_STORE_new()))
1373         goto end;
1374     lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1375     if (lookup == NULL)
1376         goto end;
1377     if (CAfile) {
1378         if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
1379             BIO_printf(bp, "Error loading file %s\n", CAfile);
1380             goto end;
1381         }
1382     } else
1383         X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
1384
1385     lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1386     if (lookup == NULL)
1387         goto end;
1388     if (CApath) {
1389         if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1390             BIO_printf(bp, "Error loading directory %s\n", CApath);
1391             goto end;
1392         }
1393     } else
1394         X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1395
1396     ERR_clear_error();
1397     return store;
1398  end:
1399     X509_STORE_free(store);
1400     return NULL;
1401 }
1402
1403 #ifndef OPENSSL_NO_ENGINE
1404 /* Try to load an engine in a shareable library */
1405 static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
1406 {
1407     ENGINE *e = ENGINE_by_id("dynamic");
1408     if (e) {
1409         if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
1410             || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
1411             ENGINE_free(e);
1412             e = NULL;
1413         }
1414     }
1415     return e;
1416 }
1417
1418 ENGINE *setup_engine(BIO *err, const char *engine, int debug)
1419 {
1420     ENGINE *e = NULL;
1421
1422     if (engine) {
1423         if (strcmp(engine, "auto") == 0) {
1424             BIO_printf(err, "enabling auto ENGINE support\n");
1425             ENGINE_register_all_complete();
1426             return NULL;
1427         }
1428         if ((e = ENGINE_by_id(engine)) == NULL
1429             && (e = try_load_engine(err, engine, debug)) == NULL) {
1430             BIO_printf(err, "invalid engine \"%s\"\n", engine);
1431             ERR_print_errors(err);
1432             return NULL;
1433         }
1434         if (debug) {
1435             ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, err, 0);
1436         }
1437         ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
1438         if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
1439             BIO_printf(err, "can't use that engine\n");
1440             ERR_print_errors(err);
1441             ENGINE_free(e);
1442             return NULL;
1443         }
1444
1445         BIO_printf(err, "engine \"%s\" set.\n", ENGINE_get_id(e));
1446
1447         /* Free our "structural" reference. */
1448         ENGINE_free(e);
1449     }
1450     return e;
1451 }
1452 #endif
1453
1454 int load_config(BIO *err, CONF *cnf)
1455 {
1456     static int load_config_called = 0;
1457     if (load_config_called)
1458         return 1;
1459     load_config_called = 1;
1460     if (!cnf)
1461         cnf = config;
1462     if (!cnf)
1463         return 1;
1464
1465     OPENSSL_load_builtin_modules();
1466
1467     if (CONF_modules_load(cnf, NULL, 0) <= 0) {
1468         BIO_printf(err, "Error configuring OpenSSL\n");
1469         ERR_print_errors(err);
1470         return 0;
1471     }
1472     return 1;
1473 }
1474
1475 char *make_config_name()
1476 {
1477     const char *t = X509_get_default_cert_area();
1478     size_t len;
1479     char *p;
1480
1481     len = strlen(t) + strlen(OPENSSL_CONF) + 2;
1482     p = OPENSSL_malloc(len);
1483     if (p == NULL)
1484         return NULL;
1485     BUF_strlcpy(p, t, len);
1486 #ifndef OPENSSL_SYS_VMS
1487     BUF_strlcat(p, "/", len);
1488 #endif
1489     BUF_strlcat(p, OPENSSL_CONF, len);
1490
1491     return p;
1492 }
1493
1494 static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
1495 {
1496     const char *n;
1497
1498     n = a[DB_serial];
1499     while (*n == '0')
1500         n++;
1501     return (lh_strhash(n));
1502 }
1503
1504 static int index_serial_cmp(const OPENSSL_CSTRING *a,
1505                             const OPENSSL_CSTRING *b)
1506 {
1507     const char *aa, *bb;
1508
1509     for (aa = a[DB_serial]; *aa == '0'; aa++) ;
1510     for (bb = b[DB_serial]; *bb == '0'; bb++) ;
1511     return (strcmp(aa, bb));
1512 }
1513
1514 static int index_name_qual(char **a)
1515 {
1516     return (a[0][0] == 'V');
1517 }
1518
1519 static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
1520 {
1521     return (lh_strhash(a[DB_name]));
1522 }
1523
1524 int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1525 {
1526     return (strcmp(a[DB_name], b[DB_name]));
1527 }
1528
1529 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1530 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1531 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1532 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1533 #undef BSIZE
1534 #define BSIZE 256
1535 BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
1536 {
1537     BIO *in = NULL;
1538     BIGNUM *ret = NULL;
1539     MS_STATIC char buf[1024];
1540     ASN1_INTEGER *ai = NULL;
1541
1542     ai = ASN1_INTEGER_new();
1543     if (ai == NULL)
1544         goto err;
1545
1546     if ((in = BIO_new(BIO_s_file())) == NULL) {
1547         ERR_print_errors(bio_err);
1548         goto err;
1549     }
1550
1551     if (BIO_read_filename(in, serialfile) <= 0) {
1552         if (!create) {
1553             perror(serialfile);
1554             goto err;
1555         } else {
1556             ret = BN_new();
1557             if (ret == NULL || !rand_serial(ret, ai))
1558                 BIO_printf(bio_err, "Out of memory\n");
1559         }
1560     } else {
1561         if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
1562             BIO_printf(bio_err, "unable to load number from %s\n",
1563                        serialfile);
1564             goto err;
1565         }
1566         ret = ASN1_INTEGER_to_BN(ai, NULL);
1567         if (ret == NULL) {
1568             BIO_printf(bio_err,
1569                        "error converting number from bin to BIGNUM\n");
1570             goto err;
1571         }
1572     }
1573
1574     if (ret && retai) {
1575         *retai = ai;
1576         ai = NULL;
1577     }
1578  err:
1579     if (in != NULL)
1580         BIO_free(in);
1581     if (ai != NULL)
1582         ASN1_INTEGER_free(ai);
1583     return (ret);
1584 }
1585
1586 int save_serial(char *serialfile, char *suffix, BIGNUM *serial,
1587                 ASN1_INTEGER **retai)
1588 {
1589     char buf[1][BSIZE];
1590     BIO *out = NULL;
1591     int ret = 0;
1592     ASN1_INTEGER *ai = NULL;
1593     int j;
1594
1595     if (suffix == NULL)
1596         j = strlen(serialfile);
1597     else
1598         j = strlen(serialfile) + strlen(suffix) + 1;
1599     if (j >= BSIZE) {
1600         BIO_printf(bio_err, "file name too long\n");
1601         goto err;
1602     }
1603
1604     if (suffix == NULL)
1605         BUF_strlcpy(buf[0], serialfile, BSIZE);
1606     else {
1607 #ifndef OPENSSL_SYS_VMS
1608         j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
1609 #else
1610         j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
1611 #endif
1612     }
1613 #ifdef RL_DEBUG
1614     BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
1615 #endif
1616     out = BIO_new(BIO_s_file());
1617     if (out == NULL) {
1618         ERR_print_errors(bio_err);
1619         goto err;
1620     }
1621     if (BIO_write_filename(out, buf[0]) <= 0) {
1622         perror(serialfile);
1623         goto err;
1624     }
1625
1626     if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1627         BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
1628         goto err;
1629     }
1630     i2a_ASN1_INTEGER(out, ai);
1631     BIO_puts(out, "\n");
1632     ret = 1;
1633     if (retai) {
1634         *retai = ai;
1635         ai = NULL;
1636     }
1637  err:
1638     if (out != NULL)
1639         BIO_free_all(out);
1640     if (ai != NULL)
1641         ASN1_INTEGER_free(ai);
1642     return (ret);
1643 }
1644
1645 int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
1646 {
1647     char buf[5][BSIZE];
1648     int i, j;
1649
1650     i = strlen(serialfile) + strlen(old_suffix);
1651     j = strlen(serialfile) + strlen(new_suffix);
1652     if (i > j)
1653         j = i;
1654     if (j + 1 >= BSIZE) {
1655         BIO_printf(bio_err, "file name too long\n");
1656         goto err;
1657     }
1658 #ifndef OPENSSL_SYS_VMS
1659     j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix);
1660 #else
1661     j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, new_suffix);
1662 #endif
1663 #ifndef OPENSSL_SYS_VMS
1664     j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix);
1665 #else
1666     j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix);
1667 #endif
1668 #ifdef RL_DEBUG
1669     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
1670                serialfile, buf[1]);
1671 #endif
1672     if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
1673 #ifdef ENOTDIR
1674         && errno != ENOTDIR
1675 #endif
1676         ) {
1677         BIO_printf(bio_err,
1678                    "unable to rename %s to %s\n", serialfile, buf[1]);
1679         perror("reason");
1680         goto err;
1681     }
1682 #ifdef RL_DEBUG
1683     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
1684                buf[0], serialfile);
1685 #endif
1686     if (rename(buf[0], serialfile) < 0) {
1687         BIO_printf(bio_err,
1688                    "unable to rename %s to %s\n", buf[0], serialfile);
1689         perror("reason");
1690         rename(buf[1], serialfile);
1691         goto err;
1692     }
1693     return 1;
1694  err:
1695     return 0;
1696 }
1697
1698 int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1699 {
1700     BIGNUM *btmp;
1701     int ret = 0;
1702     if (b)
1703         btmp = b;
1704     else
1705         btmp = BN_new();
1706
1707     if (!btmp)
1708         return 0;
1709
1710     if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1711         goto error;
1712     if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1713         goto error;
1714
1715     ret = 1;
1716
1717  error:
1718
1719     if (!b)
1720         BN_free(btmp);
1721
1722     return ret;
1723 }
1724
1725 CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
1726 {
1727     CA_DB *retdb = NULL;
1728     TXT_DB *tmpdb = NULL;
1729     BIO *in = BIO_new(BIO_s_file());
1730     CONF *dbattr_conf = NULL;
1731     char buf[1][BSIZE];
1732     long errorline = -1;
1733
1734     if (in == NULL) {
1735         ERR_print_errors(bio_err);
1736         goto err;
1737     }
1738     if (BIO_read_filename(in, dbfile) <= 0) {
1739         perror(dbfile);
1740         BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1741         goto err;
1742     }
1743     if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1744         goto err;
1745
1746 #ifndef OPENSSL_SYS_VMS
1747     BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
1748 #else
1749     BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
1750 #endif
1751     dbattr_conf = NCONF_new(NULL);
1752     if (NCONF_load(dbattr_conf, buf[0], &errorline) <= 0) {
1753         if (errorline > 0) {
1754             BIO_printf(bio_err,
1755                        "error on line %ld of db attribute file '%s'\n",
1756                        errorline, buf[0]);
1757             goto err;
1758         } else {
1759             NCONF_free(dbattr_conf);
1760             dbattr_conf = NULL;
1761         }
1762     }
1763
1764     if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) {
1765         fprintf(stderr, "Out of memory\n");
1766         goto err;
1767     }
1768
1769     retdb->db = tmpdb;
1770     tmpdb = NULL;
1771     if (db_attr)
1772         retdb->attributes = *db_attr;
1773     else {
1774         retdb->attributes.unique_subject = 1;
1775     }
1776
1777     if (dbattr_conf) {
1778         char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1779         if (p) {
1780 #ifdef RL_DEBUG
1781             BIO_printf(bio_err,
1782                        "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
1783 #endif
1784             retdb->attributes.unique_subject = parse_yesno(p, 1);
1785         }
1786     }
1787
1788  err:
1789     if (dbattr_conf)
1790         NCONF_free(dbattr_conf);
1791     if (tmpdb)
1792         TXT_DB_free(tmpdb);
1793     if (in)
1794         BIO_free_all(in);
1795     return retdb;
1796 }
1797
1798 int index_index(CA_DB *db)
1799 {
1800     if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1801                              LHASH_HASH_FN(index_serial),
1802                              LHASH_COMP_FN(index_serial))) {
1803         BIO_printf(bio_err,
1804                    "error creating serial number index:(%ld,%ld,%ld)\n",
1805                    db->db->error, db->db->arg1, db->db->arg2);
1806         return 0;
1807     }
1808
1809     if (db->attributes.unique_subject
1810         && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1811                                 LHASH_HASH_FN(index_name),
1812                                 LHASH_COMP_FN(index_name))) {
1813         BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
1814                    db->db->error, db->db->arg1, db->db->arg2);
1815         return 0;
1816     }
1817     return 1;
1818 }
1819
1820 int save_index(const char *dbfile, const char *suffix, CA_DB *db)
1821 {
1822     char buf[3][BSIZE];
1823     BIO *out = BIO_new(BIO_s_file());
1824     int j;
1825
1826     if (out == NULL) {
1827         ERR_print_errors(bio_err);
1828         goto err;
1829     }
1830
1831     j = strlen(dbfile) + strlen(suffix);
1832     if (j + 6 >= BSIZE) {
1833         BIO_printf(bio_err, "file name too long\n");
1834         goto err;
1835     }
1836 #ifndef OPENSSL_SYS_VMS
1837     j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
1838 #else
1839     j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
1840 #endif
1841 #ifndef OPENSSL_SYS_VMS
1842     j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
1843 #else
1844     j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
1845 #endif
1846 #ifndef OPENSSL_SYS_VMS
1847     j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
1848 #else
1849     j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
1850 #endif
1851 #ifdef RL_DEBUG
1852     BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
1853 #endif
1854     if (BIO_write_filename(out, buf[0]) <= 0) {
1855         perror(dbfile);
1856         BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1857         goto err;
1858     }
1859     j = TXT_DB_write(out, db->db);
1860     if (j <= 0)
1861         goto err;
1862
1863     BIO_free(out);
1864
1865     out = BIO_new(BIO_s_file());
1866 #ifdef RL_DEBUG
1867     BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
1868 #endif
1869     if (BIO_write_filename(out, buf[1]) <= 0) {
1870         perror(buf[2]);
1871         BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
1872         goto err;
1873     }
1874     BIO_printf(out, "unique_subject = %s\n",
1875                db->attributes.unique_subject ? "yes" : "no");
1876     BIO_free(out);
1877
1878     return 1;
1879  err:
1880     return 0;
1881 }
1882
1883 int rotate_index(const char *dbfile, const char *new_suffix,
1884                  const char *old_suffix)
1885 {
1886     char buf[5][BSIZE];
1887     int i, j;
1888
1889     i = strlen(dbfile) + strlen(old_suffix);
1890     j = strlen(dbfile) + strlen(new_suffix);
1891     if (i > j)
1892         j = i;
1893     if (j + 6 >= BSIZE) {
1894         BIO_printf(bio_err, "file name too long\n");
1895         goto err;
1896     }
1897 #ifndef OPENSSL_SYS_VMS
1898     j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
1899 #else
1900     j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
1901 #endif
1902 #ifndef OPENSSL_SYS_VMS
1903     j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix);
1904 #else
1905     j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", dbfile, new_suffix);
1906 #endif
1907 #ifndef OPENSSL_SYS_VMS
1908     j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix);
1909 #else
1910     j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, new_suffix);
1911 #endif
1912 #ifndef OPENSSL_SYS_VMS
1913     j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix);
1914 #else
1915     j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", dbfile, old_suffix);
1916 #endif
1917 #ifndef OPENSSL_SYS_VMS
1918     j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix);
1919 #else
1920     j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix);
1921 #endif
1922 #ifdef RL_DEBUG
1923     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", dbfile, buf[1]);
1924 #endif
1925     if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
1926 #ifdef ENOTDIR
1927         && errno != ENOTDIR
1928 #endif
1929         ) {
1930         BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]);
1931         perror("reason");
1932         goto err;
1933     }
1934 #ifdef RL_DEBUG
1935     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[0], dbfile);
1936 #endif
1937     if (rename(buf[0], dbfile) < 0) {
1938         BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile);
1939         perror("reason");
1940         rename(buf[1], dbfile);
1941         goto err;
1942     }
1943 #ifdef RL_DEBUG
1944     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[4], buf[3]);
1945 #endif
1946     if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
1947 #ifdef ENOTDIR
1948         && errno != ENOTDIR
1949 #endif
1950         ) {
1951         BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]);
1952         perror("reason");
1953         rename(dbfile, buf[0]);
1954         rename(buf[1], dbfile);
1955         goto err;
1956     }
1957 #ifdef RL_DEBUG
1958     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[2], buf[4]);
1959 #endif
1960     if (rename(buf[2], buf[4]) < 0) {
1961         BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]);
1962         perror("reason");
1963         rename(buf[3], buf[4]);
1964         rename(dbfile, buf[0]);
1965         rename(buf[1], dbfile);
1966         goto err;
1967     }
1968     return 1;
1969  err:
1970     return 0;
1971 }
1972
1973 void free_index(CA_DB *db)
1974 {
1975     if (db) {
1976         if (db->db)
1977             TXT_DB_free(db->db);
1978         OPENSSL_free(db);
1979     }
1980 }
1981
1982 int parse_yesno(const char *str, int def)
1983 {
1984     int ret = def;
1985     if (str) {
1986         switch (*str) {
1987         case 'f':              /* false */
1988         case 'F':              /* FALSE */
1989         case 'n':              /* no */
1990         case 'N':              /* NO */
1991         case '0':              /* 0 */
1992             ret = 0;
1993             break;
1994         case 't':              /* true */
1995         case 'T':              /* TRUE */
1996         case 'y':              /* yes */
1997         case 'Y':              /* YES */
1998         case '1':              /* 1 */
1999             ret = 1;
2000             break;
2001         default:
2002             ret = def;
2003             break;
2004         }
2005     }
2006     return ret;
2007 }
2008
2009 /*
2010  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2011  * where characters may be escaped by \
2012  */
2013 X509_NAME *parse_name(char *subject, long chtype, int multirdn)
2014 {
2015     size_t buflen = strlen(subject) + 1; /* to copy the types and values
2016                                           * into. due to escaping, the copy
2017                                           * can only become shorter */
2018     char *buf = OPENSSL_malloc(buflen);
2019     size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2020     char **ne_types = OPENSSL_malloc(max_ne * sizeof(char *));
2021     char **ne_values = OPENSSL_malloc(max_ne * sizeof(char *));
2022     int *mval = OPENSSL_malloc(max_ne * sizeof(int));
2023
2024     char *sp = subject, *bp = buf;
2025     int i, ne_num = 0;
2026
2027     X509_NAME *n = NULL;
2028     int nid;
2029
2030     if (!buf || !ne_types || !ne_values || !mval) {
2031         BIO_printf(bio_err, "malloc error\n");
2032         goto error;
2033     }
2034
2035     if (*subject != '/') {
2036         BIO_printf(bio_err, "Subject does not start with '/'.\n");
2037         goto error;
2038     }
2039     sp++;                       /* skip leading / */
2040
2041     /* no multivalued RDN by default */
2042     mval[ne_num] = 0;
2043
2044     while (*sp) {
2045         /* collect type */
2046         ne_types[ne_num] = bp;
2047         while (*sp) {
2048             if (*sp == '\\') {  /* is there anything to escape in the
2049                                  * type...? */
2050                 if (*++sp)
2051                     *bp++ = *sp++;
2052                 else {
2053                     BIO_printf(bio_err,
2054                                "escape character at end of string\n");
2055                     goto error;
2056                 }
2057             } else if (*sp == '=') {
2058                 sp++;
2059                 *bp++ = '\0';
2060                 break;
2061             } else
2062                 *bp++ = *sp++;
2063         }
2064         if (!*sp) {
2065             BIO_printf(bio_err,
2066                        "end of string encountered while processing type of subject name element #%d\n",
2067                        ne_num);
2068             goto error;
2069         }
2070         ne_values[ne_num] = bp;
2071         while (*sp) {
2072             if (*sp == '\\') {
2073                 if (*++sp)
2074                     *bp++ = *sp++;
2075                 else {
2076                     BIO_printf(bio_err,
2077                                "escape character at end of string\n");
2078                     goto error;
2079                 }
2080             } else if (*sp == '/') {
2081                 sp++;
2082                 /* no multivalued RDN by default */
2083                 mval[ne_num + 1] = 0;
2084                 break;
2085             } else if (*sp == '+' && multirdn) {
2086                 /*
2087                  * a not escaped + signals a mutlivalued RDN
2088                  */
2089                 sp++;
2090                 mval[ne_num + 1] = -1;
2091                 break;
2092             } else
2093                 *bp++ = *sp++;
2094         }
2095         *bp++ = '\0';
2096         ne_num++;
2097     }
2098
2099     if (!(n = X509_NAME_new()))
2100         goto error;
2101
2102     for (i = 0; i < ne_num; i++) {
2103         if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
2104             BIO_printf(bio_err,
2105                        "Subject Attribute %s has no known NID, skipped\n",
2106                        ne_types[i]);
2107             continue;
2108         }
2109
2110         if (!*ne_values[i]) {
2111             BIO_printf(bio_err,
2112                        "No value provided for Subject Attribute %s, skipped\n",
2113                        ne_types[i]);
2114             continue;
2115         }
2116
2117         if (!X509_NAME_add_entry_by_NID
2118             (n, nid, chtype, (unsigned char *)ne_values[i], -1, -1, mval[i]))
2119             goto error;
2120     }
2121
2122     OPENSSL_free(ne_values);
2123     OPENSSL_free(ne_types);
2124     OPENSSL_free(buf);
2125     OPENSSL_free(mval);
2126     return n;
2127
2128  error:
2129     X509_NAME_free(n);
2130     if (ne_values)
2131         OPENSSL_free(ne_values);
2132     if (ne_types)
2133         OPENSSL_free(ne_types);
2134     if (mval)
2135         OPENSSL_free(mval);
2136     if (buf)
2137         OPENSSL_free(buf);
2138     return NULL;
2139 }
2140
2141 int args_verify(char ***pargs, int *pargc,
2142                 int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
2143 {
2144     ASN1_OBJECT *otmp = NULL;
2145     unsigned long flags = 0;
2146     int i;
2147     int purpose = 0, depth = -1;
2148     char **oldargs = *pargs;
2149     char *arg = **pargs, *argn = (*pargs)[1];
2150     if (!strcmp(arg, "-policy")) {
2151         if (!argn)
2152             *badarg = 1;
2153         else {
2154             otmp = OBJ_txt2obj(argn, 0);
2155             if (!otmp) {
2156                 BIO_printf(err, "Invalid Policy \"%s\"\n", argn);
2157                 *badarg = 1;
2158             }
2159         }
2160         (*pargs)++;
2161     } else if (strcmp(arg, "-purpose") == 0) {
2162         X509_PURPOSE *xptmp;
2163         if (!argn)
2164             *badarg = 1;
2165         else {
2166             i = X509_PURPOSE_get_by_sname(argn);
2167             if (i < 0) {
2168                 BIO_printf(err, "unrecognized purpose\n");
2169                 *badarg = 1;
2170             } else {
2171                 xptmp = X509_PURPOSE_get0(i);
2172                 purpose = X509_PURPOSE_get_id(xptmp);
2173             }
2174         }
2175         (*pargs)++;
2176     } else if (strcmp(arg, "-verify_depth") == 0) {
2177         if (!argn)
2178             *badarg = 1;
2179         else {
2180             depth = atoi(argn);
2181             if (depth < 0) {
2182                 BIO_printf(err, "invalid depth\n");
2183                 *badarg = 1;
2184             }
2185         }
2186         (*pargs)++;
2187     } else if (!strcmp(arg, "-ignore_critical"))
2188         flags |= X509_V_FLAG_IGNORE_CRITICAL;
2189     else if (!strcmp(arg, "-issuer_checks"))
2190         flags |= X509_V_FLAG_CB_ISSUER_CHECK;
2191     else if (!strcmp(arg, "-crl_check"))
2192         flags |= X509_V_FLAG_CRL_CHECK;
2193     else if (!strcmp(arg, "-crl_check_all"))
2194         flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
2195     else if (!strcmp(arg, "-policy_check"))
2196         flags |= X509_V_FLAG_POLICY_CHECK;
2197     else if (!strcmp(arg, "-explicit_policy"))
2198         flags |= X509_V_FLAG_EXPLICIT_POLICY;
2199     else if (!strcmp(arg, "-inhibit_any"))
2200         flags |= X509_V_FLAG_INHIBIT_ANY;
2201     else if (!strcmp(arg, "-inhibit_map"))
2202         flags |= X509_V_FLAG_INHIBIT_MAP;
2203     else if (!strcmp(arg, "-x509_strict"))
2204         flags |= X509_V_FLAG_X509_STRICT;
2205     else if (!strcmp(arg, "-extended_crl"))
2206         flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
2207     else if (!strcmp(arg, "-use_deltas"))
2208         flags |= X509_V_FLAG_USE_DELTAS;
2209     else if (!strcmp(arg, "-policy_print"))
2210         flags |= X509_V_FLAG_NOTIFY_POLICY;
2211     else if (!strcmp(arg, "-check_ss_sig"))
2212         flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
2213     else
2214         return 0;
2215
2216     if (*badarg) {
2217         if (*pm)
2218             X509_VERIFY_PARAM_free(*pm);
2219         *pm = NULL;
2220         goto end;
2221     }
2222
2223     if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) {
2224         *badarg = 1;
2225         goto end;
2226     }
2227
2228     if (otmp)
2229         X509_VERIFY_PARAM_add0_policy(*pm, otmp);
2230     if (flags)
2231         X509_VERIFY_PARAM_set_flags(*pm, flags);
2232
2233     if (purpose)
2234         X509_VERIFY_PARAM_set_purpose(*pm, purpose);
2235
2236     if (depth >= 0)
2237         X509_VERIFY_PARAM_set_depth(*pm, depth);
2238
2239  end:
2240
2241     (*pargs)++;
2242
2243     if (pargc)
2244         *pargc -= *pargs - oldargs;
2245
2246     return 1;
2247
2248 }
2249
2250 /*
2251  * Read whole contents of a BIO into an allocated memory buffer and return
2252  * it.
2253  */
2254
2255 int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
2256 {
2257     BIO *mem;
2258     int len, ret;
2259     unsigned char tbuf[1024];
2260     mem = BIO_new(BIO_s_mem());
2261     if (!mem)
2262         return -1;
2263     for (;;) {
2264         if ((maxlen != -1) && maxlen < 1024)
2265             len = maxlen;
2266         else
2267             len = 1024;
2268         len = BIO_read(in, tbuf, len);
2269         if (len <= 0)
2270             break;
2271         if (BIO_write(mem, tbuf, len) != len) {
2272             BIO_free(mem);
2273             return -1;
2274         }
2275         maxlen -= len;
2276
2277         if (maxlen == 0)
2278             break;
2279     }
2280     ret = BIO_get_mem_data(mem, (char **)out);
2281     BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
2282     BIO_free(mem);
2283     return ret;
2284 }
2285
2286 int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
2287 {
2288     int rv;
2289     char *stmp, *vtmp = NULL;
2290     stmp = BUF_strdup(value);
2291     if (!stmp)
2292         return -1;
2293     vtmp = strchr(stmp, ':');
2294     if (vtmp) {
2295         *vtmp = 0;
2296         vtmp++;
2297     }
2298     rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
2299     OPENSSL_free(stmp);
2300     return rv;
2301 }
2302
2303 static void nodes_print(BIO *out, const char *name,
2304                         STACK_OF(X509_POLICY_NODE) *nodes)
2305 {
2306     X509_POLICY_NODE *node;
2307     int i;
2308     BIO_printf(out, "%s Policies:", name);
2309     if (nodes) {
2310         BIO_puts(out, "\n");
2311         for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
2312             node = sk_X509_POLICY_NODE_value(nodes, i);
2313             X509_POLICY_NODE_print(out, node, 2);
2314         }
2315     } else
2316         BIO_puts(out, " <empty>\n");
2317 }
2318
2319 void policies_print(BIO *out, X509_STORE_CTX *ctx)
2320 {
2321     X509_POLICY_TREE *tree;
2322     int explicit_policy;
2323     int free_out = 0;
2324     if (out == NULL) {
2325         out = BIO_new_fp(stderr, BIO_NOCLOSE);
2326         free_out = 1;
2327     }
2328     tree = X509_STORE_CTX_get0_policy_tree(ctx);
2329     explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
2330
2331     BIO_printf(out, "Require explicit Policy: %s\n",
2332                explicit_policy ? "True" : "False");
2333
2334     nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
2335     nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
2336     if (free_out)
2337         BIO_free(out);
2338 }
2339
2340 #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
2341
2342 static JPAKE_CTX *jpake_init(const char *us, const char *them,
2343                              const char *secret)
2344 {
2345     BIGNUM *p = NULL;
2346     BIGNUM *g = NULL;
2347     BIGNUM *q = NULL;
2348     BIGNUM *bnsecret = BN_new();
2349     JPAKE_CTX *ctx;
2350
2351     /* Use a safe prime for p (that we found earlier) */
2352     BN_hex2bn(&p,
2353               "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
2354     g = BN_new();
2355     BN_set_word(g, 2);
2356     q = BN_new();
2357     BN_rshift1(q, p);
2358
2359     BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
2360
2361     ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
2362     BN_free(bnsecret);
2363     BN_free(q);
2364     BN_free(g);
2365     BN_free(p);
2366
2367     return ctx;
2368 }
2369
2370 static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
2371 {
2372     BN_print(conn, p->gx);
2373     BIO_puts(conn, "\n");
2374     BN_print(conn, p->zkpx.gr);
2375     BIO_puts(conn, "\n");
2376     BN_print(conn, p->zkpx.b);
2377     BIO_puts(conn, "\n");
2378 }
2379
2380 static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
2381 {
2382     JPAKE_STEP1 s1;
2383
2384     JPAKE_STEP1_init(&s1);
2385     JPAKE_STEP1_generate(&s1, ctx);
2386     jpake_send_part(bconn, &s1.p1);
2387     jpake_send_part(bconn, &s1.p2);
2388     (void)BIO_flush(bconn);
2389     JPAKE_STEP1_release(&s1);
2390 }
2391
2392 static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
2393 {
2394     JPAKE_STEP2 s2;
2395
2396     JPAKE_STEP2_init(&s2);
2397     JPAKE_STEP2_generate(&s2, ctx);
2398     jpake_send_part(bconn, &s2);
2399     (void)BIO_flush(bconn);
2400     JPAKE_STEP2_release(&s2);
2401 }
2402
2403 static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
2404 {
2405     JPAKE_STEP3A s3a;
2406
2407     JPAKE_STEP3A_init(&s3a);
2408     JPAKE_STEP3A_generate(&s3a, ctx);
2409     BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
2410     (void)BIO_flush(bconn);
2411     JPAKE_STEP3A_release(&s3a);
2412 }
2413
2414 static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
2415 {
2416     JPAKE_STEP3B s3b;
2417
2418     JPAKE_STEP3B_init(&s3b);
2419     JPAKE_STEP3B_generate(&s3b, ctx);
2420     BIO_write(bconn, s3b.hk, sizeof s3b.hk);
2421     (void)BIO_flush(bconn);
2422     JPAKE_STEP3B_release(&s3b);
2423 }
2424
2425 static void readbn(BIGNUM **bn, BIO *bconn)
2426 {
2427     char buf[10240];
2428     int l;
2429
2430     l = BIO_gets(bconn, buf, sizeof buf);
2431     assert(l > 0);
2432     assert(buf[l - 1] == '\n');
2433     buf[l - 1] = '\0';
2434     BN_hex2bn(bn, buf);
2435 }
2436
2437 static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
2438 {
2439     readbn(&p->gx, bconn);
2440     readbn(&p->zkpx.gr, bconn);
2441     readbn(&p->zkpx.b, bconn);
2442 }
2443
2444 static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
2445 {
2446     JPAKE_STEP1 s1;
2447
2448     JPAKE_STEP1_init(&s1);
2449     jpake_receive_part(&s1.p1, bconn);
2450     jpake_receive_part(&s1.p2, bconn);
2451     if (!JPAKE_STEP1_process(ctx, &s1)) {
2452         ERR_print_errors(bio_err);
2453         exit(1);
2454     }
2455     JPAKE_STEP1_release(&s1);
2456 }
2457
2458 static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
2459 {
2460     JPAKE_STEP2 s2;
2461
2462     JPAKE_STEP2_init(&s2);
2463     jpake_receive_part(&s2, bconn);
2464     if (!JPAKE_STEP2_process(ctx, &s2)) {
2465         ERR_print_errors(bio_err);
2466         exit(1);
2467     }
2468     JPAKE_STEP2_release(&s2);
2469 }
2470
2471 static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
2472 {
2473     JPAKE_STEP3A s3a;
2474     int l;
2475
2476     JPAKE_STEP3A_init(&s3a);
2477     l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
2478     assert(l == sizeof s3a.hhk);
2479     if (!JPAKE_STEP3A_process(ctx, &s3a)) {
2480         ERR_print_errors(bio_err);
2481         exit(1);
2482     }
2483     JPAKE_STEP3A_release(&s3a);
2484 }
2485
2486 static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
2487 {
2488     JPAKE_STEP3B s3b;
2489     int l;
2490
2491     JPAKE_STEP3B_init(&s3b);
2492     l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
2493     assert(l == sizeof s3b.hk);
2494     if (!JPAKE_STEP3B_process(ctx, &s3b)) {
2495         ERR_print_errors(bio_err);
2496         exit(1);
2497     }
2498     JPAKE_STEP3B_release(&s3b);
2499 }
2500
2501 void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
2502 {
2503     JPAKE_CTX *ctx;
2504     BIO *bconn;
2505
2506     BIO_puts(out, "Authenticating with JPAKE\n");
2507
2508     ctx = jpake_init("client", "server", secret);
2509
2510     bconn = BIO_new(BIO_f_buffer());
2511     BIO_push(bconn, conn);
2512
2513     jpake_send_step1(bconn, ctx);
2514     jpake_receive_step1(ctx, bconn);
2515     jpake_send_step2(bconn, ctx);
2516     jpake_receive_step2(ctx, bconn);
2517     jpake_send_step3a(bconn, ctx);
2518     jpake_receive_step3b(ctx, bconn);
2519
2520     BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
2521
2522     psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
2523
2524     BIO_pop(bconn);
2525     BIO_free(bconn);
2526
2527     JPAKE_CTX_free(ctx);
2528 }
2529
2530 void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
2531 {
2532     JPAKE_CTX *ctx;
2533     BIO *bconn;
2534
2535     BIO_puts(out, "Authenticating with JPAKE\n");
2536
2537     ctx = jpake_init("server", "client", secret);
2538
2539     bconn = BIO_new(BIO_f_buffer());
2540     BIO_push(bconn, conn);
2541
2542     jpake_receive_step1(ctx, bconn);
2543     jpake_send_step1(bconn, ctx);
2544     jpake_receive_step2(ctx, bconn);
2545     jpake_send_step2(bconn, ctx);
2546     jpake_receive_step3a(ctx, bconn);
2547     jpake_send_step3b(bconn, ctx);
2548
2549     BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
2550
2551     psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
2552
2553     BIO_pop(bconn);
2554     BIO_free(bconn);
2555
2556     JPAKE_CTX_free(ctx);
2557 }
2558
2559 #endif
2560
2561 /*
2562  * Platform-specific sections
2563  */
2564 #if defined(_WIN32)
2565 # ifdef fileno
2566 #  undef fileno
2567 #  define fileno(a) (int)_fileno(a)
2568 # endif
2569
2570 # include <windows.h>
2571 # include <tchar.h>
2572
2573 static int WIN32_rename(const char *from, const char *to)
2574 {
2575     TCHAR *tfrom = NULL, *tto;
2576     DWORD err;
2577     int ret = 0;
2578
2579     if (sizeof(TCHAR) == 1) {
2580         tfrom = (TCHAR *)from;
2581         tto = (TCHAR *)to;
2582     } else {                    /* UNICODE path */
2583
2584         size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
2585         tfrom = (TCHAR *)malloc(sizeof(TCHAR) * (flen + tlen));
2586         if (tfrom == NULL)
2587             goto err;
2588         tto = tfrom + flen;
2589 # if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2590         if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
2591 # endif
2592             for (i = 0; i < flen; i++)
2593                 tfrom[i] = (TCHAR)from[i];
2594 # if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2595         if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
2596 # endif
2597             for (i = 0; i < tlen; i++)
2598                 tto[i] = (TCHAR)to[i];
2599     }
2600
2601     if (MoveFile(tfrom, tto))
2602         goto ok;
2603     err = GetLastError();
2604     if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
2605         if (DeleteFile(tto) && MoveFile(tfrom, tto))
2606             goto ok;
2607         err = GetLastError();
2608     }
2609     if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
2610         errno = ENOENT;
2611     else if (err == ERROR_ACCESS_DENIED)
2612         errno = EACCES;
2613     else
2614         errno = EINVAL;         /* we could map more codes... */
2615  err:
2616     ret = -1;
2617  ok:
2618     if (tfrom != NULL && tfrom != (TCHAR *)from)
2619         free(tfrom);
2620     return ret;
2621 }
2622 #endif
2623
2624 /* app_tminterval section */
2625 #if defined(_WIN32)
2626 double app_tminterval(int stop, int usertime)
2627 {
2628     FILETIME now;
2629     double ret = 0;
2630     static ULARGE_INTEGER tmstart;
2631     static int warning = 1;
2632 # ifdef _WIN32_WINNT
2633     static HANDLE proc = NULL;
2634
2635     if (proc == NULL) {
2636         if (check_winnt())
2637             proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
2638                                GetCurrentProcessId());
2639         if (proc == NULL)
2640             proc = (HANDLE) - 1;
2641     }
2642
2643     if (usertime && proc != (HANDLE) - 1) {
2644         FILETIME junk;
2645         GetProcessTimes(proc, &junk, &junk, &junk, &now);
2646     } else
2647 # endif
2648     {
2649         SYSTEMTIME systime;
2650
2651         if (usertime && warning) {
2652             BIO_printf(bio_err, "To get meaningful results, run "
2653                        "this program on idle system.\n");
2654             warning = 0;
2655         }
2656         GetSystemTime(&systime);
2657         SystemTimeToFileTime(&systime, &now);
2658     }
2659
2660     if (stop == TM_START) {
2661         tmstart.u.LowPart = now.dwLowDateTime;
2662         tmstart.u.HighPart = now.dwHighDateTime;
2663     } else {
2664         ULARGE_INTEGER tmstop;
2665
2666         tmstop.u.LowPart = now.dwLowDateTime;
2667         tmstop.u.HighPart = now.dwHighDateTime;
2668
2669         ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
2670     }
2671
2672     return (ret);
2673 }
2674
2675 #elif defined(OPENSSL_SYS_NETWARE)
2676 # include <time.h>
2677
2678 double app_tminterval(int stop, int usertime)
2679 {
2680     double ret = 0;
2681     static clock_t tmstart;
2682     static int warning = 1;
2683
2684     if (usertime && warning) {
2685         BIO_printf(bio_err, "To get meaningful results, run "
2686                    "this program on idle system.\n");
2687         warning = 0;
2688     }
2689
2690     if (stop == TM_START)
2691         tmstart = clock();
2692     else
2693         ret = (clock() - tmstart) / (double)CLOCKS_PER_SEC;
2694
2695     return (ret);
2696 }
2697
2698 #elif defined(OPENSSL_SYSTEM_VXWORKS)
2699 # include <time.h>
2700
2701 double app_tminterval(int stop, int usertime)
2702 {
2703     double ret = 0;
2704 # ifdef CLOCK_REALTIME
2705     static struct timespec tmstart;
2706     struct timespec now;
2707 # else
2708     static unsigned long tmstart;
2709     unsigned long now;
2710 # endif
2711     static int warning = 1;
2712
2713     if (usertime && warning) {
2714         BIO_printf(bio_err, "To get meaningful results, run "
2715                    "this program on idle system.\n");
2716         warning = 0;
2717     }
2718 # ifdef CLOCK_REALTIME
2719     clock_gettime(CLOCK_REALTIME, &now);
2720     if (stop == TM_START)
2721         tmstart = now;
2722     else
2723         ret = ((now.tv_sec + now.tv_nsec * 1e-9)
2724                - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
2725 # else
2726     now = tickGet();
2727     if (stop == TM_START)
2728         tmstart = now;
2729     else
2730         ret = (now - tmstart) / (double)sysClkRateGet();
2731 # endif
2732     return (ret);
2733 }
2734
2735 #elif defined(OPENSSL_SYSTEM_VMS)
2736 # include <time.h>
2737 # include <times.h>
2738
2739 double app_tminterval(int stop, int usertime)
2740 {
2741     static clock_t tmstart;
2742     double ret = 0;
2743     clock_t now;
2744 # ifdef __TMS
2745     struct tms rus;
2746
2747     now = times(&rus);
2748     if (usertime)
2749         now = rus.tms_utime;
2750 # else
2751     if (usertime)
2752         now = clock();          /* sum of user and kernel times */
2753     else {
2754         struct timeval tv;
2755         gettimeofday(&tv, NULL);
2756         now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
2757                         (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
2758             );
2759     }
2760 # endif
2761     if (stop == TM_START)
2762         tmstart = now;
2763     else
2764         ret = (now - tmstart) / (double)(CLK_TCK);
2765
2766     return (ret);
2767 }
2768
2769 #elif defined(_SC_CLK_TCK)      /* by means of unistd.h */
2770 # include <sys/times.h>
2771
2772 double app_tminterval(int stop, int usertime)
2773 {
2774     double ret = 0;
2775     struct tms rus;
2776     clock_t now = times(&rus);
2777     static clock_t tmstart;
2778
2779     if (usertime)
2780         now = rus.tms_utime;
2781
2782     if (stop == TM_START)
2783         tmstart = now;
2784     else {
2785         long int tck = sysconf(_SC_CLK_TCK);
2786         ret = (now - tmstart) / (double)tck;
2787     }
2788
2789     return (ret);
2790 }
2791
2792 #else
2793 # include <sys/time.h>
2794 # include <sys/resource.h>
2795
2796 double app_tminterval(int stop, int usertime)
2797 {
2798     double ret = 0;
2799     struct rusage rus;
2800     struct timeval now;
2801     static struct timeval tmstart;
2802
2803     if (usertime)
2804         getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
2805     else
2806         gettimeofday(&now, NULL);
2807
2808     if (stop == TM_START)
2809         tmstart = now;
2810     else
2811         ret = ((now.tv_sec + now.tv_usec * 1e-6)
2812                - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
2813
2814     return ret;
2815 }
2816 #endif
2817
2818 /* app_isdir section */
2819 #ifdef _WIN32
2820 int app_isdir(const char *name)
2821 {
2822     HANDLE hList;
2823     WIN32_FIND_DATA FileData;
2824 # if defined(UNICODE) || defined(_UNICODE)
2825     size_t i, len_0 = strlen(name) + 1;
2826
2827     if (len_0 > sizeof(FileData.cFileName) / sizeof(FileData.cFileName[0]))
2828         return -1;
2829
2830 #  if !defined(_WIN32_WCE) || _WIN32_WCE>=101
2831     if (!MultiByteToWideChar
2832         (CP_ACP, 0, name, len_0, FileData.cFileName, len_0))
2833 #  endif
2834         for (i = 0; i < len_0; i++)
2835             FileData.cFileName[i] = (WCHAR)name[i];
2836
2837     hList = FindFirstFile(FileData.cFileName, &FileData);
2838 # else
2839     hList = FindFirstFile(name, &FileData);
2840 # endif
2841     if (hList == INVALID_HANDLE_VALUE)
2842         return -1;
2843     FindClose(hList);
2844     return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
2845 }
2846 #else
2847 # include <sys/stat.h>
2848 # ifndef S_ISDIR
2849 #  if defined(_S_IFMT) && defined(_S_IFDIR)
2850 #   define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
2851 #  else
2852 #   define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
2853 #  endif
2854 # endif
2855
2856 int app_isdir(const char *name)
2857 {
2858 # if defined(S_ISDIR)
2859     struct stat st;
2860
2861     if (stat(name, &st) == 0)
2862         return S_ISDIR(st.st_mode);
2863     else
2864         return -1;
2865 # else
2866     return -1;
2867 # endif
2868 }
2869 #endif
2870
2871 /* raw_read|write section */
2872 #if defined(_WIN32) && defined(STD_INPUT_HANDLE)
2873 int raw_read_stdin(void *buf, int siz)
2874 {
2875     DWORD n;
2876     if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
2877         return (n);
2878     else
2879         return (-1);
2880 }
2881 #else
2882 int raw_read_stdin(void *buf, int siz)
2883 {
2884     return read(fileno(stdin), buf, siz);
2885 }
2886 #endif
2887
2888 #if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
2889 int raw_write_stdout(const void *buf, int siz)
2890 {
2891     DWORD n;
2892     if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
2893         return (n);
2894     else
2895         return (-1);
2896 }
2897 #else
2898 int raw_write_stdout(const void *buf, int siz)
2899 {
2900     return write(fileno(stdout), buf, siz);
2901 }
2902 #endif