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