summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr.bin/openssl')
-rw-r--r--src/usr.bin/openssl/Makefile31
-rw-r--r--src/usr.bin/openssl/apps.c2162
-rw-r--r--src/usr.bin/openssl/apps.h401
-rw-r--r--src/usr.bin/openssl/apps_posix.c175
-rw-r--r--src/usr.bin/openssl/asn1pars.c469
-rw-r--r--src/usr.bin/openssl/ca.c2797
-rw-r--r--src/usr.bin/openssl/certhash.c691
-rw-r--r--src/usr.bin/openssl/ciphers.c185
-rw-r--r--src/usr.bin/openssl/cms.c1988
-rw-r--r--src/usr.bin/openssl/crl.c482
-rw-r--r--src/usr.bin/openssl/crl2p7.c329
-rw-r--r--src/usr.bin/openssl/dgst.c671
-rw-r--r--src/usr.bin/openssl/dh.c248
-rw-r--r--src/usr.bin/openssl/dhparam.c446
-rw-r--r--src/usr.bin/openssl/dsa.c365
-rw-r--r--src/usr.bin/openssl/dsaparam.c316
-rw-r--r--src/usr.bin/openssl/ec.c392
-rw-r--r--src/usr.bin/openssl/ecparam.c448
-rw-r--r--src/usr.bin/openssl/enc.c783
-rw-r--r--src/usr.bin/openssl/errstr.c117
-rw-r--r--src/usr.bin/openssl/gendh.c219
-rw-r--r--src/usr.bin/openssl/gendsa.c296
-rw-r--r--src/usr.bin/openssl/genpkey.c418
-rw-r--r--src/usr.bin/openssl/genrsa.c389
-rw-r--r--src/usr.bin/openssl/ocsp.c1584
-rw-r--r--src/usr.bin/openssl/openssl.16827
-rw-r--r--src/usr.bin/openssl/openssl.c724
-rw-r--r--src/usr.bin/openssl/passwd.c524
-rw-r--r--src/usr.bin/openssl/pkcs12.c1124
-rw-r--r--src/usr.bin/openssl/pkcs7.c291
-rw-r--r--src/usr.bin/openssl/pkcs8.c365
-rw-r--r--src/usr.bin/openssl/pkey.c287
-rw-r--r--src/usr.bin/openssl/pkeyparam.c172
-rw-r--r--src/usr.bin/openssl/pkeyutl.c571
-rw-r--r--src/usr.bin/openssl/prime.c201
-rw-r--r--src/usr.bin/openssl/rand.c182
-rw-r--r--src/usr.bin/openssl/req.c1879
-rw-r--r--src/usr.bin/openssl/rsa.c410
-rw-r--r--src/usr.bin/openssl/rsautl.c402
-rw-r--r--src/usr.bin/openssl/s_cb.c930
-rw-r--r--src/usr.bin/openssl/s_client.c1823
-rw-r--r--src/usr.bin/openssl/s_server.c2415
-rw-r--r--src/usr.bin/openssl/s_socket.c325
-rw-r--r--src/usr.bin/openssl/s_time.c463
-rw-r--r--src/usr.bin/openssl/sess_id.c292
-rw-r--r--src/usr.bin/openssl/smime.c1103
-rw-r--r--src/usr.bin/openssl/speed.c2799
-rw-r--r--src/usr.bin/openssl/ts.c1256
-rw-r--r--src/usr.bin/openssl/verify.c457
-rw-r--r--src/usr.bin/openssl/version.c249
-rw-r--r--src/usr.bin/openssl/x509.c1713
51 files changed, 0 insertions, 44186 deletions
diff --git a/src/usr.bin/openssl/Makefile b/src/usr.bin/openssl/Makefile
deleted file mode 100644
index e35b788500..0000000000
--- a/src/usr.bin/openssl/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
1# $OpenBSD: Makefile,v 1.14 2024/07/08 05:59:10 tb Exp $
2
3.include <bsd.own.mk>
4
5PROG= openssl
6LDADD= -lssl -lcrypto
7DPADD= ${LIBSSL} ${LIBCRYPTO}
8
9CFLAGS+= -Wall
10CFLAGS+= -Wformat
11CFLAGS+= -Wformat-security
12CFLAGS+= -Wimplicit
13CFLAGS+= -Wreturn-type
14CFLAGS+= -Wtrigraphs
15CFLAGS+= -Wuninitialized
16CFLAGS+= -Wunused
17.if ${COMPILER_VERSION:L} == "clang"
18CFLAGS+= -Werror
19CFLAGS+= -Wshadow
20.endif
21CFLAGS+= -DLIBRESSL_INTERNAL
22
23SRCS= apps.c apps_posix.c asn1pars.c ca.c certhash.c ciphers.c cms.c crl.c \
24 crl2p7.c dgst.c dh.c dhparam.c dsa.c dsaparam.c ec.c ecparam.c enc.c \
25 errstr.c gendh.c gendsa.c genpkey.c genrsa.c ocsp.c \
26 openssl.c passwd.c pkcs12.c pkcs7.c pkcs8.c pkey.c pkeyparam.c \
27 pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c s_cb.c s_client.c \
28 s_server.c s_socket.c s_time.c sess_id.c smime.c speed.c ts.c \
29 verify.c version.c x509.c
30
31.include <bsd.prog.mk>
diff --git a/src/usr.bin/openssl/apps.c b/src/usr.bin/openssl/apps.c
deleted file mode 100644
index 46197dfd49..0000000000
--- a/src/usr.bin/openssl/apps.c
+++ /dev/null
@@ -1,2162 +0,0 @@
1/* $OpenBSD: apps.c,v 1.72 2025/03/18 13:03:08 tb Exp $ */
2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
18 * All rights reserved.
19 *
20 * This package is an SSL implementation written
21 * by Eric Young (eay@cryptsoft.com).
22 * The implementation was written so as to conform with Netscapes SSL.
23 *
24 * This library is free for commercial and non-commercial use as long as
25 * the following conditions are aheared to. The following conditions
26 * apply to all code found in this distribution, be it the RC4, RSA,
27 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
28 * included with this distribution is covered by the same copyright terms
29 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
30 *
31 * Copyright remains Eric Young's, and as such any Copyright notices in
32 * the code are not to be removed.
33 * If this package is used in a product, Eric Young should be given attribution
34 * as the author of the parts of the library used.
35 * This can be in the form of a textual message at program startup or
36 * in documentation (online or textual) provided with the package.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * "This product includes cryptographic software written by
49 * Eric Young (eay@cryptsoft.com)"
50 * The word 'cryptographic' can be left out if the rouines from the library
51 * being used are not cryptographic related :-).
52 * 4. If you include any Windows specific code (or a derivative thereof) from
53 * the apps directory (application code) you must include an acknowledgement:
54 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
55 *
56 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
67 *
68 * The licence and distribution terms for any publically available version or
69 * derivative of this code cannot be changed. i.e. this code cannot simply be
70 * copied and put under another distribution licence
71 * [including the GNU Public Licence.]
72 */
73/* ====================================================================
74 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
75 *
76 * Redistribution and use in source and binary forms, with or without
77 * modification, are permitted provided that the following conditions
78 * are met:
79 *
80 * 1. Redistributions of source code must retain the above copyright
81 * notice, this list of conditions and the following disclaimer.
82 *
83 * 2. Redistributions in binary form must reproduce the above copyright
84 * notice, this list of conditions and the following disclaimer in
85 * the documentation and/or other materials provided with the
86 * distribution.
87 *
88 * 3. All advertising materials mentioning features or use of this
89 * software must display the following acknowledgment:
90 * "This product includes software developed by the OpenSSL Project
91 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
92 *
93 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
94 * endorse or promote products derived from this software without
95 * prior written permission. For written permission, please contact
96 * openssl-core@openssl.org.
97 *
98 * 5. Products derived from this software may not be called "OpenSSL"
99 * nor may "OpenSSL" appear in their names without prior written
100 * permission of the OpenSSL Project.
101 *
102 * 6. Redistributions of any form whatsoever must retain the following
103 * acknowledgment:
104 * "This product includes software developed by the OpenSSL Project
105 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
106 *
107 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
108 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
109 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
110 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
111 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
112 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
113 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
114 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
115 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
116 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
117 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
118 * OF THE POSSIBILITY OF SUCH DAMAGE.
119 * ====================================================================
120 *
121 * This product includes cryptographic software written by Eric Young
122 * (eay@cryptsoft.com). This product includes software written by Tim
123 * Hudson (tjh@cryptsoft.com).
124 *
125 */
126
127#include <sys/types.h>
128#include <sys/stat.h>
129
130#include <ctype.h>
131#include <errno.h>
132#include <stdio.h>
133#include <stdlib.h>
134#include <limits.h>
135#include <string.h>
136#include <unistd.h>
137
138#include "apps.h"
139
140#include <openssl/bn.h>
141#include <openssl/err.h>
142#include <openssl/pem.h>
143#include <openssl/pkcs12.h>
144#include <openssl/rsa.h>
145#include <openssl/safestack.h>
146#include <openssl/ssl.h>
147#include <openssl/x509.h>
148#include <openssl/x509v3.h>
149
150typedef struct {
151 const char *name;
152 unsigned long flag;
153 unsigned long mask;
154} NAME_EX_TBL;
155
156UI_METHOD *ui_method = NULL;
157
158static int set_table_opts(unsigned long *flags, const char *arg,
159 const NAME_EX_TBL *in_tbl);
160static int set_multi_opts(unsigned long *flags, const char *arg,
161 const NAME_EX_TBL *in_tbl);
162
163int
164str2fmt(char *s)
165{
166 if (s == NULL)
167 return FORMAT_UNDEF;
168 if ((*s == 'D') || (*s == 'd'))
169 return (FORMAT_ASN1);
170 else if ((*s == 'T') || (*s == 't'))
171 return (FORMAT_TEXT);
172 else if ((*s == 'S') || (*s == 's'))
173 return (FORMAT_SMIME);
174 else if ((*s == 'M') || (*s == 'm'))
175 return (FORMAT_MSBLOB);
176 else if ((*s == '1') ||
177 (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0) ||
178 (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0))
179 return (FORMAT_PKCS12);
180 else if ((*s == 'P') || (*s == 'p')) {
181 if (s[1] == 'V' || s[1] == 'v')
182 return FORMAT_PVK;
183 else
184 return (FORMAT_PEM);
185 } else
186 return (FORMAT_UNDEF);
187}
188
189void
190program_name(char *in, char *out, int size)
191{
192 char *p;
193
194 p = strrchr(in, '/');
195 if (p != NULL)
196 p++;
197 else
198 p = in;
199 strlcpy(out, p, size);
200}
201
202int
203dump_cert_text(BIO *out, X509 *x)
204{
205 char *p;
206
207 p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
208 BIO_puts(out, "subject=");
209 BIO_puts(out, p);
210 free(p);
211
212 p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
213 BIO_puts(out, "\nissuer=");
214 BIO_puts(out, p);
215 BIO_puts(out, "\n");
216 free(p);
217
218 return 0;
219}
220
221int
222ui_open(UI *ui)
223{
224 return UI_method_get_opener(UI_OpenSSL()) (ui);
225}
226
227int
228ui_read(UI *ui, UI_STRING *uis)
229{
230 const char *password;
231 int string_type;
232
233 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
234 UI_get0_user_data(ui)) {
235 string_type = UI_get_string_type(uis);
236 if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) {
237 password =
238 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
239 if (password && password[0] != '\0') {
240 UI_set_result(ui, uis, password);
241 return 1;
242 }
243 }
244 }
245 return UI_method_get_reader(UI_OpenSSL()) (ui, uis);
246}
247
248int
249ui_write(UI *ui, UI_STRING *uis)
250{
251 const char *password;
252 int string_type;
253
254 if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD &&
255 UI_get0_user_data(ui)) {
256 string_type = UI_get_string_type(uis);
257 if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) {
258 password =
259 ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
260 if (password && password[0] != '\0')
261 return 1;
262 }
263 }
264 return UI_method_get_writer(UI_OpenSSL()) (ui, uis);
265}
266
267int
268ui_close(UI *ui)
269{
270 return UI_method_get_closer(UI_OpenSSL()) (ui);
271}
272
273int
274password_callback(char *buf, int bufsiz, int verify, void *arg)
275{
276 PW_CB_DATA *cb_tmp = arg;
277 UI *ui = NULL;
278 int res = 0;
279 const char *prompt_info = NULL;
280 const char *password = NULL;
281 PW_CB_DATA *cb_data = (PW_CB_DATA *) cb_tmp;
282
283 if (cb_data) {
284 if (cb_data->password)
285 password = cb_data->password;
286 if (cb_data->prompt_info)
287 prompt_info = cb_data->prompt_info;
288 }
289 if (password) {
290 res = strlen(password);
291 if (res > bufsiz)
292 res = bufsiz;
293 memcpy(buf, password, res);
294 return res;
295 }
296 ui = UI_new_method(ui_method);
297 if (ui) {
298 int ok = 0;
299 char *buff = NULL;
300 int ui_flags = 0;
301 char *prompt = NULL;
302
303 prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
304
305 ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
306 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
307
308 if (ok >= 0)
309 ok = UI_add_input_string(ui, prompt, ui_flags, buf,
310 PW_MIN_LENGTH, bufsiz - 1);
311 if (ok >= 0 && verify) {
312 buff = malloc(bufsiz);
313 ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
314 PW_MIN_LENGTH, bufsiz - 1, buf);
315 }
316 if (ok >= 0)
317 do {
318 ok = UI_process(ui);
319 } while (ok < 0 &&
320 UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
321
322 freezero(buff, (unsigned int) bufsiz);
323 if (ok >= 0)
324 res = strlen(buf);
325 if (ok == -1) {
326 BIO_printf(bio_err, "User interface error\n");
327 ERR_print_errors(bio_err);
328 explicit_bzero(buf, (unsigned int) bufsiz);
329 res = 0;
330 }
331 if (ok == -2) {
332 BIO_printf(bio_err, "aborted!\n");
333 explicit_bzero(buf, (unsigned int) bufsiz);
334 res = 0;
335 }
336 UI_free(ui);
337 free(prompt);
338 }
339 return res;
340}
341
342static char *app_get_pass(BIO *err, char *arg, int keepbio);
343
344int
345app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
346{
347 int same;
348
349 if (!arg2 || !arg1 || strcmp(arg1, arg2))
350 same = 0;
351 else
352 same = 1;
353 if (arg1) {
354 *pass1 = app_get_pass(err, arg1, same);
355 if (!*pass1)
356 return 0;
357 } else if (pass1)
358 *pass1 = NULL;
359 if (arg2) {
360 *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
361 if (!*pass2)
362 return 0;
363 } else if (pass2)
364 *pass2 = NULL;
365 return 1;
366}
367
368static char *
369app_get_pass(BIO *err, char *arg, int keepbio)
370{
371 char *tmp, tpass[APP_PASS_LEN];
372 static BIO *pwdbio = NULL;
373 const char *errstr = NULL;
374 int i;
375
376 if (!strncmp(arg, "pass:", 5))
377 return strdup(arg + 5);
378 if (!strncmp(arg, "env:", 4)) {
379 tmp = getenv(arg + 4);
380 if (!tmp) {
381 BIO_printf(err, "Can't read environment variable %s\n",
382 arg + 4);
383 return NULL;
384 }
385 return strdup(tmp);
386 }
387 if (!keepbio || !pwdbio) {
388 if (!strncmp(arg, "file:", 5)) {
389 pwdbio = BIO_new_file(arg + 5, "r");
390 if (!pwdbio) {
391 BIO_printf(err, "Can't open file %s\n",
392 arg + 5);
393 return NULL;
394 }
395 } else if (!strncmp(arg, "fd:", 3)) {
396 BIO *btmp;
397 i = strtonum(arg + 3, 0, INT_MAX, &errstr);
398 if (errstr) {
399 BIO_printf(err,
400 "Invalid file descriptor %s: %s\n",
401 arg, errstr);
402 return NULL;
403 }
404 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
405 if (!pwdbio) {
406 BIO_printf(err,
407 "Can't access file descriptor %s\n",
408 arg + 3);
409 return NULL;
410 }
411 /*
412 * Can't do BIO_gets on an fd BIO so add a buffering
413 * BIO
414 */
415 btmp = BIO_new(BIO_f_buffer());
416 pwdbio = BIO_push(btmp, pwdbio);
417 } else if (!strcmp(arg, "stdin")) {
418 pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
419 if (!pwdbio) {
420 BIO_printf(err, "Can't open BIO for stdin\n");
421 return NULL;
422 }
423 } else {
424 BIO_printf(err, "Invalid password argument \"%s\"\n",
425 arg);
426 return NULL;
427 }
428 }
429 i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
430 if (keepbio != 1) {
431 BIO_free_all(pwdbio);
432 pwdbio = NULL;
433 }
434 if (i <= 0) {
435 BIO_printf(err, "Error reading password from BIO\n");
436 return NULL;
437 }
438 tmp = strchr(tpass, '\n');
439 if (tmp)
440 *tmp = 0;
441 return strdup(tpass);
442}
443
444int
445add_oid_section(BIO *err, CONF *conf)
446{
447 char *p;
448 STACK_OF(CONF_VALUE) *sktmp;
449 CONF_VALUE *cnf;
450 int i;
451
452 if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) {
453 ERR_clear_error();
454 return 1;
455 }
456 if (!(sktmp = NCONF_get_section(conf, p))) {
457 BIO_printf(err, "problem loading oid section %s\n", p);
458 return 0;
459 }
460 for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
461 cnf = sk_CONF_VALUE_value(sktmp, i);
462 if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
463 BIO_printf(err, "problem creating object %s=%s\n",
464 cnf->name, cnf->value);
465 return 0;
466 }
467 }
468 return 1;
469}
470
471static int
472load_pkcs12(BIO *err, BIO *in, const char *desc, pem_password_cb *pem_cb,
473 void *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
474{
475 const char *pass;
476 char tpass[PEM_BUFSIZE];
477 int len, ret = 0;
478 PKCS12 *p12;
479
480 p12 = d2i_PKCS12_bio(in, NULL);
481 if (p12 == NULL) {
482 BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
483 goto die;
484 }
485 /* See if an empty password will do */
486 if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
487 pass = "";
488 else {
489 if (!pem_cb)
490 pem_cb = password_callback;
491 len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
492 if (len < 0) {
493 BIO_printf(err, "Passpharse callback error for %s\n",
494 desc);
495 goto die;
496 }
497 if (len < PEM_BUFSIZE)
498 tpass[len] = 0;
499 if (!PKCS12_verify_mac(p12, tpass, len)) {
500 BIO_printf(err,
501 "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
502 goto die;
503 }
504 pass = tpass;
505 }
506 ret = PKCS12_parse(p12, pass, pkey, cert, ca);
507
508 die:
509 PKCS12_free(p12);
510 return ret;
511}
512
513X509 *
514load_cert(BIO *err, const char *file, int format, const char *pass,
515 const char *cert_descrip)
516{
517 X509 *x = NULL;
518 BIO *cert;
519
520 if ((cert = BIO_new(BIO_s_file())) == NULL) {
521 ERR_print_errors(err);
522 goto end;
523 }
524 if (file == NULL) {
525 setvbuf(stdin, NULL, _IONBF, 0);
526 BIO_set_fp(cert, stdin, BIO_NOCLOSE);
527 } else {
528 if (BIO_read_filename(cert, file) <= 0) {
529 BIO_printf(err, "Error opening %s %s\n",
530 cert_descrip, file);
531 ERR_print_errors(err);
532 goto end;
533 }
534 }
535
536 if (format == FORMAT_ASN1)
537 x = d2i_X509_bio(cert, NULL);
538 else if (format == FORMAT_PEM)
539 x = PEM_read_bio_X509_AUX(cert, NULL, password_callback, NULL);
540 else if (format == FORMAT_PKCS12) {
541 if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL,
542 NULL, &x, NULL))
543 goto end;
544 } else {
545 BIO_printf(err, "bad input format specified for %s\n",
546 cert_descrip);
547 goto end;
548 }
549
550 end:
551 if (x == NULL) {
552 BIO_printf(err, "unable to load certificate\n");
553 ERR_print_errors(err);
554 }
555 BIO_free(cert);
556 return (x);
557}
558
559EVP_PKEY *
560load_key(BIO *err, const char *file, int format, int maybe_stdin,
561 const char *pass, const char *key_descrip)
562{
563 BIO *key = NULL;
564 EVP_PKEY *pkey = NULL;
565 PW_CB_DATA cb_data;
566
567 cb_data.password = pass;
568 cb_data.prompt_info = file;
569
570 if (file == NULL && (!maybe_stdin)) {
571 BIO_printf(err, "no keyfile specified\n");
572 goto end;
573 }
574 key = BIO_new(BIO_s_file());
575 if (key == NULL) {
576 ERR_print_errors(err);
577 goto end;
578 }
579 if (file == NULL && maybe_stdin) {
580 setvbuf(stdin, NULL, _IONBF, 0);
581 BIO_set_fp(key, stdin, BIO_NOCLOSE);
582 } else if (BIO_read_filename(key, file) <= 0) {
583 BIO_printf(err, "Error opening %s %s\n",
584 key_descrip, file);
585 ERR_print_errors(err);
586 goto end;
587 }
588 if (format == FORMAT_ASN1) {
589 pkey = d2i_PrivateKey_bio(key, NULL);
590 } else if (format == FORMAT_PEM) {
591 pkey = PEM_read_bio_PrivateKey(key, NULL, password_callback, &cb_data);
592 }
593 else if (format == FORMAT_PKCS12) {
594 if (!load_pkcs12(err, key, key_descrip, password_callback, &cb_data,
595 &pkey, NULL, NULL))
596 goto end;
597 }
598#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
599 else if (format == FORMAT_MSBLOB)
600 pkey = b2i_PrivateKey_bio(key);
601 else if (format == FORMAT_PVK)
602 pkey = b2i_PVK_bio(key, password_callback,
603 &cb_data);
604#endif
605 else {
606 BIO_printf(err, "bad input format specified for key file\n");
607 goto end;
608 }
609 end:
610 BIO_free(key);
611 if (pkey == NULL) {
612 BIO_printf(err, "unable to load %s\n", key_descrip);
613 ERR_print_errors(err);
614 }
615 return (pkey);
616}
617
618EVP_PKEY *
619load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
620 const char *pass, const char *key_descrip)
621{
622 BIO *key = NULL;
623 EVP_PKEY *pkey = NULL;
624 PW_CB_DATA cb_data;
625
626 cb_data.password = pass;
627 cb_data.prompt_info = file;
628
629 if (file == NULL && !maybe_stdin) {
630 BIO_printf(err, "no keyfile specified\n");
631 goto end;
632 }
633 key = BIO_new(BIO_s_file());
634 if (key == NULL) {
635 ERR_print_errors(err);
636 goto end;
637 }
638 if (file == NULL && maybe_stdin) {
639 setvbuf(stdin, NULL, _IONBF, 0);
640 BIO_set_fp(key, stdin, BIO_NOCLOSE);
641 } else if (BIO_read_filename(key, file) <= 0) {
642 BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
643 ERR_print_errors(err);
644 goto end;
645 }
646 if (format == FORMAT_ASN1) {
647 pkey = d2i_PUBKEY_bio(key, NULL);
648 }
649 else if (format == FORMAT_ASN1RSA) {
650 RSA *rsa;
651 rsa = d2i_RSAPublicKey_bio(key, NULL);
652 if (rsa) {
653 pkey = EVP_PKEY_new();
654 if (pkey)
655 EVP_PKEY_set1_RSA(pkey, rsa);
656 RSA_free(rsa);
657 } else
658 pkey = NULL;
659 } else if (format == FORMAT_PEMRSA) {
660 RSA *rsa;
661 rsa = PEM_read_bio_RSAPublicKey(key, NULL, password_callback, &cb_data);
662 if (rsa) {
663 pkey = EVP_PKEY_new();
664 if (pkey)
665 EVP_PKEY_set1_RSA(pkey, rsa);
666 RSA_free(rsa);
667 } else
668 pkey = NULL;
669 }
670 else if (format == FORMAT_PEM) {
671 pkey = PEM_read_bio_PUBKEY(key, NULL, password_callback, &cb_data);
672 }
673#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
674 else if (format == FORMAT_MSBLOB)
675 pkey = b2i_PublicKey_bio(key);
676#endif
677 else {
678 BIO_printf(err, "bad input format specified for key file\n");
679 goto end;
680 }
681
682 end:
683 BIO_free(key);
684 if (pkey == NULL)
685 BIO_printf(err, "unable to load %s\n", key_descrip);
686 return (pkey);
687}
688
689static int
690load_certs_crls(BIO *err, const char *file, int format, const char *pass,
691 const char *desc, STACK_OF(X509) **pcerts,
692 STACK_OF(X509_CRL) **pcrls)
693{
694 int i;
695 BIO *bio;
696 STACK_OF(X509_INFO) *xis = NULL;
697 X509_INFO *xi;
698 PW_CB_DATA cb_data;
699 int rv = 0;
700
701 cb_data.password = pass;
702 cb_data.prompt_info = file;
703
704 if (format != FORMAT_PEM) {
705 BIO_printf(err, "bad input format specified for %s\n", desc);
706 return 0;
707 }
708 if (file == NULL)
709 bio = BIO_new_fp(stdin, BIO_NOCLOSE);
710 else
711 bio = BIO_new_file(file, "r");
712
713 if (bio == NULL) {
714 BIO_printf(err, "Error opening %s %s\n",
715 desc, file ? file : "stdin");
716 ERR_print_errors(err);
717 return 0;
718 }
719 xis = PEM_X509_INFO_read_bio(bio, NULL, password_callback, &cb_data);
720
721 BIO_free(bio);
722
723 if (pcerts) {
724 *pcerts = sk_X509_new_null();
725 if (!*pcerts)
726 goto end;
727 }
728 if (pcrls) {
729 *pcrls = sk_X509_CRL_new_null();
730 if (!*pcrls)
731 goto end;
732 }
733 for (i = 0; i < sk_X509_INFO_num(xis); i++) {
734 xi = sk_X509_INFO_value(xis, i);
735 if (xi->x509 && pcerts) {
736 if (!sk_X509_push(*pcerts, xi->x509))
737 goto end;
738 xi->x509 = NULL;
739 }
740 if (xi->crl && pcrls) {
741 if (!sk_X509_CRL_push(*pcrls, xi->crl))
742 goto end;
743 xi->crl = NULL;
744 }
745 }
746
747 if (pcerts && sk_X509_num(*pcerts) > 0)
748 rv = 1;
749
750 if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
751 rv = 1;
752
753 end:
754 sk_X509_INFO_pop_free(xis, X509_INFO_free);
755
756 if (rv == 0) {
757 if (pcerts) {
758 sk_X509_pop_free(*pcerts, X509_free);
759 *pcerts = NULL;
760 }
761 if (pcrls) {
762 sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
763 *pcrls = NULL;
764 }
765 BIO_printf(err, "unable to load %s\n",
766 pcerts ? "certificates" : "CRLs");
767 ERR_print_errors(err);
768 }
769 return rv;
770}
771
772STACK_OF(X509) *
773load_certs(BIO *err, const char *file, int format, const char *pass,
774 const char *desc)
775{
776 STACK_OF(X509) *certs;
777
778 if (!load_certs_crls(err, file, format, pass, desc, &certs, NULL))
779 return NULL;
780 return certs;
781}
782
783STACK_OF(X509_CRL) *
784load_crls(BIO *err, const char *file, int format, const char *pass,
785 const char *desc)
786{
787 STACK_OF(X509_CRL) *crls;
788
789 if (!load_certs_crls(err, file, format, pass, desc, NULL, &crls))
790 return NULL;
791 return crls;
792}
793
794#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
795/* Return error for unknown extensions */
796#define X509V3_EXT_DEFAULT 0
797/* Print error for unknown extensions */
798#define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
799/* ASN1 parse unknown extensions */
800#define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
801/* BIO_dump unknown extensions */
802#define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
803
804#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
805 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
806
807int
808set_cert_ex(unsigned long *flags, const char *arg)
809{
810 static const NAME_EX_TBL cert_tbl[] = {
811 {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
812 {"ca_default", X509_FLAG_CA, 0xffffffffl},
813 {"no_header", X509_FLAG_NO_HEADER, 0},
814 {"no_version", X509_FLAG_NO_VERSION, 0},
815 {"no_serial", X509_FLAG_NO_SERIAL, 0},
816 {"no_signame", X509_FLAG_NO_SIGNAME, 0},
817 {"no_validity", X509_FLAG_NO_VALIDITY, 0},
818 {"no_subject", X509_FLAG_NO_SUBJECT, 0},
819 {"no_issuer", X509_FLAG_NO_ISSUER, 0},
820 {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
821 {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
822 {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
823 {"no_aux", X509_FLAG_NO_AUX, 0},
824 {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
825 {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
826 {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
827 {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
828 {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
829 {NULL, 0, 0}
830 };
831 return set_multi_opts(flags, arg, cert_tbl);
832}
833
834int
835set_name_ex(unsigned long *flags, const char *arg)
836{
837 static const NAME_EX_TBL ex_tbl[] = {
838 {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
839 {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
840 {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
841 {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
842 {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
843 {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
844 {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
845 {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
846 {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
847 {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
848 {"compat", XN_FLAG_COMPAT, 0xffffffffL},
849 {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
850 {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
851 {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
852 {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
853 {"dn_rev", XN_FLAG_DN_REV, 0},
854 {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
855 {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
856 {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
857 {"align", XN_FLAG_FN_ALIGN, 0},
858 {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
859 {"space_eq", XN_FLAG_SPC_EQ, 0},
860 {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
861 {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
862 {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
863 {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
864 {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
865 {NULL, 0, 0}
866 };
867 if (!set_multi_opts(flags, arg, ex_tbl))
868 return 0;
869 if (*flags != XN_FLAG_COMPAT && (*flags & XN_FLAG_SEP_MASK) == 0)
870 *flags |= XN_FLAG_SEP_CPLUS_SPC;
871 return 1;
872}
873
874int
875set_ext_copy(int *copy_type, const char *arg)
876{
877 if (!strcasecmp(arg, "none"))
878 *copy_type = EXT_COPY_NONE;
879 else if (!strcasecmp(arg, "copy"))
880 *copy_type = EXT_COPY_ADD;
881 else if (!strcasecmp(arg, "copyall"))
882 *copy_type = EXT_COPY_ALL;
883 else
884 return 0;
885 return 1;
886}
887
888int
889copy_extensions(X509 *x, X509_REQ *req, int copy_type)
890{
891 STACK_OF(X509_EXTENSION) *exts = NULL;
892 X509_EXTENSION *ext, *tmpext;
893 ASN1_OBJECT *obj;
894 int i, idx, ret = 0;
895
896 if (!x || !req || (copy_type == EXT_COPY_NONE))
897 return 1;
898 exts = X509_REQ_get_extensions(req);
899
900 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
901 ext = sk_X509_EXTENSION_value(exts, i);
902 obj = X509_EXTENSION_get_object(ext);
903 idx = X509_get_ext_by_OBJ(x, obj, -1);
904 /* Does extension exist? */
905 if (idx != -1) {
906 /* If normal copy don't override existing extension */
907 if (copy_type == EXT_COPY_ADD)
908 continue;
909 /* Delete all extensions of same type */
910 do {
911 tmpext = X509_get_ext(x, idx);
912 X509_delete_ext(x, idx);
913 X509_EXTENSION_free(tmpext);
914 idx = X509_get_ext_by_OBJ(x, obj, -1);
915 } while (idx != -1);
916 }
917 if (!X509_add_ext(x, ext, -1))
918 goto end;
919 }
920
921 ret = 1;
922
923 end:
924 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
925
926 return ret;
927}
928
929static int
930set_multi_opts(unsigned long *flags, const char *arg,
931 const NAME_EX_TBL *in_tbl)
932{
933 STACK_OF(CONF_VALUE) *vals;
934 CONF_VALUE *val;
935 int i, ret = 1;
936
937 if (!arg)
938 return 0;
939 vals = X509V3_parse_list(arg);
940 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
941 val = sk_CONF_VALUE_value(vals, i);
942 if (!set_table_opts(flags, val->name, in_tbl))
943 ret = 0;
944 }
945 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
946 return ret;
947}
948
949static int
950set_table_opts(unsigned long *flags, const char *arg,
951 const NAME_EX_TBL *in_tbl)
952{
953 char c;
954 const NAME_EX_TBL *ptbl;
955
956 c = arg[0];
957 if (c == '-') {
958 c = 0;
959 arg++;
960 } else if (c == '+') {
961 c = 1;
962 arg++;
963 } else
964 c = 1;
965
966 for (ptbl = in_tbl; ptbl->name; ptbl++) {
967 if (!strcasecmp(arg, ptbl->name)) {
968 *flags &= ~ptbl->mask;
969 if (c)
970 *flags |= ptbl->flag;
971 else
972 *flags &= ~ptbl->flag;
973 return 1;
974 }
975 }
976 return 0;
977}
978
979void
980print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
981{
982 char *buf;
983 char mline = 0;
984 int indent = 0;
985
986 if (title)
987 BIO_puts(out, title);
988 if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
989 mline = 1;
990 indent = 4;
991 }
992 if (lflags == XN_FLAG_COMPAT) {
993 buf = X509_NAME_oneline(nm, 0, 0);
994 BIO_puts(out, buf);
995 BIO_puts(out, "\n");
996 free(buf);
997 } else {
998 if (mline)
999 BIO_puts(out, "\n");
1000 X509_NAME_print_ex(out, nm, indent, lflags);
1001 BIO_puts(out, "\n");
1002 }
1003}
1004
1005X509_STORE *
1006setup_verify(BIO *bp, char *CAfile, char *CApath)
1007{
1008 X509_STORE *store;
1009 X509_LOOKUP *lookup;
1010
1011 if (!(store = X509_STORE_new()))
1012 goto end;
1013 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
1014 if (lookup == NULL)
1015 goto end;
1016 if (CAfile) {
1017 if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
1018 BIO_printf(bp, "Error loading file %s\n", CAfile);
1019 goto end;
1020 }
1021 } else
1022 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
1023
1024 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
1025 if (lookup == NULL)
1026 goto end;
1027 if (CApath) {
1028 if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
1029 BIO_printf(bp, "Error loading directory %s\n", CApath);
1030 goto end;
1031 }
1032 } else
1033 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
1034
1035 ERR_clear_error();
1036 return store;
1037
1038 end:
1039 X509_STORE_free(store);
1040 return NULL;
1041}
1042
1043int
1044load_config(BIO *err, CONF *cnf)
1045{
1046 static int load_config_called = 0;
1047
1048 if (load_config_called)
1049 return 1;
1050 load_config_called = 1;
1051 if (cnf == NULL)
1052 cnf = config;
1053 if (cnf == NULL)
1054 return 1;
1055
1056 OPENSSL_config(NULL);
1057
1058 if (CONF_modules_load(cnf, NULL, 0) <= 0) {
1059 BIO_printf(err, "Error configuring OpenSSL\n");
1060 ERR_print_errors(err);
1061 return 0;
1062 }
1063 return 1;
1064}
1065
1066char *
1067make_config_name(void)
1068{
1069 const char *t = X509_get_default_cert_area();
1070 char *p;
1071
1072 if (asprintf(&p, "%s/openssl.cnf", t) == -1)
1073 return NULL;
1074 return p;
1075}
1076
1077static unsigned long
1078index_serial_hash(const OPENSSL_CSTRING *a)
1079{
1080 const char *n;
1081
1082 n = a[DB_serial];
1083 while (*n == '0')
1084 n++;
1085 return (lh_strhash(n));
1086}
1087
1088static int
1089index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1090{
1091 const char *aa, *bb;
1092
1093 for (aa = a[DB_serial]; *aa == '0'; aa++)
1094 ;
1095 for (bb = b[DB_serial]; *bb == '0'; bb++)
1096 ;
1097 return (strcmp(aa, bb));
1098}
1099
1100static int
1101index_name_qual(char **a)
1102{
1103 return (a[0][0] == 'V');
1104}
1105
1106static unsigned long
1107index_name_hash(const OPENSSL_CSTRING *a)
1108{
1109 return (lh_strhash(a[DB_name]));
1110}
1111
1112int
1113index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
1114{
1115 return (strcmp(a[DB_name], b[DB_name]));
1116}
1117
1118static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
1119static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
1120static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
1121static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
1122
1123BIGNUM *
1124load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
1125{
1126 BIO *in = NULL;
1127 BIGNUM *ret = NULL;
1128 char buf[1024];
1129 ASN1_INTEGER *ai = NULL;
1130
1131 ai = ASN1_INTEGER_new();
1132 if (ai == NULL)
1133 goto err;
1134
1135 if ((in = BIO_new(BIO_s_file())) == NULL) {
1136 ERR_print_errors(bio_err);
1137 goto err;
1138 }
1139 if (BIO_read_filename(in, serialfile) <= 0) {
1140 if (!create) {
1141 perror(serialfile);
1142 goto err;
1143 } else {
1144 ret = BN_new();
1145 if (ret == NULL || !rand_serial(ret, ai))
1146 BIO_printf(bio_err, "Out of memory\n");
1147 }
1148 } else {
1149 if (!a2i_ASN1_INTEGER(in, ai, buf, sizeof buf)) {
1150 BIO_printf(bio_err, "unable to load number from %s\n",
1151 serialfile);
1152 goto err;
1153 }
1154 ret = ASN1_INTEGER_to_BN(ai, NULL);
1155 if (ret == NULL) {
1156 BIO_printf(bio_err,
1157 "error converting number from bin to BIGNUM\n");
1158 goto err;
1159 }
1160 }
1161
1162 if (ret && retai) {
1163 *retai = ai;
1164 ai = NULL;
1165 }
1166
1167 err:
1168 BIO_free(in);
1169 ASN1_INTEGER_free(ai);
1170 return (ret);
1171}
1172
1173int
1174save_serial(char *serialfile, char *suffix, BIGNUM *serial,
1175 ASN1_INTEGER **retai)
1176{
1177 char serialpath[PATH_MAX];
1178 BIO *out = NULL;
1179 int ret = 0, n;
1180 ASN1_INTEGER *ai = NULL;
1181
1182 if (suffix == NULL)
1183 n = strlcpy(serialpath, serialfile, sizeof serialpath);
1184 else
1185 n = snprintf(serialpath, sizeof serialpath, "%s.%s",
1186 serialfile, suffix);
1187 if (n < 0 || n >= sizeof(serialpath)) {
1188 BIO_printf(bio_err, "serial too long\n");
1189 goto err;
1190 }
1191 out = BIO_new(BIO_s_file());
1192 if (out == NULL) {
1193 ERR_print_errors(bio_err);
1194 goto err;
1195 }
1196 if (BIO_write_filename(out, serialpath) <= 0) {
1197 perror(serialfile);
1198 goto err;
1199 }
1200 if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
1201 BIO_printf(bio_err,
1202 "error converting serial to ASN.1 format\n");
1203 goto err;
1204 }
1205 i2a_ASN1_INTEGER(out, ai);
1206 BIO_puts(out, "\n");
1207 ret = 1;
1208 if (retai) {
1209 *retai = ai;
1210 ai = NULL;
1211 }
1212
1213 err:
1214 BIO_free_all(out);
1215 ASN1_INTEGER_free(ai);
1216 return (ret);
1217}
1218
1219int
1220rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
1221{
1222 char opath[PATH_MAX], npath[PATH_MAX];
1223
1224 if (snprintf(npath, sizeof npath, "%s.%s", serialfile,
1225 new_suffix) >= sizeof npath) {
1226 BIO_printf(bio_err, "file name too long\n");
1227 goto err;
1228 }
1229
1230 if (snprintf(opath, sizeof opath, "%s.%s", serialfile,
1231 old_suffix) >= sizeof opath) {
1232 BIO_printf(bio_err, "file name too long\n");
1233 goto err;
1234 }
1235
1236 if (rename(serialfile, opath) == -1 &&
1237 errno != ENOENT && errno != ENOTDIR) {
1238 BIO_printf(bio_err, "unable to rename %s to %s\n",
1239 serialfile, opath);
1240 perror("reason");
1241 goto err;
1242 }
1243
1244
1245 if (rename(npath, serialfile) == -1) {
1246 BIO_printf(bio_err, "unable to rename %s to %s\n",
1247 npath, serialfile);
1248 perror("reason");
1249 if (rename(opath, serialfile) == -1) {
1250 BIO_printf(bio_err, "unable to rename %s to %s\n",
1251 opath, serialfile);
1252 perror("reason");
1253 }
1254 goto err;
1255 }
1256 return 1;
1257
1258 err:
1259 return 0;
1260}
1261
1262int
1263rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
1264{
1265 BIGNUM *btmp;
1266 int ret = 0;
1267
1268 if (b)
1269 btmp = b;
1270 else
1271 btmp = BN_new();
1272
1273 if (!btmp)
1274 return 0;
1275
1276 if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
1277 goto error;
1278 if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
1279 goto error;
1280
1281 ret = 1;
1282
1283 error:
1284 if (b != btmp)
1285 BN_free(btmp);
1286
1287 return ret;
1288}
1289
1290CA_DB *
1291load_index(char *dbfile, DB_ATTR *db_attr)
1292{
1293 CA_DB *retdb = NULL;
1294 TXT_DB *tmpdb = NULL;
1295 BIO *in = BIO_new(BIO_s_file());
1296 CONF *dbattr_conf = NULL;
1297 char attrpath[PATH_MAX];
1298 long errorline = -1;
1299
1300 if (in == NULL) {
1301 ERR_print_errors(bio_err);
1302 goto err;
1303 }
1304 if (BIO_read_filename(in, dbfile) <= 0) {
1305 perror(dbfile);
1306 BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1307 goto err;
1308 }
1309 if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
1310 goto err;
1311
1312 if (snprintf(attrpath, sizeof attrpath, "%s.attr", dbfile)
1313 >= sizeof attrpath) {
1314 BIO_printf(bio_err, "attr filename too long\n");
1315 goto err;
1316 }
1317
1318 dbattr_conf = NCONF_new(NULL);
1319 if (NCONF_load(dbattr_conf, attrpath, &errorline) <= 0) {
1320 if (errorline > 0) {
1321 BIO_printf(bio_err,
1322 "error on line %ld of db attribute file '%s'\n",
1323 errorline, attrpath);
1324 goto err;
1325 } else {
1326 NCONF_free(dbattr_conf);
1327 dbattr_conf = NULL;
1328 }
1329 }
1330 if ((retdb = malloc(sizeof(CA_DB))) == NULL) {
1331 fprintf(stderr, "Out of memory\n");
1332 goto err;
1333 }
1334 retdb->db = tmpdb;
1335 tmpdb = NULL;
1336 if (db_attr)
1337 retdb->attributes = *db_attr;
1338 else {
1339 retdb->attributes.unique_subject = 1;
1340 }
1341
1342 if (dbattr_conf) {
1343 char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
1344 if (p) {
1345 retdb->attributes.unique_subject = parse_yesno(p, 1);
1346 }
1347 }
1348
1349 err:
1350 NCONF_free(dbattr_conf);
1351 TXT_DB_free(tmpdb);
1352 BIO_free_all(in);
1353 return retdb;
1354}
1355
1356int
1357index_index(CA_DB *db)
1358{
1359 if (!TXT_DB_create_index(db->db, DB_serial, NULL,
1360 LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) {
1361 BIO_printf(bio_err,
1362 "error creating serial number index:(%ld,%ld,%ld)\n",
1363 db->db->error, db->db->arg1, db->db->arg2);
1364 return 0;
1365 }
1366 if (db->attributes.unique_subject &&
1367 !TXT_DB_create_index(db->db, DB_name, index_name_qual,
1368 LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) {
1369 BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
1370 db->db->error, db->db->arg1, db->db->arg2);
1371 return 0;
1372 }
1373 return 1;
1374}
1375
1376int
1377save_index(const char *file, const char *suffix, CA_DB *db)
1378{
1379 char attrpath[PATH_MAX], dbfile[PATH_MAX];
1380 BIO *out;
1381 int ret = 0;
1382
1383 if ((out = BIO_new(BIO_s_file())) == NULL) {
1384 ERR_print_errors(bio_err);
1385 goto err;
1386 }
1387 if (snprintf(attrpath, sizeof attrpath, "%s.attr.%s",
1388 file, suffix) >= sizeof attrpath) {
1389 BIO_printf(bio_err, "file name too long\n");
1390 goto err;
1391 }
1392 if (snprintf(dbfile, sizeof dbfile, "%s.%s",
1393 file, suffix) >= sizeof dbfile) {
1394 BIO_printf(bio_err, "file name too long\n");
1395 goto err;
1396 }
1397
1398 if (BIO_write_filename(out, dbfile) <= 0) {
1399 perror(dbfile);
1400 BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
1401 goto err;
1402 }
1403
1404 if (TXT_DB_write(out, db->db) <= 0)
1405 goto err;
1406
1407 BIO_free(out);
1408 if ((out = BIO_new(BIO_s_file())) == NULL) {
1409 ERR_print_errors(bio_err);
1410 goto err;
1411 }
1412
1413 if (BIO_write_filename(out, attrpath) <= 0) {
1414 perror(attrpath);
1415 BIO_printf(bio_err, "unable to open '%s'\n", attrpath);
1416 goto err;
1417 }
1418 if (BIO_printf(out, "unique_subject = %s\n",
1419 db->attributes.unique_subject ? "yes" : "no") <= 0)
1420 goto err;
1421
1422 ret = 1;
1423
1424 err:
1425 BIO_free(out);
1426
1427 return ret;
1428}
1429
1430int
1431rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
1432{
1433 char attrpath[PATH_MAX], nattrpath[PATH_MAX], oattrpath[PATH_MAX];
1434 char dbpath[PATH_MAX], odbpath[PATH_MAX];
1435
1436 if (snprintf(attrpath, sizeof attrpath, "%s.attr",
1437 dbfile) >= sizeof attrpath) {
1438 BIO_printf(bio_err, "file name too long\n");
1439 goto err;
1440 }
1441 if (snprintf(nattrpath, sizeof nattrpath, "%s.attr.%s",
1442 dbfile, new_suffix) >= sizeof nattrpath) {
1443 BIO_printf(bio_err, "file name too long\n");
1444 goto err;
1445 }
1446 if (snprintf(oattrpath, sizeof oattrpath, "%s.attr.%s",
1447 dbfile, old_suffix) >= sizeof oattrpath) {
1448 BIO_printf(bio_err, "file name too long\n");
1449 goto err;
1450 }
1451 if (snprintf(dbpath, sizeof dbpath, "%s.%s",
1452 dbfile, new_suffix) >= sizeof dbpath) {
1453 BIO_printf(bio_err, "file name too long\n");
1454 goto err;
1455 }
1456 if (snprintf(odbpath, sizeof odbpath, "%s.%s",
1457 dbfile, old_suffix) >= sizeof odbpath) {
1458 BIO_printf(bio_err, "file name too long\n");
1459 goto err;
1460 }
1461
1462 if (rename(dbfile, odbpath) == -1 && errno != ENOENT && errno != ENOTDIR) {
1463 BIO_printf(bio_err, "unable to rename %s to %s\n",
1464 dbfile, odbpath);
1465 perror("reason");
1466 goto err;
1467 }
1468
1469 if (rename(dbpath, dbfile) == -1) {
1470 BIO_printf(bio_err, "unable to rename %s to %s\n",
1471 dbpath, dbfile);
1472 perror("reason");
1473 if (rename(odbpath, dbfile) == -1) {
1474 BIO_printf(bio_err, "unable to rename %s to %s\n",
1475 odbpath, dbfile);
1476 perror("reason");
1477 }
1478 goto err;
1479 }
1480
1481 if (rename(attrpath, oattrpath) == -1 && errno != ENOENT && errno != ENOTDIR) {
1482 BIO_printf(bio_err, "unable to rename %s to %s\n",
1483 attrpath, oattrpath);
1484 perror("reason");
1485 if (rename(dbfile, dbpath) == -1) {
1486 BIO_printf(bio_err, "unable to rename %s to %s\n",
1487 dbfile, dbpath);
1488 perror("reason");
1489 }
1490 if (rename(odbpath, dbfile) == -1) {
1491 BIO_printf(bio_err, "unable to rename %s to %s\n",
1492 odbpath, dbfile);
1493 perror("reason");
1494 }
1495 goto err;
1496 }
1497
1498 if (rename(nattrpath, attrpath) == -1) {
1499 BIO_printf(bio_err, "unable to rename %s to %s\n",
1500 nattrpath, attrpath);
1501 perror("reason");
1502 if (rename(oattrpath, attrpath) == -1) {
1503 BIO_printf(bio_err, "unable to rename %s to %s\n",
1504 oattrpath, attrpath);
1505 perror("reason");
1506 }
1507 if (rename(dbfile, dbpath) == -1) {
1508 BIO_printf(bio_err, "unable to rename %s to %s\n",
1509 dbfile, dbpath);
1510 perror("reason");
1511 }
1512 if (rename(odbpath, dbfile) == -1) {
1513 BIO_printf(bio_err, "unable to rename %s to %s\n",
1514 odbpath, dbfile);
1515 perror("reason");
1516 }
1517 goto err;
1518 }
1519 return 1;
1520
1521 err:
1522 return 0;
1523}
1524
1525void
1526free_index(CA_DB *db)
1527{
1528 if (db) {
1529 TXT_DB_free(db->db);
1530 free(db);
1531 }
1532}
1533
1534int
1535parse_yesno(const char *str, int def)
1536{
1537 int ret = def;
1538
1539 if (str) {
1540 switch (*str) {
1541 case 'f': /* false */
1542 case 'F': /* FALSE */
1543 case 'n': /* no */
1544 case 'N': /* NO */
1545 case '0': /* 0 */
1546 ret = 0;
1547 break;
1548 case 't': /* true */
1549 case 'T': /* TRUE */
1550 case 'y': /* yes */
1551 case 'Y': /* YES */
1552 case '1': /* 1 */
1553 ret = 1;
1554 break;
1555 default:
1556 ret = def;
1557 break;
1558 }
1559 }
1560 return ret;
1561}
1562
1563/*
1564 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1565 * where characters may be escaped by \
1566 */
1567X509_NAME *
1568parse_name(char *subject, long chtype, int multirdn)
1569{
1570 X509_NAME *name = NULL;
1571 size_t buflen, max_ne;
1572 char **ne_types, **ne_values;
1573 char *buf, *bp, *sp;
1574 int i, nid, ne_num = 0;
1575 int *mval;
1576
1577 /*
1578 * Buffer to copy the types and values into. Due to escaping the
1579 * copy can only become shorter.
1580 */
1581 buflen = strlen(subject) + 1;
1582 buf = malloc(buflen);
1583
1584 /* Maximum number of name elements. */
1585 max_ne = buflen / 2 + 1;
1586 ne_types = reallocarray(NULL, max_ne, sizeof(char *));
1587 ne_values = reallocarray(NULL, max_ne, sizeof(char *));
1588 mval = reallocarray(NULL, max_ne, sizeof(int));
1589
1590 if (buf == NULL || ne_types == NULL || ne_values == NULL ||
1591 mval == NULL) {
1592 BIO_printf(bio_err, "malloc error\n");
1593 goto error;
1594 }
1595
1596 bp = buf;
1597 sp = subject;
1598
1599 if (*subject != '/') {
1600 BIO_printf(bio_err, "Subject does not start with '/'.\n");
1601 goto error;
1602 }
1603
1604 /* Skip leading '/'. */
1605 sp++;
1606
1607 /* No multivalued RDN by default. */
1608 mval[ne_num] = 0;
1609
1610 while (*sp) {
1611 /* Collect type. */
1612 ne_types[ne_num] = bp;
1613 while (*sp) {
1614 /* is there anything to escape in the type...? */
1615 if (*sp == '\\') {
1616 if (*++sp)
1617 *bp++ = *sp++;
1618 else {
1619 BIO_printf(bio_err, "escape character "
1620 "at end of string\n");
1621 goto error;
1622 }
1623 } else if (*sp == '=') {
1624 sp++;
1625 *bp++ = '\0';
1626 break;
1627 } else
1628 *bp++ = *sp++;
1629 }
1630 if (!*sp) {
1631 BIO_printf(bio_err, "end of string encountered while "
1632 "processing type of subject name element #%d\n",
1633 ne_num);
1634 goto error;
1635 }
1636 ne_values[ne_num] = bp;
1637 while (*sp) {
1638 if (*sp == '\\') {
1639 if (*++sp)
1640 *bp++ = *sp++;
1641 else {
1642 BIO_printf(bio_err, "escape character "
1643 "at end of string\n");
1644 goto error;
1645 }
1646 } else if (*sp == '/') {
1647 sp++;
1648 /* no multivalued RDN by default */
1649 mval[ne_num + 1] = 0;
1650 break;
1651 } else if (*sp == '+' && multirdn) {
1652 /* a not escaped + signals a multivalued RDN */
1653 sp++;
1654 mval[ne_num + 1] = -1;
1655 break;
1656 } else
1657 *bp++ = *sp++;
1658 }
1659 *bp++ = '\0';
1660 ne_num++;
1661 }
1662
1663 if ((name = X509_NAME_new()) == NULL)
1664 goto error;
1665
1666 for (i = 0; i < ne_num; i++) {
1667 if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
1668 BIO_printf(bio_err,
1669 "Subject Attribute %s has no known NID, skipped\n",
1670 ne_types[i]);
1671 continue;
1672 }
1673 if (!*ne_values[i]) {
1674 BIO_printf(bio_err, "No value provided for Subject "
1675 "Attribute %s, skipped\n", ne_types[i]);
1676 continue;
1677 }
1678 if (!X509_NAME_add_entry_by_NID(name, nid, chtype,
1679 (unsigned char *) ne_values[i], -1, -1, mval[i]))
1680 goto error;
1681 }
1682 goto done;
1683
1684 error:
1685 X509_NAME_free(name);
1686 name = NULL;
1687
1688 done:
1689 free(ne_values);
1690 free(ne_types);
1691 free(mval);
1692 free(buf);
1693
1694 return name;
1695}
1696
1697int
1698args_verify(char ***pargs, int *pargc, int *badarg, BIO *err,
1699 X509_VERIFY_PARAM **pm)
1700{
1701 ASN1_OBJECT *otmp = NULL;
1702 unsigned long flags = 0;
1703 int i;
1704 int purpose = 0, depth = -1;
1705 char **oldargs = *pargs;
1706 char *arg = **pargs, *argn = (*pargs)[1];
1707 time_t at_time = 0;
1708 const char *errstr = NULL;
1709
1710 if (!strcmp(arg, "-policy")) {
1711 if (!argn)
1712 *badarg = 1;
1713 else {
1714 otmp = OBJ_txt2obj(argn, 0);
1715 if (!otmp) {
1716 BIO_printf(err, "Invalid Policy \"%s\"\n",
1717 argn);
1718 *badarg = 1;
1719 }
1720 }
1721 (*pargs)++;
1722 } else if (strcmp(arg, "-purpose") == 0) {
1723 const X509_PURPOSE *xptmp;
1724 if (!argn)
1725 *badarg = 1;
1726 else {
1727 i = X509_PURPOSE_get_by_sname(argn);
1728 if (i < 0) {
1729 BIO_printf(err, "unrecognized purpose\n");
1730 *badarg = 1;
1731 } else {
1732 xptmp = X509_PURPOSE_get0(i);
1733 purpose = X509_PURPOSE_get_id(xptmp);
1734 }
1735 }
1736 (*pargs)++;
1737 } else if (strcmp(arg, "-verify_depth") == 0) {
1738 if (!argn)
1739 *badarg = 1;
1740 else {
1741 depth = strtonum(argn, 1, INT_MAX, &errstr);
1742 if (errstr) {
1743 BIO_printf(err, "invalid depth %s: %s\n",
1744 argn, errstr);
1745 *badarg = 1;
1746 }
1747 }
1748 (*pargs)++;
1749 } else if (strcmp(arg, "-attime") == 0) {
1750 if (!argn)
1751 *badarg = 1;
1752 else {
1753 long long timestamp;
1754 /*
1755 * interpret the -attime argument as seconds since
1756 * Epoch
1757 */
1758 if (sscanf(argn, "%lli", &timestamp) != 1) {
1759 BIO_printf(bio_err,
1760 "Error parsing timestamp %s\n",
1761 argn);
1762 *badarg = 1;
1763 }
1764 /* XXX 2038 truncation */
1765 at_time = (time_t) timestamp;
1766 }
1767 (*pargs)++;
1768 } else if (!strcmp(arg, "-ignore_critical"))
1769 flags |= X509_V_FLAG_IGNORE_CRITICAL;
1770 else if (!strcmp(arg, "-issuer_checks"))
1771 flags |= X509_V_FLAG_CB_ISSUER_CHECK;
1772 else if (!strcmp(arg, "-crl_check"))
1773 flags |= X509_V_FLAG_CRL_CHECK;
1774 else if (!strcmp(arg, "-crl_check_all"))
1775 flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
1776 else if (!strcmp(arg, "-policy_check"))
1777 flags |= X509_V_FLAG_POLICY_CHECK;
1778 else if (!strcmp(arg, "-explicit_policy"))
1779 flags |= X509_V_FLAG_EXPLICIT_POLICY;
1780 else if (!strcmp(arg, "-legacy_verify"))
1781 flags |= X509_V_FLAG_LEGACY_VERIFY;
1782 else if (!strcmp(arg, "-inhibit_any"))
1783 flags |= X509_V_FLAG_INHIBIT_ANY;
1784 else if (!strcmp(arg, "-inhibit_map"))
1785 flags |= X509_V_FLAG_INHIBIT_MAP;
1786 else if (!strcmp(arg, "-x509_strict"))
1787 flags |= X509_V_FLAG_X509_STRICT;
1788 else if (!strcmp(arg, "-extended_crl"))
1789 flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
1790 else if (!strcmp(arg, "-use_deltas"))
1791 flags |= X509_V_FLAG_USE_DELTAS;
1792 else if (!strcmp(arg, "-policy_print"))
1793 flags |= X509_V_FLAG_NOTIFY_POLICY;
1794 else if (!strcmp(arg, "-check_ss_sig"))
1795 flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
1796 else
1797 return 0;
1798
1799 if (*badarg) {
1800 X509_VERIFY_PARAM_free(*pm);
1801 *pm = NULL;
1802 goto end;
1803 }
1804 if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) {
1805 *badarg = 1;
1806 goto end;
1807 }
1808 if (otmp) {
1809 X509_VERIFY_PARAM_add0_policy(*pm, otmp);
1810 otmp = NULL;
1811 }
1812 if (flags)
1813 X509_VERIFY_PARAM_set_flags(*pm, flags);
1814
1815 if (purpose)
1816 X509_VERIFY_PARAM_set_purpose(*pm, purpose);
1817
1818 if (depth >= 0)
1819 X509_VERIFY_PARAM_set_depth(*pm, depth);
1820
1821 if (at_time)
1822 X509_VERIFY_PARAM_set_time(*pm, at_time);
1823
1824 end:
1825 (*pargs)++;
1826
1827 if (pargc)
1828 *pargc -= *pargs - oldargs;
1829
1830 ASN1_OBJECT_free(otmp);
1831 return 1;
1832}
1833
1834/* Read whole contents of a BIO into an allocated memory buffer and
1835 * return it.
1836 */
1837
1838int
1839bio_to_mem(unsigned char **out, int maxlen, BIO *in)
1840{
1841 BIO *mem;
1842 int len, ret;
1843 unsigned char tbuf[1024];
1844
1845 mem = BIO_new(BIO_s_mem());
1846 if (!mem)
1847 return -1;
1848 for (;;) {
1849 if ((maxlen != -1) && maxlen < 1024)
1850 len = maxlen;
1851 else
1852 len = 1024;
1853 len = BIO_read(in, tbuf, len);
1854 if (len <= 0)
1855 break;
1856 if (BIO_write(mem, tbuf, len) != len) {
1857 BIO_free(mem);
1858 return -1;
1859 }
1860 maxlen -= len;
1861
1862 if (maxlen == 0)
1863 break;
1864 }
1865 ret = BIO_get_mem_data(mem, (char **) out);
1866 BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
1867 BIO_free(mem);
1868 return ret;
1869}
1870
1871int
1872pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
1873{
1874 int rv;
1875 char *stmp, *vtmp = NULL;
1876
1877 if (value == NULL)
1878 return -1;
1879 stmp = strdup(value);
1880 if (!stmp)
1881 return -1;
1882 vtmp = strchr(stmp, ':');
1883 if (vtmp) {
1884 *vtmp = 0;
1885 vtmp++;
1886 }
1887 rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
1888 free(stmp);
1889
1890 return rv;
1891}
1892
1893/*
1894 * next_protos_parse parses a comma separated list of strings into a string
1895 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
1896 * outlen: (output) set to the length of the resulting buffer on success.
1897 * err: (maybe NULL) on failure, an error message line is written to this BIO.
1898 * in: a NUL terminated string like "abc,def,ghi"
1899 *
1900 * returns: a malloced buffer or NULL on failure.
1901 */
1902unsigned char *
1903next_protos_parse(unsigned short *outlen, const char *in)
1904{
1905 size_t len;
1906 unsigned char *out;
1907 size_t i, start = 0;
1908
1909 len = strlen(in);
1910 if (len >= 65535)
1911 return NULL;
1912
1913 out = malloc(strlen(in) + 1);
1914 if (!out)
1915 return NULL;
1916
1917 for (i = 0; i <= len; ++i) {
1918 if (i == len || in[i] == ',') {
1919 if (i - start > 255) {
1920 free(out);
1921 return NULL;
1922 }
1923 out[start] = i - start;
1924 start = i + 1;
1925 } else
1926 out[i + 1] = in[i];
1927 }
1928
1929 *outlen = len + 1;
1930 return out;
1931}
1932
1933int
1934app_isdir(const char *name)
1935{
1936 struct stat st;
1937
1938 if (stat(name, &st) == 0)
1939 return S_ISDIR(st.st_mode);
1940 return -1;
1941}
1942
1943#define OPTION_WIDTH 18
1944
1945void
1946options_usage(const struct option *opts)
1947{
1948 const char *p, *q;
1949 char optstr[32];
1950 int i;
1951
1952 for (i = 0; opts[i].name != NULL; i++) {
1953 if (opts[i].desc == NULL)
1954 continue;
1955
1956 snprintf(optstr, sizeof(optstr), "-%s %s", opts[i].name,
1957 (opts[i].argname != NULL) ? opts[i].argname : "");
1958 fprintf(stderr, " %-*s", OPTION_WIDTH, optstr);
1959 if (strlen(optstr) > OPTION_WIDTH)
1960 fprintf(stderr, "\n %-*s", OPTION_WIDTH, "");
1961
1962 p = opts[i].desc;
1963 while ((q = strchr(p, '\n')) != NULL) {
1964 fprintf(stderr, " %.*s", (int)(q - p), p);
1965 fprintf(stderr, "\n %-*s", OPTION_WIDTH, "");
1966 p = q + 1;
1967 }
1968 fprintf(stderr, " %s\n", p);
1969 }
1970}
1971
1972int
1973options_parse(int argc, char **argv, const struct option *opts, char **unnamed,
1974 int *argsused)
1975{
1976 const char *errstr;
1977 const struct option *opt;
1978 long long val;
1979 char *arg, *p;
1980 int fmt, used;
1981 int ord = 0;
1982 int i, j;
1983
1984 if (unnamed != NULL)
1985 *unnamed = NULL;
1986
1987 for (i = 1; i < argc; i++) {
1988 p = arg = argv[i];
1989
1990 /* Single unnamed argument (without leading hyphen). */
1991 if (*p++ != '-') {
1992 if (argsused != NULL)
1993 goto done;
1994 if (unnamed == NULL)
1995 goto unknown;
1996 if (*unnamed != NULL)
1997 goto toomany;
1998 *unnamed = arg;
1999 continue;
2000 }
2001
2002 /* End of named options (single hyphen). */
2003 if (*p == '\0') {
2004 if (++i >= argc)
2005 goto done;
2006 if (argsused != NULL)
2007 goto done;
2008 if (unnamed != NULL && i == argc - 1) {
2009 if (*unnamed != NULL)
2010 goto toomany;
2011 *unnamed = argv[i];
2012 continue;
2013 }
2014 goto unknown;
2015 }
2016
2017 /* See if there is a matching option... */
2018 for (j = 0; opts[j].name != NULL; j++) {
2019 if (strcmp(p, opts[j].name) == 0)
2020 break;
2021 }
2022 opt = &opts[j];
2023 if (opt->name == NULL && opt->type == 0)
2024 goto unknown;
2025
2026 if (opt->type == OPTION_ARG ||
2027 opt->type == OPTION_ARG_FORMAT ||
2028 opt->type == OPTION_ARG_FUNC ||
2029 opt->type == OPTION_ARG_INT ||
2030 opt->type == OPTION_ARG_LONG ||
2031 opt->type == OPTION_ARG_TIME) {
2032 if (++i >= argc) {
2033 fprintf(stderr, "missing %s argument for -%s\n",
2034 opt->argname, opt->name);
2035 return (1);
2036 }
2037 }
2038
2039 switch (opt->type) {
2040 case OPTION_ARG:
2041 *opt->opt.arg = argv[i];
2042 break;
2043
2044 case OPTION_ARGV_FUNC:
2045 if (opt->opt.argvfunc(argc - i, &argv[i], &used) != 0)
2046 return (1);
2047 i += used - 1;
2048 break;
2049
2050 case OPTION_ARG_FORMAT:
2051 fmt = str2fmt(argv[i]);
2052 if (fmt == FORMAT_UNDEF) {
2053 fprintf(stderr, "unknown %s '%s' for -%s\n",
2054 opt->argname, argv[i], opt->name);
2055 return (1);
2056 }
2057 *opt->opt.value = fmt;
2058 break;
2059
2060 case OPTION_ARG_FUNC:
2061 if (opt->opt.argfunc(argv[i]) != 0)
2062 return (1);
2063 break;
2064
2065 case OPTION_ARG_INT:
2066 val = strtonum(argv[i], 0, INT_MAX, &errstr);
2067 if (errstr != NULL) {
2068 fprintf(stderr, "%s %s argument for -%s\n",
2069 errstr, opt->argname, opt->name);
2070 return (1);
2071 }
2072 *opt->opt.value = (int)val;
2073 break;
2074
2075 case OPTION_ARG_LONG:
2076 val = strtonum(argv[i], 0, LONG_MAX, &errstr);
2077 if (errstr != NULL) {
2078 fprintf(stderr, "%s %s argument for -%s\n",
2079 errstr, opt->argname, opt->name);
2080 return (1);
2081 }
2082 *opt->opt.lvalue = (long)val;
2083 break;
2084
2085 case OPTION_ARG_TIME:
2086 val = strtonum(argv[i], 0, LLONG_MAX, &errstr);
2087 if (errstr != NULL) {
2088 fprintf(stderr, "%s %s argument for -%s\n",
2089 errstr, opt->argname, opt->name);
2090 return (1);
2091 }
2092 *opt->opt.tvalue = val;
2093 break;
2094
2095 case OPTION_DISCARD:
2096 break;
2097
2098 case OPTION_FUNC:
2099 if (opt->opt.func() != 0)
2100 return (1);
2101 break;
2102
2103 case OPTION_FLAG:
2104 *opt->opt.flag = 1;
2105 break;
2106
2107 case OPTION_FLAG_ORD:
2108 *opt->opt.flag = ++ord;
2109 break;
2110
2111 case OPTION_VALUE:
2112 *opt->opt.value = opt->value;
2113 break;
2114
2115 case OPTION_VALUE_AND:
2116 *opt->opt.value &= opt->value;
2117 break;
2118
2119 case OPTION_VALUE_OR:
2120 *opt->opt.value |= opt->value;
2121 break;
2122
2123 case OPTION_UL_VALUE_OR:
2124 *opt->opt.ulvalue |= opt->ulvalue;
2125 break;
2126
2127 case OPTION_ORDER:
2128 *opt->opt.order = ++(*opt->order);
2129 break;
2130
2131 default:
2132 fprintf(stderr, "option %s - unknown type %i\n",
2133 opt->name, opt->type);
2134 return (1);
2135 }
2136 }
2137
2138 done:
2139 if (argsused != NULL)
2140 *argsused = i;
2141
2142 return (0);
2143
2144 toomany:
2145 fprintf(stderr, "too many arguments\n");
2146 return (1);
2147
2148 unknown:
2149 fprintf(stderr, "unknown option '%s'\n", arg);
2150 return (1);
2151}
2152
2153void
2154show_cipher(const OBJ_NAME *name, void *arg)
2155{
2156 int *n = arg;
2157
2158 if (!islower((unsigned char)*name->name))
2159 return;
2160
2161 fprintf(stderr, " -%-24s%s", name->name, (++*n % 3 != 0 ? "" : "\n"));
2162}
diff --git a/src/usr.bin/openssl/apps.h b/src/usr.bin/openssl/apps.h
deleted file mode 100644
index cd218fd1b0..0000000000
--- a/src/usr.bin/openssl/apps.h
+++ /dev/null
@@ -1,401 +0,0 @@
1/* $OpenBSD: apps.h,v 1.42 2025/01/02 13:11:26 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#ifndef HEADER_APPS_H
113#define HEADER_APPS_H
114
115#include <openssl/opensslconf.h>
116
117#include <openssl/bio.h>
118#include <openssl/conf.h>
119#include <openssl/lhash.h>
120#include <openssl/ossl_typ.h>
121#include <openssl/txt_db.h>
122#include <openssl/x509.h>
123#include <openssl/ui.h>
124
125#ifndef OPENSSL_NO_OCSP
126#include <openssl/ocsp.h>
127#endif
128
129#include <openssl/ssl.h>
130
131#include <unistd.h>
132
133/* numbers in us */
134#define DGRAM_RCV_TIMEOUT 250000
135#define DGRAM_SND_TIMEOUT 250000
136
137extern CONF *config;
138extern char *default_config_file;
139extern BIO *bio_err;
140
141#define PW_MIN_LENGTH 4
142typedef struct pw_cb_data {
143 const void *password;
144 const char *prompt_info;
145} PW_CB_DATA;
146
147int password_callback(char *buf, int bufsiz, int verify, void *cb_data);
148
149int setup_ui(void);
150void destroy_ui(void);
151
152extern UI_METHOD *ui_method;
153int ui_open(UI *ui);
154int ui_read(UI *ui, UI_STRING *uis);
155int ui_write(UI *ui, UI_STRING *uis);
156int ui_close(UI *ui);
157
158int str2fmt(char *s);
159void program_name(char *in, char *out, int size);
160#ifdef HEADER_X509_H
161int dump_cert_text(BIO *out, X509 *x);
162void print_name(BIO *out, const char *title, X509_NAME *nm,
163 unsigned long lflags);
164#endif
165int set_cert_ex(unsigned long *flags, const char *arg);
166int set_name_ex(unsigned long *flags, const char *arg);
167int set_ext_copy(int *copy_type, const char *arg);
168int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
169int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
170int add_oid_section(BIO *err, CONF *conf);
171X509 *load_cert(BIO *err, const char *file, int format,
172 const char *pass, const char *cert_descrip);
173EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
174 const char *pass, const char *key_descrip);
175EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
176 const char *pass, const char *key_descrip);
177STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
178 const char *pass, const char *cert_descrip);
179STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
180 const char *pass, const char *cert_descrip);
181X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
182
183#ifndef OPENSSL_NO_OCSP
184OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
185 char *host, char *path, char *port, int use_ssl,
186 STACK_OF(CONF_VALUE) *headers, int req_timeout);
187#endif
188
189int load_config(BIO *err, CONF *cnf);
190char *make_config_name(void);
191
192/* Functions defined in ca.c and also used in ocsp.c */
193int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
194 ASN1_GENERALIZEDTIME **pinvtm, const char *str);
195
196#define DB_type 0
197#define DB_exp_date 1
198#define DB_rev_date 2
199#define DB_serial 3 /* index - unique */
200#define DB_file 4
201#define DB_name 5 /* index - unique when active and not disabled */
202#define DB_NUMBER 6
203
204#define DB_TYPE_REV 'R'
205#define DB_TYPE_EXP 'E'
206#define DB_TYPE_VAL 'V'
207#define DB_TYPE_SUSP 'S'
208
209typedef struct db_attr_st {
210 int unique_subject;
211} DB_ATTR;
212typedef struct ca_db_st {
213 DB_ATTR attributes;
214 TXT_DB *db;
215} CA_DB;
216
217BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai);
218int save_serial(char *serialfile, char *suffix, BIGNUM *serial,
219 ASN1_INTEGER **retai);
220int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix);
221int rand_serial(BIGNUM *b, ASN1_INTEGER *ai);
222CA_DB *load_index(char *dbfile, DB_ATTR *dbattr);
223int index_index(CA_DB *db);
224int save_index(const char *dbfile, const char *suffix, CA_DB *db);
225int rotate_index(const char *dbfile, const char *new_suffix,
226 const char *old_suffix);
227void free_index(CA_DB *db);
228#define index_name_cmp_noconst(a, b) \
229 index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
230 (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
231int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
232int parse_yesno(const char *str, int def);
233
234X509_NAME *parse_name(char *str, long chtype, int multirdn);
235int args_verify(char ***pargs, int *pargc, int *badarg, BIO *err,
236 X509_VERIFY_PARAM **pm);
237int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
238int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
239int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, const char *algname,
240 int do_param);
241int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
242 STACK_OF(OPENSSL_STRING) *sigopts);
243int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
244 STACK_OF(OPENSSL_STRING) *sigopts);
245int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
246 STACK_OF(OPENSSL_STRING) *sigopts);
247
248unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
249
250#define FORMAT_UNDEF 0
251#define FORMAT_ASN1 1
252#define FORMAT_TEXT 2
253#define FORMAT_PEM 3
254
255#define FORMAT_PKCS12 5
256#define FORMAT_SMIME 6
257
258#define FORMAT_PEMRSA 9 /* PEM RSAPublicKey format */
259#define FORMAT_ASN1RSA 10 /* DER RSAPublicKey format */
260#define FORMAT_MSBLOB 11 /* MS Key blob format */
261#define FORMAT_PVK 12 /* MS PVK file format */
262
263#define EXT_COPY_NONE 0
264#define EXT_COPY_ADD 1
265#define EXT_COPY_ALL 2
266
267#define APP_PASS_LEN 1024
268
269#define SERIAL_RAND_BITS 64
270
271int app_isdir(const char *);
272
273#define TM_RESET 0
274#define TM_GET 1
275double app_timer_real(int);
276double app_timer_user(int);
277
278#define OPENSSL_NO_SSL_INTERN
279
280struct option {
281 const char *name;
282 const char *argname;
283 const char *desc;
284 enum {
285 OPTION_ARG,
286 OPTION_ARGV_FUNC,
287 OPTION_ARG_FORMAT,
288 OPTION_ARG_FUNC,
289 OPTION_ARG_INT,
290 OPTION_ARG_LONG,
291 OPTION_ARG_TIME,
292 OPTION_DISCARD,
293 OPTION_FUNC,
294 OPTION_FLAG,
295 OPTION_FLAG_ORD,
296 OPTION_VALUE,
297 OPTION_VALUE_AND,
298 OPTION_VALUE_OR,
299 OPTION_UL_VALUE_OR,
300 OPTION_ORDER,
301 } type;
302 union {
303 char **arg;
304 int (*argfunc)(char *arg);
305 int (*argvfunc)(int argc, char **argv, int *argsused);
306 int *flag;
307 int (*func)(void);
308 long *lvalue;
309 int *value;
310 unsigned long *ulvalue;
311 time_t *tvalue;
312 int *order;
313 } opt;
314 const int value;
315 const unsigned long ulvalue;
316 int *order;
317};
318
319void options_usage(const struct option *opts);
320int options_parse(int argc, char **argv, const struct option *opts,
321 char **unnamed, int *argsused);
322
323void show_cipher(const OBJ_NAME *name, void *arg);
324
325int asn1parse_main(int argc, char **argv);
326int ca_main(int argc, char **argv);
327int certhash_main(int argc, char **argv);
328int ciphers_main(int argc, char **argv);
329int cms_main(int argc, char **argv);
330int crl2pkcs7_main(int argc, char **argv);
331int crl_main(int argc, char **argv);
332int dgst_main(int argc, char **argv);
333int dh_main(int argc, char **argv);
334int dhparam_main(int argc, char **argv);
335int dsa_main(int argc, char **argv);
336int dsaparam_main(int argc, char **argv);
337int ec_main(int argc, char **argv);
338int ecparam_main(int argc, char **argv);
339int enc_main(int argc, char **argv);
340int errstr_main(int argc, char **argv);
341int gendh_main(int argc, char **argv);
342int gendsa_main(int argc, char **argv);
343int genpkey_main(int argc, char **argv);
344int genrsa_main(int argc, char **argv);
345int ocsp_main(int argc, char **argv);
346int passwd_main(int argc, char **argv);
347int pkcs7_main(int argc, char **argv);
348int pkcs8_main(int argc, char **argv);
349int pkcs12_main(int argc, char **argv);
350int pkey_main(int argc, char **argv);
351int pkeyparam_main(int argc, char **argv);
352int pkeyutl_main(int argc, char **argv);
353int prime_main(int argc, char **argv);
354int rand_main(int argc, char **argv);
355int req_main(int argc, char **argv);
356int rsa_main(int argc, char **argv);
357int rsautl_main(int argc, char **argv);
358int s_client_main(int argc, char **argv);
359int s_server_main(int argc, char **argv);
360int s_time_main(int argc, char **argv);
361int sess_id_main(int argc, char **argv);
362int smime_main(int argc, char **argv);
363int speed_main(int argc, char **argv);
364int ts_main(int argc, char **argv);
365int verify_main(int argc, char **argv);
366int version_main(int argc, char **argv);
367int x509_main(int argc, char **argv);
368
369#define PORT 4433
370#define PORT_STR "4433"
371#define PROTOCOL "tcp"
372
373extern int verify_depth;
374extern int verify_return_error;
375
376int do_server(int port, int type, int *ret,
377 int (*cb)(int s, unsigned char *context),
378 unsigned char *context, int naccept);
379int verify_callback(int ok, X509_STORE_CTX *ctx);
380int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
381int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key);
382int ssl_print_tmp_key(BIO *out, SSL *s);
383int init_client(int *sock, char *server, char *port, int type, int af);
384int extract_port(char *str, short *port_ptr);
385int extract_host_port(char *str, char **host_ptr, unsigned char *ip, char **p);
386
387long bio_dump_callback(BIO *bio, int cmd, const char *argp, int argi,
388 long argl, long ret);
389
390void apps_ssl_info_callback(const SSL *s, int where, int ret);
391void msg_cb(int write_p, int version, int content_type, const void *buf,
392 size_t len, SSL *ssl, void *arg);
393void tlsext_cb(SSL *s, int client_server, int type, unsigned char *data,
394 int len, void *arg);
395
396int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
397 unsigned int *cookie_len);
398int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
399 unsigned int cookie_len);
400
401#endif
diff --git a/src/usr.bin/openssl/apps_posix.c b/src/usr.bin/openssl/apps_posix.c
deleted file mode 100644
index cdcf821366..0000000000
--- a/src/usr.bin/openssl/apps_posix.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 5. Products derived from this software may not be called "OpenSSL"
87 * nor may "OpenSSL" appear in their names without prior written
88 * permission of the OpenSSL Project.
89 *
90 * 6. Redistributions of any form whatsoever must retain the following
91 * acknowledgment:
92 * "This product includes software developed by the OpenSSL Project
93 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
94 *
95 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
96 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
97 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
98 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
99 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
100 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
101 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
103 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
104 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
105 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
106 * OF THE POSSIBILITY OF SUCH DAMAGE.
107 * ====================================================================
108 *
109 * This product includes cryptographic software written by Eric Young
110 * (eay@cryptsoft.com). This product includes software written by Tim
111 * Hudson (tjh@cryptsoft.com).
112 *
113 */
114
115/*
116 * Functions that need to be overridden by non-POSIX operating systems.
117 */
118
119#include <sys/resource.h>
120#include <sys/time.h>
121
122#include <time.h>
123
124#include "apps.h"
125
126double
127app_timer_real(int get)
128{
129 static struct timespec start;
130 struct timespec elapsed, now;
131
132 clock_gettime(CLOCK_MONOTONIC, &now);
133 if (get) {
134 timespecsub(&now, &start, &elapsed);
135 return elapsed.tv_sec + elapsed.tv_nsec / 1000000000.0;
136 }
137 start = now;
138 return 0.0;
139}
140
141double
142app_timer_user(int get)
143{
144 static struct timeval start;
145 struct timeval elapsed;
146 struct rusage now;
147
148 getrusage(RUSAGE_SELF, &now);
149 if (get) {
150 timersub(&now.ru_utime, &start, &elapsed);
151 return elapsed.tv_sec + elapsed.tv_usec / 1000000.0;
152 }
153 start = now.ru_utime;
154 return 0.0;
155}
156
157int
158setup_ui(void)
159{
160 ui_method = UI_create_method("OpenSSL application user interface");
161 UI_method_set_opener(ui_method, ui_open);
162 UI_method_set_reader(ui_method, ui_read);
163 UI_method_set_writer(ui_method, ui_write);
164 UI_method_set_closer(ui_method, ui_close);
165 return 0;
166}
167
168void
169destroy_ui(void)
170{
171 if (ui_method) {
172 UI_destroy_method(ui_method);
173 ui_method = NULL;
174 }
175}
diff --git a/src/usr.bin/openssl/asn1pars.c b/src/usr.bin/openssl/asn1pars.c
deleted file mode 100644
index 355784169e..0000000000
--- a/src/usr.bin/openssl/asn1pars.c
+++ /dev/null
@@ -1,469 +0,0 @@
1/* $OpenBSD: asn1pars.c,v 1.17 2025/01/02 12:31:44 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/* A nice addition from Dr Stephen Henson <steve@openssl.org> to
60 * add the -strparse option which parses nested binary structures
61 */
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <limits.h>
66#include <string.h>
67
68#include "apps.h"
69
70#include <openssl/err.h>
71#include <openssl/evp.h>
72#include <openssl/pem.h>
73#include <openssl/x509.h>
74
75static struct {
76 char *derfile;
77 int dump;
78 char *genconf;
79 char *genstr;
80 int indent;
81 char *infile;
82 int informat;
83 unsigned int length;
84 int noout;
85 int offset;
86 char *oidfile;
87 STACK_OF(OPENSSL_STRING) *osk;
88} cfg;
89
90static int
91asn1pars_opt_dlimit(char *arg)
92{
93 const char *errstr;
94
95 cfg.dump = strtonum(arg, 1, INT_MAX, &errstr);
96 if (errstr) {
97 fprintf(stderr, "-dlimit must be from 1 to INT_MAX: %s\n",
98 errstr);
99 return (-1);
100 }
101 return (0);
102}
103
104static int
105asn1pars_opt_length(char *arg)
106{
107 const char *errstr;
108
109 cfg.length = strtonum(arg, 1, UINT_MAX, &errstr);
110 if (errstr) {
111 fprintf(stderr, "-length must be from 1 to UINT_MAX: %s\n",
112 errstr);
113 return (-1);
114 }
115 return (0);
116}
117
118static int
119asn1pars_opt_strparse(char *arg)
120{
121 if (sk_OPENSSL_STRING_push(cfg.osk, arg) == 0) {
122 fprintf(stderr, "-strparse cannot add argument\n");
123 return (-1);
124 }
125 return (0);
126}
127
128static const struct option asn1pars_options[] = {
129 {
130 .name = "dump",
131 .desc = "Dump unknown data in hex form",
132 .type = OPTION_VALUE,
133 .value = -1,
134 .opt.value = &cfg.dump,
135 },
136 {
137 .name = "dlimit",
138 .argname = "num",
139 .desc = "Dump the first num bytes of unknown data in hex form",
140 .type = OPTION_ARG_FUNC,
141 .opt.argfunc = asn1pars_opt_dlimit,
142 },
143 {
144 .name = "genconf",
145 .argname = "file",
146 .desc = "File to generate ASN.1 structure from",
147 .type = OPTION_ARG,
148 .opt.arg = &cfg.genconf,
149 },
150 {
151 .name = "genstr",
152 .argname = "string",
153 .desc = "String to generate ASN.1 structure from",
154 .type = OPTION_ARG,
155 .opt.arg = &cfg.genstr,
156 },
157 {
158 .name = "i",
159 .desc = "Indent output according to depth of structures",
160 .type = OPTION_FLAG,
161 .opt.flag = &cfg.indent,
162 },
163 {
164 .name = "in",
165 .argname = "file",
166 .desc = "The input file (default stdin)",
167 .type = OPTION_ARG,
168 .opt.arg = &cfg.infile,
169 },
170 {
171 .name = "inform",
172 .argname = "fmt",
173 .desc = "Input format (DER, TXT or PEM (default))",
174 .type = OPTION_ARG_FORMAT,
175 .opt.value = &cfg.informat,
176 },
177 {
178 .name = "length",
179 .argname = "num",
180 .desc = "Number of bytes to parse (default until EOF)",
181 .type = OPTION_ARG_FUNC,
182 .opt.argfunc = asn1pars_opt_length,
183 },
184 {
185 .name = "noout",
186 .desc = "Do not produce any output",
187 .type = OPTION_FLAG,
188 .opt.flag = &cfg.noout,
189 },
190 {
191 .name = "offset",
192 .argname = "num",
193 .desc = "Offset to begin parsing",
194 .type = OPTION_ARG_INT,
195 .opt.value = &cfg.offset,
196 },
197 {
198 .name = "oid",
199 .argname = "file",
200 .desc = "File containing additional object identifiers (OIDs)",
201 .type = OPTION_ARG,
202 .opt.arg = &cfg.oidfile,
203 },
204 {
205 .name = "out",
206 .argname = "file",
207 .desc = "Output file in DER format",
208 .type = OPTION_ARG,
209 .opt.arg = &cfg.derfile,
210 },
211 {
212 .name = "strparse",
213 .argname = "offset",
214 .desc = "Parse the content octets of ASN.1 object starting at"
215 " offset",
216 .type = OPTION_ARG_FUNC,
217 .opt.argfunc = asn1pars_opt_strparse,
218 },
219 { NULL },
220};
221
222static void
223asn1pars_usage(void)
224{
225 fprintf(stderr,
226 "usage: asn1parse [-i] [-dlimit num] [-dump] [-genconf file] "
227 "[-genstr string]\n"
228 " [-in file] [-inform fmt] [-length num] [-noout] [-offset num] "
229 "[-oid file]\n"
230 " [-out file] [-strparse offset]\n\n");
231 options_usage(asn1pars_options);
232}
233
234static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf);
235
236int
237asn1parse_main(int argc, char **argv)
238{
239 int i, j, ret = 1;
240 long num, tmplen;
241 BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL;
242 char *str = NULL;
243 const char *errstr = NULL;
244 unsigned char *tmpbuf;
245 const unsigned char *ctmpbuf;
246 BUF_MEM *buf = NULL;
247 ASN1_TYPE *at = NULL;
248
249 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
250 perror("pledge");
251 exit(1);
252 }
253
254 memset(&cfg, 0, sizeof(cfg));
255
256 cfg.informat = FORMAT_PEM;
257 if ((cfg.osk = sk_OPENSSL_STRING_new_null()) == NULL) {
258 BIO_printf(bio_err, "Memory allocation failure\n");
259 goto end;
260 }
261
262 if (options_parse(argc, argv, asn1pars_options, NULL, NULL) != 0) {
263 asn1pars_usage();
264 return (1);
265 }
266
267 in = BIO_new(BIO_s_file());
268 out = BIO_new(BIO_s_file());
269 if (in == NULL || out == NULL) {
270 ERR_print_errors(bio_err);
271 goto end;
272 }
273 BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
274
275 if (cfg.oidfile != NULL) {
276 if (BIO_read_filename(in, cfg.oidfile) <= 0) {
277 BIO_printf(bio_err, "problems opening %s\n",
278 cfg.oidfile);
279 ERR_print_errors(bio_err);
280 goto end;
281 }
282 OBJ_create_objects(in);
283 }
284 if (cfg.infile == NULL)
285 BIO_set_fp(in, stdin, BIO_NOCLOSE);
286 else {
287 if (BIO_read_filename(in, cfg.infile) <= 0) {
288 perror(cfg.infile);
289 goto end;
290 }
291 }
292
293 if (cfg.derfile != NULL) {
294 if ((derout = BIO_new_file(cfg.derfile, "wb")) == NULL) {
295 BIO_printf(bio_err, "problems opening %s\n",
296 cfg.derfile);
297 ERR_print_errors(bio_err);
298 goto end;
299 }
300 }
301 if ((buf = BUF_MEM_new()) == NULL)
302 goto end;
303 if (!BUF_MEM_grow(buf, BUFSIZ * 8))
304 goto end;
305
306 if (cfg.genstr != NULL || cfg.genconf) {
307 num = do_generate(bio_err, cfg.genstr, cfg.genconf, buf);
308 if (num < 0) {
309 ERR_print_errors(bio_err);
310 goto end;
311 }
312 } else {
313 if (cfg.informat == FORMAT_PEM) {
314 BIO *tmp;
315
316 if ((b64 = BIO_new(BIO_f_base64())) == NULL)
317 goto end;
318 BIO_push(b64, in);
319 tmp = in;
320 in = b64;
321 b64 = tmp;
322 }
323 num = 0;
324 for (;;) {
325 if (!BUF_MEM_grow(buf, (int) num + BUFSIZ))
326 goto end;
327 i = BIO_read(in, &(buf->data[num]), BUFSIZ);
328 if (i <= 0)
329 break;
330 num += i;
331 }
332 }
333 str = buf->data;
334
335 /* If any structs to parse go through in sequence */
336
337 if (sk_OPENSSL_STRING_num(cfg.osk) > 0) {
338 tmpbuf = (unsigned char *) str;
339 tmplen = num;
340 for (i = 0; i < sk_OPENSSL_STRING_num(cfg.osk); i++) {
341 ASN1_TYPE *atmp;
342 int typ;
343 j = strtonum(sk_OPENSSL_STRING_value(cfg.osk, i),
344 1, INT_MAX, &errstr);
345 if (errstr) {
346 BIO_printf(bio_err,
347 "'%s' is an invalid number: %s\n",
348 sk_OPENSSL_STRING_value(cfg.osk, i), errstr);
349 continue;
350 }
351 tmpbuf += j;
352 tmplen -= j;
353 atmp = at;
354 ctmpbuf = tmpbuf;
355 at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
356 ASN1_TYPE_free(atmp);
357 if (!at) {
358 BIO_printf(bio_err, "Error parsing structure\n");
359 ERR_print_errors(bio_err);
360 goto end;
361 }
362 typ = ASN1_TYPE_get(at);
363 if (typ == V_ASN1_BOOLEAN || typ == V_ASN1_NULL ||
364 typ == V_ASN1_OBJECT) {
365 BIO_printf(bio_err, "Can't parse %s type\n",
366 ASN1_tag2str(typ));
367 ERR_print_errors(bio_err);
368 goto end;
369 }
370 /* hmm... this is a little evil but it works */
371 tmpbuf = at->value.asn1_string->data;
372 tmplen = at->value.asn1_string->length;
373 }
374 str = (char *) tmpbuf;
375 num = tmplen;
376 }
377 if (cfg.offset >= num) {
378 BIO_printf(bio_err, "Error: offset too large\n");
379 goto end;
380 }
381 num -= cfg.offset;
382
383 if (cfg.length == 0 || (long)cfg.length > num)
384 cfg.length = (unsigned int) num;
385 if (derout != NULL) {
386 if (BIO_write(derout, str + cfg.offset,
387 cfg.length) != (int)cfg.length) {
388 BIO_printf(bio_err, "Error writing output\n");
389 ERR_print_errors(bio_err);
390 goto end;
391 }
392 }
393 if (!cfg.noout && !ASN1_parse_dump(out,
394 (unsigned char *)&str[cfg.offset], cfg.length, cfg.indent, cfg.dump)) {
395 ERR_print_errors(bio_err);
396 goto end;
397 }
398 ret = 0;
399 end:
400 BIO_free(derout);
401 BIO_free(in);
402 BIO_free_all(out);
403 BIO_free(b64);
404 if (ret != 0)
405 ERR_print_errors(bio_err);
406 BUF_MEM_free(buf);
407 ASN1_TYPE_free(at);
408 sk_OPENSSL_STRING_free(cfg.osk);
409 OBJ_cleanup();
410
411 return (ret);
412}
413
414static int
415do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
416{
417 CONF *cnf = NULL;
418 int len;
419 long errline;
420 unsigned char *p;
421 ASN1_TYPE *atyp = NULL;
422
423 if (genconf) {
424 cnf = NCONF_new(NULL);
425 if (!NCONF_load(cnf, genconf, &errline))
426 goto conferr;
427 if (!genstr)
428 genstr = NCONF_get_string(cnf, "default", "asn1");
429 if (!genstr) {
430 BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf);
431 goto err;
432 }
433 }
434 atyp = ASN1_generate_nconf(genstr, cnf);
435 NCONF_free(cnf);
436 cnf = NULL;
437
438 if (!atyp)
439 return -1;
440
441 len = i2d_ASN1_TYPE(atyp, NULL);
442 if (len <= 0)
443 goto err;
444
445 if (!BUF_MEM_grow(buf, len))
446 goto err;
447
448 p = (unsigned char *) buf->data;
449
450 i2d_ASN1_TYPE(atyp, &p);
451
452 ASN1_TYPE_free(atyp);
453 return len;
454
455 conferr:
456
457 if (errline > 0)
458 BIO_printf(bio, "Error on line %ld of config file '%s'\n",
459 errline, genconf);
460 else
461 BIO_printf(bio, "Error loading config file '%s'\n", genconf);
462
463 err:
464 NCONF_free(cnf);
465 ASN1_TYPE_free(atyp);
466
467 return -1;
468
469}
diff --git a/src/usr.bin/openssl/ca.c b/src/usr.bin/openssl/ca.c
deleted file mode 100644
index b644b746b9..0000000000
--- a/src/usr.bin/openssl/ca.c
+++ /dev/null
@@ -1,2797 +0,0 @@
1/* $OpenBSD: ca.c,v 1.62 2025/04/14 08:39:27 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
60
61#include <sys/types.h>
62
63#include <ctype.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <limits.h>
67#include <string.h>
68#include <unistd.h>
69
70#include "apps.h"
71
72#include <openssl/bio.h>
73#include <openssl/bn.h>
74#include <openssl/conf.h>
75#include <openssl/err.h>
76#include <openssl/evp.h>
77#include <openssl/objects.h>
78#include <openssl/ocsp.h>
79#include <openssl/pem.h>
80#include <openssl/txt_db.h>
81#include <openssl/x509.h>
82#include <openssl/x509v3.h>
83
84#define BASE_SECTION "ca"
85
86#define ENV_DEFAULT_CA "default_ca"
87
88#define STRING_MASK "string_mask"
89#define UTF8_IN "utf8"
90
91#define ENV_NEW_CERTS_DIR "new_certs_dir"
92#define ENV_CERTIFICATE "certificate"
93#define ENV_SERIAL "serial"
94#define ENV_CRLNUMBER "crlnumber"
95#define ENV_PRIVATE_KEY "private_key"
96#define ENV_DEFAULT_DAYS "default_days"
97#define ENV_DEFAULT_STARTDATE "default_startdate"
98#define ENV_DEFAULT_ENDDATE "default_enddate"
99#define ENV_DEFAULT_CRL_DAYS "default_crl_days"
100#define ENV_DEFAULT_CRL_HOURS "default_crl_hours"
101#define ENV_DEFAULT_MD "default_md"
102#define ENV_DEFAULT_EMAIL_DN "email_in_dn"
103#define ENV_PRESERVE "preserve"
104#define ENV_POLICY "policy"
105#define ENV_EXTENSIONS "x509_extensions"
106#define ENV_CRLEXT "crl_extensions"
107#define ENV_NAMEOPT "name_opt"
108#define ENV_CERTOPT "cert_opt"
109#define ENV_EXTCOPY "copy_extensions"
110#define ENV_UNIQUE_SUBJECT "unique_subject"
111
112#define ENV_DATABASE "database"
113
114/* Additional revocation information types */
115
116#define REV_NONE 0 /* No addditional information */
117#define REV_CRL_REASON 1 /* Value is CRL reason code */
118#define REV_HOLD 2 /* Value is hold instruction */
119#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
120#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
121
122static void lookup_fail(const char *name, const char *tag);
123static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
124 const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
125 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
126 unsigned long chtype, int multirdn, int email_dn, char *startdate,
127 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
128 int verbose, unsigned long certopt, unsigned long nameopt,
129 int default_op, int ext_copy, int selfsign);
130static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey,
131 X509 *x509, const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
132 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
133 unsigned long chtype, int multirdn, int email_dn, char *startdate,
134 char *enddate, long days, int batch, char *ext_sect, CONF *conf,
135 int verbose, unsigned long certopt, unsigned long nameopt, int default_op,
136 int ext_copy);
137static int write_new_certificate(BIO *bp, X509 *x, int output_der,
138 int notext);
139static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
140 const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
141 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
142 unsigned long chtype, int multirdn, int email_dn, char *startdate,
143 char *enddate, long days, int batch, int verbose, X509_REQ *req,
144 char *ext_sect, CONF *conf, unsigned long certopt, unsigned long nameopt,
145 int default_op, int ext_copy, int selfsign);
146static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
147static int get_certificate_status(const char *serial, CA_DB *db);
148static int do_updatedb(CA_DB *db);
149static int check_time_format(const char *str);
150char *make_revocation_str(int rev_type, char *rev_arg);
151int make_revoked(X509_REVOKED *rev, const char *str);
152int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
153
154static CONF *conf = NULL;
155static CONF *extconf = NULL;
156
157static struct {
158 int batch;
159 char *certfile;
160 unsigned long chtype;
161 char *configfile;
162 int create_serial;
163 char *crl_ext;
164 long crldays;
165 long crlhours;
166 long crlsec;
167 long days;
168 int dorevoke;
169 int doupdatedb;
170 int email_dn;
171 char *enddate;
172 char *extensions;
173 char *extfile;
174 int gencrl;
175 char *infile;
176 char **infiles;
177 int infiles_num;
178 char *key;
179 char *keyfile;
180 int keyform;
181 char *md;
182 int multirdn;
183 int notext;
184 char *outdir;
185 char *outfile;
186 char *passargin;
187 char *policy;
188 int preserve;
189 int req;
190 char *rev_arg;
191 int rev_type;
192 char *serial_status;
193 char *section;
194 int selfsign;
195 STACK_OF(OPENSSL_STRING) *sigopts;
196 char *ss_cert_file;
197 char *startdate;
198 char *subj;
199 int verbose;
200} cfg;
201
202static int
203ca_opt_chtype_utf8(void)
204{
205 cfg.chtype = MBSTRING_UTF8;
206 return (0);
207}
208
209static int
210ca_opt_crl_ca_compromise(char *arg)
211{
212 cfg.rev_arg = arg;
213 cfg.rev_type = REV_CA_COMPROMISE;
214 return (0);
215}
216
217static int
218ca_opt_crl_compromise(char *arg)
219{
220 cfg.rev_arg = arg;
221 cfg.rev_type = REV_KEY_COMPROMISE;
222 return (0);
223}
224
225static int
226ca_opt_crl_hold(char *arg)
227{
228 cfg.rev_arg = arg;
229 cfg.rev_type = REV_HOLD;
230 return (0);
231}
232
233static int
234ca_opt_crl_reason(char *arg)
235{
236 cfg.rev_arg = arg;
237 cfg.rev_type = REV_CRL_REASON;
238 return (0);
239}
240
241static int
242ca_opt_in(char *arg)
243{
244 cfg.infile = arg;
245 cfg.req = 1;
246 return (0);
247}
248
249static int
250ca_opt_infiles(int argc, char **argv, int *argsused)
251{
252 cfg.infiles_num = argc - 1;
253 if (cfg.infiles_num < 1)
254 return (1);
255 cfg.infiles = argv + 1;
256 cfg.req = 1;
257 *argsused = argc;
258 return (0);
259}
260
261static int
262ca_opt_revoke(char *arg)
263{
264 cfg.infile = arg;
265 cfg.dorevoke = 1;
266 return (0);
267}
268
269static int
270ca_opt_sigopt(char *arg)
271{
272 if (cfg.sigopts == NULL)
273 cfg.sigopts = sk_OPENSSL_STRING_new_null();
274 if (cfg.sigopts == NULL)
275 return (1);
276 if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
277 return (1);
278 return (0);
279}
280
281static int
282ca_opt_ss_cert(char *arg)
283{
284 cfg.ss_cert_file = arg;
285 cfg.req = 1;
286 return (0);
287}
288
289static const struct option ca_options[] = {
290 {
291 .name = "batch",
292 .desc = "Operate in batch mode",
293 .type = OPTION_FLAG,
294 .opt.flag = &cfg.batch,
295 },
296 {
297 .name = "cert",
298 .argname = "file",
299 .desc = "File containing the CA certificate",
300 .type = OPTION_ARG,
301 .opt.arg = &cfg.certfile,
302 },
303 {
304 .name = "config",
305 .argname = "file",
306 .desc = "Specify an alternative configuration file",
307 .type = OPTION_ARG,
308 .opt.arg = &cfg.configfile,
309 },
310 {
311 .name = "create_serial",
312 .desc = "If reading serial fails, create a new random serial",
313 .type = OPTION_FLAG,
314 .opt.flag = &cfg.create_serial,
315 },
316 {
317 .name = "crl_CA_compromise",
318 .argname = "time",
319 .desc = "Set the compromise time and the revocation reason to\n"
320 "CACompromise",
321 .type = OPTION_ARG_FUNC,
322 .opt.argfunc = ca_opt_crl_ca_compromise,
323 },
324 {
325 .name = "crl_compromise",
326 .argname = "time",
327 .desc = "Set the compromise time and the revocation reason to\n"
328 "keyCompromise",
329 .type = OPTION_ARG_FUNC,
330 .opt.argfunc = ca_opt_crl_compromise,
331 },
332 {
333 .name = "crl_hold",
334 .argname = "instruction",
335 .desc = "Set the hold instruction and the revocation reason to\n"
336 "certificateHold",
337 .type = OPTION_ARG_FUNC,
338 .opt.argfunc = ca_opt_crl_hold,
339 },
340 {
341 .name = "crl_reason",
342 .argname = "reason",
343 .desc = "Revocation reason",
344 .type = OPTION_ARG_FUNC,
345 .opt.argfunc = ca_opt_crl_reason,
346 },
347 {
348 .name = "crldays",
349 .argname = "days",
350 .desc = "Number of days before the next CRL is due",
351 .type = OPTION_ARG_LONG,
352 .opt.lvalue = &cfg.crldays,
353 },
354 {
355 .name = "crlexts",
356 .argname = "section",
357 .desc = "CRL extension section (override value in config file)",
358 .type = OPTION_ARG,
359 .opt.arg = &cfg.crl_ext,
360 },
361 {
362 .name = "crlhours",
363 .argname = "hours",
364 .desc = "Number of hours before the next CRL is due",
365 .type = OPTION_ARG_LONG,
366 .opt.lvalue = &cfg.crlhours,
367 },
368 {
369 .name = "crlsec",
370 .argname = "seconds",
371 .desc = "Number of seconds before the next CRL is due",
372 .type = OPTION_ARG_LONG,
373 .opt.lvalue = &cfg.crlsec,
374 },
375 {
376 .name = "days",
377 .argname = "arg",
378 .desc = "Number of days to certify the certificate for",
379 .type = OPTION_ARG_LONG,
380 .opt.lvalue = &cfg.days,
381 },
382 {
383 .name = "enddate",
384 .argname = "YYMMDDHHMMSSZ",
385 .desc = "Certificate validity notAfter (overrides -days)",
386 .type = OPTION_ARG,
387 .opt.arg = &cfg.enddate,
388 },
389 {
390 .name = "extensions",
391 .argname = "section",
392 .desc = "Extension section (override value in config file)",
393 .type = OPTION_ARG,
394 .opt.arg = &cfg.extensions,
395 },
396 {
397 .name = "extfile",
398 .argname = "file",
399 .desc = "Configuration file with X509v3 extentions to add",
400 .type = OPTION_ARG,
401 .opt.arg = &cfg.extfile,
402 },
403 {
404 .name = "gencrl",
405 .desc = "Generate a new CRL",
406 .type = OPTION_FLAG,
407 .opt.flag = &cfg.gencrl,
408 },
409 {
410 .name = "in",
411 .argname = "file",
412 .desc = "Input file containing a single certificate request",
413 .type = OPTION_ARG_FUNC,
414 .opt.argfunc = ca_opt_in,
415 },
416 {
417 .name = "infiles",
418 .argname = "...",
419 .desc = "The last argument, certificate requests to process",
420 .type = OPTION_ARGV_FUNC,
421 .opt.argvfunc = ca_opt_infiles,
422 },
423 {
424 .name = "key",
425 .argname = "password",
426 .desc = "Key to decode the private key if it is encrypted",
427 .type = OPTION_ARG,
428 .opt.arg = &cfg.key,
429 },
430 {
431 .name = "keyfile",
432 .argname = "file",
433 .desc = "Private key file",
434 .type = OPTION_ARG,
435 .opt.arg = &cfg.keyfile,
436 },
437 {
438 .name = "keyform",
439 .argname = "fmt",
440 .desc = "Private key file format (DER or PEM (default))",
441 .type = OPTION_ARG_FORMAT,
442 .opt.value = &cfg.keyform,
443 },
444 {
445 .name = "md",
446 .argname = "alg",
447 .desc = "Message digest to use",
448 .type = OPTION_ARG,
449 .opt.arg = &cfg.md,
450 },
451 {
452 .name = "multivalue-rdn",
453 .desc = "Enable support for multivalued RDNs",
454 .type = OPTION_FLAG,
455 .opt.flag = &cfg.multirdn,
456 },
457 {
458 .name = "name",
459 .argname = "section",
460 .desc = "Specifies the configuration file section to use",
461 .type = OPTION_ARG,
462 .opt.arg = &cfg.section,
463 },
464 {
465 .name = "noemailDN",
466 .desc = "Do not add the EMAIL field to the DN",
467 .type = OPTION_VALUE,
468 .opt.value = &cfg.email_dn,
469 .value = 0,
470 },
471 {
472 .name = "notext",
473 .desc = "Do not print the generated certificate",
474 .type = OPTION_FLAG,
475 .opt.flag = &cfg.notext,
476 },
477 {
478 .name = "out",
479 .argname = "file",
480 .desc = "Output file (default stdout)",
481 .type = OPTION_ARG,
482 .opt.arg = &cfg.outfile,
483 },
484 {
485 .name = "outdir",
486 .argname = "directory",
487 .desc = " Directory to output certificates to",
488 .type = OPTION_ARG,
489 .opt.arg = &cfg.outdir,
490 },
491 {
492 .name = "passin",
493 .argname = "src",
494 .desc = "Private key input password source",
495 .type = OPTION_ARG,
496 .opt.arg = &cfg.passargin,
497 },
498 {
499 .name = "policy",
500 .argname = "name",
501 .desc = "The CA 'policy' to support",
502 .type = OPTION_ARG,
503 .opt.arg = &cfg.policy,
504 },
505 {
506 .name = "preserveDN",
507 .desc = "Do not re-order the DN",
508 .type = OPTION_FLAG,
509 .opt.flag = &cfg.preserve,
510 },
511 {
512 .name = "revoke",
513 .argname = "file",
514 .desc = "Revoke a certificate (given in file)",
515 .type = OPTION_ARG_FUNC,
516 .opt.argfunc = ca_opt_revoke,
517 },
518 {
519 .name = "selfsign",
520 .desc = "Sign a certificate using the key associated with it",
521 .type = OPTION_FLAG,
522 .opt.flag = &cfg.selfsign,
523 },
524 {
525 .name = "sigopt",
526 .argname = "nm:v",
527 .desc = "Signature parameter in nm:v form",
528 .type = OPTION_ARG_FUNC,
529 .opt.argfunc = ca_opt_sigopt,
530 },
531 {
532 .name = "ss_cert",
533 .argname = "file",
534 .desc = "File contains a self signed certificate to sign",
535 .type = OPTION_ARG_FUNC,
536 .opt.argfunc = ca_opt_ss_cert,
537 },
538 {
539 .name = "startdate",
540 .argname = "YYMMDDHHMMSSZ",
541 .desc = "Certificate validity notBefore",
542 .type = OPTION_ARG,
543 .opt.arg = &cfg.startdate,
544 },
545 {
546 .name = "status",
547 .argname = "serial",
548 .desc = "Shows certificate status given the serial number",
549 .type = OPTION_ARG,
550 .opt.arg = &cfg.serial_status,
551 },
552 {
553 .name = "subj",
554 .argname = "arg",
555 .desc = "Use arg instead of request's subject",
556 .type = OPTION_ARG,
557 .opt.arg = &cfg.subj,
558 },
559 {
560 .name = "updatedb",
561 .desc = "Updates db for expired certificates",
562 .type = OPTION_FLAG,
563 .opt.flag = &cfg.doupdatedb,
564 },
565 {
566 .name = "utf8",
567 .desc = "Input characters are in UTF-8 (default ASCII)",
568 .type = OPTION_FUNC,
569 .opt.func = ca_opt_chtype_utf8,
570 },
571 {
572 .name = "verbose",
573 .desc = "Verbose output during processing",
574 .type = OPTION_FLAG,
575 .opt.flag = &cfg.verbose,
576 },
577 { NULL },
578};
579
580static void
581ca_usage(void)
582{
583 fprintf(stderr,
584 "usage: ca [-batch] [-cert file] [-config file] [-create_serial]\n"
585 " [-crl_CA_compromise time] [-crl_compromise time]\n"
586 " [-crl_hold instruction] [-crl_reason reason] [-crldays days]\n"
587 " [-crlexts section] [-crlhours hours] [-crlsec seconds]\n"
588 " [-days arg] [-enddate date] [-extensions section]\n"
589 " [-extfile file] [-gencrl] [-in file] [-infiles]\n"
590 " [-key password] [-keyfile file] [-keyform pem | der]\n"
591 " [-md alg] [-multivalue-rdn] [-name section]\n"
592 " [-noemailDN] [-notext] [-out file] [-outdir directory]\n"
593 " [-passin arg] [-policy name] [-preserveDN] [-revoke file]\n"
594 " [-selfsign] [-sigopt nm:v] [-ss_cert file]\n"
595 " [-startdate date] [-status serial] [-subj arg] [-updatedb]\n"
596 " [-utf8] [-verbose]\n\n");
597 options_usage(ca_options);
598 fprintf(stderr, "\n");
599}
600
601int
602ca_main(int argc, char **argv)
603{
604 int free_key = 0;
605 int total = 0;
606 int total_done = 0;
607 long errorline = -1;
608 EVP_PKEY *pkey = NULL;
609 int output_der = 0;
610 char *serialfile = NULL;
611 char *crlnumberfile = NULL;
612 char *tmp_email_dn = NULL;
613 BIGNUM *serial = NULL;
614 BIGNUM *crlnumber = NULL;
615 unsigned long nameopt = 0, certopt = 0;
616 int default_op = 1;
617 int ext_copy = EXT_COPY_NONE;
618 X509 *x509 = NULL, *x509p = NULL;
619 X509 *x = NULL;
620 BIO *in = NULL, *out = NULL, *Sout = NULL, *Cout = NULL;
621 char *dbfile = NULL;
622 CA_DB *db = NULL;
623 X509_CRL *crl = NULL;
624 X509_REVOKED *r = NULL;
625 ASN1_TIME *tmptm = NULL;
626 ASN1_INTEGER *tmpserial;
627 char *f;
628 const char *p;
629 char *const *pp;
630 int i, j;
631 const EVP_MD *dgst = NULL;
632 STACK_OF(CONF_VALUE) *attribs = NULL;
633 STACK_OF(X509) *cert_sk = NULL;
634 char *tofree = NULL;
635 DB_ATTR db_attr;
636 int default_nid, rv;
637 int ret = 1;
638
639 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
640 perror("pledge");
641 exit(1);
642 }
643
644 memset(&cfg, 0, sizeof(cfg));
645 cfg.email_dn = 1;
646 cfg.keyform = FORMAT_PEM;
647 cfg.chtype = MBSTRING_ASC;
648 cfg.rev_type = REV_NONE;
649
650 conf = NULL;
651
652 if (options_parse(argc, argv, ca_options, NULL, NULL) != 0) {
653 ca_usage();
654 goto err;
655 }
656
657 /*****************************************************************/
658 tofree = NULL;
659 if (cfg.configfile == NULL)
660 cfg.configfile = getenv("OPENSSL_CONF");
661 if (cfg.configfile == NULL) {
662 if ((tofree = make_config_name()) == NULL) {
663 BIO_printf(bio_err, "error making config file name\n");
664 goto err;
665 }
666 cfg.configfile = tofree;
667 }
668 BIO_printf(bio_err, "Using configuration from %s\n",
669 cfg.configfile);
670 conf = NCONF_new(NULL);
671 if (NCONF_load(conf, cfg.configfile, &errorline) <= 0) {
672 if (errorline <= 0)
673 BIO_printf(bio_err,
674 "error loading the config file '%s'\n",
675 cfg.configfile);
676 else
677 BIO_printf(bio_err,
678 "error on line %ld of config file '%s'\n",
679 errorline, cfg.configfile);
680 goto err;
681 }
682 free(tofree);
683 tofree = NULL;
684
685 /* Lets get the config section we are using */
686 if (cfg.section == NULL) {
687 cfg.section = NCONF_get_string(conf, BASE_SECTION,
688 ENV_DEFAULT_CA);
689 if (cfg.section == NULL) {
690 lookup_fail(BASE_SECTION, ENV_DEFAULT_CA);
691 goto err;
692 }
693 }
694 if (conf != NULL) {
695 p = NCONF_get_string(conf, NULL, "oid_file");
696 if (p == NULL)
697 ERR_clear_error();
698 if (p != NULL) {
699 BIO *oid_bio;
700
701 oid_bio = BIO_new_file(p, "r");
702 if (oid_bio == NULL) {
703 /*
704 BIO_printf(bio_err,
705 "problems opening %s for extra oid's\n", p);
706 ERR_print_errors(bio_err);
707 */
708 ERR_clear_error();
709 } else {
710 OBJ_create_objects(oid_bio);
711 BIO_free(oid_bio);
712 }
713 }
714 if (!add_oid_section(bio_err, conf)) {
715 ERR_print_errors(bio_err);
716 goto err;
717 }
718 }
719 f = NCONF_get_string(conf, cfg.section, STRING_MASK);
720 if (f == NULL)
721 ERR_clear_error();
722
723 if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
724 BIO_printf(bio_err,
725 "Invalid global string mask setting %s\n", f);
726 goto err;
727 }
728 if (cfg.chtype != MBSTRING_UTF8) {
729 f = NCONF_get_string(conf, cfg.section, UTF8_IN);
730 if (f == NULL)
731 ERR_clear_error();
732 else if (strcmp(f, "yes") == 0)
733 cfg.chtype = MBSTRING_UTF8;
734 }
735 db_attr.unique_subject = 1;
736 p = NCONF_get_string(conf, cfg.section, ENV_UNIQUE_SUBJECT);
737 if (p != NULL) {
738 db_attr.unique_subject = parse_yesno(p, 1);
739 } else
740 ERR_clear_error();
741
742 in = BIO_new(BIO_s_file());
743 out = BIO_new(BIO_s_file());
744 Sout = BIO_new(BIO_s_file());
745 Cout = BIO_new(BIO_s_file());
746 if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL)) {
747 ERR_print_errors(bio_err);
748 goto err;
749 }
750 /*****************************************************************/
751 /* report status of cert with serial number given on command line */
752 if (cfg.serial_status) {
753 if ((dbfile = NCONF_get_string(conf, cfg.section,
754 ENV_DATABASE)) == NULL) {
755 lookup_fail(cfg.section, ENV_DATABASE);
756 goto err;
757 }
758 db = load_index(dbfile, &db_attr);
759 if (db == NULL)
760 goto err;
761
762 if (!index_index(db))
763 goto err;
764
765 if (get_certificate_status(cfg.serial_status, db) != 1)
766 BIO_printf(bio_err, "Error verifying serial %s!\n",
767 cfg.serial_status);
768 goto err;
769 }
770 /*****************************************************************/
771 /* we definitely need a private key, so let's get it */
772
773 if ((cfg.keyfile == NULL) &&
774 ((cfg.keyfile = NCONF_get_string(conf, cfg.section,
775 ENV_PRIVATE_KEY)) == NULL)) {
776 lookup_fail(cfg.section, ENV_PRIVATE_KEY);
777 goto err;
778 }
779 if (cfg.key == NULL) {
780 free_key = 1;
781 if (!app_passwd(bio_err, cfg.passargin, NULL,
782 &cfg.key, NULL)) {
783 BIO_printf(bio_err, "Error getting password\n");
784 goto err;
785 }
786 }
787 pkey = load_key(bio_err, cfg.keyfile, cfg.keyform, 0,
788 cfg.key, "CA private key");
789 if (cfg.key != NULL)
790 explicit_bzero(cfg.key, strlen(cfg.key));
791 if (pkey == NULL) {
792 /* load_key() has already printed an appropriate message */
793 goto err;
794 }
795 /*****************************************************************/
796 /* we need a certificate */
797 if (!cfg.selfsign || cfg.ss_cert_file != NULL || cfg.gencrl) {
798 if ((cfg.certfile == NULL) &&
799 ((cfg.certfile = NCONF_get_string(conf,
800 cfg.section, ENV_CERTIFICATE)) == NULL)) {
801 lookup_fail(cfg.section, ENV_CERTIFICATE);
802 goto err;
803 }
804 x509 = load_cert(bio_err, cfg.certfile, FORMAT_PEM, NULL,
805 "CA certificate");
806 if (x509 == NULL)
807 goto err;
808
809 if (!X509_check_private_key(x509, pkey)) {
810 BIO_printf(bio_err,
811 "CA certificate and CA private key do not match\n");
812 goto err;
813 }
814 }
815 if (!cfg.selfsign)
816 x509p = x509;
817
818 f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE);
819 if (f == NULL)
820 ERR_clear_error();
821 if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
822 cfg.preserve = 1;
823
824 f = NCONF_get_string(conf, cfg.section, ENV_NAMEOPT);
825
826 if (f != NULL) {
827 if (!set_name_ex(&nameopt, f)) {
828 BIO_printf(bio_err,
829 "Invalid name options: \"%s\"\n", f);
830 goto err;
831 }
832 default_op = 0;
833 } else
834 ERR_clear_error();
835
836 f = NCONF_get_string(conf, cfg.section, ENV_CERTOPT);
837
838 if (f != NULL) {
839 if (!set_cert_ex(&certopt, f)) {
840 BIO_printf(bio_err,
841 "Invalid certificate options: \"%s\"\n", f);
842 goto err;
843 }
844 default_op = 0;
845 } else
846 ERR_clear_error();
847
848 f = NCONF_get_string(conf, cfg.section, ENV_EXTCOPY);
849
850 if (f != NULL) {
851 if (!set_ext_copy(&ext_copy, f)) {
852 BIO_printf(bio_err,
853 "Invalid extension copy option: \"%s\"\n", f);
854 goto err;
855 }
856 } else
857 ERR_clear_error();
858
859 /*****************************************************************/
860 /* lookup where to write new certificates */
861 if (cfg.outdir == NULL && cfg.req) {
862 if ((cfg.outdir = NCONF_get_string(conf,
863 cfg.section, ENV_NEW_CERTS_DIR)) == NULL) {
864 BIO_printf(bio_err, "output directory %s not defined\n",
865 ENV_NEW_CERTS_DIR);
866 goto err;
867 }
868 }
869 /*****************************************************************/
870 /* we need to load the database file */
871 if ((dbfile = NCONF_get_string(conf, cfg.section,
872 ENV_DATABASE)) == NULL) {
873 lookup_fail(cfg.section, ENV_DATABASE);
874 goto err;
875 }
876 db = load_index(dbfile, &db_attr);
877 if (db == NULL)
878 goto err;
879
880 /* Lets check some fields */
881 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
882 pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
883 if ((pp[DB_type][0] != DB_TYPE_REV) &&
884 (pp[DB_rev_date][0] != '\0')) {
885 BIO_printf(bio_err,
886 "entry %d: not revoked yet, but has a revocation date\n",
887 i + 1);
888 goto err;
889 }
890 if ((pp[DB_type][0] == DB_TYPE_REV) &&
891 !make_revoked(NULL, pp[DB_rev_date])) {
892 BIO_printf(bio_err, " in entry %d\n", i + 1);
893 goto err;
894 }
895 if (!check_time_format((char *) pp[DB_exp_date])) {
896 BIO_printf(bio_err, "entry %d: invalid expiry date\n",
897 i + 1);
898 goto err;
899 }
900 p = pp[DB_serial];
901 j = strlen(p);
902 if (*p == '-') {
903 p++;
904 j--;
905 }
906 if ((j & 1) || (j < 2)) {
907 BIO_printf(bio_err,
908 "entry %d: bad serial number length (%d)\n",
909 i + 1, j);
910 goto err;
911 }
912 while (*p) {
913 if (!(((*p >= '0') && (*p <= '9')) ||
914 ((*p >= 'A') && (*p <= 'F')) ||
915 ((*p >= 'a') && (*p <= 'f')))) {
916 BIO_printf(bio_err,
917 "entry %d: bad serial number characters, char pos %ld, char is '%c'\n",
918 i + 1, (long) (p - pp[DB_serial]), *p);
919 goto err;
920 }
921 p++;
922 }
923 }
924 if (cfg.verbose) {
925 BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
926 TXT_DB_write(out, db->db);
927 BIO_printf(bio_err, "%d entries loaded from the database\n",
928 sk_OPENSSL_PSTRING_num(db->db->data));
929 BIO_printf(bio_err, "generating index\n");
930 }
931 if (!index_index(db))
932 goto err;
933
934 /*****************************************************************/
935 /* Update the db file for expired certificates */
936 if (cfg.doupdatedb) {
937 if (cfg.verbose)
938 BIO_printf(bio_err, "Updating %s ...\n", dbfile);
939
940 i = do_updatedb(db);
941 if (i == -1) {
942 BIO_printf(bio_err, "Malloc failure\n");
943 goto err;
944 } else if (i == 0) {
945 if (cfg.verbose)
946 BIO_printf(bio_err,
947 "No entries found to mark expired\n");
948 } else {
949 if (!save_index(dbfile, "new", db))
950 goto err;
951
952 if (!rotate_index(dbfile, "new", "old"))
953 goto err;
954
955 if (cfg.verbose)
956 BIO_printf(bio_err,
957 "Done. %d entries marked as expired\n", i);
958 }
959 }
960 /*****************************************************************/
961 /* Read extentions config file */
962 if (cfg.extfile != NULL) {
963 extconf = NCONF_new(NULL);
964 if (NCONF_load(extconf, cfg.extfile, &errorline) <= 0) {
965 if (errorline <= 0)
966 BIO_printf(bio_err,
967 "ERROR: loading the config file '%s'\n",
968 cfg.extfile);
969 else
970 BIO_printf(bio_err,
971 "ERROR: on line %ld of config file '%s'\n",
972 errorline, cfg.extfile);
973 ret = 1;
974 goto err;
975 }
976 if (cfg.verbose)
977 BIO_printf(bio_err,
978 "Successfully loaded extensions file %s\n",
979 cfg.extfile);
980
981 /* We can have sections in the ext file */
982 if (cfg.extensions == NULL &&
983 (cfg.extensions = NCONF_get_string(extconf, "default",
984 "extensions")) == NULL)
985 cfg.extensions = "default";
986 }
987 /*****************************************************************/
988 if (cfg.req || cfg.gencrl) {
989 if (cfg.outfile != NULL) {
990 if (BIO_write_filename(Sout, cfg.outfile) <= 0) {
991 perror(cfg.outfile);
992 goto err;
993 }
994 } else {
995 BIO_set_fp(Sout, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
996 }
997 }
998
999 rv = EVP_PKEY_get_default_digest_nid(pkey, &default_nid);
1000 if (rv == 2 && default_nid == NID_undef) {
1001 /* The digest is required to be EVP_md_null() (EdDSA). */
1002 dgst = EVP_md_null();
1003 } else {
1004 /* Ignore rv unless we need a valid default_nid. */
1005 if (cfg.md == NULL)
1006 cfg.md = NCONF_get_string(conf, cfg.section,
1007 ENV_DEFAULT_MD);
1008 if (cfg.md == NULL) {
1009 lookup_fail(cfg.section, ENV_DEFAULT_MD);
1010 goto err;
1011 }
1012 if (strcmp(cfg.md, "default") == 0) {
1013 if (rv <= 0) {
1014 BIO_puts(bio_err, "no default digest\n");
1015 goto err;
1016 }
1017 cfg.md = (char *)OBJ_nid2sn(default_nid);
1018 }
1019 if (cfg.md == NULL)
1020 goto err;
1021 if ((dgst = EVP_get_digestbyname(cfg.md)) == NULL) {
1022 BIO_printf(bio_err, "%s is an unsupported "
1023 "message digest type\n", cfg.md);
1024 goto err;
1025 }
1026 }
1027 if (cfg.req) {
1028 if ((cfg.email_dn == 1) &&
1029 ((tmp_email_dn = NCONF_get_string(conf, cfg.section,
1030 ENV_DEFAULT_EMAIL_DN)) != NULL)) {
1031 if (strcmp(tmp_email_dn, "no") == 0)
1032 cfg.email_dn = 0;
1033 }
1034 if (cfg.verbose)
1035 BIO_printf(bio_err, "message digest is %s\n",
1036 OBJ_nid2ln(EVP_MD_type(dgst)));
1037 if ((cfg.policy == NULL) &&
1038 ((cfg.policy = NCONF_get_string(conf,
1039 cfg.section, ENV_POLICY)) == NULL)) {
1040 lookup_fail(cfg.section, ENV_POLICY);
1041 goto err;
1042 }
1043 if (cfg.verbose)
1044 BIO_printf(bio_err, "policy is %s\n", cfg.policy);
1045
1046 if ((serialfile = NCONF_get_string(conf, cfg.section,
1047 ENV_SERIAL)) == NULL) {
1048 lookup_fail(cfg.section, ENV_SERIAL);
1049 goto err;
1050 }
1051 if (extconf == NULL) {
1052 /*
1053 * no '-extfile' option, so we look for extensions in
1054 * the main configuration file
1055 */
1056 if (cfg.extensions == NULL) {
1057 cfg.extensions = NCONF_get_string(conf,
1058 cfg.section, ENV_EXTENSIONS);
1059 if (cfg.extensions == NULL)
1060 ERR_clear_error();
1061 }
1062 if (cfg.extensions != NULL) {
1063 /* Check syntax of file */
1064 X509V3_CTX ctx;
1065 X509V3_set_ctx_test(&ctx);
1066 X509V3_set_nconf(&ctx, conf);
1067 if (!X509V3_EXT_add_nconf(conf, &ctx,
1068 cfg.extensions, NULL)) {
1069 BIO_printf(bio_err,
1070 "Error Loading extension section %s\n",
1071 cfg.extensions);
1072 ret = 1;
1073 goto err;
1074 }
1075 }
1076 }
1077 if (cfg.startdate == NULL) {
1078 cfg.startdate = NCONF_get_string(conf,
1079 cfg.section, ENV_DEFAULT_STARTDATE);
1080 if (cfg.startdate == NULL)
1081 ERR_clear_error();
1082 }
1083 if (cfg.startdate == NULL)
1084 cfg.startdate = "today";
1085
1086 if (cfg.enddate == NULL) {
1087 cfg.enddate = NCONF_get_string(conf,
1088 cfg.section, ENV_DEFAULT_ENDDATE);
1089 if (cfg.enddate == NULL)
1090 ERR_clear_error();
1091 }
1092 if (cfg.days == 0 && cfg.enddate == NULL) {
1093 if (!NCONF_get_number(conf, cfg.section,
1094 ENV_DEFAULT_DAYS, &cfg.days))
1095 cfg.days = 0;
1096 }
1097 if (cfg.enddate == NULL && cfg.days == 0) {
1098 BIO_printf(bio_err,
1099 "cannot lookup how many days to certify for\n");
1100 goto err;
1101 }
1102 if ((serial = load_serial(serialfile, cfg.create_serial,
1103 NULL)) == NULL) {
1104 BIO_printf(bio_err,
1105 "error while loading serial number\n");
1106 goto err;
1107 }
1108 if (cfg.verbose) {
1109 if (BN_is_zero(serial))
1110 BIO_printf(bio_err,
1111 "next serial number is 00\n");
1112 else {
1113 if ((f = BN_bn2hex(serial)) == NULL)
1114 goto err;
1115 BIO_printf(bio_err,
1116 "next serial number is %s\n", f);
1117 free(f);
1118 }
1119 }
1120 if ((attribs = NCONF_get_section(conf, cfg.policy)) ==
1121 NULL) {
1122 BIO_printf(bio_err, "unable to find 'section' for %s\n",
1123 cfg.policy);
1124 goto err;
1125 }
1126 if ((cert_sk = sk_X509_new_null()) == NULL) {
1127 BIO_printf(bio_err, "Memory allocation failure\n");
1128 goto err;
1129 }
1130 if (cfg.ss_cert_file != NULL) {
1131 total++;
1132 j = certify_cert(&x, cfg.ss_cert_file, pkey, x509,
1133 dgst, cfg.sigopts, attribs, db, serial,
1134 cfg.subj, cfg.chtype,
1135 cfg.multirdn, cfg.email_dn,
1136 cfg.startdate, cfg.enddate,
1137 cfg.days, cfg.batch,
1138 cfg.extensions, conf, cfg.verbose,
1139 certopt, nameopt, default_op, ext_copy);
1140 if (j < 0)
1141 goto err;
1142 if (j > 0) {
1143 total_done++;
1144 BIO_printf(bio_err, "\n");
1145 if (!BN_add_word(serial, 1))
1146 goto err;
1147 if (!sk_X509_push(cert_sk, x)) {
1148 BIO_printf(bio_err,
1149 "Memory allocation failure\n");
1150 goto err;
1151 }
1152 }
1153 }
1154 if (cfg.infile != NULL) {
1155 total++;
1156 j = certify(&x, cfg.infile, pkey, x509p, dgst,
1157 cfg.sigopts, attribs, db, serial,
1158 cfg.subj, cfg.chtype,
1159 cfg.multirdn, cfg.email_dn,
1160 cfg.startdate, cfg.enddate,
1161 cfg.days, cfg.batch,
1162 cfg.extensions, conf, cfg.verbose,
1163 certopt, nameopt, default_op, ext_copy,
1164 cfg.selfsign);
1165 if (j < 0)
1166 goto err;
1167 if (j > 0) {
1168 total_done++;
1169 BIO_printf(bio_err, "\n");
1170 if (!BN_add_word(serial, 1))
1171 goto err;
1172 if (!sk_X509_push(cert_sk, x)) {
1173 BIO_printf(bio_err,
1174 "Memory allocation failure\n");
1175 goto err;
1176 }
1177 }
1178 }
1179 for (i = 0; i < cfg.infiles_num; i++) {
1180 total++;
1181 j = certify(&x, cfg.infiles[i], pkey, x509p, dgst,
1182 cfg.sigopts, attribs, db, serial,
1183 cfg.subj, cfg.chtype,
1184 cfg.multirdn, cfg.email_dn,
1185 cfg.startdate, cfg.enddate,
1186 cfg.days, cfg.batch,
1187 cfg.extensions, conf, cfg.verbose,
1188 certopt, nameopt, default_op, ext_copy,
1189 cfg.selfsign);
1190 if (j < 0)
1191 goto err;
1192 if (j > 0) {
1193 total_done++;
1194 BIO_printf(bio_err, "\n");
1195 if (!BN_add_word(serial, 1))
1196 goto err;
1197 if (!sk_X509_push(cert_sk, x)) {
1198 BIO_printf(bio_err,
1199 "Memory allocation failure\n");
1200 goto err;
1201 }
1202 }
1203 }
1204 /*
1205 * we have a stack of newly certified certificates and a data
1206 * base and serial number that need updating
1207 */
1208
1209 if (sk_X509_num(cert_sk) > 0) {
1210 if (!cfg.batch) {
1211 char answer[10];
1212
1213 BIO_printf(bio_err,
1214 "\n%d out of %d certificate requests certified, commit? [y/n]",
1215 total_done, total);
1216 (void) BIO_flush(bio_err);
1217 if (fgets(answer, sizeof answer - 1, stdin) ==
1218 NULL) {
1219 BIO_printf(bio_err,
1220 "CERTIFICATION CANCELED: I/O error\n");
1221 ret = 0;
1222 goto err;
1223 }
1224 if ((answer[0] != 'y') && (answer[0] != 'Y')) {
1225 BIO_printf(bio_err,
1226 "CERTIFICATION CANCELED\n");
1227 ret = 0;
1228 goto err;
1229 }
1230 }
1231 BIO_printf(bio_err,
1232 "Write out database with %d new entries\n",
1233 sk_X509_num(cert_sk));
1234
1235 if (!save_serial(serialfile, "new", serial, NULL))
1236 goto err;
1237
1238 if (!save_index(dbfile, "new", db))
1239 goto err;
1240 }
1241 if (cfg.verbose)
1242 BIO_printf(bio_err, "writing new certificates\n");
1243 for (i = 0; i < sk_X509_num(cert_sk); i++) {
1244 BIGNUM *bn;
1245 char *serialstr;
1246 char pempath[PATH_MAX];
1247 int k;
1248
1249 x = sk_X509_value(cert_sk, i);
1250
1251 if ((bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x),
1252 NULL)) == NULL)
1253 goto err;
1254
1255 if (BN_is_zero(bn)) {
1256 /* For consistency, BN_bn2hex(0) is 0, not 00. */
1257 serialstr = strdup("00");
1258 } else {
1259 /*
1260 * Historical behavior is to ignore the sign
1261 * that shouldn't be there anyway.
1262 */
1263 BN_set_negative(bn, 0);
1264 serialstr = BN_bn2hex(bn);
1265 }
1266 BN_free(bn);
1267
1268 if (serialstr != NULL) {
1269 k = snprintf(pempath, sizeof(pempath),
1270 "%s/%s.pem", cfg.outdir, serialstr);
1271 free(serialstr);
1272 if (k < 0 || k >= sizeof(pempath)) {
1273 BIO_printf(bio_err,
1274 "certificate file name too long\n");
1275 goto err;
1276 }
1277 } else {
1278 BIO_printf(bio_err,
1279 "memory allocation failed\n");
1280 goto err;
1281 }
1282 if (cfg.verbose)
1283 BIO_printf(bio_err, "writing %s\n", pempath);
1284
1285 if (BIO_write_filename(Cout, pempath) <= 0) {
1286 perror(pempath);
1287 goto err;
1288 }
1289 if (!write_new_certificate(Cout, x, 0,
1290 cfg.notext))
1291 goto err;
1292 if (!write_new_certificate(Sout, x, output_der,
1293 cfg.notext))
1294 goto err;
1295 }
1296
1297 if (sk_X509_num(cert_sk)) {
1298 /* Rename the database and the serial file */
1299 if (!rotate_serial(serialfile, "new", "old"))
1300 goto err;
1301
1302 if (!rotate_index(dbfile, "new", "old"))
1303 goto err;
1304
1305 BIO_printf(bio_err, "Data Base Updated\n");
1306 }
1307 }
1308 /*****************************************************************/
1309 if (cfg.gencrl) {
1310 int crl_v2 = 0;
1311 if (cfg.crl_ext == NULL) {
1312 cfg.crl_ext = NCONF_get_string(conf,
1313 cfg.section, ENV_CRLEXT);
1314 if (cfg.crl_ext == NULL)
1315 ERR_clear_error();
1316 }
1317 if (cfg.crl_ext != NULL) {
1318 /* Check syntax of file */
1319 X509V3_CTX ctx;
1320 X509V3_set_ctx_test(&ctx);
1321 X509V3_set_nconf(&ctx, conf);
1322 if (!X509V3_EXT_add_nconf(conf, &ctx, cfg.crl_ext,
1323 NULL)) {
1324 BIO_printf(bio_err,
1325 "Error Loading CRL extension section %s\n",
1326 cfg.crl_ext);
1327 ret = 1;
1328 goto err;
1329 }
1330 }
1331 if ((crlnumberfile = NCONF_get_string(conf, cfg.section,
1332 ENV_CRLNUMBER)) != NULL)
1333 if ((crlnumber = load_serial(crlnumberfile, 0,
1334 NULL)) == NULL) {
1335 BIO_printf(bio_err,
1336 "error while loading CRL number\n");
1337 goto err;
1338 }
1339 if (!cfg.crldays && !cfg.crlhours &&
1340 !cfg.crlsec) {
1341 if (!NCONF_get_number(conf, cfg.section,
1342 ENV_DEFAULT_CRL_DAYS, &cfg.crldays))
1343 cfg.crldays = 0;
1344 if (!NCONF_get_number(conf, cfg.section,
1345 ENV_DEFAULT_CRL_HOURS, &cfg.crlhours))
1346 cfg.crlhours = 0;
1347 ERR_clear_error();
1348 }
1349 if ((cfg.crldays == 0) && (cfg.crlhours == 0) &&
1350 (cfg.crlsec == 0)) {
1351 BIO_printf(bio_err,
1352 "cannot lookup how long until the next CRL is issued\n");
1353 goto err;
1354 }
1355 if (cfg.verbose)
1356 BIO_printf(bio_err, "making CRL\n");
1357 if ((crl = X509_CRL_new()) == NULL)
1358 goto err;
1359 if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509)))
1360 goto err;
1361
1362 if ((tmptm = X509_gmtime_adj(NULL, 0)) == NULL)
1363 goto err;
1364 if (!X509_CRL_set_lastUpdate(crl, tmptm))
1365 goto err;
1366 if (X509_time_adj_ex(tmptm, cfg.crldays,
1367 cfg.crlhours * 60 * 60 + cfg.crlsec, NULL) ==
1368 NULL) {
1369 BIO_puts(bio_err, "error setting CRL nextUpdate\n");
1370 goto err;
1371 }
1372 if (!X509_CRL_set_nextUpdate(crl, tmptm))
1373 goto err;
1374 ASN1_TIME_free(tmptm);
1375 tmptm = NULL;
1376
1377 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
1378 pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
1379 if (pp[DB_type][0] == DB_TYPE_REV) {
1380 if ((r = X509_REVOKED_new()) == NULL)
1381 goto err;
1382 j = make_revoked(r, pp[DB_rev_date]);
1383 if (!j)
1384 goto err;
1385 if (j == 2)
1386 crl_v2 = 1;
1387 if (!BN_hex2bn(&serial, pp[DB_serial]))
1388 goto err;
1389 tmpserial = BN_to_ASN1_INTEGER(serial, NULL);
1390 BN_free(serial);
1391 serial = NULL;
1392 if (tmpserial == NULL)
1393 goto err;
1394 if (!X509_REVOKED_set_serialNumber(r, tmpserial)) {
1395 ASN1_INTEGER_free(tmpserial);
1396 goto err;
1397 }
1398 ASN1_INTEGER_free(tmpserial);
1399 if (!X509_CRL_add0_revoked(crl, r))
1400 goto err;
1401 r = NULL;
1402 }
1403 }
1404
1405 /*
1406 * sort the data so it will be written in serial number order
1407 */
1408 X509_CRL_sort(crl);
1409
1410 /* we now have a CRL */
1411 if (cfg.verbose)
1412 BIO_printf(bio_err, "signing CRL\n");
1413
1414 /* Add any extensions asked for */
1415
1416 if (cfg.crl_ext != NULL || crlnumberfile != NULL) {
1417 X509V3_CTX crlctx;
1418 X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
1419 X509V3_set_nconf(&crlctx, conf);
1420
1421 if (cfg.crl_ext != NULL)
1422 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx,
1423 cfg.crl_ext, crl))
1424 goto err;
1425 if (crlnumberfile != NULL) {
1426 tmpserial = BN_to_ASN1_INTEGER(crlnumber, NULL);
1427 if (tmpserial == NULL)
1428 goto err;
1429 if (!X509_CRL_add1_ext_i2d(crl, NID_crl_number,
1430 tmpserial, 0, 0)) {
1431 ASN1_INTEGER_free(tmpserial);
1432 goto err;
1433 }
1434 ASN1_INTEGER_free(tmpserial);
1435 crl_v2 = 1;
1436 if (!BN_add_word(crlnumber, 1))
1437 goto err;
1438 }
1439 }
1440 if (cfg.crl_ext != NULL || crl_v2) {
1441 if (!X509_CRL_set_version(crl, 1))
1442 goto err; /* version 2 CRL */
1443 }
1444 if (crlnumberfile != NULL) /* we have a CRL number that
1445 * need updating */
1446 if (!save_serial(crlnumberfile, "new", crlnumber, NULL))
1447 goto err;
1448
1449 BN_free(crlnumber);
1450 crlnumber = NULL;
1451
1452 if (!do_X509_CRL_sign(bio_err, crl, pkey, dgst,
1453 cfg.sigopts))
1454 goto err;
1455
1456 if (!PEM_write_bio_X509_CRL(Sout, crl))
1457 goto err;
1458
1459 if (crlnumberfile != NULL) /* Rename the crlnumber file */
1460 if (!rotate_serial(crlnumberfile, "new", "old"))
1461 goto err;
1462
1463 }
1464 /*****************************************************************/
1465 if (cfg.dorevoke) {
1466 if (cfg.infile == NULL) {
1467 BIO_printf(bio_err, "no input files\n");
1468 goto err;
1469 } else {
1470 X509 *revcert;
1471 revcert = load_cert(bio_err, cfg.infile,
1472 FORMAT_PEM, NULL, cfg.infile);
1473 if (revcert == NULL)
1474 goto err;
1475 j = do_revoke(revcert, db, cfg.rev_type,
1476 cfg.rev_arg);
1477 if (j <= 0)
1478 goto err;
1479 X509_free(revcert);
1480
1481 if (!save_index(dbfile, "new", db))
1482 goto err;
1483
1484 if (!rotate_index(dbfile, "new", "old"))
1485 goto err;
1486
1487 BIO_printf(bio_err, "Data Base Updated\n");
1488 }
1489 }
1490 /*****************************************************************/
1491 ret = 0;
1492
1493 err:
1494 free(tofree);
1495
1496 BIO_free_all(Cout);
1497 BIO_free_all(Sout);
1498 BIO_free_all(out);
1499 BIO_free_all(in);
1500
1501 sk_X509_pop_free(cert_sk, X509_free);
1502
1503 if (ret)
1504 ERR_print_errors(bio_err);
1505 if (free_key)
1506 free(cfg.key);
1507 BN_free(serial);
1508 BN_free(crlnumber);
1509 free_index(db);
1510 sk_OPENSSL_STRING_free(cfg.sigopts);
1511 EVP_PKEY_free(pkey);
1512 X509_free(x509);
1513 X509_CRL_free(crl);
1514 X509_REVOKED_free(r);
1515 ASN1_TIME_free(tmptm);
1516 NCONF_free(conf);
1517 NCONF_free(extconf);
1518 OBJ_cleanup();
1519
1520 return (ret);
1521}
1522
1523static void
1524lookup_fail(const char *name, const char *tag)
1525{
1526 BIO_printf(bio_err, "variable lookup failed for %s::%s\n", name, tag);
1527}
1528
1529static int
1530certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1531 const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1532 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1533 unsigned long chtype, int multirdn, int email_dn, char *startdate,
1534 char *enddate, long days, int batch, char *ext_sect, CONF *lconf,
1535 int verbose, unsigned long certopt, unsigned long nameopt, int default_op,
1536 int ext_copy, int selfsign)
1537{
1538 X509_REQ *req = NULL;
1539 BIO *in = NULL;
1540 EVP_PKEY *pktmp = NULL;
1541 int ok = -1, i;
1542
1543 in = BIO_new(BIO_s_file());
1544
1545 if (BIO_read_filename(in, infile) <= 0) {
1546 perror(infile);
1547 goto err;
1548 }
1549 if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) {
1550 BIO_printf(bio_err, "Error reading certificate request in %s\n",
1551 infile);
1552 goto err;
1553 }
1554 if (verbose) {
1555 if (!X509_REQ_print(bio_err, req))
1556 goto err;
1557 }
1558
1559 BIO_printf(bio_err, "Check that the request matches the signature\n");
1560
1561 if (selfsign && !X509_REQ_check_private_key(req, pkey)) {
1562 BIO_printf(bio_err,
1563 "Certificate request and CA private key do not match\n");
1564 ok = 0;
1565 goto err;
1566 }
1567 if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
1568 BIO_printf(bio_err, "error unpacking public key\n");
1569 goto err;
1570 }
1571 i = X509_REQ_verify(req, pktmp);
1572 if (i < 0) {
1573 ok = 0;
1574 BIO_printf(bio_err, "Signature verification problems....\n");
1575 goto err;
1576 }
1577 if (i == 0) {
1578 ok = 0;
1579 BIO_printf(bio_err,
1580 "Signature did not match the certificate request\n");
1581 goto err;
1582 } else
1583 BIO_printf(bio_err, "Signature ok\n");
1584
1585 ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial,
1586 subj, chtype, multirdn, email_dn, startdate, enddate, days, batch,
1587 verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
1588 ext_copy, selfsign);
1589
1590 err:
1591 X509_REQ_free(req);
1592 BIO_free(in);
1593
1594 return (ok);
1595}
1596
1597static int
1598certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1599 const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1600 STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
1601 unsigned long chtype, int multirdn, int email_dn, char *startdate,
1602 char *enddate, long days, int batch, char *ext_sect, CONF *lconf,
1603 int verbose, unsigned long certopt, unsigned long nameopt, int default_op,
1604 int ext_copy)
1605{
1606 X509 *req = NULL;
1607 X509_REQ *rreq = NULL;
1608 EVP_PKEY *pktmp = NULL;
1609 int ok = -1, i;
1610
1611 if ((req = load_cert(bio_err, infile, FORMAT_PEM, NULL,
1612 infile)) == NULL)
1613 goto err;
1614 if (verbose) {
1615 if (!X509_print(bio_err, req))
1616 goto err;
1617 }
1618
1619 BIO_printf(bio_err, "Check that the request matches the signature\n");
1620
1621 if ((pktmp = X509_get0_pubkey(req)) == NULL) {
1622 BIO_printf(bio_err, "error unpacking public key\n");
1623 goto err;
1624 }
1625 i = X509_verify(req, pktmp);
1626 if (i < 0) {
1627 ok = 0;
1628 BIO_printf(bio_err, "Signature verification problems....\n");
1629 goto err;
1630 }
1631 if (i == 0) {
1632 ok = 0;
1633 BIO_printf(bio_err,
1634 "Signature did not match the certificate\n");
1635 goto err;
1636 } else
1637 BIO_printf(bio_err, "Signature ok\n");
1638
1639 if ((rreq = X509_to_X509_REQ(req, NULL, EVP_md5())) == NULL)
1640 goto err;
1641
1642 ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial,
1643 subj, chtype, multirdn, email_dn, startdate, enddate, days, batch,
1644 verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
1645 ext_copy, 0);
1646
1647 err:
1648 X509_REQ_free(rreq);
1649 X509_free(req);
1650
1651 return (ok);
1652}
1653
1654static int
1655do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1656 STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy,
1657 CA_DB *db, BIGNUM *serial, char *subj, unsigned long chtype, int multirdn,
1658 int email_dn, char *startdate, char *enddate, long days, int batch,
1659 int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1660 unsigned long certopt, unsigned long nameopt, int default_op,
1661 int ext_copy, int selfsign)
1662{
1663 X509_NAME *name = NULL, *CAname = NULL;
1664 X509_NAME *subject = NULL, *dn_subject = NULL;
1665 ASN1_UTCTIME *tm;
1666 ASN1_STRING *str, *str2;
1667 ASN1_OBJECT *obj;
1668 X509 *ret = NULL;
1669 X509_NAME_ENTRY *ne;
1670 X509_NAME_ENTRY *tne, *push;
1671 EVP_PKEY *pktmp;
1672 int ok = -1, i, j, last;
1673 const char *p;
1674 CONF_VALUE *cv;
1675 OPENSSL_STRING row[DB_NUMBER];
1676 OPENSSL_STRING *irow = NULL;
1677 OPENSSL_STRING *rrow = NULL;
1678 const STACK_OF(X509_EXTENSION) *exts;
1679
1680 *xret = NULL;
1681
1682 for (i = 0; i < DB_NUMBER; i++)
1683 row[i] = NULL;
1684
1685 if (subj != NULL) {
1686 X509_NAME *n = parse_name(subj, chtype, multirdn);
1687
1688 if (n == NULL) {
1689 ERR_print_errors(bio_err);
1690 goto err;
1691 }
1692 if (!X509_REQ_set_subject_name(req, n)) {
1693 X509_NAME_free(n);
1694 goto err;
1695 }
1696 X509_NAME_free(n);
1697 }
1698 if (default_op)
1699 BIO_printf(bio_err,
1700 "The Subject's Distinguished Name is as follows\n");
1701
1702 name = X509_REQ_get_subject_name(req);
1703 for (i = 0; i < X509_NAME_entry_count(name); i++) {
1704 ne = X509_NAME_get_entry(name, i);
1705 if (ne == NULL)
1706 goto err;
1707 str = X509_NAME_ENTRY_get_data(ne);
1708 if (str == NULL)
1709 goto err;
1710 obj = X509_NAME_ENTRY_get_object(ne);
1711 if (obj == NULL)
1712 goto err;
1713
1714 /* If no EMAIL is wanted in the subject */
1715 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
1716 continue;
1717
1718 /* check some things */
1719 if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
1720 (str->type != V_ASN1_IA5STRING)) {
1721 BIO_printf(bio_err,
1722 "\nemailAddress type needs to be of type IA5STRING\n");
1723 goto err;
1724 }
1725 if ((str->type != V_ASN1_BMPSTRING) &&
1726 (str->type != V_ASN1_UTF8STRING)) {
1727 j = ASN1_PRINTABLE_type(str->data, str->length);
1728 if (((j == V_ASN1_T61STRING) &&
1729 (str->type != V_ASN1_T61STRING)) ||
1730 ((j == V_ASN1_IA5STRING) &&
1731 (str->type == V_ASN1_PRINTABLESTRING))) {
1732 BIO_printf(bio_err,
1733 "\nThe string contains characters that are illegal for the ASN.1 type\n");
1734 goto err;
1735 }
1736 }
1737 if (default_op)
1738 old_entry_print(bio_err, obj, str);
1739 }
1740
1741 /* Ok, now we check the 'policy' stuff. */
1742 if ((subject = X509_NAME_new()) == NULL) {
1743 BIO_printf(bio_err, "Memory allocation failure\n");
1744 goto err;
1745 }
1746 /* take a copy of the issuer name before we mess with it. */
1747 if (selfsign)
1748 CAname = X509_NAME_dup(name);
1749 else
1750 CAname = X509_NAME_dup(X509_get_subject_name(x509));
1751 if (CAname == NULL)
1752 goto err;
1753 str = str2 = NULL;
1754
1755 for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
1756 cv = sk_CONF_VALUE_value(policy, i); /* get the object id */
1757 if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
1758 BIO_printf(bio_err,
1759 "%s:unknown object type in 'policy' configuration\n",
1760 cv->name);
1761 goto err;
1762 }
1763 obj = OBJ_nid2obj(j);
1764 if (obj == NULL)
1765 goto err;
1766
1767 last = -1;
1768 for (;;) {
1769 /* lookup the object in the supplied name list */
1770 j = X509_NAME_get_index_by_OBJ(name, obj, last);
1771 if (j < 0) {
1772 if (last != -1)
1773 break;
1774 tne = NULL;
1775 } else {
1776 tne = X509_NAME_get_entry(name, j);
1777 if (tne == NULL)
1778 goto err;
1779 }
1780 last = j;
1781
1782 /* depending on the 'policy', decide what to do. */
1783 push = NULL;
1784 if (strcmp(cv->value, "optional") == 0) {
1785 if (tne != NULL)
1786 push = tne;
1787 } else if (strcmp(cv->value, "supplied") == 0) {
1788 if (tne == NULL) {
1789 BIO_printf(bio_err,
1790 "The %s field needed to be supplied and was missing\n",
1791 cv->name);
1792 goto err;
1793 } else
1794 push = tne;
1795 } else if (strcmp(cv->value, "match") == 0) {
1796 int last2;
1797
1798 if (tne == NULL) {
1799 BIO_printf(bio_err,
1800 "The mandatory %s field was missing\n",
1801 cv->name);
1802 goto err;
1803 }
1804 last2 = -1;
1805
1806 again2:
1807 j = X509_NAME_get_index_by_OBJ(CAname, obj,
1808 last2);
1809 if ((j < 0) && (last2 == -1)) {
1810 BIO_printf(bio_err,
1811 "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",
1812 cv->name);
1813 goto err;
1814 }
1815 if (j >= 0) {
1816 push = X509_NAME_get_entry(CAname, j);
1817 if (push == NULL)
1818 goto err;
1819 str = X509_NAME_ENTRY_get_data(tne);
1820 if (str == NULL)
1821 goto err;
1822 str2 = X509_NAME_ENTRY_get_data(push);
1823 if (str2 == NULL)
1824 goto err;
1825 last2 = j;
1826 if (ASN1_STRING_cmp(str, str2) != 0)
1827 goto again2;
1828 }
1829 if (j < 0) {
1830 BIO_printf(bio_err,
1831 "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",
1832 cv->name, ((str2 == NULL) ?
1833 "NULL" : (char *) str2->data),
1834 ((str == NULL) ?
1835 "NULL" : (char *) str->data));
1836 goto err;
1837 }
1838 } else {
1839 BIO_printf(bio_err,
1840 "%s:invalid type in 'policy' configuration\n",
1841 cv->value);
1842 goto err;
1843 }
1844
1845 if (push != NULL) {
1846 if (!X509_NAME_add_entry(subject, push,
1847 -1, 0)) {
1848 X509_NAME_ENTRY_free(push);
1849 BIO_printf(bio_err,
1850 "Memory allocation failure\n");
1851 goto err;
1852 }
1853 }
1854 if (j < 0)
1855 break;
1856 }
1857 }
1858
1859 if (cfg.preserve) {
1860 X509_NAME_free(subject);
1861 /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
1862 subject = X509_NAME_dup(name);
1863 if (subject == NULL)
1864 goto err;
1865 }
1866
1867 /* We are now totally happy, lets make and sign the certificate */
1868 if (verbose)
1869 BIO_printf(bio_err,
1870 "Everything appears to be ok, creating and signing the certificate\n");
1871
1872 if ((ret = X509_new()) == NULL)
1873 goto err;
1874
1875#ifdef X509_V3
1876 /* Make it an X509 v3 certificate. */
1877 if (!X509_set_version(ret, 2))
1878 goto err;
1879#endif
1880 if (X509_get_serialNumber(ret) == NULL)
1881 goto err;
1882 if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
1883 goto err;
1884 if (selfsign) {
1885 if (!X509_set_issuer_name(ret, subject))
1886 goto err;
1887 } else {
1888 if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
1889 goto err;
1890 }
1891
1892 if (strcmp(startdate, "today") == 0) {
1893 if (X509_gmtime_adj(X509_get_notBefore(ret), 0) == NULL)
1894 goto err;
1895 } else if (!ASN1_TIME_set_string_X509(X509_get_notBefore(ret), startdate)) {
1896 BIO_printf(bio_err, "Invalid start date %s\n", startdate);
1897 goto err;
1898 }
1899
1900 if (enddate == NULL) {
1901 if (X509_time_adj_ex(X509_get_notAfter(ret), days, 0,
1902 NULL) == NULL)
1903 goto err;
1904 } else if (!ASN1_TIME_set_string_X509(X509_get_notAfter(ret), enddate)) {
1905 BIO_printf(bio_err, "Invalid end date %s\n", enddate);
1906 goto err;
1907 }
1908
1909 if (!X509_set_subject_name(ret, subject))
1910 goto err;
1911
1912 if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL)
1913 goto err;
1914
1915 if (!X509_set_pubkey(ret, pktmp))
1916 goto err;
1917
1918 /* Lets add the extensions, if there are any */
1919 if (ext_sect != NULL) {
1920 X509V3_CTX ctx;
1921
1922 /* Initialize the context structure */
1923 if (selfsign)
1924 X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
1925 else
1926 X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1927
1928 if (extconf != NULL) {
1929 if (verbose)
1930 BIO_printf(bio_err,
1931 "Extra configuration file found\n");
1932
1933 /* Use the extconf configuration db LHASH */
1934 X509V3_set_nconf(&ctx, extconf);
1935
1936 /* Test the structure (needed?) */
1937 /* X509V3_set_ctx_test(&ctx); */
1938
1939 /* Adds exts contained in the configuration file */
1940 if (!X509V3_EXT_add_nconf(extconf, &ctx,
1941 ext_sect, ret)) {
1942 BIO_printf(bio_err,
1943 "ERROR: adding extensions in section %s\n",
1944 ext_sect);
1945 ERR_print_errors(bio_err);
1946 goto err;
1947 }
1948 if (verbose)
1949 BIO_printf(bio_err,
1950 "Successfully added extensions from file.\n");
1951 } else if (ext_sect != NULL) {
1952 /* We found extensions to be set from config file */
1953 X509V3_set_nconf(&ctx, lconf);
1954
1955 if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
1956 BIO_printf(bio_err,
1957 "ERROR: adding extensions in section %s\n",
1958 ext_sect);
1959 ERR_print_errors(bio_err);
1960 goto err;
1961 }
1962 if (verbose)
1963 BIO_printf(bio_err,
1964 "Successfully added extensions from config\n");
1965 }
1966 }
1967
1968 /* Copy extensions from request (if any) */
1969 if (!copy_extensions(ret, req, ext_copy)) {
1970 BIO_printf(bio_err, "ERROR: adding extensions from request\n");
1971 ERR_print_errors(bio_err);
1972 goto err;
1973 }
1974
1975 exts = X509_get0_extensions(ret);
1976 if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0) {
1977 /* Make it an X509 v3 certificate. */
1978 if (!X509_set_version(ret, 2))
1979 goto err;
1980 }
1981
1982 if (verbose)
1983 BIO_printf(bio_err,
1984 "The subject name appears to be ok, checking data base for clashes\n");
1985
1986 /* Build the correct Subject if no email is wanted in the subject */
1987 if (!email_dn) {
1988 X509_NAME_ENTRY *tmpne;
1989 /*
1990 * Its best to dup the subject DN and then delete any email
1991 * addresses because this retains its structure.
1992 */
1993 if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
1994 BIO_printf(bio_err, "Memory allocation failure\n");
1995 goto err;
1996 }
1997 while ((i = X509_NAME_get_index_by_NID(dn_subject,
1998 NID_pkcs9_emailAddress, -1)) >= 0) {
1999 tmpne = X509_NAME_get_entry(dn_subject, i);
2000 if (tmpne == NULL)
2001 goto err;
2002 if (X509_NAME_delete_entry(dn_subject, i) == NULL) {
2003 X509_NAME_ENTRY_free(tmpne);
2004 goto err;
2005 }
2006 X509_NAME_ENTRY_free(tmpne);
2007 }
2008
2009 if (!X509_set_subject_name(ret, dn_subject))
2010 goto err;
2011
2012 X509_NAME_free(dn_subject);
2013 dn_subject = NULL;
2014 }
2015
2016 row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
2017 if (row[DB_name] == NULL) {
2018 BIO_printf(bio_err, "Memory allocation failure\n");
2019 goto err;
2020 }
2021
2022 if (BN_is_zero(serial))
2023 row[DB_serial] = strdup("00");
2024 else
2025 row[DB_serial] = BN_bn2hex(serial);
2026 if (row[DB_serial] == NULL) {
2027 BIO_printf(bio_err, "Memory allocation failure\n");
2028 goto err;
2029 }
2030
2031 if (row[DB_name][0] == '\0') {
2032 /*
2033 * An empty subject! We'll use the serial number instead. If
2034 * unique_subject is in use then we don't want different
2035 * entries with empty subjects matching each other.
2036 */
2037 free(row[DB_name]);
2038 row[DB_name] = strdup(row[DB_serial]);
2039 if (row[DB_name] == NULL) {
2040 BIO_printf(bio_err, "Memory allocation failure\n");
2041 goto err;
2042 }
2043 }
2044
2045 if (db->attributes.unique_subject) {
2046 OPENSSL_STRING *crow = row;
2047
2048 rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
2049 if (rrow != NULL) {
2050 BIO_printf(bio_err,
2051 "ERROR:There is already a certificate for %s\n",
2052 row[DB_name]);
2053 }
2054 }
2055 if (rrow == NULL) {
2056 rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2057 if (rrow != NULL) {
2058 BIO_printf(bio_err,
2059 "ERROR:Serial number %s has already been issued,\n",
2060 row[DB_serial]);
2061 BIO_printf(bio_err,
2062 " check the database/serial_file for corruption\n");
2063 }
2064 }
2065 if (rrow != NULL) {
2066 BIO_printf(bio_err,
2067 "The matching entry has the following details\n");
2068 if (rrow[DB_type][0] == DB_TYPE_EXP)
2069 p = "Expired";
2070 else if (rrow[DB_type][0] == DB_TYPE_REV)
2071 p = "Revoked";
2072 else if (rrow[DB_type][0] == DB_TYPE_VAL)
2073 p = "Valid";
2074 else
2075 p = "\ninvalid type, Data base error\n";
2076 BIO_printf(bio_err, "Type :%s\n", p);
2077 if (rrow[DB_type][0] == DB_TYPE_REV) {
2078 p = rrow[DB_exp_date];
2079 if (p == NULL)
2080 p = "undef";
2081 BIO_printf(bio_err, "Was revoked on:%s\n", p);
2082 }
2083 p = rrow[DB_exp_date];
2084 if (p == NULL)
2085 p = "undef";
2086 BIO_printf(bio_err, "Expires on :%s\n", p);
2087 p = rrow[DB_serial];
2088 if (p == NULL)
2089 p = "undef";
2090 BIO_printf(bio_err, "Serial Number :%s\n", p);
2091 p = rrow[DB_file];
2092 if (p == NULL)
2093 p = "undef";
2094 BIO_printf(bio_err, "File name :%s\n", p);
2095 p = rrow[DB_name];
2096 if (p == NULL)
2097 p = "undef";
2098 BIO_printf(bio_err, "Subject Name :%s\n", p);
2099 ok = -1; /* This is now a 'bad' error. */
2100 goto err;
2101 }
2102
2103 if (!default_op) {
2104 BIO_printf(bio_err, "Certificate Details:\n");
2105 /*
2106 * Never print signature details because signature not
2107 * present
2108 */
2109 certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
2110 if (!X509_print_ex(bio_err, ret, nameopt, certopt))
2111 goto err;
2112 }
2113 BIO_printf(bio_err, "Certificate is to be certified until ");
2114 ASN1_TIME_print(bio_err, X509_get_notAfter(ret));
2115 if (days)
2116 BIO_printf(bio_err, " (%ld days)", days);
2117 BIO_printf(bio_err, "\n");
2118
2119 if (!batch) {
2120 char answer[25];
2121
2122 BIO_printf(bio_err, "Sign the certificate? [y/n]:");
2123 (void) BIO_flush(bio_err);
2124 if (!fgets(answer, sizeof(answer) - 1, stdin)) {
2125 BIO_printf(bio_err,
2126 "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
2127 ok = 0;
2128 goto err;
2129 }
2130 if (!((answer[0] == 'y') || (answer[0] == 'Y'))) {
2131 BIO_printf(bio_err,
2132 "CERTIFICATE WILL NOT BE CERTIFIED\n");
2133 ok = 0;
2134 goto err;
2135 }
2136 }
2137
2138 if ((pktmp = X509_get0_pubkey(ret)) == NULL)
2139 goto err;
2140
2141 if (EVP_PKEY_missing_parameters(pktmp) &&
2142 !EVP_PKEY_missing_parameters(pkey)) {
2143 if (!EVP_PKEY_copy_parameters(pktmp, pkey)) {
2144 goto err;
2145 }
2146 }
2147
2148 if (!do_X509_sign(bio_err, ret, pkey, dgst, sigopts))
2149 goto err;
2150
2151 /* We now just add it to the database */
2152 row[DB_type] = malloc(2);
2153
2154 if ((tm = X509_get_notAfter(ret)) == NULL)
2155 goto err;
2156 row[DB_exp_date] = strndup(tm->data, tm->length);
2157 if (row[DB_type] == NULL || row[DB_exp_date] == NULL) {
2158 BIO_printf(bio_err, "Memory allocation failure\n");
2159 goto err;
2160 }
2161
2162 row[DB_rev_date] = NULL;
2163
2164 /* row[DB_serial] done already */
2165 row[DB_file] = malloc(8);
2166
2167 if ((row[DB_type] == NULL) || (row[DB_file] == NULL) ||
2168 (row[DB_name] == NULL)) {
2169 BIO_printf(bio_err, "Memory allocation failure\n");
2170 goto err;
2171 }
2172 (void) strlcpy(row[DB_file], "unknown", 8);
2173 row[DB_type][0] = DB_TYPE_VAL;
2174 row[DB_type][1] = '\0';
2175
2176 if ((irow = reallocarray(NULL, DB_NUMBER + 1, sizeof(char *))) ==
2177 NULL) {
2178 BIO_printf(bio_err, "Memory allocation failure\n");
2179 goto err;
2180 }
2181 for (i = 0; i < DB_NUMBER; i++) {
2182 irow[i] = row[i];
2183 row[i] = NULL;
2184 }
2185 irow[DB_NUMBER] = NULL;
2186
2187 if (!TXT_DB_insert(db->db, irow)) {
2188 BIO_printf(bio_err, "failed to update database\n");
2189 BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
2190 goto err;
2191 }
2192
2193 *xret = ret;
2194 ret = NULL;
2195 ok = 1;
2196
2197 err:
2198 for (i = 0; i < DB_NUMBER; i++)
2199 free(row[i]);
2200
2201 X509_NAME_free(CAname);
2202 X509_NAME_free(subject);
2203 X509_NAME_free(dn_subject);
2204 X509_free(ret);
2205
2206 return (ok);
2207}
2208
2209static int
2210write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
2211{
2212 if (output_der) {
2213 if (!i2d_X509_bio(bp, x))
2214 return (0);
2215 }
2216 if (!notext) {
2217 if (!X509_print(bp, x))
2218 return (0);
2219 }
2220
2221 return PEM_write_bio_X509(bp, x);
2222}
2223
2224static int
2225check_time_format(const char *str)
2226{
2227 return ASN1_TIME_set_string(NULL, str);
2228}
2229
2230static int
2231do_revoke(X509 *x509, CA_DB *db, int type, char *value)
2232{
2233 ASN1_UTCTIME *tm = NULL;
2234 char *row[DB_NUMBER], **rrow, **irow;
2235 char *rev_str = NULL;
2236 BIGNUM *bn = NULL;
2237 int ok = -1, i;
2238
2239 for (i = 0; i < DB_NUMBER; i++)
2240 row[i] = NULL;
2241 row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0);
2242 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL);
2243 if (bn == NULL)
2244 goto err;
2245 if (BN_is_zero(bn))
2246 row[DB_serial] = strdup("00");
2247 else
2248 row[DB_serial] = BN_bn2hex(bn);
2249 BN_free(bn);
2250
2251 if (row[DB_name] != NULL && row[DB_name][0] == '\0') {
2252 /*
2253 * Entries with empty Subjects actually use the serial number
2254 * instead
2255 */
2256 free(row[DB_name]);
2257 row[DB_name] = strdup(row[DB_serial]);
2258 if (row[DB_name] == NULL) {
2259 BIO_printf(bio_err, "Memory allocation failure\n");
2260 goto err;
2261 }
2262 }
2263
2264 if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
2265 BIO_printf(bio_err, "Memory allocation failure\n");
2266 goto err;
2267 }
2268 /*
2269 * We have to lookup by serial number because name lookup skips
2270 * revoked certs
2271 */
2272 rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2273 if (rrow == NULL) {
2274 BIO_printf(bio_err,
2275 "Adding Entry with serial number %s to DB for %s\n",
2276 row[DB_serial], row[DB_name]);
2277
2278 /* We now just add it to the database */
2279 row[DB_type] = malloc(2);
2280
2281 if ((tm = X509_get_notAfter(x509)) == NULL)
2282 goto err;
2283 row[DB_exp_date] = strndup(tm->data, tm->length);
2284 if (row[DB_type] == NULL || row[DB_exp_date] == NULL) {
2285 BIO_printf(bio_err, "Memory allocation failure\n");
2286 goto err;
2287 }
2288
2289 row[DB_rev_date] = NULL;
2290
2291 /* row[DB_serial] done already */
2292 row[DB_file] = malloc(8);
2293
2294 /* row[DB_name] done already */
2295
2296 if ((row[DB_type] == NULL) || (row[DB_file] == NULL)) {
2297 BIO_printf(bio_err, "Memory allocation failure\n");
2298 goto err;
2299 }
2300 (void) strlcpy(row[DB_file], "unknown", 8);
2301 row[DB_type][0] = DB_TYPE_VAL;
2302 row[DB_type][1] = '\0';
2303
2304 if ((irow = reallocarray(NULL, sizeof(char *),
2305 (DB_NUMBER + 1))) == NULL) {
2306 BIO_printf(bio_err, "Memory allocation failure\n");
2307 goto err;
2308 }
2309 for (i = 0; i < DB_NUMBER; i++) {
2310 irow[i] = row[i];
2311 row[i] = NULL;
2312 }
2313 irow[DB_NUMBER] = NULL;
2314
2315 if (!TXT_DB_insert(db->db, irow)) {
2316 BIO_printf(bio_err, "failed to update database\n");
2317 BIO_printf(bio_err, "TXT_DB error number %ld\n",
2318 db->db->error);
2319 goto err;
2320 }
2321 /* Revoke Certificate */
2322 ok = do_revoke(x509, db, type, value);
2323
2324 goto err;
2325
2326 } else if (index_name_cmp_noconst(row, rrow)) {
2327 BIO_printf(bio_err, "ERROR:name does not match %s\n",
2328 row[DB_name]);
2329 goto err;
2330 } else if (rrow[DB_type][0] == DB_TYPE_REV) {
2331 BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
2332 row[DB_serial]);
2333 goto err;
2334 } else {
2335 BIO_printf(bio_err, "Revoking Certificate %s.\n",
2336 rrow[DB_serial]);
2337 rev_str = make_revocation_str(type, value);
2338 if (rev_str == NULL) {
2339 BIO_printf(bio_err, "Error in revocation arguments\n");
2340 goto err;
2341 }
2342 rrow[DB_type][0] = DB_TYPE_REV;
2343 rrow[DB_type][1] = '\0';
2344 rrow[DB_rev_date] = rev_str;
2345 }
2346 ok = 1;
2347
2348 err:
2349 for (i = 0; i < DB_NUMBER; i++)
2350 free(row[i]);
2351
2352 return (ok);
2353}
2354
2355static int
2356get_certificate_status(const char *serial, CA_DB *db)
2357{
2358 char *row[DB_NUMBER], **rrow;
2359 int ok = -1, i;
2360
2361 /* Free Resources */
2362 for (i = 0; i < DB_NUMBER; i++)
2363 row[i] = NULL;
2364
2365 /* Malloc needed char spaces */
2366 row[DB_serial] = malloc(strlen(serial) + 2);
2367 if (row[DB_serial] == NULL) {
2368 BIO_printf(bio_err, "Malloc failure\n");
2369 goto err;
2370 }
2371 if (strlen(serial) % 2) {
2372 row[DB_serial][0] = '0';
2373
2374 /* Copy String from serial to row[DB_serial] */
2375 memcpy(row[DB_serial] + 1, serial, strlen(serial));
2376 row[DB_serial][strlen(serial) + 1] = '\0';
2377 } else {
2378 /* Copy String from serial to row[DB_serial] */
2379 memcpy(row[DB_serial], serial, strlen(serial));
2380 row[DB_serial][strlen(serial)] = '\0';
2381 }
2382
2383 /* Make it Upper Case */
2384 for (i = 0; row[DB_serial][i] != '\0'; i++)
2385 row[DB_serial][i] = toupper((unsigned char) row[DB_serial][i]);
2386
2387
2388 ok = 1;
2389
2390 /* Search for the certificate */
2391 rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
2392 if (rrow == NULL) {
2393 BIO_printf(bio_err, "Serial %s not present in db.\n",
2394 row[DB_serial]);
2395 ok = -1;
2396 goto err;
2397 } else if (rrow[DB_type][0] == DB_TYPE_VAL) {
2398 BIO_printf(bio_err, "%s=Valid (%c)\n",
2399 row[DB_serial], rrow[DB_type][0]);
2400 goto err;
2401 } else if (rrow[DB_type][0] == DB_TYPE_REV) {
2402 BIO_printf(bio_err, "%s=Revoked (%c)\n",
2403 row[DB_serial], rrow[DB_type][0]);
2404 goto err;
2405 } else if (rrow[DB_type][0] == DB_TYPE_EXP) {
2406 BIO_printf(bio_err, "%s=Expired (%c)\n",
2407 row[DB_serial], rrow[DB_type][0]);
2408 goto err;
2409 } else if (rrow[DB_type][0] == DB_TYPE_SUSP) {
2410 BIO_printf(bio_err, "%s=Suspended (%c)\n",
2411 row[DB_serial], rrow[DB_type][0]);
2412 goto err;
2413 } else {
2414 BIO_printf(bio_err, "%s=Unknown (%c).\n",
2415 row[DB_serial], rrow[DB_type][0]);
2416 ok = -1;
2417 }
2418
2419 err:
2420 for (i = 0; i < DB_NUMBER; i++)
2421 free(row[i]);
2422
2423 return (ok);
2424}
2425
2426static int
2427do_updatedb(CA_DB *db)
2428{
2429 ASN1_UTCTIME *a_tm = NULL;
2430 int i, cnt = 0;
2431 int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */
2432 char **rrow, *a_tm_s = NULL;
2433
2434 a_tm = ASN1_UTCTIME_new();
2435 if (a_tm == NULL) {
2436 cnt = -1;
2437 goto err;
2438 }
2439
2440 /* get actual time and make a string */
2441 a_tm = X509_gmtime_adj(a_tm, 0);
2442 if (a_tm == NULL) {
2443 cnt = -1;
2444 goto err;
2445 }
2446 a_tm_s = strndup(a_tm->data, a_tm->length);
2447 if (a_tm_s == NULL) {
2448 cnt = -1;
2449 goto err;
2450 }
2451
2452 if (strncmp(a_tm_s, "49", 2) <= 0)
2453 a_y2k = 1;
2454 else
2455 a_y2k = 0;
2456
2457 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
2458 rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
2459
2460 if (rrow[DB_type][0] == DB_TYPE_VAL) {
2461 /* ignore entries that are not valid */
2462 if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
2463 db_y2k = 1;
2464 else
2465 db_y2k = 0;
2466
2467 if (db_y2k == a_y2k) {
2468 /* all on the same y2k side */
2469 if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) {
2470 rrow[DB_type][0] = DB_TYPE_EXP;
2471 rrow[DB_type][1] = '\0';
2472 cnt++;
2473
2474 BIO_printf(bio_err, "%s=Expired\n",
2475 rrow[DB_serial]);
2476 }
2477 } else if (db_y2k < a_y2k) {
2478 rrow[DB_type][0] = DB_TYPE_EXP;
2479 rrow[DB_type][1] = '\0';
2480 cnt++;
2481
2482 BIO_printf(bio_err, "%s=Expired\n",
2483 rrow[DB_serial]);
2484 }
2485 }
2486 }
2487
2488 err:
2489 ASN1_UTCTIME_free(a_tm);
2490 free(a_tm_s);
2491
2492 return (cnt);
2493}
2494
2495static const char *crl_reasons[] = {
2496 /* CRL reason strings */
2497 "unspecified",
2498 "keyCompromise",
2499 "CACompromise",
2500 "affiliationChanged",
2501 "superseded",
2502 "cessationOfOperation",
2503 "certificateHold",
2504 "removeFromCRL",
2505 /* Additional pseudo reasons */
2506 "holdInstruction",
2507 "keyTime",
2508 "CAkeyTime"
2509};
2510
2511#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
2512
2513/* Given revocation information convert to a DB string.
2514 * The format of the string is:
2515 * revtime[,reason,extra]. Where 'revtime' is the
2516 * revocation time (the current time). 'reason' is the
2517 * optional CRL reason and 'extra' is any additional
2518 * argument
2519 */
2520
2521char *
2522make_revocation_str(int rev_type, char *rev_arg)
2523{
2524 char *other = NULL, *str;
2525 const char *reason = NULL;
2526 ASN1_OBJECT *otmp;
2527 ASN1_UTCTIME *revtm = NULL;
2528 int i;
2529 switch (rev_type) {
2530 case REV_NONE:
2531 break;
2532
2533 case REV_CRL_REASON:
2534 for (i = 0; i < 8; i++) {
2535 if (strcasecmp(rev_arg, crl_reasons[i]) == 0) {
2536 reason = crl_reasons[i];
2537 break;
2538 }
2539 }
2540 if (reason == NULL) {
2541 BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
2542 return NULL;
2543 }
2544 break;
2545
2546 case REV_HOLD:
2547 /* Argument is an OID */
2548 otmp = OBJ_txt2obj(rev_arg, 0);
2549 ASN1_OBJECT_free(otmp);
2550
2551 if (otmp == NULL) {
2552 BIO_printf(bio_err,
2553 "Invalid object identifier %s\n", rev_arg);
2554 return NULL;
2555 }
2556 reason = "holdInstruction";
2557 other = rev_arg;
2558 break;
2559
2560 case REV_KEY_COMPROMISE:
2561 case REV_CA_COMPROMISE:
2562 /* Argument is the key compromise time */
2563 if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
2564 BIO_printf(bio_err,
2565 "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n",
2566 rev_arg);
2567 return NULL;
2568 }
2569 other = rev_arg;
2570 if (rev_type == REV_KEY_COMPROMISE)
2571 reason = "keyTime";
2572 else
2573 reason = "CAkeyTime";
2574
2575 break;
2576 }
2577
2578 revtm = X509_gmtime_adj(NULL, 0);
2579 if (revtm == NULL)
2580 return NULL;
2581
2582 if (asprintf(&str, "%s%s%s%s%s", revtm->data,
2583 reason ? "," : "", reason ? reason : "",
2584 other ? "," : "", other ? other : "") == -1)
2585 str = NULL;
2586
2587 ASN1_UTCTIME_free(revtm);
2588
2589 return str;
2590}
2591
2592/* Convert revocation field to X509_REVOKED entry
2593 * return code:
2594 * 0 error
2595 * 1 OK
2596 * 2 OK and some extensions added (i.e. V2 CRL)
2597 */
2598
2599int
2600make_revoked(X509_REVOKED *rev, const char *str)
2601{
2602 char *tmp = NULL;
2603 int reason_code = -1;
2604 int i, ret = 0;
2605 ASN1_OBJECT *hold = NULL;
2606 ASN1_GENERALIZEDTIME *comp_time = NULL;
2607 ASN1_ENUMERATED *rtmp = NULL;
2608
2609 ASN1_TIME *revDate = NULL;
2610
2611 i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
2612
2613 if (i == 0)
2614 goto err;
2615
2616 if (rev != NULL && !X509_REVOKED_set_revocationDate(rev, revDate))
2617 goto err;
2618
2619 if (rev != NULL && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) {
2620 rtmp = ASN1_ENUMERATED_new();
2621 if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code))
2622 goto err;
2623 if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
2624 goto err;
2625 }
2626 if (rev != NULL && comp_time != NULL) {
2627 if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date,
2628 comp_time, 0, 0))
2629 goto err;
2630 }
2631 if (rev != NULL && hold != NULL) {
2632 if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code,
2633 hold, 0, 0))
2634 goto err;
2635 }
2636 if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
2637 ret = 2;
2638 else
2639 ret = 1;
2640
2641 err:
2642 free(tmp);
2643
2644 ASN1_OBJECT_free(hold);
2645 ASN1_GENERALIZEDTIME_free(comp_time);
2646 ASN1_ENUMERATED_free(rtmp);
2647 ASN1_TIME_free(revDate);
2648
2649 return ret;
2650}
2651
2652int
2653old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2654{
2655 char buf[25], *pbuf, *p;
2656 int j;
2657
2658 j = i2a_ASN1_OBJECT(bp, obj);
2659 pbuf = buf;
2660 for (j = 22 - j; j > 0; j--)
2661 *(pbuf++) = ' ';
2662 *(pbuf++) = ':';
2663 *(pbuf++) = '\0';
2664 BIO_puts(bp, buf);
2665
2666 if (str->type == V_ASN1_PRINTABLESTRING)
2667 BIO_printf(bp, "PRINTABLE:'");
2668 else if (str->type == V_ASN1_T61STRING)
2669 BIO_printf(bp, "T61STRING:'");
2670 else if (str->type == V_ASN1_IA5STRING)
2671 BIO_printf(bp, "IA5STRING:'");
2672 else if (str->type == V_ASN1_UNIVERSALSTRING)
2673 BIO_printf(bp, "UNIVERSALSTRING:'");
2674 else
2675 BIO_printf(bp, "ASN.1 %2d:'", str->type);
2676
2677 p = (char *) str->data;
2678 for (j = str->length; j > 0; j--) {
2679 if ((*p >= ' ') && (*p <= '~'))
2680 BIO_printf(bp, "%c", *p);
2681 else if (*p & 0x80)
2682 BIO_printf(bp, "\\0x%02X", *p);
2683 else if ((unsigned char) *p == 0xf7)
2684 BIO_printf(bp, "^?");
2685 else
2686 BIO_printf(bp, "^%c", *p + '@');
2687 p++;
2688 }
2689 BIO_printf(bp, "'\n");
2690 return 1;
2691}
2692
2693int
2694unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
2695 ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2696{
2697 char *tmp = NULL;
2698 char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2699 int reason_code = -1;
2700 int ret = 0;
2701 unsigned int i;
2702 ASN1_OBJECT *hold = NULL;
2703 ASN1_GENERALIZEDTIME *comp_time = NULL;
2704
2705 if ((tmp = strdup(str)) == NULL) {
2706 BIO_printf(bio_err, "malloc failed\n");
2707 goto err;
2708 }
2709 p = strchr(tmp, ',');
2710 rtime_str = tmp;
2711
2712 if (p != NULL) {
2713 *p = '\0';
2714 p++;
2715 reason_str = p;
2716 p = strchr(p, ',');
2717 if (p != NULL) {
2718 *p = '\0';
2719 arg_str = p + 1;
2720 }
2721 }
2722 if (prevtm != NULL) {
2723 *prevtm = ASN1_UTCTIME_new();
2724 if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) {
2725 BIO_printf(bio_err, "invalid revocation date %s\n",
2726 rtime_str);
2727 goto err;
2728 }
2729 }
2730 if (reason_str != NULL) {
2731 for (i = 0; i < NUM_REASONS; i++) {
2732 if (strcasecmp(reason_str, crl_reasons[i]) == 0) {
2733 reason_code = i;
2734 break;
2735 }
2736 }
2737 if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) {
2738 BIO_printf(bio_err, "invalid reason code %s\n",
2739 reason_str);
2740 goto err;
2741 }
2742 if (reason_code == 7)
2743 reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
2744 else if (reason_code == 8) { /* Hold instruction */
2745 if (arg_str == NULL) {
2746 BIO_printf(bio_err,
2747 "missing hold instruction\n");
2748 goto err;
2749 }
2750 reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
2751 hold = OBJ_txt2obj(arg_str, 0);
2752
2753 if (hold == NULL) {
2754 BIO_printf(bio_err,
2755 "invalid object identifier %s\n", arg_str);
2756 goto err;
2757 }
2758 if (phold != NULL)
2759 *phold = hold;
2760 } else if ((reason_code == 9) || (reason_code == 10)) {
2761 if (arg_str == NULL) {
2762 BIO_printf(bio_err,
2763 "missing compromised time\n");
2764 goto err;
2765 }
2766 comp_time = ASN1_GENERALIZEDTIME_new();
2767 if (!ASN1_GENERALIZEDTIME_set_string(comp_time,
2768 arg_str)) {
2769 BIO_printf(bio_err,
2770 "invalid compromised time %s\n", arg_str);
2771 goto err;
2772 }
2773 if (reason_code == 9)
2774 reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
2775 else
2776 reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
2777 }
2778 }
2779 if (preason != NULL)
2780 *preason = reason_code;
2781 if (pinvtm != NULL)
2782 *pinvtm = comp_time;
2783 else
2784 ASN1_GENERALIZEDTIME_free(comp_time);
2785
2786 ret = 1;
2787
2788 err:
2789 free(tmp);
2790
2791 if (phold == NULL)
2792 ASN1_OBJECT_free(hold);
2793 if (pinvtm == NULL)
2794 ASN1_GENERALIZEDTIME_free(comp_time);
2795
2796 return ret;
2797}
diff --git a/src/usr.bin/openssl/certhash.c b/src/usr.bin/openssl/certhash.c
deleted file mode 100644
index 5ee29b8d01..0000000000
--- a/src/usr.bin/openssl/certhash.c
+++ /dev/null
@@ -1,691 +0,0 @@
1/* $OpenBSD: certhash.c,v 1.21 2023/03/06 14:32:05 tb Exp $ */
2/*
3 * Copyright (c) 2014, 2015 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <sys/stat.h>
20
21#include <errno.h>
22#include <dirent.h>
23#include <fcntl.h>
24#include <limits.h>
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28
29#include <openssl/bio.h>
30#include <openssl/evp.h>
31#include <openssl/pem.h>
32#include <openssl/x509.h>
33
34#include "apps.h"
35
36static struct {
37 int dryrun;
38 int verbose;
39} cfg;
40
41static const struct option certhash_options[] = {
42 {
43 .name = "n",
44 .desc = "Perform a dry-run - do not make any changes",
45 .type = OPTION_FLAG,
46 .opt.flag = &cfg.dryrun,
47 },
48 {
49 .name = "v",
50 .desc = "Verbose",
51 .type = OPTION_FLAG,
52 .opt.flag = &cfg.verbose,
53 },
54 { NULL },
55};
56
57struct hashinfo {
58 char *filename;
59 char *target;
60 unsigned long hash;
61 unsigned int index;
62 unsigned char fingerprint[EVP_MAX_MD_SIZE];
63 int is_crl;
64 int is_dup;
65 int exists;
66 int changed;
67 struct hashinfo *reference;
68 struct hashinfo *next;
69};
70
71static struct hashinfo *
72hashinfo(const char *filename, unsigned long hash, unsigned char *fingerprint)
73{
74 struct hashinfo *hi;
75
76 if ((hi = calloc(1, sizeof(*hi))) == NULL)
77 return (NULL);
78 if (filename != NULL) {
79 if ((hi->filename = strdup(filename)) == NULL) {
80 free(hi);
81 return (NULL);
82 }
83 }
84 hi->hash = hash;
85 if (fingerprint != NULL)
86 memcpy(hi->fingerprint, fingerprint, sizeof(hi->fingerprint));
87
88 return (hi);
89}
90
91static void
92hashinfo_free(struct hashinfo *hi)
93{
94 if (hi == NULL)
95 return;
96
97 free(hi->filename);
98 free(hi->target);
99 free(hi);
100}
101
102#ifdef DEBUG
103static void
104hashinfo_print(struct hashinfo *hi)
105{
106 int i;
107
108 printf("hashinfo %s %08lx %u %i\n", hi->filename, hi->hash,
109 hi->index, hi->is_crl);
110 for (i = 0; i < (int)EVP_MAX_MD_SIZE; i++) {
111 printf("%02X%c", hi->fingerprint[i],
112 (i + 1 == (int)EVP_MAX_MD_SIZE) ? '\n' : ':');
113 }
114}
115#endif
116
117static int
118hashinfo_compare(const void *a, const void *b)
119{
120 struct hashinfo *hia = *(struct hashinfo **)a;
121 struct hashinfo *hib = *(struct hashinfo **)b;
122 int rv;
123
124 rv = hia->hash < hib->hash ? -1 : hia->hash > hib->hash;
125 if (rv != 0)
126 return (rv);
127 rv = memcmp(hia->fingerprint, hib->fingerprint,
128 sizeof(hia->fingerprint));
129 if (rv != 0)
130 return (rv);
131 return strcmp(hia->filename, hib->filename);
132}
133
134static struct hashinfo *
135hashinfo_chain(struct hashinfo *head, struct hashinfo *entry)
136{
137 struct hashinfo *hi = head;
138
139 if (hi == NULL)
140 return (entry);
141 while (hi->next != NULL)
142 hi = hi->next;
143 hi->next = entry;
144
145 return (head);
146}
147
148static void
149hashinfo_chain_free(struct hashinfo *hi)
150{
151 struct hashinfo *next;
152
153 while (hi != NULL) {
154 next = hi->next;
155 hashinfo_free(hi);
156 hi = next;
157 }
158}
159
160static size_t
161hashinfo_chain_length(struct hashinfo *hi)
162{
163 int len = 0;
164
165 while (hi != NULL) {
166 len++;
167 hi = hi->next;
168 }
169 return (len);
170}
171
172static int
173hashinfo_chain_sort(struct hashinfo **head)
174{
175 struct hashinfo **list, *entry;
176 size_t len;
177 int i;
178
179 if (*head == NULL)
180 return (0);
181
182 len = hashinfo_chain_length(*head);
183 if ((list = reallocarray(NULL, len, sizeof(struct hashinfo *))) == NULL)
184 return (-1);
185
186 for (entry = *head, i = 0; entry != NULL; entry = entry->next, i++)
187 list[i] = entry;
188 qsort(list, len, sizeof(struct hashinfo *), hashinfo_compare);
189
190 *head = entry = list[0];
191 for (i = 1; i < len; i++) {
192 entry->next = list[i];
193 entry = list[i];
194 }
195 entry->next = NULL;
196
197 free(list);
198 return (0);
199}
200
201static char *
202hashinfo_linkname(struct hashinfo *hi)
203{
204 char *filename;
205
206 if (asprintf(&filename, "%08lx.%s%u", hi->hash,
207 (hi->is_crl ? "r" : ""), hi->index) == -1)
208 return (NULL);
209
210 return (filename);
211}
212
213static int
214filename_is_hash(const char *filename)
215{
216 const char *p = filename;
217
218 while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f'))
219 p++;
220 if (*p++ != '.')
221 return (0);
222 if (*p == 'r') /* CRL format. */
223 p++;
224 while (*p >= '0' && *p <= '9')
225 p++;
226 if (*p != '\0')
227 return (0);
228
229 return (1);
230}
231
232static int
233filename_is_pem(const char *filename)
234{
235 const char *q, *p = filename;
236
237 if ((q = strchr(p, '\0')) == NULL)
238 return (0);
239 if ((q - p) < 4)
240 return (0);
241 if (strncmp((q - 4), ".pem", 4) != 0)
242 return (0);
243
244 return (1);
245}
246
247static struct hashinfo *
248hashinfo_from_linkname(const char *linkname, const char *target)
249{
250 struct hashinfo *hi = NULL;
251 const char *errstr;
252 char *l, *p, *ep;
253 long long val;
254
255 if ((l = strdup(linkname)) == NULL)
256 goto err;
257 if ((p = strchr(l, '.')) == NULL)
258 goto err;
259 *p++ = '\0';
260
261 if ((hi = hashinfo(linkname, 0, NULL)) == NULL)
262 goto err;
263 if ((hi->target = strdup(target)) == NULL)
264 goto err;
265
266 errno = 0;
267 val = strtoll(l, &ep, 16);
268 if (l[0] == '\0' || *ep != '\0')
269 goto err;
270 if (errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN))
271 goto err;
272 if (val < 0 || val > ULONG_MAX)
273 goto err;
274 hi->hash = (unsigned long)val;
275
276 if (*p == 'r') {
277 hi->is_crl = 1;
278 p++;
279 }
280
281 val = strtonum(p, 0, 0xffffffff, &errstr);
282 if (errstr != NULL)
283 goto err;
284
285 hi->index = (unsigned int)val;
286
287 goto done;
288
289 err:
290 hashinfo_free(hi);
291 hi = NULL;
292
293 done:
294 free(l);
295
296 return (hi);
297}
298
299static struct hashinfo *
300certhash_cert(BIO *bio, const char *filename)
301{
302 unsigned char fingerprint[EVP_MAX_MD_SIZE];
303 struct hashinfo *hi = NULL;
304 const EVP_MD *digest;
305 X509 *cert = NULL;
306 unsigned long hash;
307 unsigned int len;
308
309 if ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL)
310 goto err;
311
312 hash = X509_subject_name_hash(cert);
313
314 digest = EVP_sha256();
315 if (X509_digest(cert, digest, fingerprint, &len) != 1) {
316 fprintf(stderr, "out of memory\n");
317 goto err;
318 }
319
320 hi = hashinfo(filename, hash, fingerprint);
321
322 err:
323 X509_free(cert);
324
325 return (hi);
326}
327
328static struct hashinfo *
329certhash_crl(BIO *bio, const char *filename)
330{
331 unsigned char fingerprint[EVP_MAX_MD_SIZE];
332 struct hashinfo *hi = NULL;
333 const EVP_MD *digest;
334 X509_CRL *crl = NULL;
335 unsigned long hash;
336 unsigned int len;
337
338 if ((crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) == NULL)
339 return (NULL);
340
341 hash = X509_NAME_hash(X509_CRL_get_issuer(crl));
342
343 digest = EVP_sha256();
344 if (X509_CRL_digest(crl, digest, fingerprint, &len) != 1) {
345 fprintf(stderr, "out of memory\n");
346 goto err;
347 }
348
349 hi = hashinfo(filename, hash, fingerprint);
350
351 err:
352 X509_CRL_free(crl);
353
354 return (hi);
355}
356
357static int
358certhash_addlink(struct hashinfo **links, struct hashinfo *hi)
359{
360 struct hashinfo *link = NULL;
361
362 if ((link = hashinfo(NULL, hi->hash, hi->fingerprint)) == NULL)
363 goto err;
364
365 if ((link->filename = hashinfo_linkname(hi)) == NULL)
366 goto err;
367
368 link->reference = hi;
369 link->changed = 1;
370 *links = hashinfo_chain(*links, link);
371 hi->reference = link;
372
373 return (0);
374
375 err:
376 hashinfo_free(link);
377 return (-1);
378}
379
380static void
381certhash_findlink(struct hashinfo *links, struct hashinfo *hi)
382{
383 struct hashinfo *link;
384
385 for (link = links; link != NULL; link = link->next) {
386 if (link->is_crl == hi->is_crl &&
387 link->hash == hi->hash &&
388 link->index == hi->index &&
389 link->reference == NULL) {
390 link->reference = hi;
391 if (link->target == NULL ||
392 strcmp(link->target, hi->filename) != 0)
393 link->changed = 1;
394 hi->reference = link;
395 break;
396 }
397 }
398}
399
400static void
401certhash_index(struct hashinfo *head, const char *name)
402{
403 struct hashinfo *last, *entry;
404 int index = 0;
405
406 last = NULL;
407 for (entry = head; entry != NULL; entry = entry->next) {
408 if (last != NULL) {
409 if (entry->hash == last->hash) {
410 if (memcmp(entry->fingerprint,
411 last->fingerprint,
412 sizeof(entry->fingerprint)) == 0) {
413 fprintf(stderr, "WARNING: duplicate %s "
414 "in %s (using %s), ignoring...\n",
415 name, entry->filename,
416 last->filename);
417 entry->is_dup = 1;
418 continue;
419 }
420 index++;
421 } else {
422 index = 0;
423 }
424 }
425 entry->index = index;
426 last = entry;
427 }
428}
429
430static int
431certhash_merge(struct hashinfo **links, struct hashinfo **certs,
432 struct hashinfo **crls)
433{
434 struct hashinfo *cert, *crl;
435
436 /* Pass 1 - sort and index entries. */
437 if (hashinfo_chain_sort(certs) == -1)
438 return (-1);
439 if (hashinfo_chain_sort(crls) == -1)
440 return (-1);
441 certhash_index(*certs, "certificate");
442 certhash_index(*crls, "CRL");
443
444 /* Pass 2 - map to existing links. */
445 for (cert = *certs; cert != NULL; cert = cert->next) {
446 if (cert->is_dup == 1)
447 continue;
448 certhash_findlink(*links, cert);
449 }
450 for (crl = *crls; crl != NULL; crl = crl->next) {
451 if (crl->is_dup == 1)
452 continue;
453 certhash_findlink(*links, crl);
454 }
455
456 /* Pass 3 - determine missing links. */
457 for (cert = *certs; cert != NULL; cert = cert->next) {
458 if (cert->is_dup == 1 || cert->reference != NULL)
459 continue;
460 if (certhash_addlink(links, cert) == -1)
461 return (-1);
462 }
463 for (crl = *crls; crl != NULL; crl = crl->next) {
464 if (crl->is_dup == 1 || crl->reference != NULL)
465 continue;
466 if (certhash_addlink(links, crl) == -1)
467 return (-1);
468 }
469
470 return (0);
471}
472
473static int
474certhash_link(struct dirent *dep, struct hashinfo **links)
475{
476 struct hashinfo *hi = NULL;
477 char target[PATH_MAX];
478 struct stat sb;
479 int n;
480
481 if (lstat(dep->d_name, &sb) == -1) {
482 fprintf(stderr, "failed to stat %s\n", dep->d_name);
483 return (-1);
484 }
485 if (!S_ISLNK(sb.st_mode))
486 return (0);
487
488 n = readlink(dep->d_name, target, sizeof(target) - 1);
489 if (n == -1) {
490 fprintf(stderr, "failed to readlink %s\n", dep->d_name);
491 return (-1);
492 }
493 if (n >= sizeof(target) - 1) {
494 fprintf(stderr, "symbolic link is too long %s\n", dep->d_name);
495 return (-1);
496 }
497 target[n] = '\0';
498
499 hi = hashinfo_from_linkname(dep->d_name, target);
500 if (hi == NULL) {
501 fprintf(stderr, "failed to get hash info %s\n", dep->d_name);
502 return (-1);
503 }
504 hi->exists = 1;
505 *links = hashinfo_chain(*links, hi);
506
507 return (0);
508}
509
510static int
511certhash_file(struct dirent *dep, struct hashinfo **certs,
512 struct hashinfo **crls)
513{
514 struct hashinfo *hi = NULL;
515 int has_cert, has_crl;
516 int ret = -1;
517 BIO *bio = NULL;
518 FILE *f;
519
520 has_cert = has_crl = 0;
521
522 if ((f = fopen(dep->d_name, "r")) == NULL) {
523 fprintf(stderr, "failed to fopen %s\n", dep->d_name);
524 goto err;
525 }
526 if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
527 fprintf(stderr, "failed to create bio\n");
528 fclose(f);
529 goto err;
530 }
531
532 if ((hi = certhash_cert(bio, dep->d_name)) != NULL) {
533 has_cert = 1;
534 *certs = hashinfo_chain(*certs, hi);
535 }
536
537 if (BIO_reset(bio) != 0) {
538 fprintf(stderr, "BIO_reset failed\n");
539 goto err;
540 }
541
542 if ((hi = certhash_crl(bio, dep->d_name)) != NULL) {
543 has_crl = hi->is_crl = 1;
544 *crls = hashinfo_chain(*crls, hi);
545 }
546
547 if (!has_cert && !has_crl)
548 fprintf(stderr, "PEM file %s does not contain a certificate "
549 "or CRL, ignoring...\n", dep->d_name);
550
551 ret = 0;
552
553 err:
554 BIO_free(bio);
555
556 return (ret);
557}
558
559static int
560certhash_directory(const char *path)
561{
562 struct hashinfo *links = NULL, *certs = NULL, *crls = NULL, *link;
563 int ret = 0;
564 struct dirent *dep;
565 DIR *dip = NULL;
566
567 if ((dip = opendir(".")) == NULL) {
568 fprintf(stderr, "failed to open directory %s\n", path);
569 goto err;
570 }
571
572 if (cfg.verbose)
573 fprintf(stdout, "scanning directory %s\n", path);
574
575 /* Create lists of existing hash links, certs and CRLs. */
576 while ((dep = readdir(dip)) != NULL) {
577 if (filename_is_hash(dep->d_name)) {
578 if (certhash_link(dep, &links) == -1)
579 goto err;
580 }
581 if (filename_is_pem(dep->d_name)) {
582 if (certhash_file(dep, &certs, &crls) == -1)
583 goto err;
584 }
585 }
586
587 if (certhash_merge(&links, &certs, &crls) == -1) {
588 fprintf(stderr, "certhash merge failed\n");
589 goto err;
590 }
591
592 /* Remove spurious links. */
593 for (link = links; link != NULL; link = link->next) {
594 if (link->exists == 0 ||
595 (link->reference != NULL && link->changed == 0))
596 continue;
597 if (cfg.verbose)
598 fprintf(stdout, "%s link %s -> %s\n",
599 (cfg.dryrun ? "would remove" :
600 "removing"), link->filename, link->target);
601 if (cfg.dryrun)
602 continue;
603 if (unlink(link->filename) == -1) {
604 fprintf(stderr, "failed to remove link %s\n",
605 link->filename);
606 goto err;
607 }
608 }
609
610 /* Create missing links. */
611 for (link = links; link != NULL; link = link->next) {
612 if (link->exists == 1 && link->changed == 0)
613 continue;
614 if (cfg.verbose)
615 fprintf(stdout, "%s link %s -> %s\n",
616 (cfg.dryrun ? "would create" :
617 "creating"), link->filename,
618 link->reference->filename);
619 if (cfg.dryrun)
620 continue;
621 if (symlink(link->reference->filename, link->filename) == -1) {
622 fprintf(stderr, "failed to create link %s -> %s\n",
623 link->filename, link->reference->filename);
624 goto err;
625 }
626 }
627
628 goto done;
629
630 err:
631 ret = 1;
632
633 done:
634 hashinfo_chain_free(certs);
635 hashinfo_chain_free(crls);
636 hashinfo_chain_free(links);
637
638 if (dip != NULL)
639 closedir(dip);
640 return (ret);
641}
642
643static void
644certhash_usage(void)
645{
646 fprintf(stderr, "usage: certhash [-nv] dir ...\n");
647 options_usage(certhash_options);
648}
649
650int
651certhash_main(int argc, char **argv)
652{
653 int argsused;
654 int i, cwdfd, ret = 0;
655
656 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
657 perror("pledge");
658 exit(1);
659 }
660
661 memset(&cfg, 0, sizeof(cfg));
662
663 if (options_parse(argc, argv, certhash_options, NULL, &argsused) != 0) {
664 certhash_usage();
665 return (1);
666 }
667
668 if ((cwdfd = open(".", O_RDONLY)) == -1) {
669 perror("failed to open current directory");
670 return (1);
671 }
672
673 for (i = argsused; i < argc; i++) {
674 if (chdir(argv[i]) == -1) {
675 fprintf(stderr,
676 "failed to change to directory %s: %s\n",
677 argv[i], strerror(errno));
678 ret = 1;
679 continue;
680 }
681 ret |= certhash_directory(argv[i]);
682 if (fchdir(cwdfd) == -1) {
683 perror("failed to restore current directory");
684 ret = 1;
685 break; /* can't continue safely */
686 }
687 }
688 close(cwdfd);
689
690 return (ret);
691}
diff --git a/src/usr.bin/openssl/ciphers.c b/src/usr.bin/openssl/ciphers.c
deleted file mode 100644
index 9549fa3607..0000000000
--- a/src/usr.bin/openssl/ciphers.c
+++ /dev/null
@@ -1,185 +0,0 @@
1/* $OpenBSD: ciphers.c,v 1.20 2025/01/02 12:31:44 tb Exp $ */
2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20
21#include <openssl/err.h>
22#include <openssl/ssl.h>
23
24#include "apps.h"
25
26static struct {
27 int usage;
28 int use_supported;
29 int verbose;
30 int version;
31} cfg;
32
33static const struct option ciphers_options[] = {
34 {
35 .name = "h",
36 .type = OPTION_FLAG,
37 .opt.flag = &cfg.usage,
38 },
39 {
40 .name = "?",
41 .type = OPTION_FLAG,
42 .opt.flag = &cfg.usage,
43 },
44 {
45 .name = "s",
46 .desc = "Only list ciphers that are supported by the TLS method",
47 .type = OPTION_FLAG,
48 .opt.flag = &cfg.use_supported,
49 },
50 {
51 .name = "tls1_2",
52 .desc = "Use TLS protocol version 1.2",
53 .type = OPTION_VALUE,
54 .opt.value = &cfg.version,
55 .value = TLS1_2_VERSION,
56 },
57 {
58 .name = "tls1_3",
59 .desc = "Use TLS protocol version 1.3",
60 .type = OPTION_VALUE,
61 .opt.value = &cfg.version,
62 .value = TLS1_3_VERSION,
63 },
64 {
65 .name = "v",
66 .desc = "Provide cipher listing",
67 .type = OPTION_VALUE,
68 .opt.value = &cfg.verbose,
69 .value = 1,
70 },
71 {
72 .name = "V",
73 .desc = "Provide cipher listing with cipher suite values",
74 .type = OPTION_VALUE,
75 .opt.value = &cfg.verbose,
76 .value = 2,
77 },
78 { NULL },
79};
80
81static void
82ciphers_usage(void)
83{
84 fprintf(stderr, "usage: ciphers [-hsVv] [-tls1_2] "
85 "[-tls1_3] [cipherlist]\n");
86 options_usage(ciphers_options);
87}
88
89int
90ciphers_main(int argc, char **argv)
91{
92 char *cipherlist = NULL;
93 STACK_OF(SSL_CIPHER) *ciphers;
94 STACK_OF(SSL_CIPHER) *supported_ciphers = NULL;
95 const SSL_CIPHER *cipher;
96 SSL_CTX *ssl_ctx = NULL;
97 SSL *ssl = NULL;
98 uint16_t value;
99 int i, rv = 0;
100 char *desc;
101
102 if (pledge("stdio rpath", NULL) == -1) {
103 perror("pledge");
104 exit(1);
105 }
106
107 memset(&cfg, 0, sizeof(cfg));
108
109 if (options_parse(argc, argv, ciphers_options, &cipherlist,
110 NULL) != 0) {
111 ciphers_usage();
112 return (1);
113 }
114
115 if (cfg.usage) {
116 ciphers_usage();
117 return (1);
118 }
119
120 if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL)
121 goto err;
122
123 if (cfg.version != 0) {
124 if (!SSL_CTX_set_min_proto_version(ssl_ctx,
125 cfg.version))
126 goto err;
127 if (!SSL_CTX_set_max_proto_version(ssl_ctx,
128 cfg.version))
129 goto err;
130 }
131
132 if (cipherlist != NULL) {
133 if (SSL_CTX_set_cipher_list(ssl_ctx, cipherlist) == 0)
134 goto err;
135 }
136
137 if ((ssl = SSL_new(ssl_ctx)) == NULL)
138 goto err;
139
140 if (cfg.use_supported) {
141 if ((supported_ciphers =
142 SSL_get1_supported_ciphers(ssl)) == NULL)
143 goto err;
144 ciphers = supported_ciphers;
145 } else {
146 if ((ciphers = SSL_get_ciphers(ssl)) == NULL)
147 goto err;
148 }
149
150 for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
151 cipher = sk_SSL_CIPHER_value(ciphers, i);
152 if (cfg.verbose == 0) {
153 fprintf(stdout, "%s%s", (i ? ":" : ""),
154 SSL_CIPHER_get_name(cipher));
155 continue;
156 }
157 if (cfg.verbose > 1) {
158 value = SSL_CIPHER_get_value(cipher);
159 fprintf(stdout, "%-*s0x%02X,0x%02X - ", 10, "",
160 ((value >> 8) & 0xff), (value & 0xff));
161 }
162 desc = SSL_CIPHER_description(cipher, NULL, 0);
163 if (strcmp(desc, "OPENSSL_malloc Error") == 0) {
164 fprintf(stderr, "out of memory\n");
165 goto err;
166 }
167 fprintf(stdout, "%s", desc);
168 free(desc);
169 }
170 if (cfg.verbose == 0)
171 fprintf(stdout, "\n");
172
173 goto done;
174
175 err:
176 ERR_print_errors_fp(stderr);
177 rv = 1;
178
179 done:
180 sk_SSL_CIPHER_free(supported_ciphers);
181 SSL_CTX_free(ssl_ctx);
182 SSL_free(ssl);
183
184 return (rv);
185}
diff --git a/src/usr.bin/openssl/cms.c b/src/usr.bin/openssl/cms.c
deleted file mode 100644
index 7420d0ab8c..0000000000
--- a/src/usr.bin/openssl/cms.c
+++ /dev/null
@@ -1,1988 +0,0 @@
1/* $OpenBSD: cms.c,v 1.36 2024/08/12 15:34:58 job Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 */
53
54/* CMS utility function */
55
56#include <stdio.h>
57#include <string.h>
58
59#include "apps.h"
60
61#ifndef OPENSSL_NO_CMS
62
63#include <openssl/crypto.h>
64#include <openssl/err.h>
65#include <openssl/pem.h>
66#include <openssl/x509_vfy.h>
67#include <openssl/x509v3.h>
68
69#include <openssl/cms.h>
70
71static int save_certs(char *signerfile, STACK_OF(X509) *signers);
72static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
73static CMS_ReceiptRequest *make_receipt_request(
74 STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
75 STACK_OF(OPENSSL_STRING) *rr_from);
76static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
77 STACK_OF(OPENSSL_STRING) *param);
78
79#define SMIME_OP 0x10
80#define SMIME_IP 0x20
81#define SMIME_SIGNERS 0x40
82#define SMIME_ENCRYPT (1 | SMIME_OP)
83#define SMIME_DECRYPT (2 | SMIME_IP)
84#define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS)
85#define SMIME_VERIFY (4 | SMIME_IP)
86#define SMIME_CMSOUT (5 | SMIME_IP | SMIME_OP)
87#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
88#define SMIME_DATAOUT (7 | SMIME_IP)
89#define SMIME_DATA_CREATE (8 | SMIME_OP)
90#define SMIME_DIGEST_VERIFY (9 | SMIME_IP)
91#define SMIME_DIGEST_CREATE (10 | SMIME_OP)
92#define SMIME_UNCOMPRESS (11 | SMIME_IP)
93#define SMIME_COMPRESS (12 | SMIME_OP)
94#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
95#define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP)
96#define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP)
97#define SMIME_VERIFY_RECEIPT (16 | SMIME_IP)
98
99int verify_err = 0;
100
101struct cms_key_param {
102 int idx;
103 STACK_OF(OPENSSL_STRING) *param;
104 struct cms_key_param *next;
105};
106
107static struct {
108 char *CAfile;
109 char *CApath;
110 X509 *cert;
111 char *certfile;
112 char *certsoutfile;
113 char *crlfile;
114 const EVP_CIPHER *cipher;
115 char *contfile;
116 ASN1_OBJECT *econtent_type;
117 STACK_OF(X509) *encerts;
118 int flags;
119 char *from;
120 char *infile;
121 int informat;
122 struct cms_key_param *key_first;
123 struct cms_key_param *key_param;
124 char *keyfile;
125 int keyform;
126 int noout;
127 int operation;
128 char *outfile;
129 int outformat;
130 char *passargin;
131 int print;
132 unsigned char *pwri_pass;
133 int rr_allorfirst;
134 STACK_OF(OPENSSL_STRING) *rr_from;
135 int rr_print;
136 STACK_OF(OPENSSL_STRING) *rr_to;
137 char *rctfile;
138 int rctformat;
139 char *recipfile;
140 unsigned char *secret_key;
141 unsigned char *secret_keyid;
142 size_t secret_keyidlen;
143 size_t secret_keylen;
144 const EVP_MD *sign_md;
145 char *signerfile;
146 STACK_OF(OPENSSL_STRING) *skkeys;
147 STACK_OF(OPENSSL_STRING) *sksigners;
148 char *subject;
149 char *to;
150 int verify_retcode;
151 X509_VERIFY_PARAM *vpm;
152} cfg;
153
154static const EVP_CIPHER *
155get_cipher_by_name(char *name)
156{
157 if (name == NULL || strcmp(name, "") == 0)
158 return (NULL);
159#ifndef OPENSSL_NO_AES
160 else if (strcmp(name, "aes128") == 0)
161 return EVP_aes_128_cbc();
162 else if (strcmp(name, "aes192") == 0)
163 return EVP_aes_192_cbc();
164 else if (strcmp(name, "aes256") == 0)
165 return EVP_aes_256_cbc();
166#endif
167#ifndef OPENSSL_NO_CAMELLIA
168 else if (strcmp(name, "camellia128") == 0)
169 return EVP_camellia_128_cbc();
170 else if (strcmp(name, "camellia192") == 0)
171 return EVP_camellia_192_cbc();
172 else if (strcmp(name, "camellia256") == 0)
173 return EVP_camellia_256_cbc();
174#endif
175#ifndef OPENSSL_NO_DES
176 else if (strcmp(name, "des") == 0)
177 return EVP_des_cbc();
178 else if (strcmp(name, "des3") == 0)
179 return EVP_des_ede3_cbc();
180#endif
181#ifndef OPENSSL_NO_RC2
182 else if (!strcmp(name, "rc2-40"))
183 return EVP_rc2_40_cbc();
184 else if (!strcmp(name, "rc2-64"))
185 return EVP_rc2_64_cbc();
186 else if (!strcmp(name, "rc2-128"))
187 return EVP_rc2_cbc();
188#endif
189 else
190 return (NULL);
191}
192
193static int
194cms_opt_cipher(int argc, char **argv, int *argsused)
195{
196 char *name = argv[0];
197
198 if (*name++ != '-')
199 return (1);
200
201 if ((cfg.cipher = get_cipher_by_name(name)) == NULL)
202 if ((cfg.cipher = EVP_get_cipherbyname(name)) == NULL)
203 return (1);
204
205 *argsused = 1;
206 return (0);
207}
208
209static int
210cms_opt_econtent_type(char *arg)
211{
212 ASN1_OBJECT_free(cfg.econtent_type);
213
214 if ((cfg.econtent_type = OBJ_txt2obj(arg, 0)) == NULL) {
215 BIO_printf(bio_err, "Invalid OID %s\n", arg);
216 return (1);
217 }
218 return (0);
219}
220
221static int
222cms_opt_inkey(char *arg)
223{
224 if (cfg.keyfile == NULL) {
225 cfg.keyfile = arg;
226 return (0);
227 }
228
229 if (cfg.signerfile == NULL) {
230 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
231 return (1);
232 }
233
234 if (cfg.sksigners == NULL)
235 cfg.sksigners = sk_OPENSSL_STRING_new_null();
236 if (cfg.sksigners == NULL)
237 return (1);
238 if (!sk_OPENSSL_STRING_push(cfg.sksigners, cfg.signerfile))
239 return (1);
240
241 cfg.signerfile = NULL;
242
243 if (cfg.skkeys == NULL)
244 cfg.skkeys = sk_OPENSSL_STRING_new_null();
245 if (cfg.skkeys == NULL)
246 return (1);
247 if (!sk_OPENSSL_STRING_push(cfg.skkeys, cfg.keyfile))
248 return (1);
249
250 cfg.keyfile = arg;
251 return (0);
252}
253
254static int
255cms_opt_keyopt(char *arg)
256{
257 int keyidx = -1;
258
259 if (cfg.operation == SMIME_ENCRYPT) {
260 if (cfg.encerts != NULL)
261 keyidx += sk_X509_num(cfg.encerts);
262 } else {
263 if (cfg.keyfile != NULL || cfg.signerfile != NULL)
264 keyidx++;
265 if (cfg.skkeys != NULL)
266 keyidx += sk_OPENSSL_STRING_num(cfg.skkeys);
267 }
268
269 if (keyidx < 0) {
270 BIO_printf(bio_err, "No key specified\n");
271 return (1);
272 }
273
274 if (cfg.key_param == NULL ||
275 cfg.key_param->idx != keyidx) {
276 struct cms_key_param *nparam;
277
278 if ((nparam = calloc(1, sizeof(struct cms_key_param))) == NULL)
279 return (1);
280
281 nparam->idx = keyidx;
282 if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) {
283 free(nparam);
284 return (1);
285 }
286
287 nparam->next = NULL;
288 if (cfg.key_first == NULL)
289 cfg.key_first = nparam;
290 else
291 cfg.key_param->next = nparam;
292
293 cfg.key_param = nparam;
294 }
295
296 if (!sk_OPENSSL_STRING_push(cfg.key_param->param, arg))
297 return (1);
298
299 return (0);
300}
301
302static int
303cms_opt_md(char *arg)
304{
305 if ((cfg.sign_md = EVP_get_digestbyname(arg)) == NULL) {
306 BIO_printf(bio_err, "Unknown digest %s\n", arg);
307 return (1);
308 }
309 return (0);
310}
311
312static int
313cms_opt_print(void)
314{
315 cfg.noout = 1;
316 cfg.print = 1;
317 return (0);
318}
319
320static int
321cms_opt_pwri_pass(char *arg)
322{
323 cfg.pwri_pass = (unsigned char *)arg;
324 return (0);
325}
326
327static int
328cms_opt_recip(char *arg)
329{
330 if (cfg.operation == SMIME_ENCRYPT) {
331 if (cfg.encerts == NULL) {
332 if ((cfg.encerts = sk_X509_new_null()) == NULL)
333 return (1);
334 }
335
336 cfg.cert = load_cert(bio_err, arg, FORMAT_PEM,
337 NULL, "recipient certificate file");
338 if (cfg.cert == NULL)
339 return (1);
340
341 if (!sk_X509_push(cfg.encerts, cfg.cert))
342 return (1);
343
344 cfg.cert = NULL;
345 } else {
346 cfg.recipfile = arg;
347 }
348 return (0);
349}
350
351static int
352cms_opt_receipt_request_from(char *arg)
353{
354 if (cfg.rr_from == NULL)
355 cfg.rr_from = sk_OPENSSL_STRING_new_null();
356 if (cfg.rr_from == NULL)
357 return (1);
358 if (!sk_OPENSSL_STRING_push(cfg.rr_from, arg))
359 return (1);
360
361 return (0);
362}
363
364static int
365cms_opt_receipt_request_to(char *arg)
366{
367 if (cfg.rr_to == NULL)
368 cfg.rr_to = sk_OPENSSL_STRING_new_null();
369 if (cfg.rr_to == NULL)
370 return (1);
371 if (!sk_OPENSSL_STRING_push(cfg.rr_to, arg))
372 return (1);
373
374 return (0);
375}
376
377static int
378cms_opt_secretkey(char *arg)
379{
380 long ltmp;
381
382 free(cfg.secret_key);
383
384 if ((cfg.secret_key = string_to_hex(arg, &ltmp)) == NULL) {
385 BIO_printf(bio_err, "Invalid key %s\n", arg);
386 return (1);
387 }
388 cfg.secret_keylen = (size_t)ltmp;
389 return (0);
390}
391
392static int
393cms_opt_secretkeyid(char *arg)
394{
395 long ltmp;
396
397 free(cfg.secret_keyid);
398
399 if ((cfg.secret_keyid = string_to_hex(arg, &ltmp)) == NULL) {
400 BIO_printf(bio_err, "Invalid id %s\n", arg);
401 return (1);
402 }
403 cfg.secret_keyidlen = (size_t)ltmp;
404 return (0);
405}
406
407static int
408cms_opt_signer(char *arg)
409{
410 if (cfg.signerfile == NULL) {
411 cfg.signerfile = arg;
412 return (0);
413 }
414
415 if (cfg.sksigners == NULL)
416 cfg.sksigners = sk_OPENSSL_STRING_new_null();
417 if (cfg.sksigners == NULL)
418 return (1);
419 if (!sk_OPENSSL_STRING_push(cfg.sksigners, cfg.signerfile))
420 return (1);
421
422 if (cfg.keyfile == NULL)
423 cfg.keyfile = cfg.signerfile;
424
425 if (cfg.skkeys == NULL)
426 cfg.skkeys = sk_OPENSSL_STRING_new_null();
427 if (cfg.skkeys == NULL)
428 return (1);
429 if (!sk_OPENSSL_STRING_push(cfg.skkeys, cfg.keyfile))
430 return (1);
431
432 cfg.keyfile = NULL;
433
434 cfg.signerfile = arg;
435 return (0);
436}
437
438static int
439cms_opt_verify_param(int argc, char **argv, int *argsused)
440{
441 int oargc = argc;
442 int badarg = 0;
443
444 if (!args_verify(&argv, &argc, &badarg, bio_err, &cfg.vpm))
445 return (1);
446 if (badarg)
447 return (1);
448
449 *argsused = oargc - argc;
450
451 return (0);
452}
453
454static int
455cms_opt_verify_receipt(char *arg)
456{
457 cfg.operation = SMIME_VERIFY_RECEIPT;
458 cfg.rctfile = arg;
459 return (0);
460}
461
462static const struct option cms_options[] = {
463#ifndef OPENSSL_NO_AES
464 {
465 .name = "aes128",
466 .desc = "Encrypt PEM output with CBC AES",
467 .type = OPTION_ARGV_FUNC,
468 .opt.argvfunc = cms_opt_cipher,
469 },
470 {
471 .name = "aes192",
472 .desc = "Encrypt PEM output with CBC AES",
473 .type = OPTION_ARGV_FUNC,
474 .opt.argvfunc = cms_opt_cipher,
475 },
476 {
477 .name = "aes256",
478 .desc = "Encrypt PEM output with CBC AES",
479 .type = OPTION_ARGV_FUNC,
480 .opt.argvfunc = cms_opt_cipher,
481 },
482#endif
483#ifndef OPENSSL_NO_CAMELLIA
484 {
485 .name = "camellia128",
486 .desc = "Encrypt PEM output with CBC Camellia",
487 .type = OPTION_ARGV_FUNC,
488 .opt.argvfunc = cms_opt_cipher,
489 },
490 {
491 .name = "camellia192",
492 .desc = "Encrypt PEM output with CBC Camellia",
493 .type = OPTION_ARGV_FUNC,
494 .opt.argvfunc = cms_opt_cipher,
495 },
496 {
497 .name = "camellia256",
498 .desc = "Encrypt PEM output with CBC Camellia",
499 .type = OPTION_ARGV_FUNC,
500 .opt.argvfunc = cms_opt_cipher,
501 },
502#endif
503#ifndef OPENSSL_NO_DES
504 {
505 .name = "des",
506 .desc = "Encrypt with DES",
507 .type = OPTION_ARGV_FUNC,
508 .opt.argvfunc = cms_opt_cipher,
509 },
510 {
511 .name = "des3",
512 .desc = "Encrypt with triple DES (default)",
513 .type = OPTION_ARGV_FUNC,
514 .opt.argvfunc = cms_opt_cipher,
515 },
516#endif
517#ifndef OPENSSL_NO_RC2
518 {
519 .name = "rc2-40",
520 .desc = "Encrypt with RC2-40",
521 .type = OPTION_ARGV_FUNC,
522 .opt.argvfunc = cms_opt_cipher,
523 },
524 {
525 .name = "rc2-64",
526 .desc = "Encrypt with RC2-64",
527 .type = OPTION_ARGV_FUNC,
528 .opt.argvfunc = cms_opt_cipher,
529 },
530 {
531 .name = "rc2-128",
532 .desc = "Encrypt with RC2-128",
533 .type = OPTION_ARGV_FUNC,
534 .opt.argvfunc = cms_opt_cipher,
535 },
536#endif
537 {
538 .name = "CAfile",
539 .argname = "file",
540 .desc = "Certificate Authority file",
541 .type = OPTION_ARG,
542 .opt.arg = &cfg.CAfile,
543 },
544 {
545 .name = "CApath",
546 .argname = "path",
547 .desc = "Certificate Authority path",
548 .type = OPTION_ARG,
549 .opt.arg = &cfg.CApath,
550 },
551 {
552 .name = "CRLfile",
553 .argname = "file",
554 .desc = "Other certificate revocation lists file",
555 .type = OPTION_ARG,
556 .opt.arg = &cfg.crlfile,
557 },
558 {
559 .name = "binary",
560 .desc = "Do not translate message to text",
561 .type = OPTION_VALUE_OR,
562 .opt.value = &cfg.flags,
563 .value = CMS_BINARY,
564 },
565 {
566 .name = "certfile",
567 .argname = "file",
568 .desc = "Other certificates file",
569 .type = OPTION_ARG,
570 .opt.arg = &cfg.certfile,
571 },
572 {
573 .name = "certsout",
574 .argname = "file",
575 .desc = "Certificate output file",
576 .type = OPTION_ARG,
577 .opt.arg = &cfg.certsoutfile,
578 },
579 {
580 .name = "cmsout",
581 .desc = "Output CMS structure",
582 .type = OPTION_VALUE,
583 .opt.value = &cfg.operation,
584 .value = SMIME_CMSOUT,
585 },
586 {
587 .name = "compress",
588 .desc = "Create CMS CompressedData type",
589 .type = OPTION_VALUE,
590 .opt.value = &cfg.operation,
591 .value = SMIME_COMPRESS,
592 },
593 {
594 .name = "content",
595 .argname = "file",
596 .desc = "Supply or override content for detached signature",
597 .type = OPTION_ARG,
598 .opt.arg = &cfg.contfile,
599 },
600 {
601 .name = "crlfeol",
602 .desc = "Use CRLF as EOL termination instead of CR only",
603 .type = OPTION_VALUE_OR,
604 .opt.value = &cfg.flags,
605 .value = CMS_CRLFEOL,
606 },
607 {
608 .name = "data_create",
609 .desc = "Create CMS Data type",
610 .type = OPTION_VALUE,
611 .opt.value = &cfg.operation,
612 .value = SMIME_DATA_CREATE,
613 },
614 {
615 .name = "data_out",
616 .desc = "Output content from the input CMS Data type",
617 .type = OPTION_VALUE,
618 .opt.value = &cfg.operation,
619 .value = SMIME_DATAOUT,
620 },
621 {
622 .name = "debug_decrypt",
623 .desc = "Set the CMS_DEBUG_DECRYPT flag when decrypting",
624 .type = OPTION_VALUE_OR,
625 .opt.value = &cfg.flags,
626 .value = CMS_DEBUG_DECRYPT,
627 },
628 {
629 .name = "decrypt",
630 .desc = "Decrypt encrypted message",
631 .type = OPTION_VALUE,
632 .opt.value = &cfg.operation,
633 .value = SMIME_DECRYPT,
634 },
635 {
636 .name = "digest_create",
637 .desc = "Create CMS DigestedData type",
638 .type = OPTION_VALUE,
639 .opt.value = &cfg.operation,
640 .value = SMIME_DIGEST_CREATE,
641 },
642 {
643 .name = "digest_verify",
644 .desc = "Verify CMS DigestedData type and output the content",
645 .type = OPTION_VALUE,
646 .opt.value = &cfg.operation,
647 .value = SMIME_DIGEST_VERIFY,
648 },
649 {
650 .name = "econtent_type",
651 .argname = "type",
652 .desc = "Set the encapsulated content type",
653 .type = OPTION_ARG_FUNC,
654 .opt.argfunc = cms_opt_econtent_type,
655 },
656 {
657 .name = "encrypt",
658 .desc = "Encrypt message",
659 .type = OPTION_VALUE,
660 .opt.value = &cfg.operation,
661 .value = SMIME_ENCRYPT,
662 },
663 {
664 .name = "EncryptedData_decrypt",
665 .desc = "Decrypt CMS EncryptedData",
666 .type = OPTION_VALUE,
667 .opt.value = &cfg.operation,
668 .value = SMIME_ENCRYPTED_DECRYPT,
669 },
670 {
671 .name = "EncryptedData_encrypt",
672 .desc = "Encrypt content using supplied symmetric key and algorithm",
673 .type = OPTION_VALUE,
674 .opt.value = &cfg.operation,
675 .value = SMIME_ENCRYPTED_ENCRYPT,
676 },
677 {
678 .name = "from",
679 .argname = "addr",
680 .desc = "From address",
681 .type = OPTION_ARG,
682 .opt.arg = &cfg.from,
683 },
684 {
685 .name = "in",
686 .argname = "file",
687 .desc = "Input file",
688 .type = OPTION_ARG,
689 .opt.arg = &cfg.infile,
690 },
691 {
692 .name = "indef",
693 .desc = "Same as -stream",
694 .type = OPTION_VALUE_OR,
695 .opt.value = &cfg.flags,
696 .value = CMS_STREAM,
697 },
698 {
699 .name = "inform",
700 .argname = "fmt",
701 .desc = "Input format (DER, PEM or SMIME (default))",
702 .type = OPTION_ARG_FORMAT,
703 .opt.value = &cfg.informat,
704 },
705 {
706 .name = "inkey",
707 .argname = "file",
708 .desc = "Input key file",
709 .type = OPTION_ARG_FUNC,
710 .opt.argfunc = cms_opt_inkey,
711 },
712 {
713 .name = "keyform",
714 .argname = "fmt",
715 .desc = "Input key format (DER or PEM (default))",
716 .type = OPTION_ARG_FORMAT,
717 .opt.value = &cfg.keyform,
718 },
719 {
720 .name = "keyid",
721 .desc = "Use subject key identifier",
722 .type = OPTION_VALUE_OR,
723 .opt.value = &cfg.flags,
724 .value = CMS_USE_KEYID,
725 },
726 {
727 .name = "keyopt",
728 .argname = "nm:v",
729 .desc = "Set public key parameters",
730 .type = OPTION_ARG_FUNC,
731 .opt.argfunc = cms_opt_keyopt,
732 },
733 {
734 .name = "md",
735 .argname = "digest",
736 .desc = "Digest to use when signing or resigning",
737 .type = OPTION_ARG_FUNC,
738 .opt.argfunc = cms_opt_md,
739 },
740 {
741 .name = "no_attr_verify",
742 .desc = "Do not verify the signer's attribute of a signature",
743 .type = OPTION_VALUE_OR,
744 .opt.value = &cfg.flags,
745 .value = CMS_NO_ATTR_VERIFY,
746 },
747 {
748 .name = "no_content_verify",
749 .desc = "Do not verify the content of a signed message",
750 .type = OPTION_VALUE_OR,
751 .opt.value = &cfg.flags,
752 .value = CMS_NO_CONTENT_VERIFY,
753 },
754 {
755 .name = "no_signer_cert_verify",
756 .desc = "Do not verify the signer's certificate",
757 .type = OPTION_VALUE_OR,
758 .opt.value = &cfg.flags,
759 .value = CMS_NO_SIGNER_CERT_VERIFY,
760 },
761 {
762 .name = "noattr",
763 .desc = "Do not include any signed attributes",
764 .type = OPTION_VALUE_OR,
765 .opt.value = &cfg.flags,
766 .value = CMS_NOATTR,
767 },
768 {
769 .name = "nocerts",
770 .desc = "Do not include signer's certificate when signing",
771 .type = OPTION_VALUE_OR,
772 .opt.value = &cfg.flags,
773 .value = CMS_NOCERTS,
774 },
775 {
776 .name = "nodetach",
777 .desc = "Use opaque signing",
778 .type = OPTION_VALUE_AND,
779 .opt.value = &cfg.flags,
780 .value = ~CMS_DETACHED,
781 },
782 {
783 .name = "noindef",
784 .desc = "Disable CMS streaming",
785 .type = OPTION_VALUE_AND,
786 .opt.value = &cfg.flags,
787 .value = ~CMS_STREAM,
788 },
789 {
790 .name = "nointern",
791 .desc = "Do not search certificates in message for signer",
792 .type = OPTION_VALUE_OR,
793 .opt.value = &cfg.flags,
794 .value = CMS_NOINTERN,
795 },
796 {
797 .name = "nooldmime",
798 .desc = "Output old S/MIME content type",
799 .type = OPTION_VALUE_OR,
800 .opt.value = &cfg.flags,
801 .value = CMS_NOOLDMIMETYPE,
802 },
803 {
804 .name = "noout",
805 .desc = "Do not output the parsed CMS structure",
806 .type = OPTION_FLAG,
807 .opt.flag = &cfg.noout,
808 },
809 {
810 .name = "nosigs",
811 .desc = "Do not verify message signature",
812 .type = OPTION_VALUE_OR,
813 .opt.value = &cfg.flags,
814 .value = CMS_NOSIGS,
815 },
816 {
817 .name = "nosmimecap",
818 .desc = "Omit the SMIMECapabilities attribute",
819 .type = OPTION_VALUE_OR,
820 .opt.value = &cfg.flags,
821 .value = CMS_NOSMIMECAP,
822 },
823 {
824 .name = "noverify",
825 .desc = "Do not verify signer's certificate",
826 .type = OPTION_VALUE_OR,
827 .opt.value = &cfg.flags,
828 .value = CMS_NO_SIGNER_CERT_VERIFY,
829 },
830 {
831 .name = "out",
832 .argname = "file",
833 .desc = "Output file",
834 .type = OPTION_ARG,
835 .opt.arg = &cfg.outfile,
836 },
837 {
838 .name = "outform",
839 .argname = "fmt",
840 .desc = "Output format (DER, PEM or SMIME (default))",
841 .type = OPTION_ARG_FORMAT,
842 .opt.value = &cfg.outformat,
843 },
844 {
845 .name = "passin",
846 .argname = "src",
847 .desc = "Private key password source",
848 .type = OPTION_ARG,
849 .opt.arg = &cfg.passargin,
850 },
851 {
852 .name = "print",
853 .desc = "Print out all fields of the CMS structure for the -cmsout",
854 .type = OPTION_FUNC,
855 .opt.func = cms_opt_print,
856 },
857 {
858 .name = "pwri_password",
859 .argname = "arg",
860 .desc = "Specify PasswordRecipientInfo (PWRI) password to use",
861 .type = OPTION_ARG_FUNC,
862 .opt.argfunc = cms_opt_pwri_pass,
863 },
864 {
865 .name = "rctform",
866 .argname = "fmt",
867 .desc = "Receipt file format (DER, PEM or SMIME (default))",
868 .type = OPTION_ARG_FORMAT,
869 .opt.value = &cfg.rctformat,
870 },
871 {
872 .name = "receipt_request_all",
873 .desc = "Indicate requests should be provided by all recipients",
874 .type = OPTION_VALUE,
875 .opt.value = &cfg.rr_allorfirst,
876 .value = 0,
877 },
878 {
879 .name = "receipt_request_first",
880 .desc = "Indicate requests should be provided by first tier recipient",
881 .type = OPTION_VALUE,
882 .opt.value = &cfg.rr_allorfirst,
883 .value = 1,
884 },
885 {
886 .name = "receipt_request_from",
887 .argname = "addr",
888 .desc = "Add explicit email address where receipts should be supplied",
889 .type = OPTION_ARG_FUNC,
890 .opt.argfunc = cms_opt_receipt_request_from,
891 },
892 {
893 .name = "receipt_request_print",
894 .desc = "Print out the contents of any signed receipt requests",
895 .type = OPTION_FLAG,
896 .opt.flag = &cfg.rr_print,
897 },
898 {
899 .name = "receipt_request_to",
900 .argname = "addr",
901 .desc = "Add explicit email address where receipts should be sent to",
902 .type = OPTION_ARG_FUNC,
903 .opt.argfunc = cms_opt_receipt_request_to,
904 },
905 {
906 .name = "recip",
907 .argname = "file",
908 .desc = "Recipient certificate file for decryption",
909 .type = OPTION_ARG_FUNC,
910 .opt.argfunc = cms_opt_recip,
911 },
912 {
913 .name = "resign",
914 .desc = "Resign a signed message",
915 .type = OPTION_VALUE,
916 .opt.value = &cfg.operation,
917 .value = SMIME_RESIGN,
918 },
919 {
920 .name = "secretkey",
921 .argname = "key",
922 .desc = "Specify symmetric key to use",
923 .type = OPTION_ARG_FUNC,
924 .opt.argfunc = cms_opt_secretkey,
925 },
926 {
927 .name = "secretkeyid",
928 .argname = "id",
929 .desc = "The key identifier for the supplied symmetric key",
930 .type = OPTION_ARG_FUNC,
931 .opt.argfunc = cms_opt_secretkeyid,
932 },
933 {
934 .name = "sign",
935 .desc = "Sign message",
936 .type = OPTION_VALUE,
937 .opt.value = &cfg.operation,
938 .value = SMIME_SIGN,
939 },
940 {
941 .name = "sign_receipt",
942 .desc = "Generate a signed receipt for the message",
943 .type = OPTION_VALUE,
944 .opt.value = &cfg.operation,
945 .value = SMIME_SIGN_RECEIPT,
946 },
947 {
948 .name = "signer",
949 .argname = "file",
950 .desc = "Signer certificate file",
951 .type = OPTION_ARG_FUNC,
952 .opt.argfunc = cms_opt_signer,
953 },
954 {
955 .name = "stream",
956 .desc = "Enable CMS streaming",
957 .type = OPTION_VALUE_OR,
958 .opt.value = &cfg.flags,
959 .value = CMS_STREAM,
960 },
961 {
962 .name = "subject",
963 .argname = "s",
964 .desc = "Subject",
965 .type = OPTION_ARG,
966 .opt.arg = &cfg.subject,
967 },
968 {
969 .name = "text",
970 .desc = "Include or delete text MIME headers",
971 .type = OPTION_VALUE_OR,
972 .opt.value = &cfg.flags,
973 .value = CMS_TEXT,
974 },
975 {
976 .name = "to",
977 .argname = "addr",
978 .desc = "To address",
979 .type = OPTION_ARG,
980 .opt.arg = &cfg.to,
981 },
982 {
983 .name = "uncompress",
984 .desc = "Uncompress CMS CompressedData type",
985 .type = OPTION_VALUE,
986 .opt.value = &cfg.operation,
987 .value = SMIME_UNCOMPRESS,
988 },
989 {
990 .name = "verify",
991 .desc = "Verify signed message",
992 .type = OPTION_VALUE,
993 .opt.value = &cfg.operation,
994 .value = SMIME_VERIFY,
995 },
996 {
997 .name = "verify_receipt",
998 .argname = "file",
999 .desc = "Verify a signed receipt in file",
1000 .type = OPTION_ARG_FUNC,
1001 .opt.argfunc = cms_opt_verify_receipt,
1002 },
1003 {
1004 .name = "verify_retcode",
1005 .desc = "Set verification error code to exit code",
1006 .type = OPTION_FLAG,
1007 .opt.flag = &cfg.verify_retcode,
1008 },
1009 {
1010 .name = "check_ss_sig",
1011 .type = OPTION_ARGV_FUNC,
1012 .opt.argvfunc = cms_opt_verify_param,
1013 },
1014 {
1015 .name = "crl_check",
1016 .type = OPTION_ARGV_FUNC,
1017 .opt.argvfunc = cms_opt_verify_param,
1018 },
1019 {
1020 .name = "crl_check_all",
1021 .type = OPTION_ARGV_FUNC,
1022 .opt.argvfunc = cms_opt_verify_param,
1023 },
1024 {
1025 .name = "extended_crl",
1026 .type = OPTION_ARGV_FUNC,
1027 .opt.argvfunc = cms_opt_verify_param,
1028 },
1029 {
1030 .name = "ignore_critical",
1031 .type = OPTION_ARGV_FUNC,
1032 .opt.argvfunc = cms_opt_verify_param,
1033 },
1034 {
1035 .name = "issuer_checks",
1036 .type = OPTION_ARGV_FUNC,
1037 .opt.argvfunc = cms_opt_verify_param,
1038 },
1039 {
1040 .name = "policy",
1041 .type = OPTION_ARGV_FUNC,
1042 .opt.argvfunc = cms_opt_verify_param,
1043 },
1044 {
1045 .name = "policy_check",
1046 .type = OPTION_ARGV_FUNC,
1047 .opt.argvfunc = cms_opt_verify_param,
1048 },
1049 {
1050 .name = "purpose",
1051 .type = OPTION_ARGV_FUNC,
1052 .opt.argvfunc = cms_opt_verify_param,
1053 },
1054 {
1055 .name = "x509_strict",
1056 .type = OPTION_ARGV_FUNC,
1057 .opt.argvfunc = cms_opt_verify_param,
1058 },
1059 {
1060 .name = NULL,
1061 .type = OPTION_ARGV_FUNC,
1062 .opt.argvfunc = cms_opt_cipher,
1063 },
1064 { NULL },
1065};
1066
1067static const struct option verify_shared_options[] = {
1068 {
1069 .name = "check_ss_sig",
1070 .desc = "Check the root CA self-signed certificate signature",
1071 },
1072 {
1073 .name = "crl_check",
1074 .desc = "Enable CRL checking for the leaf certificate",
1075 },
1076 {
1077 .name = "crl_check_all",
1078 .desc = "Enable CRL checking for the entire certificate chain",
1079 },
1080 {
1081 .name = "extended_crl",
1082 .desc = "Enable extended CRL support",
1083 },
1084 {
1085 .name = "ignore_critical",
1086 .desc = "Disable critical extension checking",
1087 },
1088 {
1089 .name = "issuer_checks",
1090 .desc = "Enable debugging of certificate issuer checks",
1091 },
1092 {
1093 .name = "policy",
1094 .argname = "name",
1095 .desc = "Add given policy to the acceptable set",
1096 },
1097 {
1098 .name = "policy_check",
1099 .desc = "Enable certificate policy checking",
1100 },
1101 {
1102 .name = "purpose",
1103 .argname = "name",
1104 .desc = "Verify for the given purpose",
1105 },
1106 {
1107 .name = "x509_strict",
1108 .desc = "Use strict X.509 rules (disables workarounds)",
1109 },
1110 { NULL },
1111};
1112
1113static void
1114cms_usage(void)
1115{
1116 int i;
1117
1118 fprintf(stderr, "usage: cms "
1119 "[-aes128 | -aes192 | -aes256 | -camellia128 |\n"
1120 " -camellia192 | -camellia256 | -des | -des3 |\n"
1121 " -rc2-40 | -rc2-64 | -rc2-128] [-CAfile file]\n"
1122 " [-CApath directory] [-CRLfile file] [-binary]\n"
1123 " [-certfile file] [-certsout file] [-cmsout] [-compress]\n"
1124 " [-content file] [-crlfeol] [-data_create] [-data_out]\n"
1125 " [-debug_decrypt] [-decrypt] [-digest_create] [-digest_verify]\n"
1126 " [-econtent_type type] [-encrypt] [-EncryptedData_decrypt]\n"
1127 " [-EncryptedData_encrypt] [-from addr] [-in file]\n"
1128 " [-inform der | pem | smime] [-inkey file]\n"
1129 " [-keyform der | pem] [-keyid] [-keyopt nm:v] [-md digest]\n"
1130 " [-no_attr_verify] [-no_content_verify]\n"
1131 " [-no_signer_cert_verify] [-noattr] [-nocerts] [-nodetach]\n"
1132 " [-nointern] [-nooldmime] [-noout] [-nosigs] [-nosmimecap]\n"
1133 " [-noverify] [-out file] [-outform der | pem | smime]\n"
1134 " [-passin src] [-print] [-pwri_password arg]\n"
1135 " [-rctform der | pem | smime]\n"
1136 " [-receipt_request_all | -receipt_request_first]\n"
1137 " [-receipt_request_from addr] [-receipt_request_print]\n"
1138 " [-receipt_request_to addr] [-recip file] [-resign]\n"
1139 " [-secretkey key] [-secretkeyid id] [-sign] [-sign_receipt]\n"
1140 " [-signer file] [-stream | -indef | -noindef] [-subject s]\n"
1141 " [-text] [-to addr] [-uncompress] [-verify]\n"
1142 " [-verify_receipt file] [-verify_retcode] [cert.pem ...]\n\n");
1143
1144 options_usage(cms_options);
1145
1146 fprintf(stderr, "\nVerification options:\n\n");
1147 options_usage(verify_shared_options);
1148
1149 fprintf(stderr, "\nValid purposes:\n\n");
1150 for (i = 0; i < X509_PURPOSE_get_count(); i++) {
1151 const X509_PURPOSE *ptmp = X509_PURPOSE_get0(i);
1152 fprintf(stderr, " %-18s%s\n", X509_PURPOSE_get0_sname(ptmp),
1153 X509_PURPOSE_get0_name(ptmp));
1154 }
1155}
1156
1157int
1158cms_main(int argc, char **argv)
1159{
1160 int ret = 0;
1161 char **args;
1162 int argsused = 0;
1163 const char *inmode = "r", *outmode = "w";
1164 CMS_ContentInfo *cms = NULL, *rcms = NULL;
1165 X509_STORE *store = NULL;
1166 X509 *recip = NULL, *signer = NULL;
1167 EVP_PKEY *key = NULL;
1168 STACK_OF(X509) *other = NULL;
1169 STACK_OF(X509_CRL) *crls = NULL;
1170 BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
1171 int badarg = 0;
1172 CMS_ReceiptRequest *rr = NULL;
1173 char *passin = NULL;
1174 unsigned char *pwri_tmp = NULL;
1175
1176 if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
1177 perror("pledge");
1178 exit(1);
1179 }
1180
1181 memset(&cfg, 0, sizeof(cfg));
1182 cfg.flags = CMS_DETACHED;
1183 cfg.rr_allorfirst = -1;
1184 cfg.informat = FORMAT_SMIME;
1185 cfg.outformat = FORMAT_SMIME;
1186 cfg.rctformat = FORMAT_SMIME;
1187 cfg.keyform = FORMAT_PEM;
1188 if (options_parse(argc, argv, cms_options, NULL, &argsused) != 0) {
1189 goto argerr;
1190 }
1191 args = argv + argsused;
1192 ret = 1;
1193
1194 if (((cfg.rr_allorfirst != -1) || cfg.rr_from != NULL) &&
1195 cfg.rr_to == NULL) {
1196 BIO_puts(bio_err, "No Signed Receipts Recipients\n");
1197 goto argerr;
1198 }
1199 if (!(cfg.operation & SMIME_SIGNERS) &&
1200 (cfg.rr_to != NULL || cfg.rr_from != NULL)) {
1201 BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
1202 goto argerr;
1203 }
1204 if (!(cfg.operation & SMIME_SIGNERS) &&
1205 (cfg.skkeys != NULL || cfg.sksigners != NULL)) {
1206 BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
1207 goto argerr;
1208 }
1209 if (cfg.operation & SMIME_SIGNERS) {
1210 if (cfg.keyfile != NULL &&
1211 cfg.signerfile == NULL) {
1212 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
1213 goto argerr;
1214 }
1215 /* Check to see if any final signer needs to be appended */
1216 if (cfg.signerfile != NULL) {
1217 if (cfg.sksigners == NULL &&
1218 (cfg.sksigners =
1219 sk_OPENSSL_STRING_new_null()) == NULL)
1220 goto end;
1221 if (!sk_OPENSSL_STRING_push(cfg.sksigners,
1222 cfg.signerfile))
1223 goto end;
1224 if (cfg.skkeys == NULL &&
1225 (cfg.skkeys =
1226 sk_OPENSSL_STRING_new_null()) == NULL)
1227 goto end;
1228 if (cfg.keyfile == NULL)
1229 cfg.keyfile = cfg.signerfile;
1230 if (!sk_OPENSSL_STRING_push(cfg.skkeys,
1231 cfg.keyfile))
1232 goto end;
1233 }
1234 if (cfg.sksigners == NULL) {
1235 BIO_printf(bio_err,
1236 "No signer certificate specified\n");
1237 badarg = 1;
1238 }
1239 cfg.signerfile = NULL;
1240 cfg.keyfile = NULL;
1241 } else if (cfg.operation == SMIME_DECRYPT) {
1242 if (cfg.recipfile == NULL &&
1243 cfg.keyfile == NULL &&
1244 cfg.secret_key == NULL &&
1245 cfg.pwri_pass == NULL) {
1246 BIO_printf(bio_err,
1247 "No recipient certificate or key specified\n");
1248 badarg = 1;
1249 }
1250 } else if (cfg.operation == SMIME_ENCRYPT) {
1251 if (*args == NULL && cfg.secret_key == NULL &&
1252 cfg.pwri_pass == NULL &&
1253 cfg.encerts == NULL) {
1254 BIO_printf(bio_err,
1255 "No recipient(s) certificate(s) specified\n");
1256 badarg = 1;
1257 }
1258 } else if (!cfg.operation) {
1259 badarg = 1;
1260 }
1261
1262 if (badarg) {
1263 argerr:
1264 cms_usage();
1265 goto end;
1266 }
1267
1268 if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
1269 BIO_printf(bio_err, "Error getting password\n");
1270 goto end;
1271 }
1272 ret = 2;
1273
1274 if (!(cfg.operation & SMIME_SIGNERS))
1275 cfg.flags &= ~CMS_DETACHED;
1276
1277 if (cfg.operation & SMIME_OP) {
1278 if (cfg.outformat == FORMAT_ASN1)
1279 outmode = "wb";
1280 } else {
1281 if (cfg.flags & CMS_BINARY)
1282 outmode = "wb";
1283 }
1284
1285 if (cfg.operation & SMIME_IP) {
1286 if (cfg.informat == FORMAT_ASN1)
1287 inmode = "rb";
1288 } else {
1289 if (cfg.flags & CMS_BINARY)
1290 inmode = "rb";
1291 }
1292
1293 if (cfg.operation == SMIME_ENCRYPT) {
1294 if (cfg.cipher == NULL) {
1295#ifndef OPENSSL_NO_DES
1296 cfg.cipher = EVP_des_ede3_cbc();
1297#else
1298 BIO_printf(bio_err, "No cipher selected\n");
1299 goto end;
1300#endif
1301 }
1302 if (cfg.secret_key != NULL &&
1303 cfg.secret_keyid == NULL) {
1304 BIO_printf(bio_err, "No secret key id\n");
1305 goto end;
1306 }
1307 if (*args != NULL && cfg.encerts == NULL)
1308 if ((cfg.encerts = sk_X509_new_null()) == NULL)
1309 goto end;
1310 while (*args) {
1311 if ((cfg.cert = load_cert(bio_err, *args,
1312 FORMAT_PEM, NULL,
1313 "recipient certificate file")) == NULL)
1314 goto end;
1315 if (!sk_X509_push(cfg.encerts, cfg.cert))
1316 goto end;
1317 cfg.cert = NULL;
1318 args++;
1319 }
1320 }
1321 if (cfg.certfile != NULL) {
1322 if ((other = load_certs(bio_err, cfg.certfile,
1323 FORMAT_PEM, NULL, "certificate file")) == NULL) {
1324 ERR_print_errors(bio_err);
1325 goto end;
1326 }
1327 }
1328
1329 if (cfg.crlfile != NULL) {
1330 crls = load_crls(bio_err, cfg.crlfile, FORMAT_PEM, NULL,
1331 "other CRLs");
1332 if (crls == NULL)
1333 goto end;
1334 }
1335
1336 if (cfg.recipfile != NULL &&
1337 (cfg.operation == SMIME_DECRYPT)) {
1338 if ((recip = load_cert(bio_err, cfg.recipfile,
1339 FORMAT_PEM, NULL, "recipient certificate file")) == NULL) {
1340 ERR_print_errors(bio_err);
1341 goto end;
1342 }
1343 }
1344 if (cfg.operation == SMIME_SIGN_RECEIPT) {
1345 if ((signer = load_cert(bio_err, cfg.signerfile,
1346 FORMAT_PEM, NULL,
1347 "receipt signer certificate file")) == NULL) {
1348 ERR_print_errors(bio_err);
1349 goto end;
1350 }
1351 }
1352 if (cfg.operation == SMIME_DECRYPT) {
1353 if (cfg.keyfile == NULL)
1354 cfg.keyfile = cfg.recipfile;
1355 } else if ((cfg.operation == SMIME_SIGN) ||
1356 (cfg.operation == SMIME_SIGN_RECEIPT)) {
1357 if (cfg.keyfile == NULL)
1358 cfg.keyfile = cfg.signerfile;
1359 } else {
1360 cfg.keyfile = NULL;
1361 }
1362
1363 if (cfg.keyfile != NULL) {
1364 key = load_key(bio_err, cfg.keyfile, cfg.keyform,
1365 0, passin, "signing key file");
1366 if (key == NULL)
1367 goto end;
1368 }
1369 if (cfg.infile != NULL) {
1370 if ((in = BIO_new_file(cfg.infile, inmode)) == NULL) {
1371 BIO_printf(bio_err,
1372 "Can't open input file %s\n", cfg.infile);
1373 goto end;
1374 }
1375 } else {
1376 if ((in = BIO_new_fp(stdin, BIO_NOCLOSE)) == NULL)
1377 goto end;
1378 }
1379
1380 if (cfg.operation & SMIME_IP) {
1381 if (cfg.informat == FORMAT_SMIME)
1382 cms = SMIME_read_CMS(in, &indata);
1383 else if (cfg.informat == FORMAT_PEM)
1384 cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
1385 else if (cfg.informat == FORMAT_ASN1)
1386 cms = d2i_CMS_bio(in, NULL);
1387 else {
1388 BIO_printf(bio_err, "Bad input format for CMS file\n");
1389 goto end;
1390 }
1391
1392 if (cms == NULL) {
1393 BIO_printf(bio_err, "Error reading S/MIME message\n");
1394 goto end;
1395 }
1396 if (cfg.contfile != NULL) {
1397 BIO_free(indata);
1398 if ((indata = BIO_new_file(cfg.contfile,
1399 "rb")) == NULL) {
1400 BIO_printf(bio_err,
1401 "Can't read content file %s\n",
1402 cfg.contfile);
1403 goto end;
1404 }
1405 }
1406 if (cfg.certsoutfile != NULL) {
1407 STACK_OF(X509) *allcerts;
1408 if ((allcerts = CMS_get1_certs(cms)) == NULL)
1409 goto end;
1410 if (!save_certs(cfg.certsoutfile, allcerts)) {
1411 BIO_printf(bio_err,
1412 "Error writing certs to %s\n",
1413 cfg.certsoutfile);
1414 sk_X509_pop_free(allcerts, X509_free);
1415 ret = 5;
1416 goto end;
1417 }
1418 sk_X509_pop_free(allcerts, X509_free);
1419 }
1420 }
1421 if (cfg.rctfile != NULL) {
1422 char *rctmode = (cfg.rctformat == FORMAT_ASN1) ?
1423 "rb" : "r";
1424 if ((rctin = BIO_new_file(cfg.rctfile, rctmode)) == NULL) {
1425 BIO_printf(bio_err,
1426 "Can't open receipt file %s\n", cfg.rctfile);
1427 goto end;
1428 }
1429 if (cfg.rctformat == FORMAT_SMIME)
1430 rcms = SMIME_read_CMS(rctin, NULL);
1431 else if (cfg.rctformat == FORMAT_PEM)
1432 rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
1433 else if (cfg.rctformat == FORMAT_ASN1)
1434 rcms = d2i_CMS_bio(rctin, NULL);
1435 else {
1436 BIO_printf(bio_err, "Bad input format for receipt\n");
1437 goto end;
1438 }
1439
1440 if (rcms == NULL) {
1441 BIO_printf(bio_err, "Error reading receipt\n");
1442 goto end;
1443 }
1444 }
1445 if (cfg.outfile != NULL) {
1446 if ((out = BIO_new_file(cfg.outfile, outmode)) == NULL) {
1447 BIO_printf(bio_err,
1448 "Can't open output file %s\n", cfg.outfile);
1449 goto end;
1450 }
1451 } else {
1452 if ((out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
1453 goto end;
1454 }
1455
1456 if ((cfg.operation == SMIME_VERIFY) ||
1457 (cfg.operation == SMIME_VERIFY_RECEIPT)) {
1458 if ((store = setup_verify(bio_err, cfg.CAfile,
1459 cfg.CApath)) == NULL)
1460 goto end;
1461 if (cfg.vpm != NULL) {
1462 if (!X509_STORE_set1_param(store, cfg.vpm))
1463 goto end;
1464 }
1465 }
1466 ret = 3;
1467
1468 if (cfg.operation == SMIME_DATA_CREATE) {
1469 cms = CMS_data_create(in, cfg.flags);
1470 } else if (cfg.operation == SMIME_DIGEST_CREATE) {
1471 cms = CMS_digest_create(in, cfg.sign_md,
1472 cfg.flags);
1473 } else if (cfg.operation == SMIME_COMPRESS) {
1474 cms = CMS_compress(in, -1, cfg.flags);
1475 } else if (cfg.operation == SMIME_ENCRYPT) {
1476 int i;
1477 cfg.flags |= CMS_PARTIAL;
1478 cms = CMS_encrypt(NULL, in, cfg.cipher,
1479 cfg.flags);
1480 if (cms == NULL)
1481 goto end;
1482 for (i = 0; i < sk_X509_num(cfg.encerts); i++) {
1483 CMS_RecipientInfo *ri;
1484 struct cms_key_param *kparam;
1485 int tflags = cfg.flags;
1486 X509 *x;
1487
1488 if ((x = sk_X509_value(cfg.encerts, i)) == NULL)
1489 goto end;
1490 for (kparam = cfg.key_first; kparam != NULL;
1491 kparam = kparam->next) {
1492 if (kparam->idx == i) {
1493 tflags |= CMS_KEY_PARAM;
1494 break;
1495 }
1496 }
1497 ri = CMS_add1_recipient_cert(cms, x, tflags);
1498 if (ri == NULL)
1499 goto end;
1500 if (kparam != NULL) {
1501 EVP_PKEY_CTX *pctx;
1502 if ((pctx = CMS_RecipientInfo_get0_pkey_ctx(
1503 ri)) == NULL)
1504 goto end;
1505 if (!cms_set_pkey_param(pctx, kparam->param))
1506 goto end;
1507 }
1508 }
1509
1510 if (cfg.secret_key != NULL) {
1511 if (CMS_add0_recipient_key(cms, NID_undef,
1512 cfg.secret_key, cfg.secret_keylen,
1513 cfg.secret_keyid, cfg.secret_keyidlen,
1514 NULL, NULL, NULL) == NULL)
1515 goto end;
1516 /* NULL these because call absorbs them */
1517 cfg.secret_key = NULL;
1518 cfg.secret_keyid = NULL;
1519 }
1520 if (cfg.pwri_pass != NULL) {
1521 pwri_tmp = strdup(cfg.pwri_pass);
1522 if (pwri_tmp == NULL)
1523 goto end;
1524 if (CMS_add0_recipient_password(cms, -1, NID_undef,
1525 NID_undef, pwri_tmp, -1, NULL) == NULL)
1526 goto end;
1527 pwri_tmp = NULL;
1528 }
1529 if (!(cfg.flags & CMS_STREAM)) {
1530 if (!CMS_final(cms, in, NULL, cfg.flags))
1531 goto end;
1532 }
1533 } else if (cfg.operation == SMIME_ENCRYPTED_ENCRYPT) {
1534 cms = CMS_EncryptedData_encrypt(in, cfg.cipher,
1535 cfg.secret_key, cfg.secret_keylen,
1536 cfg.flags);
1537
1538 } else if (cfg.operation == SMIME_SIGN_RECEIPT) {
1539 CMS_ContentInfo *srcms = NULL;
1540 STACK_OF(CMS_SignerInfo) *sis;
1541 CMS_SignerInfo *si;
1542 sis = CMS_get0_SignerInfos(cms);
1543 if (sis == NULL)
1544 goto end;
1545 si = sk_CMS_SignerInfo_value(sis, 0);
1546 if (si == NULL)
1547 goto end;
1548 srcms = CMS_sign_receipt(si, signer, key, other,
1549 cfg.flags);
1550 if (srcms == NULL)
1551 goto end;
1552 CMS_ContentInfo_free(cms);
1553 cms = srcms;
1554 } else if (cfg.operation & SMIME_SIGNERS) {
1555 int i;
1556 /*
1557 * If detached data content we enable streaming if S/MIME
1558 * output format.
1559 */
1560 if (cfg.operation == SMIME_SIGN) {
1561
1562 if (cfg.flags & CMS_DETACHED) {
1563 if (cfg.outformat == FORMAT_SMIME)
1564 cfg.flags |= CMS_STREAM;
1565 }
1566 cfg.flags |= CMS_PARTIAL;
1567 cms = CMS_sign(NULL, NULL, other, in, cfg.flags);
1568 if (cms == NULL)
1569 goto end;
1570 if (cfg.econtent_type != NULL)
1571 if (!CMS_set1_eContentType(cms,
1572 cfg.econtent_type))
1573 goto end;
1574
1575 if (cfg.rr_to != NULL) {
1576 rr = make_receipt_request(cfg.rr_to,
1577 cfg.rr_allorfirst,
1578 cfg.rr_from);
1579 if (rr == NULL) {
1580 BIO_puts(bio_err,
1581 "Signed Receipt Request Creation Error\n");
1582 goto end;
1583 }
1584 }
1585 } else {
1586 cfg.flags |= CMS_REUSE_DIGEST;
1587 }
1588
1589 for (i = 0; i < sk_OPENSSL_STRING_num(cfg.sksigners); i++) {
1590 CMS_SignerInfo *si;
1591 struct cms_key_param *kparam;
1592 int tflags = cfg.flags;
1593
1594 cfg.signerfile = sk_OPENSSL_STRING_value(
1595 cfg.sksigners, i);
1596 cfg.keyfile = sk_OPENSSL_STRING_value(
1597 cfg.skkeys, i);
1598
1599 signer = load_cert(bio_err, cfg.signerfile,
1600 FORMAT_PEM, NULL, "signer certificate");
1601 if (signer == NULL)
1602 goto end;
1603 key = load_key(bio_err, cfg.keyfile,
1604 cfg.keyform, 0, passin, "signing key file");
1605 if (key == NULL)
1606 goto end;
1607 for (kparam = cfg.key_first; kparam != NULL;
1608 kparam = kparam->next) {
1609 if (kparam->idx == i) {
1610 tflags |= CMS_KEY_PARAM;
1611 break;
1612 }
1613 }
1614 si = CMS_add1_signer(cms, signer, key,
1615 cfg.sign_md, tflags);
1616 if (si == NULL)
1617 goto end;
1618 if (kparam != NULL) {
1619 EVP_PKEY_CTX *pctx;
1620 if ((pctx = CMS_SignerInfo_get0_pkey_ctx(
1621 si)) == NULL)
1622 goto end;
1623 if (!cms_set_pkey_param(pctx, kparam->param))
1624 goto end;
1625 }
1626 if (rr != NULL && !CMS_add1_ReceiptRequest(si, rr))
1627 goto end;
1628 X509_free(signer);
1629 signer = NULL;
1630 EVP_PKEY_free(key);
1631 key = NULL;
1632 }
1633 /* If not streaming or resigning finalize structure */
1634 if ((cfg.operation == SMIME_SIGN) &&
1635 !(cfg.flags & CMS_STREAM)) {
1636 if (!CMS_final(cms, in, NULL, cfg.flags))
1637 goto end;
1638 }
1639 }
1640 if (cms == NULL) {
1641 BIO_printf(bio_err, "Error creating CMS structure\n");
1642 goto end;
1643 }
1644 ret = 4;
1645 if (cfg.operation == SMIME_DECRYPT) {
1646 if (cfg.flags & CMS_DEBUG_DECRYPT)
1647 CMS_decrypt(cms, NULL, NULL, NULL, NULL,
1648 cfg.flags);
1649
1650 if (cfg.secret_key != NULL) {
1651 if (!CMS_decrypt_set1_key(cms, cfg.secret_key,
1652 cfg.secret_keylen, cfg.secret_keyid,
1653 cfg.secret_keyidlen)) {
1654 BIO_puts(bio_err,
1655 "Error decrypting CMS using secret key\n");
1656 goto end;
1657 }
1658 }
1659 if (key != NULL) {
1660 if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
1661 BIO_puts(bio_err,
1662 "Error decrypting CMS using private key\n");
1663 goto end;
1664 }
1665 }
1666 if (cfg.pwri_pass != NULL) {
1667 if (!CMS_decrypt_set1_password(cms,
1668 cfg.pwri_pass, -1)) {
1669 BIO_puts(bio_err,
1670 "Error decrypting CMS using password\n");
1671 goto end;
1672 }
1673 }
1674 if (!CMS_decrypt(cms, NULL, NULL, indata, out,
1675 cfg.flags)) {
1676 BIO_printf(bio_err, "Error decrypting CMS structure\n");
1677 goto end;
1678 }
1679 } else if (cfg.operation == SMIME_DATAOUT) {
1680 if (!CMS_data(cms, out, cfg.flags))
1681 goto end;
1682 } else if (cfg.operation == SMIME_UNCOMPRESS) {
1683 if (!CMS_uncompress(cms, indata, out, cfg.flags))
1684 goto end;
1685 } else if (cfg.operation == SMIME_DIGEST_VERIFY) {
1686 if (CMS_digest_verify(cms, indata, out, cfg.flags) > 0)
1687 BIO_printf(bio_err, "Verification successful\n");
1688 else {
1689 BIO_printf(bio_err, "Verification failure\n");
1690 goto end;
1691 }
1692 } else if (cfg.operation == SMIME_ENCRYPTED_DECRYPT) {
1693 if (!CMS_EncryptedData_decrypt(cms, cfg.secret_key,
1694 cfg.secret_keylen, indata, out, cfg.flags))
1695 goto end;
1696 } else if (cfg.operation == SMIME_VERIFY) {
1697 if (cfg.crlfile != NULL) {
1698 int i;
1699
1700 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
1701 X509_CRL *crl = sk_X509_CRL_value(crls, i);
1702 if (!CMS_add1_crl(cms, crl))
1703 goto end;
1704 }
1705 }
1706 if (CMS_verify(cms, other, store, indata, out,
1707 cfg.flags) > 0) {
1708 BIO_printf(bio_err, "Verification successful\n");
1709 } else {
1710 BIO_printf(bio_err, "Verification failure\n");
1711 if (cfg.verify_retcode)
1712 ret = verify_err + 32;
1713 goto end;
1714 }
1715 if (cfg.signerfile != NULL) {
1716 STACK_OF(X509) *signers;
1717 if ((signers = CMS_get0_signers(cms)) == NULL)
1718 goto end;
1719 if (!save_certs(cfg.signerfile, signers)) {
1720 BIO_printf(bio_err,
1721 "Error writing signers to %s\n",
1722 cfg.signerfile);
1723 sk_X509_free(signers);
1724 ret = 5;
1725 goto end;
1726 }
1727 sk_X509_free(signers);
1728 }
1729 if (cfg.rr_print)
1730 receipt_request_print(bio_err, cms);
1731
1732 } else if (cfg.operation == SMIME_VERIFY_RECEIPT) {
1733 if (CMS_verify_receipt(rcms, cms, other, store,
1734 cfg.flags) > 0) {
1735 BIO_printf(bio_err, "Verification successful\n");
1736 } else {
1737 BIO_printf(bio_err, "Verification failure\n");
1738 goto end;
1739 }
1740 } else {
1741 if (cfg.noout) {
1742 if (cfg.print &&
1743 !CMS_ContentInfo_print_ctx(out, cms, 0, NULL))
1744 goto end;
1745 } else if (cfg.outformat == FORMAT_SMIME) {
1746 if (cfg.to != NULL)
1747 BIO_printf(out, "To: %s\n", cfg.to);
1748 if (cfg.from != NULL)
1749 BIO_printf(out, "From: %s\n", cfg.from);
1750 if (cfg.subject != NULL)
1751 BIO_printf(out, "Subject: %s\n",
1752 cfg.subject);
1753 if (cfg.operation == SMIME_RESIGN)
1754 ret = SMIME_write_CMS(out, cms, indata,
1755 cfg.flags);
1756 else
1757 ret = SMIME_write_CMS(out, cms, in,
1758 cfg.flags);
1759 } else if (cfg.outformat == FORMAT_PEM) {
1760 ret = PEM_write_bio_CMS_stream(out, cms, in,
1761 cfg.flags);
1762 } else if (cfg.outformat == FORMAT_ASN1) {
1763 ret = i2d_CMS_bio_stream(out, cms, in, cfg.flags);
1764 } else {
1765 BIO_printf(bio_err, "Bad output format for CMS file\n");
1766 goto end;
1767 }
1768 if (ret <= 0) {
1769 ret = 6;
1770 goto end;
1771 }
1772 }
1773 ret = 0;
1774
1775 end:
1776 if (ret)
1777 ERR_print_errors(bio_err);
1778
1779 sk_X509_pop_free(cfg.encerts, X509_free);
1780 sk_X509_pop_free(other, X509_free);
1781 sk_X509_CRL_pop_free(crls, X509_CRL_free);
1782 X509_VERIFY_PARAM_free(cfg.vpm);
1783 sk_OPENSSL_STRING_free(cfg.sksigners);
1784 sk_OPENSSL_STRING_free(cfg.skkeys);
1785 free(cfg.secret_key);
1786 free(cfg.secret_keyid);
1787 free(pwri_tmp);
1788 ASN1_OBJECT_free(cfg.econtent_type);
1789 CMS_ReceiptRequest_free(rr);
1790 sk_OPENSSL_STRING_free(cfg.rr_to);
1791 sk_OPENSSL_STRING_free(cfg.rr_from);
1792 for (cfg.key_param = cfg.key_first; cfg.key_param;) {
1793 struct cms_key_param *tparam;
1794 sk_OPENSSL_STRING_free(cfg.key_param->param);
1795 tparam = cfg.key_param->next;
1796 free(cfg.key_param);
1797 cfg.key_param = tparam;
1798 }
1799 X509_STORE_free(store);
1800 X509_free(cfg.cert);
1801 X509_free(recip);
1802 X509_free(signer);
1803 EVP_PKEY_free(key);
1804 CMS_ContentInfo_free(cms);
1805 CMS_ContentInfo_free(rcms);
1806 BIO_free(rctin);
1807 BIO_free(in);
1808 BIO_free(indata);
1809 BIO_free_all(out);
1810 free(passin);
1811
1812 return (ret);
1813}
1814
1815static int
1816save_certs(char *signerfile, STACK_OF(X509) *signers)
1817{
1818 int i;
1819 BIO *tmp;
1820
1821 if (signerfile == NULL)
1822 return 1;
1823 tmp = BIO_new_file(signerfile, "w");
1824 if (tmp == NULL)
1825 return 0;
1826 for (i = 0; i < sk_X509_num(signers); i++)
1827 PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1828 BIO_free(tmp);
1829 return 1;
1830}
1831
1832static void
1833gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
1834{
1835 STACK_OF(GENERAL_NAME) *gens;
1836 GENERAL_NAME *gen;
1837 int i, j;
1838
1839 for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
1840 gens = sk_GENERAL_NAMES_value(gns, i);
1841 for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
1842 gen = sk_GENERAL_NAME_value(gens, j);
1843 BIO_puts(out, " ");
1844 GENERAL_NAME_print(out, gen);
1845 BIO_puts(out, "\n");
1846 }
1847 }
1848 return;
1849}
1850
1851static void
1852receipt_request_print(BIO *out, CMS_ContentInfo *cms)
1853{
1854 STACK_OF(CMS_SignerInfo) *sis;
1855 CMS_SignerInfo *si;
1856 CMS_ReceiptRequest *rr;
1857 int allorfirst;
1858 STACK_OF(GENERAL_NAMES) *rto, *rlist;
1859 ASN1_STRING *scid;
1860 int i, rv;
1861
1862 if ((sis = CMS_get0_SignerInfos(cms)) == NULL)
1863 return;
1864 for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
1865 if ((si = sk_CMS_SignerInfo_value(sis, i)) == NULL)
1866 return;
1867 rv = CMS_get1_ReceiptRequest(si, &rr);
1868 BIO_printf(bio_err, "Signer %d:\n", i + 1);
1869 if (rv == 0) {
1870 BIO_puts(bio_err, " No Receipt Request\n");
1871 } else if (rv < 0) {
1872 BIO_puts(bio_err, " Receipt Request Parse Error\n");
1873 ERR_print_errors(bio_err);
1874 } else {
1875 char *id;
1876 int idlen;
1877
1878 CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1879 &rlist, &rto);
1880 BIO_puts(out, " Signed Content ID:\n");
1881 idlen = ASN1_STRING_length(scid);
1882 id = (char *) ASN1_STRING_data(scid);
1883 BIO_dump_indent(out, id, idlen, 4);
1884 BIO_puts(out, " Receipts From");
1885 if (rlist != NULL) {
1886 BIO_puts(out, " List:\n");
1887 gnames_stack_print(out, rlist);
1888 } else if (allorfirst == 1) {
1889 BIO_puts(out, ": First Tier\n");
1890 } else if (allorfirst == 0) {
1891 BIO_puts(out, ": All\n");
1892 } else {
1893 BIO_printf(out, " Unknown (%d)\n", allorfirst);
1894 }
1895 BIO_puts(out, " Receipts To:\n");
1896 gnames_stack_print(out, rto);
1897 }
1898 CMS_ReceiptRequest_free(rr);
1899 }
1900}
1901
1902static STACK_OF(GENERAL_NAMES) *
1903make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
1904{
1905 int i;
1906 STACK_OF(GENERAL_NAMES) *ret;
1907 GENERAL_NAMES *gens = NULL;
1908 GENERAL_NAME *gen = NULL;
1909
1910 if ((ret = sk_GENERAL_NAMES_new_null()) == NULL)
1911 goto err;
1912 for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
1913 char *str = sk_OPENSSL_STRING_value(ns, i);
1914 gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1915 if (gen == NULL)
1916 goto err;
1917 gens = GENERAL_NAMES_new();
1918 if (gens == NULL)
1919 goto err;
1920 if (!sk_GENERAL_NAME_push(gens, gen))
1921 goto err;
1922 gen = NULL;
1923 if (!sk_GENERAL_NAMES_push(ret, gens))
1924 goto err;
1925 gens = NULL;
1926 }
1927
1928 return ret;
1929
1930 err:
1931 sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1932 GENERAL_NAMES_free(gens);
1933 GENERAL_NAME_free(gen);
1934
1935 return NULL;
1936}
1937
1938
1939static CMS_ReceiptRequest *
1940make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
1941 STACK_OF(OPENSSL_STRING) *rr_from)
1942{
1943 STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
1944 CMS_ReceiptRequest *rr;
1945
1946 rct_to = make_names_stack(rr_to);
1947 if (rct_to == NULL)
1948 goto err;
1949 if (rr_from != NULL) {
1950 rct_from = make_names_stack(rr_from);
1951 if (rct_from == NULL)
1952 goto err;
1953 } else {
1954 rct_from = NULL;
1955 }
1956
1957 if ((rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
1958 rct_to)) == NULL)
1959 goto err;
1960
1961 return rr;
1962
1963 err:
1964 sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
1965 sk_GENERAL_NAMES_pop_free(rct_from, GENERAL_NAMES_free);
1966 return NULL;
1967}
1968
1969static int
1970cms_set_pkey_param(EVP_PKEY_CTX *pctx, STACK_OF(OPENSSL_STRING) *param)
1971{
1972 char *keyopt;
1973 int i;
1974
1975 if (sk_OPENSSL_STRING_num(param) <= 0)
1976 return 1;
1977 for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) {
1978 keyopt = sk_OPENSSL_STRING_value(param, i);
1979 if (pkey_ctrl_string(pctx, keyopt) <= 0) {
1980 BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt);
1981 ERR_print_errors(bio_err);
1982 return 0;
1983 }
1984 }
1985 return 1;
1986}
1987
1988#endif
diff --git a/src/usr.bin/openssl/crl.c b/src/usr.bin/openssl/crl.c
deleted file mode 100644
index e64038dfda..0000000000
--- a/src/usr.bin/openssl/crl.c
+++ /dev/null
@@ -1,482 +0,0 @@
1/* $OpenBSD: crl.c,v 1.17 2023/03/06 14:32:05 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include "apps.h"
64
65#include <openssl/bio.h>
66#include <openssl/err.h>
67#include <openssl/pem.h>
68#include <openssl/x509.h>
69#include <openssl/x509v3.h>
70
71static struct {
72 char *cafile;
73 char *capath;
74 int crlnumber;
75 int fingerprint;
76 int hash;
77 int hash_old;
78 char *infile;
79 int informat;
80 int issuer;
81 int lastupdate;
82 char *nameopt;
83 int nextupdate;
84 int noout;
85 char *outfile;
86 int outformat;
87 int text;
88 int verify;
89} cfg;
90
91static const struct option crl_options[] = {
92 {
93 .name = "CAfile",
94 .argname = "file",
95 .desc = "Verify the CRL using certificates in the given file",
96 .type = OPTION_ARG,
97 .opt.arg = &cfg.cafile,
98 },
99 {
100 .name = "CApath",
101 .argname = "path",
102 .desc = "Verify the CRL using certificates in the given path",
103 .type = OPTION_ARG,
104 .opt.arg = &cfg.capath,
105 },
106 {
107 .name = "crlnumber",
108 .desc = "Print the CRL number",
109 .type = OPTION_FLAG_ORD,
110 .opt.flag = &cfg.crlnumber,
111 },
112 {
113 .name = "fingerprint",
114 .desc = "Print the CRL fingerprint",
115 .type = OPTION_FLAG_ORD,
116 .opt.flag = &cfg.fingerprint,
117 },
118 {
119 .name = "hash",
120 .desc = "Print the hash of the issuer name",
121 .type = OPTION_FLAG_ORD,
122 .opt.flag = &cfg.hash,
123 },
124 {
125 .name = "hash_old",
126 .desc = "Print an old-style (MD5) hash of the issuer name",
127 .type = OPTION_FLAG_ORD,
128 .opt.flag = &cfg.hash_old,
129 },
130 {
131 .name = "in",
132 .argname = "file",
133 .desc = "Input file to read from (stdin if unspecified)",
134 .type = OPTION_ARG,
135 .opt.arg = &cfg.infile,
136 },
137 {
138 .name = "inform",
139 .argname = "format",
140 .desc = "Input format (DER or PEM)",
141 .type = OPTION_ARG_FORMAT,
142 .opt.value = &cfg.informat,
143 },
144 {
145 .name = "issuer",
146 .desc = "Print the issuer name",
147 .type = OPTION_FLAG_ORD,
148 .opt.flag = &cfg.issuer,
149 },
150 {
151 .name = "lastupdate",
152 .desc = "Print the lastUpdate field",
153 .type = OPTION_FLAG_ORD,
154 .opt.flag = &cfg.lastupdate,
155 },
156 {
157 .name = "nameopt",
158 .argname = "options",
159 .desc = "Specify certificate name options",
160 .type = OPTION_ARG,
161 .opt.arg = &cfg.nameopt,
162 },
163 {
164 .name = "nextupdate",
165 .desc = "Print the nextUpdate field",
166 .type = OPTION_FLAG_ORD,
167 .opt.flag = &cfg.nextupdate,
168 },
169 {
170 .name = "noout",
171 .desc = "Do not output the encoded version of the CRL",
172 .type = OPTION_FLAG,
173 .opt.flag = &cfg.noout,
174 },
175 {
176 .name = "out",
177 .argname = "file",
178 .desc = "Output file to write to (stdout if unspecified)",
179 .type = OPTION_ARG,
180 .opt.arg = &cfg.outfile,
181 },
182 {
183 .name = "outform",
184 .argname = "format",
185 .desc = "Output format (DER or PEM)",
186 .type = OPTION_ARG_FORMAT,
187 .opt.value = &cfg.outformat,
188 },
189 {
190 .name = "text",
191 .desc = "Print out the CRL in text form",
192 .type = OPTION_FLAG,
193 .opt.flag = &cfg.text,
194 },
195 {
196 .name = "verify",
197 .desc = "Verify the signature on the CRL",
198 .type = OPTION_FLAG,
199 .opt.flag = &cfg.verify,
200 },
201 {NULL},
202};
203
204static void
205crl_usage(void)
206{
207 fprintf(stderr,
208 "usage: crl [-CAfile file] [-CApath dir] [-fingerprint] [-hash]\n"
209 " [-in file] [-inform DER | PEM] [-issuer] [-lastupdate]\n"
210 " [-nextupdate] [-noout] [-out file] [-outform DER | PEM]\n"
211 " [-text]\n\n");
212 options_usage(crl_options);
213}
214
215static X509_CRL *load_crl(char *file, int format);
216static BIO *bio_out = NULL;
217
218int
219crl_main(int argc, char **argv)
220{
221 unsigned long nmflag = 0;
222 X509_CRL *x = NULL;
223 int ret = 1, i;
224 BIO *out = NULL;
225 X509_STORE *store = NULL;
226 X509_STORE_CTX *ctx = NULL;
227 X509_LOOKUP *lookup = NULL;
228 X509_OBJECT *xobj = NULL;
229 EVP_PKEY *pkey;
230 const EVP_MD *digest;
231 char *digest_name = NULL;
232
233 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
234 perror("pledge");
235 exit(1);
236 }
237
238 if (bio_out == NULL) {
239 if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
240 BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
241 }
242 }
243
244 digest = EVP_sha256();
245
246 memset(&cfg, 0, sizeof(cfg));
247 cfg.informat = FORMAT_PEM;
248 cfg.outformat = FORMAT_PEM;
249
250 if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) {
251 crl_usage();
252 goto end;
253 }
254
255 if (cfg.cafile != NULL || cfg.capath != NULL)
256 cfg.verify = 1;
257
258 if (cfg.nameopt != NULL) {
259 if (set_name_ex(&nmflag, cfg.nameopt) != 1) {
260 fprintf(stderr,
261 "Invalid -nameopt argument '%s'\n",
262 cfg.nameopt);
263 goto end;
264 }
265 }
266
267 if (digest_name != NULL) {
268 if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
269 fprintf(stderr,
270 "Unknown message digest algorithm '%s'\n",
271 digest_name);
272 goto end;
273 }
274 }
275
276 x = load_crl(cfg.infile, cfg.informat);
277 if (x == NULL)
278 goto end;
279
280 if (cfg.verify) {
281 store = X509_STORE_new();
282 if (store == NULL)
283 goto end;
284 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
285 if (lookup == NULL)
286 goto end;
287 if (!X509_LOOKUP_load_file(lookup, cfg.cafile,
288 X509_FILETYPE_PEM))
289 X509_LOOKUP_load_file(lookup, NULL,
290 X509_FILETYPE_DEFAULT);
291
292 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
293 if (lookup == NULL)
294 goto end;
295 if (!X509_LOOKUP_add_dir(lookup, cfg.capath,
296 X509_FILETYPE_PEM))
297 X509_LOOKUP_add_dir(lookup, NULL,
298 X509_FILETYPE_DEFAULT);
299 ERR_clear_error();
300
301 if ((ctx = X509_STORE_CTX_new()) == NULL)
302 goto end;
303 if ((xobj = X509_OBJECT_new()) == NULL)
304 goto end;
305
306 if (!X509_STORE_CTX_init(ctx, store, NULL, NULL)) {
307 BIO_printf(bio_err,
308 "Error initialising X509 store\n");
309 goto end;
310 }
311 i = X509_STORE_get_by_subject(ctx, X509_LU_X509,
312 X509_CRL_get_issuer(x), xobj);
313 if (i <= 0) {
314 BIO_printf(bio_err,
315 "Error getting CRL issuer certificate\n");
316 goto end;
317 }
318 pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj));
319 X509_OBJECT_free(xobj);
320 xobj = NULL;
321 if (!pkey) {
322 BIO_printf(bio_err,
323 "Error getting CRL issuer public key\n");
324 goto end;
325 }
326 i = X509_CRL_verify(x, pkey);
327 EVP_PKEY_free(pkey);
328 if (i < 0)
329 goto end;
330 if (i == 0)
331 BIO_printf(bio_err, "verify failure\n");
332 else
333 BIO_printf(bio_err, "verify OK\n");
334 }
335
336 /* Print requested information the order that the flags were given. */
337 for (i = 1; i <= argc; i++) {
338 if (cfg.issuer == i) {
339 print_name(bio_out, "issuer=",
340 X509_CRL_get_issuer(x), nmflag);
341 }
342 if (cfg.crlnumber == i) {
343 ASN1_INTEGER *crlnum;
344 crlnum = X509_CRL_get_ext_d2i(x,
345 NID_crl_number, NULL, NULL);
346 BIO_printf(bio_out, "crlNumber=");
347 if (crlnum) {
348 i2a_ASN1_INTEGER(bio_out, crlnum);
349 ASN1_INTEGER_free(crlnum);
350 } else
351 BIO_puts(bio_out, "<NONE>");
352 BIO_printf(bio_out, "\n");
353 }
354 if (cfg.hash == i) {
355 BIO_printf(bio_out, "%08lx\n",
356 X509_NAME_hash(X509_CRL_get_issuer(x)));
357 }
358#ifndef OPENSSL_NO_MD5
359 if (cfg.hash_old == i) {
360 BIO_printf(bio_out, "%08lx\n",
361 X509_NAME_hash_old(X509_CRL_get_issuer(x)));
362 }
363#endif
364 if (cfg.lastupdate == i) {
365 BIO_printf(bio_out, "lastUpdate=");
366 ASN1_TIME_print(bio_out,
367 X509_CRL_get_lastUpdate(x));
368 BIO_printf(bio_out, "\n");
369 }
370 if (cfg.nextupdate == i) {
371 BIO_printf(bio_out, "nextUpdate=");
372 if (X509_CRL_get_nextUpdate(x))
373 ASN1_TIME_print(bio_out,
374 X509_CRL_get_nextUpdate(x));
375 else
376 BIO_printf(bio_out, "NONE");
377 BIO_printf(bio_out, "\n");
378 }
379 if (cfg.fingerprint == i) {
380 int j;
381 unsigned int n;
382 unsigned char md[EVP_MAX_MD_SIZE];
383
384 if (!X509_CRL_digest(x, digest, md, &n)) {
385 BIO_printf(bio_err, "out of memory\n");
386 goto end;
387 }
388 BIO_printf(bio_out, "%s Fingerprint=",
389 OBJ_nid2sn(EVP_MD_type(digest)));
390 for (j = 0; j < (int) n; j++) {
391 BIO_printf(bio_out, "%02X%c", md[j],
392 (j + 1 == (int)n) ? '\n' : ':');
393 }
394 }
395 }
396
397 out = BIO_new(BIO_s_file());
398 if (out == NULL) {
399 ERR_print_errors(bio_err);
400 goto end;
401 }
402 if (cfg.outfile == NULL) {
403 BIO_set_fp(out, stdout, BIO_NOCLOSE);
404 } else {
405 if (BIO_write_filename(out, cfg.outfile) <= 0) {
406 perror(cfg.outfile);
407 goto end;
408 }
409 }
410
411 if (cfg.text)
412 X509_CRL_print(out, x);
413
414 if (cfg.noout) {
415 ret = 0;
416 goto end;
417 }
418 if (cfg.outformat == FORMAT_ASN1)
419 i = (int) i2d_X509_CRL_bio(out, x);
420 else if (cfg.outformat == FORMAT_PEM)
421 i = PEM_write_bio_X509_CRL(out, x);
422 else {
423 BIO_printf(bio_err,
424 "bad output format specified for outfile\n");
425 goto end;
426 }
427 if (!i) {
428 BIO_printf(bio_err, "unable to write CRL\n");
429 goto end;
430 }
431 ret = 0;
432
433 end:
434 BIO_free_all(out);
435 BIO_free_all(bio_out);
436 bio_out = NULL;
437 X509_CRL_free(x);
438 X509_STORE_CTX_free(ctx);
439 X509_STORE_free(store);
440 X509_OBJECT_free(xobj);
441
442 return (ret);
443}
444
445static X509_CRL *
446load_crl(char *infile, int format)
447{
448 X509_CRL *x = NULL;
449 BIO *in = NULL;
450
451 in = BIO_new(BIO_s_file());
452 if (in == NULL) {
453 ERR_print_errors(bio_err);
454 goto end;
455 }
456 if (infile == NULL)
457 BIO_set_fp(in, stdin, BIO_NOCLOSE);
458 else {
459 if (BIO_read_filename(in, infile) <= 0) {
460 perror(infile);
461 goto end;
462 }
463 }
464 if (format == FORMAT_ASN1)
465 x = d2i_X509_CRL_bio(in, NULL);
466 else if (format == FORMAT_PEM)
467 x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
468 else {
469 BIO_printf(bio_err,
470 "bad input format specified for input crl\n");
471 goto end;
472 }
473 if (x == NULL) {
474 BIO_printf(bio_err, "unable to load CRL\n");
475 ERR_print_errors(bio_err);
476 goto end;
477 }
478
479 end:
480 BIO_free(in);
481 return (x);
482}
diff --git a/src/usr.bin/openssl/crl2p7.c b/src/usr.bin/openssl/crl2p7.c
deleted file mode 100644
index 697d9ca96c..0000000000
--- a/src/usr.bin/openssl/crl2p7.c
+++ /dev/null
@@ -1,329 +0,0 @@
1/* $OpenBSD: crl2p7.c,v 1.12 2024/12/26 14:07:58 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
60 * and donated 'to the cause' along with lots and lots of other fixes to
61 * the library. */
62
63#include <sys/types.h>
64
65#include <stdio.h>
66#include <string.h>
67
68#include "apps.h"
69
70#include <openssl/err.h>
71#include <openssl/evp.h>
72#include <openssl/objects.h>
73#include <openssl/pem.h>
74#include <openssl/pkcs7.h>
75#include <openssl/x509.h>
76
77static int add_certs_from_file(STACK_OF(X509) * stack, char *certfile);
78
79static struct {
80 STACK_OF(OPENSSL_STRING) *certflst;
81 char *infile;
82 int informat;
83 int nocrl;
84 char *outfile;
85 int outformat;
86} cfg;
87
88static int
89crl2p7_opt_certfile(char *arg)
90{
91 if (cfg.certflst == NULL)
92 cfg.certflst = sk_OPENSSL_STRING_new_null();
93 if (cfg.certflst == NULL) {
94 fprintf(stderr, "out of memory\n");
95 return (1);
96 }
97 if (!sk_OPENSSL_STRING_push(cfg.certflst, arg)) {
98 fprintf(stderr, "out of memory\n");
99 return (1);
100 }
101
102 return (0);
103}
104
105static const struct option crl2p7_options[] = {
106 {
107 .name = "certfile",
108 .argname = "file",
109 .desc = "Chain of PEM certificates to a trusted CA",
110 .type = OPTION_ARG_FUNC,
111 .opt.argfunc = crl2p7_opt_certfile,
112 },
113 {
114 .name = "in",
115 .argname = "file",
116 .desc = "Input file (default stdin)",
117 .type = OPTION_ARG,
118 .opt.arg = &cfg.infile,
119 },
120 {
121 .name = "inform",
122 .argname = "format",
123 .desc = "Input format (DER or PEM (default))",
124 .type = OPTION_ARG_FORMAT,
125 .opt.value = &cfg.informat,
126 },
127 {
128 .name = "nocrl",
129 .desc = "Do not read CRL from input or include CRL in output",
130 .type = OPTION_FLAG,
131 .opt.flag = &cfg.nocrl,
132 },
133 {
134 .name = "out",
135 .argname = "file",
136 .desc = "Output file (default stdout)",
137 .type = OPTION_ARG,
138 .opt.arg = &cfg.outfile,
139 },
140 {
141 .name = "outform",
142 .argname = "format",
143 .desc = "Output format (DER or PEM (default))",
144 .type = OPTION_ARG_FORMAT,
145 .opt.value = &cfg.outformat,
146 },
147 { NULL },
148};
149
150static void
151crl2p7_usage(void)
152{
153 fprintf(stderr,
154 "usage: crl2p7 [-certfile file] [-in file] [-inform DER | PEM]\n"
155 " [-nocrl] [-out file] [-outform DER | PEM]\n\n");
156 options_usage(crl2p7_options);
157}
158
159int
160crl2pkcs7_main(int argc, char **argv)
161{
162 int i;
163 BIO *in = NULL, *out = NULL;
164 char *certfile;
165 PKCS7 *p7 = NULL;
166 PKCS7_SIGNED *p7s = NULL;
167 X509_CRL *crl = NULL;
168 STACK_OF(X509_CRL) *crl_stack = NULL;
169 STACK_OF(X509) *cert_stack = NULL;
170 int ret = 1;
171
172 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
173 perror("pledge");
174 exit(1);
175 }
176
177 memset(&cfg, 0, sizeof(cfg));
178
179 cfg.informat = FORMAT_PEM;
180 cfg.outformat = FORMAT_PEM;
181
182 if (options_parse(argc, argv, crl2p7_options, NULL, NULL) != 0) {
183 crl2p7_usage();
184 goto end;
185 }
186
187 in = BIO_new(BIO_s_file());
188 out = BIO_new(BIO_s_file());
189 if (in == NULL || out == NULL) {
190 ERR_print_errors(bio_err);
191 goto end;
192 }
193 if (!cfg.nocrl) {
194 if (cfg.infile == NULL)
195 BIO_set_fp(in, stdin, BIO_NOCLOSE);
196 else {
197 if (BIO_read_filename(in, cfg.infile) <= 0) {
198 perror(cfg.infile);
199 goto end;
200 }
201 }
202
203 if (cfg.informat == FORMAT_ASN1)
204 crl = d2i_X509_CRL_bio(in, NULL);
205 else if (cfg.informat == FORMAT_PEM)
206 crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
207 else {
208 BIO_printf(bio_err,
209 "bad input format specified for input crl\n");
210 goto end;
211 }
212 if (crl == NULL) {
213 BIO_printf(bio_err, "unable to load CRL\n");
214 ERR_print_errors(bio_err);
215 goto end;
216 }
217 }
218 if ((p7 = PKCS7_new()) == NULL)
219 goto end;
220 if ((p7s = PKCS7_SIGNED_new()) == NULL)
221 goto end;
222 p7->type = OBJ_nid2obj(NID_pkcs7_signed);
223 p7->d.sign = p7s;
224 p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
225
226 if (!ASN1_INTEGER_set(p7s->version, 1))
227 goto end;
228 if ((crl_stack = sk_X509_CRL_new_null()) == NULL)
229 goto end;
230 p7s->crl = crl_stack;
231 if (crl != NULL) {
232 if (!sk_X509_CRL_push(crl_stack, crl))
233 goto end;
234 crl = NULL;
235 }
236 if ((cert_stack = sk_X509_new_null()) == NULL)
237 goto end;
238 p7s->cert = cert_stack;
239
240 if (cfg.certflst) {
241 for (i = 0; i < sk_OPENSSL_STRING_num(cfg.certflst); i++) {
242 certfile = sk_OPENSSL_STRING_value(cfg.certflst, i);
243 if (add_certs_from_file(cert_stack, certfile) < 0) {
244 BIO_printf(bio_err,
245 "error loading certificates\n");
246 ERR_print_errors(bio_err);
247 goto end;
248 }
249 }
250 }
251
252 if (cfg.outfile == NULL) {
253 BIO_set_fp(out, stdout, BIO_NOCLOSE);
254 } else {
255 if (BIO_write_filename(out, cfg.outfile) <= 0) {
256 perror(cfg.outfile);
257 goto end;
258 }
259 }
260
261 if (cfg.outformat == FORMAT_ASN1)
262 i = i2d_PKCS7_bio(out, p7);
263 else if (cfg.outformat == FORMAT_PEM)
264 i = PEM_write_bio_PKCS7(out, p7);
265 else {
266 BIO_printf(bio_err,
267 "bad output format specified for outfile\n");
268 goto end;
269 }
270 if (!i) {
271 BIO_printf(bio_err, "unable to write pkcs7 object\n");
272 ERR_print_errors(bio_err);
273 goto end;
274 }
275
276 ret = 0;
277
278 end:
279 BIO_free(in);
280 BIO_free_all(out);
281 PKCS7_free(p7);
282 X509_CRL_free(crl);
283 sk_OPENSSL_STRING_free(cfg.certflst);
284
285 return ret;
286}
287
288static int
289add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
290{
291 BIO *in = NULL;
292 int count = 0;
293 int ret = -1;
294 STACK_OF(X509_INFO) *sk = NULL;
295 X509_INFO *xi = NULL;
296
297 in = BIO_new(BIO_s_file());
298 if (in == NULL || BIO_read_filename(in, certfile) <= 0) {
299 BIO_printf(bio_err, "error opening the file, %s\n", certfile);
300 goto end;
301 }
302 /* This loads from a file, a stack of x509/crl/pkey sets */
303 sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
304 if (sk == NULL) {
305 BIO_printf(bio_err, "error reading the file, %s\n", certfile);
306 goto end;
307 }
308 /* scan over it and pull out the CRL's */
309 while (sk_X509_INFO_num(sk) > 0) {
310 xi = sk_X509_INFO_shift(sk);
311 if (xi->x509 != NULL) {
312 if (!sk_X509_push(stack, xi->x509))
313 goto end;
314 xi->x509 = NULL;
315 count++;
316 }
317 X509_INFO_free(xi);
318 xi = NULL;
319 }
320
321 ret = count;
322
323 end:
324 BIO_free(in);
325 X509_INFO_free(xi);
326 sk_X509_INFO_free(sk);
327
328 return ret;
329}
diff --git a/src/usr.bin/openssl/dgst.c b/src/usr.bin/openssl/dgst.c
deleted file mode 100644
index 3979966481..0000000000
--- a/src/usr.bin/openssl/dgst.c
+++ /dev/null
@@ -1,671 +0,0 @@
1/* $OpenBSD: dgst.c,v 1.21 2023/03/06 14:32:05 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include "apps.h"
64
65#include <openssl/bio.h>
66#include <openssl/err.h>
67#include <openssl/evp.h>
68#include <openssl/hmac.h>
69#include <openssl/objects.h>
70#include <openssl/pem.h>
71#include <openssl/x509.h>
72
73#define BUFSIZE 1024*8
74
75int
76do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout,
77 EVP_PKEY * key, unsigned char *sigin, int siglen,
78 const char *sig_name, const char *md_name,
79 const char *file, BIO * bmd);
80
81static struct {
82 int argsused;
83 int debug;
84 int do_verify;
85 char *hmac_key;
86 char *keyfile;
87 int keyform;
88 const EVP_MD *m;
89 char *mac_name;
90 STACK_OF(OPENSSL_STRING) *macopts;
91 const EVP_MD *md;
92 int out_bin;
93 char *outfile;
94 char *passargin;
95 int separator;
96 char *sigfile;
97 STACK_OF(OPENSSL_STRING) *sigopts;
98 int want_pub;
99} cfg;
100
101static int
102dgst_opt_macopt(char *arg)
103{
104 if (arg == NULL)
105 return (1);
106
107 if (cfg.macopts == NULL &&
108 (cfg.macopts = sk_OPENSSL_STRING_new_null()) == NULL)
109 return (1);
110
111 if (!sk_OPENSSL_STRING_push(cfg.macopts, arg))
112 return (1);
113
114 return (0);
115}
116
117static int
118dgst_opt_md(int argc, char **argv, int *argsused)
119{
120 char *name = argv[0];
121
122 if (*name++ != '-')
123 return (1);
124
125 if ((cfg.m = EVP_get_digestbyname(name)) == NULL)
126 return (1);
127
128 cfg.md = cfg.m;
129
130 *argsused = 1;
131 return (0);
132}
133
134static int
135dgst_opt_prverify(char *arg)
136{
137 if (arg == NULL)
138 return (1);
139
140 cfg.keyfile = arg;
141 cfg.do_verify = 1;
142 return (0);
143}
144
145static int
146dgst_opt_sigopt(char *arg)
147{
148 if (arg == NULL)
149 return (1);
150
151 if (cfg.sigopts == NULL &&
152 (cfg.sigopts = sk_OPENSSL_STRING_new_null()) == NULL)
153 return (1);
154
155 if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
156 return (1);
157
158 return (0);
159}
160
161static int
162dgst_opt_verify(char *arg)
163{
164 if (arg == NULL)
165 return (1);
166
167 cfg.keyfile = arg;
168 cfg.want_pub = 1;
169 cfg.do_verify = 1;
170 return (0);
171}
172
173static const struct option dgst_options[] = {
174 {
175 .name = "binary",
176 .desc = "Output the digest or signature in binary form",
177 .type = OPTION_VALUE,
178 .opt.value = &cfg.out_bin,
179 .value = 1,
180 },
181 {
182 .name = "c",
183 .desc = "Print the digest in two-digit groups separated by colons",
184 .type = OPTION_VALUE,
185 .opt.value = &cfg.separator,
186 .value = 1,
187 },
188 {
189 .name = "d",
190 .desc = "Print BIO debugging information",
191 .type = OPTION_FLAG,
192 .opt.flag = &cfg.debug,
193 },
194 {
195 .name = "hex",
196 .desc = "Output as hex dump",
197 .type = OPTION_VALUE,
198 .opt.value = &cfg.out_bin,
199 .value = 0,
200 },
201 {
202 .name = "hmac",
203 .argname = "key",
204 .desc = "Create hashed MAC with key",
205 .type = OPTION_ARG,
206 .opt.arg = &cfg.hmac_key,
207 },
208 {
209 .name = "keyform",
210 .argname = "format",
211 .desc = "Key file format (PEM)",
212 .type = OPTION_ARG_FORMAT,
213 .opt.value = &cfg.keyform,
214 },
215 {
216 .name = "mac",
217 .argname = "algorithm",
218 .desc = "Create MAC (not necessarily HMAC)",
219 .type = OPTION_ARG,
220 .opt.arg = &cfg.mac_name,
221 },
222 {
223 .name = "macopt",
224 .argname = "nm:v",
225 .desc = "MAC algorithm parameters or key",
226 .type = OPTION_ARG_FUNC,
227 .opt.argfunc = dgst_opt_macopt,
228 },
229 {
230 .name = "out",
231 .argname = "file",
232 .desc = "Output to file rather than stdout",
233 .type = OPTION_ARG,
234 .opt.arg = &cfg.outfile,
235 },
236 {
237 .name = "passin",
238 .argname = "arg",
239 .desc = "Input file passphrase source",
240 .type = OPTION_ARG,
241 .opt.arg = &cfg.passargin,
242 },
243 {
244 .name = "prverify",
245 .argname = "file",
246 .desc = "Verify a signature using private key in file",
247 .type = OPTION_ARG_FUNC,
248 .opt.argfunc = dgst_opt_prverify,
249 },
250 {
251 .name = "r",
252 .desc = "Output the digest in coreutils format",
253 .type = OPTION_VALUE,
254 .opt.value = &cfg.separator,
255 .value = 2,
256 },
257 {
258 .name = "sign",
259 .argname = "file",
260 .desc = "Sign digest using private key in file",
261 .type = OPTION_ARG,
262 .opt.arg = &cfg.keyfile,
263 },
264 {
265 .name = "signature",
266 .argname = "file",
267 .desc = "Signature to verify",
268 .type = OPTION_ARG,
269 .opt.arg = &cfg.sigfile,
270 },
271 {
272 .name = "sigopt",
273 .argname = "nm:v",
274 .desc = "Signature parameter",
275 .type = OPTION_ARG_FUNC,
276 .opt.argfunc = dgst_opt_sigopt,
277 },
278 {
279 .name = "verify",
280 .argname = "file",
281 .desc = "Verify a signature using public key in file",
282 .type = OPTION_ARG_FUNC,
283 .opt.argfunc = dgst_opt_verify,
284 },
285 {
286 .name = NULL,
287 .desc = "",
288 .type = OPTION_ARGV_FUNC,
289 .opt.argvfunc = dgst_opt_md,
290 },
291 { NULL },
292};
293
294static void
295list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg)
296{
297 const char *mname;
298 /* Skip aliases */
299 if (!m)
300 return;
301 mname = OBJ_nid2ln(EVP_MD_type(m));
302 /* Skip shortnames */
303 if (strcmp(from, mname))
304 return;
305 if (strchr(mname, ' '))
306 mname = EVP_MD_name(m);
307 BIO_printf(arg, " -%-17s To use the %s message digest algorithm\n",
308 mname, mname);
309}
310
311static void
312dgst_usage(void)
313{
314 fprintf(stderr, "usage: dgst [-cdr] [-binary] [-digest] [-hex]");
315 fprintf(stderr, " [-hmac key] [-keyform fmt]\n");
316 fprintf(stderr, " [-mac algorithm] [-macopt nm:v] [-out file]");
317 fprintf(stderr, " [-passin arg]\n");
318 fprintf(stderr, " [-prverify file] [-sign file]");
319 fprintf(stderr, " [-signature file]\n");
320 fprintf(stderr, " [-sigopt nm:v] [-verify file] [file ...]\n\n");
321 options_usage(dgst_options);
322 EVP_MD_do_all_sorted(list_md_fn, bio_err);
323 fprintf(stderr, "\n");
324}
325
326int
327dgst_main(int argc, char **argv)
328{
329 unsigned char *buf = NULL;
330 int i, err = 1;
331 BIO *in = NULL, *inp;
332 BIO *bmd = NULL;
333 BIO *out = NULL;
334#define PROG_NAME_SIZE 39
335 char pname[PROG_NAME_SIZE + 1];
336 EVP_PKEY *sigkey = NULL;
337 unsigned char *sigbuf = NULL;
338 int siglen = 0;
339 char *passin = NULL;
340
341 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
342 perror("pledge");
343 exit(1);
344 }
345
346 if ((buf = malloc(BUFSIZE)) == NULL) {
347 BIO_printf(bio_err, "out of memory\n");
348 goto end;
349 }
350
351 memset(&cfg, 0, sizeof(cfg));
352 cfg.keyform = FORMAT_PEM;
353 cfg.out_bin = -1;
354
355 /* first check the program name */
356 program_name(argv[0], pname, sizeof pname);
357
358 cfg.md = EVP_get_digestbyname(pname);
359
360 if (options_parse(argc, argv, dgst_options, NULL,
361 &cfg.argsused) != 0) {
362 dgst_usage();
363 goto end;
364 }
365 argc -= cfg.argsused;
366 argv += cfg.argsused;
367
368 if (cfg.do_verify && !cfg.sigfile) {
369 BIO_printf(bio_err,
370 "No signature to verify: use the -signature option\n");
371 goto end;
372 }
373
374 in = BIO_new(BIO_s_file());
375 bmd = BIO_new(BIO_f_md());
376 if (in == NULL || bmd == NULL) {
377 ERR_print_errors(bio_err);
378 goto end;
379 }
380
381 if (cfg.debug) {
382 BIO_set_callback(in, BIO_debug_callback);
383 /* needed for windows 3.1 */
384 BIO_set_callback_arg(in, (char *) bio_err);
385 }
386 if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
387 BIO_printf(bio_err, "Error getting password\n");
388 goto end;
389 }
390 if (cfg.out_bin == -1) {
391 if (cfg.keyfile)
392 cfg.out_bin = 1;
393 else
394 cfg.out_bin = 0;
395 }
396
397 if (cfg.outfile) {
398 if (cfg.out_bin)
399 out = BIO_new_file(cfg.outfile, "wb");
400 else
401 out = BIO_new_file(cfg.outfile, "w");
402 } else {
403 out = BIO_new_fp(stdout, BIO_NOCLOSE);
404 }
405
406 if (!out) {
407 BIO_printf(bio_err, "Error opening output file %s\n",
408 cfg.outfile ? cfg.outfile : "(stdout)");
409 ERR_print_errors(bio_err);
410 goto end;
411 }
412 if ((!!cfg.mac_name + !!cfg.keyfile +
413 !!cfg.hmac_key) > 1) {
414 BIO_printf(bio_err,
415 "MAC and Signing key cannot both be specified\n");
416 goto end;
417 }
418 if (cfg.keyfile) {
419 if (cfg.want_pub)
420 sigkey = load_pubkey(bio_err, cfg.keyfile,
421 cfg.keyform, 0, NULL, "key file");
422 else
423 sigkey = load_key(bio_err, cfg.keyfile,
424 cfg.keyform, 0, passin, "key file");
425 if (!sigkey) {
426 /*
427 * load_[pub]key() has already printed an appropriate
428 * message
429 */
430 goto end;
431 }
432 }
433 if (cfg.mac_name) {
434 EVP_PKEY_CTX *mac_ctx = NULL;
435 int r = 0;
436 if (!init_gen_str(bio_err, &mac_ctx, cfg.mac_name, 0))
437 goto mac_end;
438 if (cfg.macopts) {
439 char *macopt;
440 for (i = 0; i < sk_OPENSSL_STRING_num(
441 cfg.macopts); i++) {
442 macopt = sk_OPENSSL_STRING_value(
443 cfg.macopts, i);
444 if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
445 BIO_printf(bio_err,
446 "MAC parameter error \"%s\"\n",
447 macopt);
448 ERR_print_errors(bio_err);
449 goto mac_end;
450 }
451 }
452 }
453 if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
454 BIO_puts(bio_err, "Error generating key\n");
455 ERR_print_errors(bio_err);
456 goto mac_end;
457 }
458 r = 1;
459 mac_end:
460 EVP_PKEY_CTX_free(mac_ctx);
461 if (r == 0)
462 goto end;
463 }
464 if (cfg.hmac_key) {
465 sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
466 (unsigned char *) cfg.hmac_key, -1);
467 if (!sigkey)
468 goto end;
469 }
470 if (sigkey) {
471 EVP_MD_CTX *mctx = NULL;
472 EVP_PKEY_CTX *pctx = NULL;
473 int r;
474 if (!BIO_get_md_ctx(bmd, &mctx)) {
475 BIO_printf(bio_err, "Error getting context\n");
476 ERR_print_errors(bio_err);
477 goto end;
478 }
479 if (cfg.do_verify)
480 r = EVP_DigestVerifyInit(mctx, &pctx, cfg.md,
481 NULL, sigkey);
482 else
483 r = EVP_DigestSignInit(mctx, &pctx, cfg.md,
484 NULL, sigkey);
485 if (!r) {
486 BIO_printf(bio_err, "Error setting context\n");
487 ERR_print_errors(bio_err);
488 goto end;
489 }
490 if (cfg.sigopts) {
491 char *sigopt;
492 for (i = 0; i < sk_OPENSSL_STRING_num(
493 cfg.sigopts); i++) {
494 sigopt = sk_OPENSSL_STRING_value(
495 cfg.sigopts, i);
496 if (pkey_ctrl_string(pctx, sigopt) <= 0) {
497 BIO_printf(bio_err,
498 "parameter error \"%s\"\n",
499 sigopt);
500 ERR_print_errors(bio_err);
501 goto end;
502 }
503 }
504 }
505 }
506 /* we use md as a filter, reading from 'in' */
507 else {
508 if (cfg.md == NULL)
509 cfg.md = EVP_sha256();
510 if (!BIO_set_md(bmd, cfg.md)) {
511 BIO_printf(bio_err, "Error setting digest %s\n", pname);
512 ERR_print_errors(bio_err);
513 goto end;
514 }
515 }
516
517 if (cfg.sigfile && sigkey) {
518 BIO *sigbio;
519 siglen = EVP_PKEY_size(sigkey);
520 sigbuf = malloc(siglen);
521 if (sigbuf == NULL) {
522 BIO_printf(bio_err, "out of memory\n");
523 ERR_print_errors(bio_err);
524 goto end;
525 }
526 sigbio = BIO_new_file(cfg.sigfile, "rb");
527 if (!sigbio) {
528 BIO_printf(bio_err, "Error opening signature file %s\n",
529 cfg.sigfile);
530 ERR_print_errors(bio_err);
531 goto end;
532 }
533 siglen = BIO_read(sigbio, sigbuf, siglen);
534 BIO_free(sigbio);
535 if (siglen <= 0) {
536 BIO_printf(bio_err, "Error reading signature file %s\n",
537 cfg.sigfile);
538 ERR_print_errors(bio_err);
539 goto end;
540 }
541 }
542 inp = BIO_push(bmd, in);
543
544 if (cfg.md == NULL) {
545 EVP_MD_CTX *tctx;
546 BIO_get_md_ctx(bmd, &tctx);
547 cfg.md = EVP_MD_CTX_md(tctx);
548 }
549 if (argc == 0) {
550 BIO_set_fp(in, stdin, BIO_NOCLOSE);
551 err = do_fp(out, buf, inp, cfg.separator,
552 cfg.out_bin, sigkey, sigbuf, siglen, NULL, NULL,
553 "stdin", bmd);
554 } else {
555 const char *md_name = NULL, *sig_name = NULL;
556 if (!cfg.out_bin) {
557 if (sigkey) {
558 const EVP_PKEY_ASN1_METHOD *ameth;
559 ameth = EVP_PKEY_get0_asn1(sigkey);
560 if (ameth)
561 EVP_PKEY_asn1_get0_info(NULL, NULL,
562 NULL, NULL, &sig_name, ameth);
563 }
564 md_name = EVP_MD_name(cfg.md);
565 }
566 err = 0;
567 for (i = 0; i < argc; i++) {
568 int r;
569 if (BIO_read_filename(in, argv[i]) <= 0) {
570 perror(argv[i]);
571 err++;
572 continue;
573 } else {
574 r = do_fp(out, buf, inp, cfg.separator,
575 cfg.out_bin, sigkey, sigbuf, siglen,
576 sig_name, md_name, argv[i], bmd);
577 }
578 if (r)
579 err = r;
580 (void) BIO_reset(bmd);
581 }
582 }
583
584 end:
585 freezero(buf, BUFSIZE);
586 BIO_free(in);
587 free(passin);
588 BIO_free_all(out);
589 EVP_PKEY_free(sigkey);
590 sk_OPENSSL_STRING_free(cfg.sigopts);
591 sk_OPENSSL_STRING_free(cfg.macopts);
592 free(sigbuf);
593 BIO_free(bmd);
594
595 return (err);
596}
597
598int
599do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout,
600 EVP_PKEY * key, unsigned char *sigin, int siglen,
601 const char *sig_name, const char *md_name,
602 const char *file, BIO * bmd)
603{
604 size_t len;
605 int i;
606
607 for (;;) {
608 i = BIO_read(bp, (char *) buf, BUFSIZE);
609 if (i < 0) {
610 BIO_printf(bio_err, "Read Error in %s\n", file);
611 ERR_print_errors(bio_err);
612 return 1;
613 }
614 if (i == 0)
615 break;
616 }
617 if (sigin) {
618 EVP_MD_CTX *ctx;
619 BIO_get_md_ctx(bp, &ctx);
620 i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int) siglen);
621 if (i > 0)
622 BIO_printf(out, "Verified OK\n");
623 else if (i == 0) {
624 BIO_printf(out, "Verification Failure\n");
625 return 1;
626 } else {
627 BIO_printf(bio_err, "Error Verifying Data\n");
628 ERR_print_errors(bio_err);
629 return 1;
630 }
631 return 0;
632 }
633 if (key) {
634 EVP_MD_CTX *ctx;
635 BIO_get_md_ctx(bp, &ctx);
636 len = BUFSIZE;
637 if (!EVP_DigestSignFinal(ctx, buf, &len)) {
638 BIO_printf(bio_err, "Error Signing Data\n");
639 ERR_print_errors(bio_err);
640 return 1;
641 }
642 } else {
643 len = BIO_gets(bp, (char *) buf, BUFSIZE);
644 if ((int) len < 0) {
645 ERR_print_errors(bio_err);
646 return 1;
647 }
648 }
649
650 if (binout)
651 BIO_write(out, buf, len);
652 else if (sep == 2) {
653 for (i = 0; i < (int) len; i++)
654 BIO_printf(out, "%02x", buf[i]);
655 BIO_printf(out, " *%s\n", file);
656 } else {
657 if (sig_name)
658 BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
659 else if (md_name)
660 BIO_printf(out, "%s(%s)= ", md_name, file);
661 else
662 BIO_printf(out, "(%s)= ", file);
663 for (i = 0; i < (int) len; i++) {
664 if (sep && (i != 0))
665 BIO_printf(out, ":");
666 BIO_printf(out, "%02x", buf[i]);
667 }
668 BIO_printf(out, "\n");
669 }
670 return 0;
671}
diff --git a/src/usr.bin/openssl/dh.c b/src/usr.bin/openssl/dh.c
deleted file mode 100644
index d7c7d2db91..0000000000
--- a/src/usr.bin/openssl/dh.c
+++ /dev/null
@@ -1,248 +0,0 @@
1/* $OpenBSD: dh.c,v 1.16 2025/01/19 10:24:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
60
61#ifndef OPENSSL_NO_DH
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include <time.h>
67
68#include "apps.h"
69
70#include <openssl/bio.h>
71#include <openssl/bn.h>
72#include <openssl/err.h>
73#include <openssl/dh.h>
74#include <openssl/pem.h>
75#include <openssl/x509.h>
76
77static struct {
78 int check;
79 char *infile;
80 int informat;
81 int noout;
82 char *outfile;
83 int outformat;
84 int text;
85} cfg;
86
87static const struct option dh_options[] = {
88 {
89 .name = "check",
90 .desc = "Check the DH parameters",
91 .type = OPTION_FLAG,
92 .opt.flag = &cfg.check,
93 },
94 {
95 .name = "in",
96 .argname = "file",
97 .desc = "Input file (default stdin)",
98 .type = OPTION_ARG,
99 .opt.arg = &cfg.infile,
100 },
101 {
102 .name = "inform",
103 .argname = "format",
104 .desc = "Input format (DER or PEM (default))",
105 .type = OPTION_ARG_FORMAT,
106 .opt.value = &cfg.informat,
107 },
108 {
109 .name = "noout",
110 .desc = "No output",
111 .type = OPTION_FLAG,
112 .opt.flag = &cfg.noout,
113 },
114 {
115 .name = "out",
116 .argname = "file",
117 .desc = "Output file (default stdout)",
118 .type = OPTION_ARG,
119 .opt.arg = &cfg.outfile,
120 },
121 {
122 .name = "outform",
123 .argname = "format",
124 .desc = "Output format (DER or PEM (default))",
125 .type = OPTION_ARG_FORMAT,
126 .opt.value = &cfg.outformat,
127 },
128 {
129 .name = "text",
130 .desc = "Print a text form of the DH parameters",
131 .type = OPTION_FLAG,
132 .opt.flag = &cfg.text,
133 },
134 { NULL },
135};
136
137static void
138dh_usage(void)
139{
140 fprintf(stderr,
141 "usage: dh [-check] [-in file] [-inform format]\n"
142 " [-noout] [-out file] [-outform format] [-text]\n\n");
143 options_usage(dh_options);
144}
145
146int
147dh_main(int argc, char **argv)
148{
149 DH *dh = NULL;
150 int i;
151 BIO *in = NULL, *out = NULL;
152 int ret = 1;
153
154 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
155 perror("pledge");
156 exit(1);
157 }
158
159 memset(&cfg, 0, sizeof(cfg));
160
161 cfg.informat = FORMAT_PEM;
162 cfg.outformat = FORMAT_PEM;
163
164 if (options_parse(argc, argv, dh_options, NULL, NULL) != 0) {
165 dh_usage();
166 goto end;
167 }
168
169 in = BIO_new(BIO_s_file());
170 out = BIO_new(BIO_s_file());
171 if (in == NULL || out == NULL) {
172 ERR_print_errors(bio_err);
173 goto end;
174 }
175 if (cfg.infile == NULL)
176 BIO_set_fp(in, stdin, BIO_NOCLOSE);
177 else {
178 if (BIO_read_filename(in, cfg.infile) <= 0) {
179 perror(cfg.infile);
180 goto end;
181 }
182 }
183 if (cfg.outfile == NULL) {
184 BIO_set_fp(out, stdout, BIO_NOCLOSE);
185 } else {
186 if (BIO_write_filename(out, cfg.outfile) <= 0) {
187 perror(cfg.outfile);
188 goto end;
189 }
190 }
191
192 if (cfg.informat == FORMAT_ASN1)
193 dh = d2i_DHparams_bio(in, NULL);
194 else if (cfg.informat == FORMAT_PEM)
195 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
196 else {
197 BIO_printf(bio_err, "bad input format specified\n");
198 goto end;
199 }
200 if (dh == NULL) {
201 BIO_printf(bio_err, "unable to load DH parameters\n");
202 ERR_print_errors(bio_err);
203 goto end;
204 }
205 if (cfg.text) {
206 DHparams_print(out, dh);
207 }
208 if (cfg.check) {
209 if (!DH_check(dh, &i)) {
210 ERR_print_errors(bio_err);
211 goto end;
212 }
213 if (i & DH_CHECK_P_NOT_PRIME)
214 printf("p value is not prime\n");
215 if (i & DH_CHECK_P_NOT_SAFE_PRIME)
216 printf("p value is not a safe prime\n");
217 if (i & DH_UNABLE_TO_CHECK_GENERATOR)
218 printf("unable to check the generator value\n");
219 if (i & DH_NOT_SUITABLE_GENERATOR)
220 printf("the g value is not a generator\n");
221 if (i == 0)
222 printf("DH parameters appear to be ok.\n");
223 }
224 if (!cfg.noout) {
225 if (cfg.outformat == FORMAT_ASN1)
226 i = i2d_DHparams_bio(out, dh);
227 else if (cfg.outformat == FORMAT_PEM)
228 i = PEM_write_bio_DHparams(out, dh);
229 else {
230 BIO_printf(bio_err, "bad output format specified for outfile\n");
231 goto end;
232 }
233 if (!i) {
234 BIO_printf(bio_err, "unable to write DH parameters\n");
235 ERR_print_errors(bio_err);
236 goto end;
237 }
238 }
239 ret = 0;
240
241 end:
242 BIO_free(in);
243 BIO_free_all(out);
244 DH_free(dh);
245
246 return (ret);
247}
248#endif
diff --git a/src/usr.bin/openssl/dhparam.c b/src/usr.bin/openssl/dhparam.c
deleted file mode 100644
index 752f9ee01a..0000000000
--- a/src/usr.bin/openssl/dhparam.c
+++ /dev/null
@@ -1,446 +0,0 @@
1/* $OpenBSD: dhparam.c,v 1.19 2025/01/19 10:24:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
113
114#ifndef OPENSSL_NO_DH
115
116#include <stdio.h>
117#include <stdlib.h>
118#include <string.h>
119#include <time.h>
120
121#include "apps.h"
122
123#include <openssl/bio.h>
124#include <openssl/bn.h>
125#include <openssl/err.h>
126#include <openssl/dh.h>
127#include <openssl/pem.h>
128#include <openssl/x509.h>
129
130#include <openssl/dsa.h>
131
132#define DEFBITS 2048
133
134static struct {
135 int check;
136 int dsaparam;
137 int g;
138 char *infile;
139 int informat;
140 int noout;
141 char *outfile;
142 int outformat;
143 int text;
144} cfg;
145
146static const struct option dhparam_options[] = {
147 {
148 .name = "2",
149 .desc = "Generate DH parameters with a generator value of 2 "
150 "(default)",
151 .type = OPTION_VALUE,
152 .opt.value = &cfg.g,
153 .value = 2,
154 },
155 {
156 .name = "5",
157 .desc = "Generate DH parameters with a generator value of 5",
158 .type = OPTION_VALUE,
159 .opt.value = &cfg.g,
160 .value = 5,
161 },
162 {
163 .name = "check",
164 .desc = "Check the DH parameters",
165 .type = OPTION_FLAG,
166 .opt.flag = &cfg.check,
167 },
168 {
169 .name = "dsaparam",
170 .desc = "Read or generate DSA parameters and convert to DH",
171 .type = OPTION_FLAG,
172 .opt.flag = &cfg.dsaparam,
173 },
174 {
175 .name = "in",
176 .argname = "file",
177 .desc = "Input file (default stdin)",
178 .type = OPTION_ARG,
179 .opt.arg = &cfg.infile,
180 },
181 {
182 .name = "inform",
183 .argname = "format",
184 .desc = "Input format (DER or PEM (default))",
185 .type = OPTION_ARG_FORMAT,
186 .opt.value = &cfg.informat,
187 },
188 {
189 .name = "noout",
190 .desc = "Do not output encoded version of DH parameters",
191 .type = OPTION_FLAG,
192 .opt.flag = &cfg.noout,
193 },
194 {
195 .name = "out",
196 .argname = "file",
197 .desc = "Output file (default stdout)",
198 .type = OPTION_ARG,
199 .opt.arg = &cfg.outfile,
200 },
201 {
202 .name = "outform",
203 .argname = "format",
204 .desc = "Output format (DER or PEM (default))",
205 .type = OPTION_ARG_FORMAT,
206 .opt.value = &cfg.outformat,
207 },
208 {
209 .name = "text",
210 .desc = "Print DH parameters in plain text",
211 .type = OPTION_FLAG,
212 .opt.flag = &cfg.text,
213 },
214 { NULL },
215};
216
217static void
218dhparam_usage(void)
219{
220 fprintf(stderr,
221 "usage: dhparam [-2 | -5] [-check] [-dsaparam]\n"
222 " [-in file] [-inform DER | PEM] [-noout] [-out file]\n"
223 " [-outform DER | PEM] [-text] [numbits]\n\n");
224 options_usage(dhparam_options);
225}
226
227static int dh_cb(int p, int n, BN_GENCB *cb);
228
229int
230dhparam_main(int argc, char **argv)
231{
232 BIO *in = NULL, *out = NULL;
233 BN_GENCB *cb = NULL;
234 char *num_bits = NULL;
235 DH *dh = NULL;
236 int num = 0;
237 int ret = 1;
238 int i;
239
240 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
241 perror("pledge");
242 exit(1);
243 }
244
245 memset(&cfg, 0, sizeof(cfg));
246
247 cfg.informat = FORMAT_PEM;
248 cfg.outformat = FORMAT_PEM;
249
250 if (options_parse(argc, argv, dhparam_options, &num_bits, NULL) != 0) {
251 dhparam_usage();
252 return (1);
253 }
254
255 if (num_bits != NULL) {
256 if(sscanf(num_bits, "%d", &num) == 0 || num <= 0) {
257 BIO_printf(bio_err, "invalid number of bits: %s\n",
258 num_bits);
259 return (1);
260 }
261 }
262
263 if (cfg.g && !num)
264 num = DEFBITS;
265
266 if (cfg.dsaparam) {
267 if (cfg.g) {
268 BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n");
269 goto end;
270 }
271 } else {
272 /* DH parameters */
273 if (num && !cfg.g)
274 cfg.g = 2;
275 }
276
277 if (num) {
278 if ((cb = BN_GENCB_new()) == NULL) {
279 BIO_printf(bio_err,
280 "Error allocating BN_GENCB object\n");
281 goto end;
282 }
283
284 BN_GENCB_set(cb, dh_cb, bio_err);
285 if (cfg.dsaparam) {
286 DSA *dsa = DSA_new();
287
288 BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num);
289 if (!dsa || !DSA_generate_parameters_ex(dsa, num,
290 NULL, 0, NULL, NULL, cb)) {
291 DSA_free(dsa);
292 ERR_print_errors(bio_err);
293 goto end;
294 }
295 dh = DSA_dup_DH(dsa);
296 DSA_free(dsa);
297 if (dh == NULL) {
298 ERR_print_errors(bio_err);
299 goto end;
300 }
301 } else {
302 dh = DH_new();
303 BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, cfg.g);
304 BIO_printf(bio_err, "This is going to take a long time\n");
305 if (!dh || !DH_generate_parameters_ex(dh, num, cfg.g, cb)) {
306 ERR_print_errors(bio_err);
307 goto end;
308 }
309 }
310 } else {
311
312 in = BIO_new(BIO_s_file());
313 if (in == NULL) {
314 ERR_print_errors(bio_err);
315 goto end;
316 }
317 if (cfg.infile == NULL)
318 BIO_set_fp(in, stdin, BIO_NOCLOSE);
319 else {
320 if (BIO_read_filename(in, cfg.infile) <= 0) {
321 perror(cfg.infile);
322 goto end;
323 }
324 }
325
326 if (cfg.informat != FORMAT_ASN1 &&
327 cfg.informat != FORMAT_PEM) {
328 BIO_printf(bio_err, "bad input format specified\n");
329 goto end;
330 }
331 if (cfg.dsaparam) {
332 DSA *dsa;
333
334 if (cfg.informat == FORMAT_ASN1)
335 dsa = d2i_DSAparams_bio(in, NULL);
336 else /* informat == FORMAT_PEM */
337 dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
338
339 if (dsa == NULL) {
340 BIO_printf(bio_err, "unable to load DSA parameters\n");
341 ERR_print_errors(bio_err);
342 goto end;
343 }
344 dh = DSA_dup_DH(dsa);
345 DSA_free(dsa);
346 if (dh == NULL) {
347 ERR_print_errors(bio_err);
348 goto end;
349 }
350 } else
351 {
352 if (cfg.informat == FORMAT_ASN1)
353 dh = d2i_DHparams_bio(in, NULL);
354 else /* informat == FORMAT_PEM */
355 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
356
357 if (dh == NULL) {
358 BIO_printf(bio_err, "unable to load DH parameters\n");
359 ERR_print_errors(bio_err);
360 goto end;
361 }
362 }
363
364 /* dh != NULL */
365 }
366
367 out = BIO_new(BIO_s_file());
368 if (out == NULL) {
369 ERR_print_errors(bio_err);
370 goto end;
371 }
372 if (cfg.outfile == NULL) {
373 BIO_set_fp(out, stdout, BIO_NOCLOSE);
374 } else {
375 if (BIO_write_filename(out, cfg.outfile) <= 0) {
376 perror(cfg.outfile);
377 goto end;
378 }
379 }
380
381
382 if (cfg.text) {
383 DHparams_print(out, dh);
384 }
385 if (cfg.check) {
386 if (!DH_check(dh, &i)) {
387 ERR_print_errors(bio_err);
388 goto end;
389 }
390 if (i & DH_CHECK_P_NOT_PRIME)
391 printf("p value is not prime\n");
392 if (i & DH_CHECK_P_NOT_SAFE_PRIME)
393 printf("p value is not a safe prime\n");
394 if (i & DH_UNABLE_TO_CHECK_GENERATOR)
395 printf("unable to check the generator value\n");
396 if (i & DH_NOT_SUITABLE_GENERATOR)
397 printf("the g value is not a generator\n");
398 if (i == 0)
399 printf("DH parameters appear to be ok.\n");
400 }
401 if (!cfg.noout) {
402 if (cfg.outformat == FORMAT_ASN1)
403 i = i2d_DHparams_bio(out, dh);
404 else if (cfg.outformat == FORMAT_PEM)
405 i = PEM_write_bio_DHparams(out, dh);
406 else {
407 BIO_printf(bio_err, "bad output format specified for outfile\n");
408 goto end;
409 }
410 if (!i) {
411 BIO_printf(bio_err, "unable to write DH parameters\n");
412 ERR_print_errors(bio_err);
413 goto end;
414 }
415 }
416 ret = 0;
417
418 end:
419 BIO_free(in);
420 BIO_free_all(out);
421 BN_GENCB_free(cb);
422 DH_free(dh);
423
424 return (ret);
425}
426
427/* dh_cb is identical to dsa_cb in apps/dsaparam.c */
428static int
429dh_cb(int p, int n, BN_GENCB *cb)
430{
431 char c = '*';
432
433 if (p == 0)
434 c = '.';
435 if (p == 1)
436 c = '+';
437 if (p == 2)
438 c = '*';
439 if (p == 3)
440 c = '\n';
441 BIO_write(BN_GENCB_get_arg(cb), &c, 1);
442 (void) BIO_flush(BN_GENCB_get_arg(cb));
443 return 1;
444}
445
446#endif
diff --git a/src/usr.bin/openssl/dsa.c b/src/usr.bin/openssl/dsa.c
deleted file mode 100644
index f1de78cf4d..0000000000
--- a/src/usr.bin/openssl/dsa.c
+++ /dev/null
@@ -1,365 +0,0 @@
1/* $OpenBSD: dsa.c,v 1.18 2023/03/06 14:32:06 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <time.h>
64#include <string.h>
65
66#include "apps.h"
67
68#include <openssl/bio.h>
69#include <openssl/bn.h>
70#include <openssl/dsa.h>
71#include <openssl/err.h>
72#include <openssl/evp.h>
73#include <openssl/pem.h>
74#include <openssl/x509.h>
75
76static struct {
77 const EVP_CIPHER *enc;
78 char *infile;
79 int informat;
80 int modulus;
81 int noout;
82 char *outfile;
83 int outformat;
84 char *passargin;
85 char *passargout;
86 int pubin;
87 int pubout;
88 int pvk_encr;
89 int text;
90} cfg;
91
92static int
93dsa_opt_enc(int argc, char **argv, int *argsused)
94{
95 char *name = argv[0];
96
97 if (*name++ != '-')
98 return (1);
99
100 if ((cfg.enc = EVP_get_cipherbyname(name)) != NULL) {
101 *argsused = 1;
102 return (0);
103 }
104
105 return (1);
106}
107
108static const struct option dsa_options[] = {
109 {
110 .name = "in",
111 .argname = "file",
112 .desc = "Input file (default stdin)",
113 .type = OPTION_ARG,
114 .opt.arg = &cfg.infile,
115 },
116 {
117 .name = "inform",
118 .argname = "format",
119 .desc = "Input format (PEM (default) or any other supported"
120 " format)",
121 .type = OPTION_ARG_FORMAT,
122 .opt.value = &cfg.informat,
123 },
124 {
125 .name = "modulus",
126 .desc = "Print the DSA public value",
127 .type = OPTION_FLAG,
128 .opt.flag = &cfg.modulus,
129 },
130 {
131 .name = "noout",
132 .desc = "No output",
133 .type = OPTION_FLAG,
134 .opt.flag = &cfg.noout,
135 },
136 {
137 .name = "out",
138 .argname = "file",
139 .desc = "Output file (default stdout)",
140 .type = OPTION_ARG,
141 .opt.arg = &cfg.outfile,
142 },
143 {
144 .name = "outform",
145 .argname = "format",
146 .desc = "Output format (DER, MSBLOB, PEM (default) or PVK)",
147 .type = OPTION_ARG_FORMAT,
148 .opt.value = &cfg.outformat,
149 },
150 {
151 .name = "passin",
152 .argname = "source",
153 .desc = "Input file passphrase source",
154 .type = OPTION_ARG,
155 .opt.arg = &cfg.passargin,
156 },
157 {
158 .name = "passout",
159 .argname = "source",
160 .desc = "Output file passphrase source",
161 .type = OPTION_ARG,
162 .opt.arg = &cfg.passargout,
163 },
164 {
165 .name = "pubin",
166 .desc = "Read a public key from the input file instead of"
167 " private key",
168 .type = OPTION_FLAG,
169 .opt.flag = &cfg.pubin,
170 },
171 {
172 .name = "pubout",
173 .desc = "Output a public key instead of private key",
174 .type = OPTION_FLAG,
175 .opt.flag = &cfg.pubout,
176 },
177 {
178 .name = "pvk-none",
179 .desc = "PVK encryption level",
180 .type = OPTION_VALUE,
181 .value = 0,
182 .opt.value = &cfg.pvk_encr,
183 },
184 {
185 .name = "pvk-strong",
186 .desc = "PVK encryption level (default)",
187 .type = OPTION_VALUE,
188 .value = 2,
189 .opt.value = &cfg.pvk_encr,
190 },
191 {
192 .name = "pvk-weak",
193 .desc = "PVK encryption level",
194 .type = OPTION_VALUE,
195 .value = 1,
196 .opt.value = &cfg.pvk_encr,
197 },
198 {
199 .name = "text",
200 .desc = "Print the key in text form",
201 .type = OPTION_FLAG,
202 .opt.flag = &cfg.text,
203 },
204 {
205 .name = NULL,
206 .type = OPTION_ARGV_FUNC,
207 .opt.argvfunc = dsa_opt_enc,
208 },
209 { NULL },
210};
211
212static void
213dsa_usage(void)
214{
215 int n = 0;
216
217 fprintf(stderr,
218 "usage: dsa [-in file] [-inform format] [-modulus] [-noout]\n"
219 " [-out file] [-outform format] [-passin src] [-passout src]\n"
220 " [-pubin] [-pubout] [-pvk-none | -pvk-strong | -pvk-weak]\n"
221 " [-text] [-ciphername]\n\n");
222 options_usage(dsa_options);
223 fprintf(stderr, "\n");
224
225 fprintf(stderr, "Valid ciphername values:\n\n");
226 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
227 fprintf(stderr, "\n");
228}
229
230int
231dsa_main(int argc, char **argv)
232{
233 int ret = 1;
234 DSA *dsa = NULL;
235 int i;
236 BIO *in = NULL, *out = NULL;
237 char *passin = NULL, *passout = NULL;
238
239 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
240 perror("pledge");
241 exit(1);
242 }
243
244 memset(&cfg, 0, sizeof(cfg));
245
246 cfg.pvk_encr = 2;
247 cfg.informat = FORMAT_PEM;
248 cfg.outformat = FORMAT_PEM;
249
250 if (options_parse(argc, argv, dsa_options, NULL, NULL) != 0) {
251 dsa_usage();
252 goto end;
253 }
254
255 if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
256 &passin, &passout)) {
257 BIO_printf(bio_err, "Error getting passwords\n");
258 goto end;
259 }
260
261 in = BIO_new(BIO_s_file());
262 out = BIO_new(BIO_s_file());
263 if (in == NULL || out == NULL) {
264 ERR_print_errors(bio_err);
265 goto end;
266 }
267 if (cfg.infile == NULL)
268 BIO_set_fp(in, stdin, BIO_NOCLOSE);
269 else {
270 if (BIO_read_filename(in, cfg.infile) <= 0) {
271 perror(cfg.infile);
272 goto end;
273 }
274 }
275
276 BIO_printf(bio_err, "read DSA key\n");
277
278 {
279 EVP_PKEY *pkey;
280
281 if (cfg.pubin)
282 pkey = load_pubkey(bio_err, cfg.infile,
283 cfg.informat, 1, passin, "Public Key");
284 else
285 pkey = load_key(bio_err, cfg.infile,
286 cfg.informat, 1, passin, "Private Key");
287
288 if (pkey) {
289 dsa = EVP_PKEY_get1_DSA(pkey);
290 EVP_PKEY_free(pkey);
291 }
292 }
293 if (dsa == NULL) {
294 BIO_printf(bio_err, "unable to load Key\n");
295 ERR_print_errors(bio_err);
296 goto end;
297 }
298 if (cfg.outfile == NULL) {
299 BIO_set_fp(out, stdout, BIO_NOCLOSE);
300 } else {
301 if (BIO_write_filename(out, cfg.outfile) <= 0) {
302 perror(cfg.outfile);
303 goto end;
304 }
305 }
306
307 if (cfg.text) {
308 if (!DSA_print(out, dsa, 0)) {
309 perror(cfg.outfile);
310 ERR_print_errors(bio_err);
311 goto end;
312 }
313 }
314 if (cfg.modulus) {
315 fprintf(stdout, "Public Key=");
316 BN_print(out, DSA_get0_pub_key(dsa));
317 fprintf(stdout, "\n");
318 }
319 if (cfg.noout)
320 goto end;
321 BIO_printf(bio_err, "writing DSA key\n");
322 if (cfg.outformat == FORMAT_ASN1) {
323 if (cfg.pubin || cfg.pubout)
324 i = i2d_DSA_PUBKEY_bio(out, dsa);
325 else
326 i = i2d_DSAPrivateKey_bio(out, dsa);
327 } else if (cfg.outformat == FORMAT_PEM) {
328 if (cfg.pubin || cfg.pubout)
329 i = PEM_write_bio_DSA_PUBKEY(out, dsa);
330 else
331 i = PEM_write_bio_DSAPrivateKey(out, dsa, cfg.enc,
332 NULL, 0, NULL, passout);
333#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4)
334 } else if (cfg.outformat == FORMAT_MSBLOB ||
335 cfg.outformat == FORMAT_PVK) {
336 EVP_PKEY *pk;
337 pk = EVP_PKEY_new();
338 EVP_PKEY_set1_DSA(pk, dsa);
339 if (cfg.outformat == FORMAT_PVK)
340 i = i2b_PVK_bio(out, pk, cfg.pvk_encr, 0,
341 passout);
342 else if (cfg.pubin || cfg.pubout)
343 i = i2b_PublicKey_bio(out, pk);
344 else
345 i = i2b_PrivateKey_bio(out, pk);
346 EVP_PKEY_free(pk);
347#endif
348 } else {
349 BIO_printf(bio_err, "bad output format specified for outfile\n");
350 goto end;
351 }
352 if (i <= 0) {
353 BIO_printf(bio_err, "unable to write private key\n");
354 ERR_print_errors(bio_err);
355 } else
356 ret = 0;
357 end:
358 BIO_free(in);
359 BIO_free_all(out);
360 DSA_free(dsa);
361 free(passin);
362 free(passout);
363
364 return (ret);
365}
diff --git a/src/usr.bin/openssl/dsaparam.c b/src/usr.bin/openssl/dsaparam.c
deleted file mode 100644
index 962f261210..0000000000
--- a/src/usr.bin/openssl/dsaparam.c
+++ /dev/null
@@ -1,316 +0,0 @@
1/* $OpenBSD: dsaparam.c,v 1.16 2025/01/19 10:24:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
60
61/* Until the key-gen callbacks are modified to use newer prototypes, we allow
62 * deprecated functions for openssl-internal code */
63#ifdef OPENSSL_NO_DEPRECATED
64#undef OPENSSL_NO_DEPRECATED
65#endif
66
67#include <limits.h>
68#include <stdio.h>
69#include <stdlib.h>
70#include <string.h>
71#include <time.h>
72
73#include "apps.h"
74
75#include <openssl/bio.h>
76#include <openssl/bn.h>
77#include <openssl/err.h>
78#include <openssl/dsa.h>
79#include <openssl/pem.h>
80#include <openssl/x509.h>
81
82static struct {
83 int genkey;
84 char *infile;
85 int informat;
86 int noout;
87 char *outfile;
88 int outformat;
89 int text;
90} cfg;
91
92static const struct option dsaparam_options[] = {
93 {
94 .name = "genkey",
95 .desc = "Generate a DSA key",
96 .type = OPTION_FLAG,
97 .opt.flag = &cfg.genkey,
98 },
99 {
100 .name = "in",
101 .argname = "file",
102 .desc = "Input file (default stdin)",
103 .type = OPTION_ARG,
104 .opt.arg = &cfg.infile,
105 },
106 {
107 .name = "inform",
108 .argname = "format",
109 .desc = "Input format (DER or PEM (default))",
110 .type = OPTION_ARG_FORMAT,
111 .opt.value = &cfg.informat,
112 },
113 {
114 .name = "noout",
115 .desc = "No output",
116 .type = OPTION_FLAG,
117 .opt.flag = &cfg.noout,
118 },
119 {
120 .name = "out",
121 .argname = "file",
122 .desc = "Output file (default stdout)",
123 .type = OPTION_ARG,
124 .opt.arg = &cfg.outfile,
125 },
126 {
127 .name = "outform",
128 .argname = "format",
129 .desc = "Output format (DER or PEM (default))",
130 .type = OPTION_ARG_FORMAT,
131 .opt.value = &cfg.outformat,
132 },
133 {
134 .name = "text",
135 .desc = "Print as text",
136 .type = OPTION_FLAG,
137 .opt.flag = &cfg.text,
138 },
139 { NULL },
140};
141
142static void
143dsaparam_usage(void)
144{
145 fprintf(stderr,
146 "usage: dsaparam [-genkey] [-in file]\n"
147 " [-inform format] [-noout] [-out file] [-outform format]\n"
148 " [-text] [numbits]\n\n");
149 options_usage(dsaparam_options);
150}
151
152static int dsa_cb(int p, int n, BN_GENCB *cb);
153
154int
155dsaparam_main(int argc, char **argv)
156{
157 DSA *dsa = NULL;
158 int i;
159 BIO *in = NULL, *out = NULL;
160 BN_GENCB *cb = NULL;
161 int ret = 1;
162 int numbits = -1;
163 char *strbits = NULL;
164
165 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
166 perror("pledge");
167 exit(1);
168 }
169
170 memset(&cfg, 0, sizeof(cfg));
171
172 cfg.informat = FORMAT_PEM;
173 cfg.outformat = FORMAT_PEM;
174
175 if (options_parse(argc, argv, dsaparam_options, &strbits, NULL) != 0) {
176 dsaparam_usage();
177 goto end;
178 }
179
180 if (strbits != NULL) {
181 const char *errstr;
182 numbits = strtonum(strbits, 0, INT_MAX, &errstr);
183 if (errstr) {
184 fprintf(stderr, "Invalid number of bits: %s", errstr);
185 goto end;
186 }
187 }
188
189 in = BIO_new(BIO_s_file());
190 out = BIO_new(BIO_s_file());
191 if (in == NULL || out == NULL) {
192 ERR_print_errors(bio_err);
193 goto end;
194 }
195 if (cfg.infile == NULL)
196 BIO_set_fp(in, stdin, BIO_NOCLOSE);
197 else {
198 if (BIO_read_filename(in, cfg.infile) <= 0) {
199 perror(cfg.infile);
200 goto end;
201 }
202 }
203 if (cfg.outfile == NULL) {
204 BIO_set_fp(out, stdout, BIO_NOCLOSE);
205 } else {
206 if (BIO_write_filename(out, cfg.outfile) <= 0) {
207 perror(cfg.outfile);
208 goto end;
209 }
210 }
211
212 if (numbits > 0) {
213 if ((cb = BN_GENCB_new()) == NULL) {
214 BIO_printf(bio_err,
215 "Error allocating BN_GENCB object\n");
216 goto end;
217 }
218
219 BN_GENCB_set(cb, dsa_cb, bio_err);
220
221 dsa = DSA_new();
222 if (!dsa) {
223 BIO_printf(bio_err, "Error allocating DSA object\n");
224 goto end;
225 }
226 BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", numbits);
227 BIO_printf(bio_err, "This could take some time\n");
228 if (!DSA_generate_parameters_ex(dsa, numbits, NULL, 0, NULL, NULL, cb)) {
229 ERR_print_errors(bio_err);
230 BIO_printf(bio_err, "Error, DSA key generation failed\n");
231 goto end;
232 }
233 } else if (cfg.informat == FORMAT_ASN1)
234 dsa = d2i_DSAparams_bio(in, NULL);
235 else if (cfg.informat == FORMAT_PEM)
236 dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
237 else {
238 BIO_printf(bio_err, "bad input format specified\n");
239 goto end;
240 }
241 if (dsa == NULL) {
242 BIO_printf(bio_err, "unable to load DSA parameters\n");
243 ERR_print_errors(bio_err);
244 goto end;
245 }
246 if (cfg.text) {
247 DSAparams_print(out, dsa);
248 }
249 if (!cfg.noout) {
250 if (cfg.outformat == FORMAT_ASN1)
251 i = i2d_DSAparams_bio(out, dsa);
252 else if (cfg.outformat == FORMAT_PEM)
253 i = PEM_write_bio_DSAparams(out, dsa);
254 else {
255 BIO_printf(bio_err, "bad output format specified for outfile\n");
256 goto end;
257 }
258 if (!i) {
259 BIO_printf(bio_err, "unable to write DSA parameters\n");
260 ERR_print_errors(bio_err);
261 goto end;
262 }
263 }
264 if (cfg.genkey) {
265 DSA *dsakey;
266
267 if ((dsakey = DSAparams_dup(dsa)) == NULL)
268 goto end;
269 if (!DSA_generate_key(dsakey)) {
270 ERR_print_errors(bio_err);
271 DSA_free(dsakey);
272 goto end;
273 }
274 if (cfg.outformat == FORMAT_ASN1)
275 i = i2d_DSAPrivateKey_bio(out, dsakey);
276 else if (cfg.outformat == FORMAT_PEM)
277 i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL);
278 else {
279 BIO_printf(bio_err, "bad output format specified for outfile\n");
280 DSA_free(dsakey);
281 goto end;
282 }
283 DSA_free(dsakey);
284 }
285 ret = 0;
286
287 end:
288 BIO_free(in);
289 BIO_free_all(out);
290 BN_GENCB_free(cb);
291 DSA_free(dsa);
292
293 return (ret);
294}
295
296static int
297dsa_cb(int p, int n, BN_GENCB *cb)
298{
299 char c = '*';
300
301 if (p == 0)
302 c = '.';
303 if (p == 1)
304 c = '+';
305 if (p == 2)
306 c = '*';
307 if (p == 3)
308 c = '\n';
309 BIO_write(BN_GENCB_get_arg(cb), &c, 1);
310 (void) BIO_flush(BN_GENCB_get_arg(cb));
311#ifdef GENCB_TEST
312 if (stop_keygen_flag)
313 return 0;
314#endif
315 return 1;
316}
diff --git a/src/usr.bin/openssl/ec.c b/src/usr.bin/openssl/ec.c
deleted file mode 100644
index c6af1263d4..0000000000
--- a/src/usr.bin/openssl/ec.c
+++ /dev/null
@@ -1,392 +0,0 @@
1/* $OpenBSD: ec.c,v 1.16 2023/03/06 14:32:06 tb Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/opensslconf.h>
60
61#ifndef OPENSSL_NO_EC
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66
67#include "apps.h"
68
69#include <openssl/bio.h>
70#include <openssl/err.h>
71#include <openssl/evp.h>
72#include <openssl/pem.h>
73
74static struct {
75 int asn1_flag;
76 const EVP_CIPHER *enc;
77 point_conversion_form_t form;
78 char *infile;
79 int informat;
80 char *outfile;
81 int outformat;
82 int new_asn1_flag;
83 int new_form;
84 int noout;
85 int param_out;
86 char *passargin;
87 char *passargout;
88 int pubin;
89 int pubout;
90 int text;
91} cfg;
92
93static int
94ec_opt_enc(int argc, char **argv, int *argsused)
95{
96 char *name = argv[0];
97
98 if (*name++ != '-')
99 return (1);
100
101 if ((cfg.enc = EVP_get_cipherbyname(name)) != NULL) {
102 *argsused = 1;
103 return (0);
104 }
105
106 return (1);
107}
108
109static int
110ec_opt_form(char *arg)
111{
112 if (strcmp(arg, "compressed") == 0)
113 cfg.form = POINT_CONVERSION_COMPRESSED;
114 else if (strcmp(arg, "uncompressed") == 0)
115 cfg.form = POINT_CONVERSION_UNCOMPRESSED;
116 else if (strcmp(arg, "hybrid") == 0)
117 cfg.form = POINT_CONVERSION_HYBRID;
118 else {
119 fprintf(stderr, "Invalid point conversion: %s\n", arg);
120 return (1);
121 }
122
123 cfg.new_form = 1;
124 return (0);
125}
126
127static int
128ec_opt_named(char *arg)
129{
130 if (strcmp(arg, "named_curve") == 0)
131 cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
132 else if (strcmp(arg, "explicit") == 0)
133 cfg.asn1_flag = 0;
134 else {
135 fprintf(stderr, "Invalid curve type: %s\n", arg);
136 return (1);
137 }
138
139 cfg.new_asn1_flag = 1;
140 return (0);
141}
142
143static const struct option ec_options[] = {
144 {
145 .name = "conv_form",
146 .argname = "form",
147 .desc = "Specify the point conversion form (default"
148 " \"named_curve\")",
149 .type = OPTION_ARG_FUNC,
150 .opt.argfunc = ec_opt_form,
151 },
152 {
153 .name = "in",
154 .argname = "file",
155 .desc = "Input file (default stdin)",
156 .type = OPTION_ARG,
157 .opt.arg = &cfg.infile,
158 },
159 {
160 .name = "inform",
161 .argname = "format",
162 .desc = "Input format (DER or PEM (default))",
163 .type = OPTION_ARG_FORMAT,
164 .opt.value = &cfg.informat,
165 },
166 {
167 .name = "noout",
168 .desc = "No output",
169 .type = OPTION_FLAG,
170 .opt.flag = &cfg.noout,
171 },
172 {
173 .name = "out",
174 .argname = "file",
175 .desc = "Output file (default stdout)",
176 .type = OPTION_ARG,
177 .opt.arg = &cfg.outfile,
178 },
179 {
180 .name = "outform",
181 .argname = "format",
182 .desc = "Output format (DER or PEM (default))",
183 .type = OPTION_ARG_FORMAT,
184 .opt.value = &cfg.outformat,
185 },
186 {
187 .name = "param_enc",
188 .argname = "type",
189 .desc = "Specify the way the ec parameters are encoded"
190 " (default \"uncompressed\")",
191 .type = OPTION_ARG_FUNC,
192 .opt.argfunc = ec_opt_named,
193 },
194 {
195 .name = "param_out",
196 .desc = "Print the elliptic curve parameters",
197 .type = OPTION_FLAG,
198 .opt.flag = &cfg.param_out,
199 },
200 {
201 .name = "passin",
202 .argname = "source",
203 .desc = "Input file passphrase source",
204 .type = OPTION_ARG,
205 .opt.arg = &cfg.passargin,
206 },
207 {
208 .name = "passout",
209 .argname = "source",
210 .desc = "Output file passphrase source",
211 .type = OPTION_ARG,
212 .opt.arg = &cfg.passargout,
213 },
214 {
215 .name = "pubin",
216 .desc = "Read public key instead of private key from input",
217 .type = OPTION_FLAG,
218 .opt.flag = &cfg.pubin,
219 },
220 {
221 .name = "pubout",
222 .desc = "Output public key instead of private key in output",
223 .type = OPTION_FLAG,
224 .opt.flag = &cfg.pubout,
225 },
226 {
227 .name = "text",
228 .desc = "Print the public/private key components and parameters",
229 .type = OPTION_FLAG,
230 .opt.flag = &cfg.text,
231 },
232 {
233 .name = NULL,
234 .desc = "Cipher to encrypt the output if using PEM format",
235 .type = OPTION_ARGV_FUNC,
236 .opt.argvfunc = ec_opt_enc,
237 },
238 { NULL },
239};
240
241static void
242ec_usage(void)
243{
244 int n = 0;
245
246 fprintf(stderr,
247 "usage: ec [-conv_form form] [-in file]\n"
248 " [-inform format] [-noout] [-out file] [-outform format]\n"
249 " [-param_enc type] [-param_out] [-passin file]\n"
250 " [-passout file] [-pubin] [-pubout] [-text] [-ciphername]\n\n");
251 options_usage(ec_options);
252
253 fprintf(stderr, "\n");
254
255 fprintf(stderr, "Valid ciphername values:\n\n");
256 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
257 fprintf(stderr, "\n");
258}
259
260int
261ec_main(int argc, char **argv)
262{
263 int ret = 1;
264 EC_KEY *eckey = NULL;
265 const EC_GROUP *group;
266 int i;
267 BIO *in = NULL, *out = NULL;
268 char *passin = NULL, *passout = NULL;
269
270 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
271 perror("pledge");
272 exit(1);
273 }
274
275 memset(&cfg, 0, sizeof(cfg));
276
277 cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
278 cfg.form = POINT_CONVERSION_UNCOMPRESSED;
279 cfg.informat = FORMAT_PEM;
280 cfg.outformat = FORMAT_PEM;
281
282 if (options_parse(argc, argv, ec_options, NULL, NULL) != 0) {
283 ec_usage();
284 goto end;
285 }
286
287 if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
288 &passin, &passout)) {
289 BIO_printf(bio_err, "Error getting passwords\n");
290 goto end;
291 }
292 in = BIO_new(BIO_s_file());
293 out = BIO_new(BIO_s_file());
294 if (in == NULL || out == NULL) {
295 ERR_print_errors(bio_err);
296 goto end;
297 }
298 if (cfg.infile == NULL)
299 BIO_set_fp(in, stdin, BIO_NOCLOSE);
300 else {
301 if (BIO_read_filename(in, cfg.infile) <= 0) {
302 perror(cfg.infile);
303 goto end;
304 }
305 }
306
307 BIO_printf(bio_err, "read EC key\n");
308 if (cfg.informat == FORMAT_ASN1) {
309 if (cfg.pubin)
310 eckey = d2i_EC_PUBKEY_bio(in, NULL);
311 else
312 eckey = d2i_ECPrivateKey_bio(in, NULL);
313 } else if (cfg.informat == FORMAT_PEM) {
314 if (cfg.pubin)
315 eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL,
316 NULL);
317 else
318 eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
319 passin);
320 } else {
321 BIO_printf(bio_err, "bad input format specified for key\n");
322 goto end;
323 }
324 if (eckey == NULL) {
325 BIO_printf(bio_err, "unable to load Key\n");
326 ERR_print_errors(bio_err);
327 goto end;
328 }
329 if (cfg.outfile == NULL) {
330 BIO_set_fp(out, stdout, BIO_NOCLOSE);
331 } else {
332 if (BIO_write_filename(out, cfg.outfile) <= 0) {
333 perror(cfg.outfile);
334 goto end;
335 }
336 }
337
338 group = EC_KEY_get0_group(eckey);
339
340 if (cfg.new_form)
341 EC_KEY_set_conv_form(eckey, cfg.form);
342
343 if (cfg.new_asn1_flag)
344 EC_KEY_set_asn1_flag(eckey, cfg.asn1_flag);
345
346 if (cfg.text)
347 if (!EC_KEY_print(out, eckey, 0)) {
348 perror(cfg.outfile);
349 ERR_print_errors(bio_err);
350 goto end;
351 }
352 if (cfg.noout) {
353 ret = 0;
354 goto end;
355 }
356 BIO_printf(bio_err, "writing EC key\n");
357 if (cfg.outformat == FORMAT_ASN1) {
358 if (cfg.param_out)
359 i = i2d_ECPKParameters_bio(out, group);
360 else if (cfg.pubin || cfg.pubout)
361 i = i2d_EC_PUBKEY_bio(out, eckey);
362 else
363 i = i2d_ECPrivateKey_bio(out, eckey);
364 } else if (cfg.outformat == FORMAT_PEM) {
365 if (cfg.param_out)
366 i = PEM_write_bio_ECPKParameters(out, group);
367 else if (cfg.pubin || cfg.pubout)
368 i = PEM_write_bio_EC_PUBKEY(out, eckey);
369 else
370 i = PEM_write_bio_ECPrivateKey(out, eckey,
371 cfg.enc, NULL, 0, NULL, passout);
372 } else {
373 BIO_printf(bio_err, "bad output format specified for "
374 "outfile\n");
375 goto end;
376 }
377
378 if (!i) {
379 BIO_printf(bio_err, "unable to write private key\n");
380 ERR_print_errors(bio_err);
381 } else
382 ret = 0;
383 end:
384 BIO_free(in);
385 BIO_free_all(out);
386 EC_KEY_free(eckey);
387 free(passin);
388 free(passout);
389
390 return (ret);
391}
392#endif
diff --git a/src/usr.bin/openssl/ecparam.c b/src/usr.bin/openssl/ecparam.c
deleted file mode 100644
index 285f5d563e..0000000000
--- a/src/usr.bin/openssl/ecparam.c
+++ /dev/null
@@ -1,448 +0,0 @@
1/* $OpenBSD: ecparam.c,v 1.25 2025/01/19 10:24:17 tb Exp $ */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the OpenSSL open source
65 * license provided above.
66 *
67 * The elliptic curve binary polynomial software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
71
72#include <openssl/opensslconf.h>
73
74#ifndef OPENSSL_NO_EC
75
76#include <stdio.h>
77#include <stdlib.h>
78#include <string.h>
79#include <time.h>
80
81#include "apps.h"
82
83#include <openssl/bio.h>
84#include <openssl/bn.h>
85#include <openssl/ec.h>
86#include <openssl/err.h>
87#include <openssl/pem.h>
88#include <openssl/x509.h>
89
90static struct {
91 int asn1_flag;
92 int check;
93 char *curve_name;
94 point_conversion_form_t form;
95 int genkey;
96 char *infile;
97 int informat;
98 int list_curves;
99 int new_asn1_flag;
100 int new_form;
101 int no_seed;
102 int noout;
103 char *outfile;
104 int outformat;
105 int text;
106} cfg;
107
108static int
109ecparam_opt_form(char *arg)
110{
111 if (strcmp(arg, "compressed") == 0)
112 cfg.form = POINT_CONVERSION_COMPRESSED;
113 else if (strcmp(arg, "uncompressed") == 0)
114 cfg.form = POINT_CONVERSION_UNCOMPRESSED;
115 else if (strcmp(arg, "hybrid") == 0)
116 cfg.form = POINT_CONVERSION_HYBRID;
117 else
118 return (1);
119
120 cfg.new_form = 1;
121 return (0);
122}
123
124static int
125ecparam_opt_enctype(char *arg)
126{
127 if (strcmp(arg, "explicit") == 0)
128 cfg.asn1_flag = 0;
129 else if (strcmp(arg, "named_curve") == 0)
130 cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
131 else
132 return (1);
133
134 cfg.new_asn1_flag = 1;
135 return (0);
136}
137
138static const struct option ecparam_options[] = {
139 {
140 .name = "check",
141 .desc = "Validate the elliptic curve parameters",
142 .type = OPTION_FLAG,
143 .opt.flag = &cfg.check,
144 },
145 {
146 .name = "conv_form",
147 .argname = "form",
148 .desc = "Specify point conversion form:\n"
149 " compressed, uncompressed (default), hybrid",
150 .type = OPTION_ARG_FUNC,
151 .opt.argfunc = ecparam_opt_form,
152 },
153 {
154 .name = "genkey",
155 .desc = "Generate an EC private key using the specified "
156 "parameters",
157 .type = OPTION_FLAG,
158 .opt.flag = &cfg.genkey,
159 },
160 {
161 .name = "in",
162 .argname = "file",
163 .desc = "Input file to read parameters from (default stdin)",
164 .type = OPTION_ARG,
165 .opt.arg = &cfg.infile,
166 },
167 {
168 .name = "inform",
169 .argname = "format",
170 .desc = "Input format (DER or PEM)",
171 .type = OPTION_ARG_FORMAT,
172 .opt.value = &cfg.informat,
173 },
174 {
175 .name = "list_curves",
176 .desc = "Print list of all currently implemented EC "
177 "parameter names",
178 .type = OPTION_FLAG,
179 .opt.flag = &cfg.list_curves,
180 },
181 {
182 .name = "name",
183 .argname = "curve",
184 .desc = "Use the EC parameters with the specified name",
185 .type = OPTION_ARG,
186 .opt.arg = &cfg.curve_name,
187 },
188 {
189 .name = "no_seed",
190 .desc = "Do not output seed with explicit parameter encoding",
191 .type = OPTION_FLAG,
192 .opt.flag = &cfg.no_seed,
193 },
194 {
195 .name = "noout",
196 .desc = "Do not output encoded version of EC parameters",
197 .type = OPTION_FLAG,
198 .opt.flag = &cfg.noout,
199 },
200 {
201 .name = "out",
202 .argname = "file",
203 .desc = "Output file to write parameters to (default stdout)",
204 .type = OPTION_ARG,
205 .opt.arg = &cfg.outfile,
206 },
207 {
208 .name = "outform",
209 .argname = "format",
210 .desc = "Output format (DER or PEM)",
211 .type = OPTION_ARG_FORMAT,
212 .opt.value = &cfg.outformat,
213 },
214 {
215 .name = "param_enc",
216 .argname = "type",
217 .desc = "Specify EC parameter ASN.1 encoding type:\n"
218 " explicit, named_curve (default)",
219 .type = OPTION_ARG_FUNC,
220 .opt.argfunc = ecparam_opt_enctype,
221 },
222 {
223 .name = "text",
224 .desc = "Print out the EC parameters in human readable form",
225 .type = OPTION_FLAG,
226 .opt.flag = &cfg.text,
227 },
228 {NULL},
229};
230
231static void
232ecparam_usage(void)
233{
234 fprintf(stderr, "usage: ecparam [-check] [-conv_form arg] "
235 " [-genkey]\n"
236 " [-in file] [-inform DER | PEM] [-list_curves] [-name arg]\n"
237 " [-no_seed] [-noout] [-out file] [-outform DER | PEM]\n"
238 " [-param_enc arg] [-text]\n\n");
239 options_usage(ecparam_options);
240}
241
242int
243ecparam_main(int argc, char **argv)
244{
245 EC_GROUP *group = NULL;
246 BIO *in = NULL, *out = NULL;
247 int i, ret = 1;
248
249 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
250 perror("pledge");
251 exit(1);
252 }
253
254 memset(&cfg, 0, sizeof(cfg));
255 cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
256 cfg.form = POINT_CONVERSION_UNCOMPRESSED;
257 cfg.informat = FORMAT_PEM;
258 cfg.outformat = FORMAT_PEM;
259
260 if (options_parse(argc, argv, ecparam_options, NULL, NULL) != 0) {
261 ecparam_usage();
262 goto end;
263 }
264
265 in = BIO_new(BIO_s_file());
266 out = BIO_new(BIO_s_file());
267 if ((in == NULL) || (out == NULL)) {
268 ERR_print_errors(bio_err);
269 goto end;
270 }
271 if (cfg.infile == NULL)
272 BIO_set_fp(in, stdin, BIO_NOCLOSE);
273 else {
274 if (BIO_read_filename(in, cfg.infile) <= 0) {
275 perror(cfg.infile);
276 goto end;
277 }
278 }
279 if (cfg.outfile == NULL) {
280 BIO_set_fp(out, stdout, BIO_NOCLOSE);
281 } else {
282 if (BIO_write_filename(out, cfg.outfile) <= 0) {
283 perror(cfg.outfile);
284 goto end;
285 }
286 }
287
288 if (cfg.list_curves) {
289 EC_builtin_curve *curves = NULL;
290 size_t crv_len = 0;
291 size_t n = 0;
292
293 crv_len = EC_get_builtin_curves(NULL, 0);
294
295 curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));
296 if (curves == NULL)
297 goto end;
298
299 if (!EC_get_builtin_curves(curves, crv_len)) {
300 free(curves);
301 goto end;
302 }
303 for (n = 0; n < crv_len; n++) {
304 const char *comment;
305 const char *sname;
306 comment = curves[n].comment;
307 sname = OBJ_nid2sn(curves[n].nid);
308 if (comment == NULL)
309 comment = "CURVE DESCRIPTION NOT AVAILABLE";
310 if (sname == NULL)
311 sname = "";
312
313 BIO_printf(out, " %-10s: ", sname);
314 BIO_printf(out, "%s\n", comment);
315 }
316
317 free(curves);
318 ret = 0;
319 goto end;
320 }
321 if (cfg.curve_name != NULL) {
322 int nid;
323
324 /*
325 * workaround for the SECG curve names secp192r1 and
326 * secp256r1 (which are the same as the curves prime192v1 and
327 * prime256v1 defined in X9.62)
328 */
329 if (!strcmp(cfg.curve_name, "secp192r1")) {
330 BIO_printf(bio_err, "using curve name prime192v1 "
331 "instead of secp192r1\n");
332 nid = NID_X9_62_prime192v1;
333 } else if (!strcmp(cfg.curve_name, "secp256r1")) {
334 BIO_printf(bio_err, "using curve name prime256v1 "
335 "instead of secp256r1\n");
336 nid = NID_X9_62_prime256v1;
337 } else
338 nid = OBJ_sn2nid(cfg.curve_name);
339
340 if (nid == 0)
341 nid = EC_curve_nist2nid(cfg.curve_name);
342
343 if (nid == 0) {
344 BIO_printf(bio_err, "unknown curve name (%s)\n",
345 cfg.curve_name);
346 goto end;
347 }
348 group = EC_GROUP_new_by_curve_name(nid);
349 if (group == NULL) {
350 BIO_printf(bio_err, "unable to create curve (%s)\n",
351 cfg.curve_name);
352 goto end;
353 }
354 EC_GROUP_set_asn1_flag(group, cfg.asn1_flag);
355 EC_GROUP_set_point_conversion_form(group, cfg.form);
356 } else if (cfg.informat == FORMAT_ASN1) {
357 group = d2i_ECPKParameters_bio(in, NULL);
358 } else if (cfg.informat == FORMAT_PEM) {
359 group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
360 } else {
361 BIO_printf(bio_err, "bad input format specified\n");
362 goto end;
363 }
364
365 if (group == NULL) {
366 BIO_printf(bio_err,
367 "unable to load elliptic curve parameters\n");
368 ERR_print_errors(bio_err);
369 goto end;
370 }
371 if (cfg.new_form)
372 EC_GROUP_set_point_conversion_form(group, cfg.form);
373
374 if (cfg.new_asn1_flag)
375 EC_GROUP_set_asn1_flag(group, cfg.asn1_flag);
376
377 if (cfg.no_seed)
378 EC_GROUP_set_seed(group, NULL, 0);
379
380 if (cfg.text) {
381 if (!ECPKParameters_print(out, group, 0))
382 goto end;
383 }
384 if (cfg.check) {
385 BIO_printf(bio_err, "checking elliptic curve parameters: ");
386 if (!EC_GROUP_check(group, NULL)) {
387 BIO_printf(bio_err, "failed\n");
388 ERR_print_errors(bio_err);
389 } else
390 BIO_printf(bio_err, "ok\n");
391
392 }
393 if (!cfg.noout) {
394 if (cfg.outformat == FORMAT_ASN1)
395 i = i2d_ECPKParameters_bio(out, group);
396 else if (cfg.outformat == FORMAT_PEM)
397 i = PEM_write_bio_ECPKParameters(out, group);
398 else {
399 BIO_printf(bio_err, "bad output format specified for"
400 " outfile\n");
401 goto end;
402 }
403 if (!i) {
404 BIO_printf(bio_err, "unable to write elliptic "
405 "curve parameters\n");
406 ERR_print_errors(bio_err);
407 goto end;
408 }
409 }
410 if (cfg.genkey) {
411 EC_KEY *eckey = EC_KEY_new();
412
413 if (eckey == NULL)
414 goto end;
415
416 if (EC_KEY_set_group(eckey, group) == 0) {
417 EC_KEY_free(eckey);
418 goto end;
419 }
420
421 if (!EC_KEY_generate_key(eckey)) {
422 EC_KEY_free(eckey);
423 goto end;
424 }
425 if (cfg.outformat == FORMAT_ASN1)
426 i = i2d_ECPrivateKey_bio(out, eckey);
427 else if (cfg.outformat == FORMAT_PEM)
428 i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
429 NULL, 0, NULL, NULL);
430 else {
431 BIO_printf(bio_err, "bad output format specified "
432 "for outfile\n");
433 EC_KEY_free(eckey);
434 goto end;
435 }
436 EC_KEY_free(eckey);
437 }
438 ret = 0;
439
440 end:
441 BIO_free(in);
442 BIO_free_all(out);
443 EC_GROUP_free(group);
444
445 return (ret);
446}
447
448#endif
diff --git a/src/usr.bin/openssl/enc.c b/src/usr.bin/openssl/enc.c
deleted file mode 100644
index 41732fd056..0000000000
--- a/src/usr.bin/openssl/enc.c
+++ /dev/null
@@ -1,783 +0,0 @@
1/* $OpenBSD: enc.c,v 1.31 2023/07/29 17:15:45 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#include <unistd.h>
63
64#include "apps.h"
65
66#include <openssl/bio.h>
67#include <openssl/err.h>
68#include <openssl/evp.h>
69#include <openssl/objects.h>
70
71int set_hex(char *in, unsigned char *out, int size);
72
73#define SIZE (512)
74#define BSIZE (8*1024)
75
76static struct {
77 int base64;
78 char *bufsize;
79 const EVP_CIPHER *cipher;
80 int debug;
81 int enc;
82 char *hiv;
83 char *hkey;
84 char *hsalt;
85 char *inf;
86 int iter;
87 char *keyfile;
88 char *keystr;
89 char *md;
90 int nopad;
91 int nosalt;
92 int olb64;
93 char *outf;
94 char *passarg;
95 int pbkdf2;
96 int printkey;
97 int verbose;
98} cfg;
99
100static int
101enc_opt_cipher(int argc, char **argv, int *argsused)
102{
103 char *name = argv[0];
104
105 if (*name++ != '-')
106 return (1);
107
108 if (strcmp(name, "none") == 0) {
109 cfg.cipher = NULL;
110 *argsused = 1;
111 return (0);
112 }
113
114 if ((cfg.cipher = EVP_get_cipherbyname(name)) != NULL) {
115 *argsused = 1;
116 return (0);
117 }
118
119 return (1);
120}
121
122static const struct option enc_options[] = {
123 {
124 .name = "A",
125 .desc = "Process base64 data on one line (requires -a)",
126 .type = OPTION_FLAG,
127 .opt.flag = &cfg.olb64,
128 },
129 {
130 .name = "a",
131 .desc = "Perform base64 encoding/decoding (alias -base64)",
132 .type = OPTION_FLAG,
133 .opt.flag = &cfg.base64,
134 },
135 {
136 .name = "base64",
137 .type = OPTION_FLAG,
138 .opt.flag = &cfg.base64,
139 },
140 {
141 .name = "bufsize",
142 .argname = "size",
143 .desc = "Specify the buffer size to use for I/O",
144 .type = OPTION_ARG,
145 .opt.arg = &cfg.bufsize,
146 },
147 {
148 .name = "d",
149 .desc = "Decrypt the input data",
150 .type = OPTION_VALUE,
151 .opt.value = &cfg.enc,
152 .value = 0,
153 },
154 {
155 .name = "debug",
156 .desc = "Print debugging information",
157 .type = OPTION_FLAG,
158 .opt.flag = &cfg.debug,
159 },
160 {
161 .name = "e",
162 .desc = "Encrypt the input data (default)",
163 .type = OPTION_VALUE,
164 .opt.value = &cfg.enc,
165 .value = 1,
166 },
167 {
168 .name = "in",
169 .argname = "file",
170 .desc = "Input file to read from (default stdin)",
171 .type = OPTION_ARG,
172 .opt.arg = &cfg.inf,
173 },
174 {
175 .name = "iter",
176 .argname = "iterations",
177 .desc = "Specify iteration count and force use of PBKDF2",
178 .type = OPTION_ARG_INT,
179 .opt.value = &cfg.iter,
180 },
181 {
182 .name = "iv",
183 .argname = "IV",
184 .desc = "IV to use, specified as a hexadecimal string",
185 .type = OPTION_ARG,
186 .opt.arg = &cfg.hiv,
187 },
188 {
189 .name = "K",
190 .argname = "key",
191 .desc = "Key to use, specified as a hexadecimal string",
192 .type = OPTION_ARG,
193 .opt.arg = &cfg.hkey,
194 },
195 {
196 .name = "k", /* Superseded by -pass. */
197 .type = OPTION_ARG,
198 .opt.arg = &cfg.keystr,
199 },
200 {
201 .name = "kfile", /* Superseded by -pass. */
202 .type = OPTION_ARG,
203 .opt.arg = &cfg.keyfile,
204 },
205 {
206 .name = "md",
207 .argname = "digest",
208 .desc = "Digest to use to create a key from the passphrase",
209 .type = OPTION_ARG,
210 .opt.arg = &cfg.md,
211 },
212 {
213 .name = "none",
214 .desc = "Use NULL cipher (no encryption or decryption)",
215 .type = OPTION_ARGV_FUNC,
216 .opt.argvfunc = enc_opt_cipher,
217 },
218 {
219 .name = "nopad",
220 .desc = "Disable standard block padding",
221 .type = OPTION_FLAG,
222 .opt.flag = &cfg.nopad,
223 },
224 {
225 .name = "nosalt",
226 .type = OPTION_VALUE,
227 .opt.value = &cfg.nosalt,
228 .value = 1,
229 },
230 {
231 .name = "out",
232 .argname = "file",
233 .desc = "Output file to write to (default stdout)",
234 .type = OPTION_ARG,
235 .opt.arg = &cfg.outf,
236 },
237 {
238 .name = "P",
239 .desc = "Print out the salt, key and IV used, then exit\n"
240 " (no encryption or decryption is performed)",
241 .type = OPTION_VALUE,
242 .opt.value = &cfg.printkey,
243 .value = 2,
244 },
245 {
246 .name = "p",
247 .desc = "Print out the salt, key and IV used",
248 .type = OPTION_VALUE,
249 .opt.value = &cfg.printkey,
250 .value = 1,
251 },
252 {
253 .name = "pass",
254 .argname = "source",
255 .desc = "Password source",
256 .type = OPTION_ARG,
257 .opt.arg = &cfg.passarg,
258 },
259 {
260 .name = "pbkdf2",
261 .desc = "Use the pbkdf2 key derivation function",
262 .type = OPTION_FLAG,
263 .opt.flag = &cfg.pbkdf2,
264 },
265 {
266 .name = "S",
267 .argname = "salt",
268 .desc = "Salt to use, specified as a hexadecimal string",
269 .type = OPTION_ARG,
270 .opt.arg = &cfg.hsalt,
271 },
272 {
273 .name = "salt",
274 .desc = "Use a salt in the key derivation routines (default)",
275 .type = OPTION_VALUE,
276 .opt.value = &cfg.nosalt,
277 .value = 0,
278 },
279 {
280 .name = "v",
281 .desc = "Verbose",
282 .type = OPTION_FLAG,
283 .opt.flag = &cfg.verbose,
284 },
285 {
286 .name = NULL,
287 .type = OPTION_ARGV_FUNC,
288 .opt.argvfunc = enc_opt_cipher,
289 },
290 { NULL },
291};
292
293static void
294skip_aead_and_xts(const OBJ_NAME *name, void *arg)
295{
296 const EVP_CIPHER *cipher;
297
298 if ((cipher = EVP_get_cipherbyname(name->name)) == NULL)
299 return;
300
301 if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0)
302 return;
303 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)
304 return;
305
306 show_cipher(name, arg);
307}
308
309static void
310enc_usage(void)
311{
312 int n = 0;
313
314 fprintf(stderr, "usage: enc -ciphername [-AadePp] [-base64] "
315 "[-bufsize number] [-debug]\n"
316 " [-in file] [-iter iterations] [-iv IV] [-K key] "
317 "[-k password]\n"
318 " [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]\n"
319 " [-out file] [-pass source] [-pbkdf2] [-S salt] [-salt]\n\n");
320 options_usage(enc_options);
321 fprintf(stderr, "\n");
322
323 fprintf(stderr, "Valid ciphername values:\n\n");
324 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, skip_aead_and_xts, &n);
325 fprintf(stderr, "\n");
326}
327
328int
329enc_main(int argc, char **argv)
330{
331 static const char magic[] = "Salted__";
332 char mbuf[sizeof magic - 1];
333 char *strbuf = NULL, *pass = NULL;
334 unsigned char *buff = NULL;
335 int bsize = BSIZE;
336 int ret = 1, inl;
337 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
338 unsigned char salt[PKCS5_SALT_LEN];
339 EVP_CIPHER_CTX *ctx = NULL;
340 const EVP_MD *dgst = NULL;
341 BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL;
342 BIO *rbio = NULL, *wbio = NULL;
343#define PROG_NAME_SIZE 39
344 char pname[PROG_NAME_SIZE + 1];
345 int i;
346
347 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
348 perror("pledge");
349 exit(1);
350 }
351
352 memset(&cfg, 0, sizeof(cfg));
353 cfg.enc = 1;
354
355 /* first check the program name */
356 program_name(argv[0], pname, sizeof(pname));
357
358 if (strcmp(pname, "base64") == 0)
359 cfg.base64 = 1;
360
361 cfg.cipher = EVP_get_cipherbyname(pname);
362
363 if (!cfg.base64 && cfg.cipher == NULL && strcmp(pname, "enc") != 0) {
364 BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
365 goto end;
366 }
367
368 if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) {
369 enc_usage();
370 goto end;
371 }
372
373 if (cfg.keyfile != NULL) {
374 static char buf[128];
375 FILE *infile;
376
377 infile = fopen(cfg.keyfile, "r");
378 if (infile == NULL) {
379 BIO_printf(bio_err, "unable to read key from '%s'\n",
380 cfg.keyfile);
381 goto end;
382 }
383 buf[0] = '\0';
384 if (!fgets(buf, sizeof buf, infile)) {
385 BIO_printf(bio_err, "unable to read key from '%s'\n",
386 cfg.keyfile);
387 fclose(infile);
388 goto end;
389 }
390 fclose(infile);
391 i = strlen(buf);
392 if (i > 0 && (buf[i - 1] == '\n' || buf[i - 1] == '\r'))
393 buf[--i] = '\0';
394 if (i > 0 && (buf[i - 1] == '\n' || buf[i - 1] == '\r'))
395 buf[--i] = '\0';
396 if (i < 1) {
397 BIO_printf(bio_err, "zero length password\n");
398 goto end;
399 }
400 cfg.keystr = buf;
401 }
402
403 if (cfg.cipher != NULL &&
404 (EVP_CIPHER_flags(cfg.cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) {
405 BIO_printf(bio_err, "enc does not support AEAD ciphers\n");
406 goto end;
407 }
408
409 if (cfg.cipher != NULL &&
410 EVP_CIPHER_mode(cfg.cipher) == EVP_CIPH_XTS_MODE) {
411 BIO_printf(bio_err, "enc does not support XTS mode\n");
412 goto end;
413 }
414
415 if (cfg.md != NULL &&
416 (dgst = EVP_get_digestbyname(cfg.md)) == NULL) {
417 BIO_printf(bio_err,
418 "%s is an unsupported message digest type\n",
419 cfg.md);
420 goto end;
421 }
422 if (dgst == NULL)
423 dgst = EVP_sha256();
424
425 if (cfg.bufsize != NULL) {
426 char *p = cfg.bufsize;
427 unsigned long n;
428
429 /* XXX - provide an OPTION_ARG_DISKUNIT. */
430 for (n = 0; *p != '\0'; p++) {
431 i = *p;
432 if ((i <= '9') && (i >= '0'))
433 n = n * 10 + i - '0';
434 else if (i == 'k') {
435 n *= 1024;
436 p++;
437 break;
438 }
439 }
440 if (*p != '\0') {
441 BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
442 goto end;
443 }
444 /* It must be large enough for a base64 encoded line. */
445 if (cfg.base64 && n < 80)
446 n = 80;
447
448 bsize = (int)n;
449 if (cfg.verbose)
450 BIO_printf(bio_err, "bufsize=%d\n", bsize);
451 }
452 strbuf = malloc(SIZE);
453 buff = malloc(EVP_ENCODE_LENGTH(bsize));
454 if (buff == NULL || strbuf == NULL) {
455 BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize));
456 goto end;
457 }
458 in = BIO_new(BIO_s_file());
459 out = BIO_new(BIO_s_file());
460 if (in == NULL || out == NULL) {
461 ERR_print_errors(bio_err);
462 goto end;
463 }
464 if (cfg.debug) {
465 BIO_set_callback(in, BIO_debug_callback);
466 BIO_set_callback(out, BIO_debug_callback);
467 BIO_set_callback_arg(in, (char *) bio_err);
468 BIO_set_callback_arg(out, (char *) bio_err);
469 }
470 if (cfg.inf == NULL) {
471 if (cfg.bufsize != NULL)
472 setvbuf(stdin, (char *) NULL, _IONBF, 0);
473 BIO_set_fp(in, stdin, BIO_NOCLOSE);
474 } else {
475 if (BIO_read_filename(in, cfg.inf) <= 0) {
476 perror(cfg.inf);
477 goto end;
478 }
479 }
480
481 if (!cfg.keystr && cfg.passarg) {
482 if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) {
483 BIO_printf(bio_err, "Error getting password\n");
484 goto end;
485 }
486 cfg.keystr = pass;
487 }
488 if (cfg.keystr == NULL && cfg.cipher != NULL && cfg.hkey == NULL) {
489 for (;;) {
490 char buf[200];
491 int retval;
492
493 retval = snprintf(buf, sizeof buf,
494 "enter %s %s password:",
495 OBJ_nid2ln(EVP_CIPHER_nid(cfg.cipher)),
496 cfg.enc ? "encryption" : "decryption");
497 if ((size_t)retval >= sizeof buf) {
498 BIO_printf(bio_err,
499 "Password prompt too long\n");
500 goto end;
501 }
502 strbuf[0] = '\0';
503 i = EVP_read_pw_string((char *)strbuf, SIZE, buf,
504 cfg.enc);
505 if (i == 0) {
506 if (strbuf[0] == '\0') {
507 ret = 1;
508 goto end;
509 }
510 cfg.keystr = strbuf;
511 break;
512 }
513 if (i < 0) {
514 BIO_printf(bio_err, "bad password read\n");
515 goto end;
516 }
517 }
518 }
519 if (cfg.outf == NULL) {
520 BIO_set_fp(out, stdout, BIO_NOCLOSE);
521 if (cfg.bufsize != NULL)
522 setvbuf(stdout, (char *)NULL, _IONBF, 0);
523 } else {
524 if (BIO_write_filename(out, cfg.outf) <= 0) {
525 perror(cfg.outf);
526 goto end;
527 }
528 }
529
530 rbio = in;
531 wbio = out;
532
533 if (cfg.base64) {
534 if ((b64 = BIO_new(BIO_f_base64())) == NULL)
535 goto end;
536 if (cfg.debug) {
537 BIO_set_callback(b64, BIO_debug_callback);
538 BIO_set_callback_arg(b64, (char *) bio_err);
539 }
540 if (cfg.olb64)
541 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
542 if (cfg.enc)
543 wbio = BIO_push(b64, wbio);
544 else
545 rbio = BIO_push(b64, rbio);
546 }
547 if (cfg.cipher != NULL) {
548 /*
549 * Note that keystr is NULL if a key was passed on the command
550 * line, so we get no salt in that case. Is this a bug?
551 */
552 if (cfg.keystr != NULL) {
553 /*
554 * Salt handling: if encrypting generate a salt and
555 * write to output BIO. If decrypting read salt from
556 * input BIO.
557 */
558 unsigned char *sptr;
559 if (cfg.nosalt)
560 sptr = NULL;
561 else {
562 if (cfg.enc) {
563 if (cfg.hsalt) {
564 if (!set_hex(cfg.hsalt, salt, sizeof salt)) {
565 BIO_printf(bio_err,
566 "invalid hex salt value\n");
567 goto end;
568 }
569 } else
570 arc4random_buf(salt,
571 sizeof(salt));
572 /*
573 * If -P option then don't bother
574 * writing
575 */
576 if ((cfg.printkey != 2)
577 && (BIO_write(wbio, magic,
578 sizeof magic - 1) != sizeof magic - 1
579 || BIO_write(wbio,
580 (char *) salt,
581 sizeof salt) != sizeof salt)) {
582 BIO_printf(bio_err, "error writing output file\n");
583 goto end;
584 }
585 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
586 || BIO_read(rbio,
587 (unsigned char *) salt,
588 sizeof salt) != sizeof salt) {
589 BIO_printf(bio_err, "error reading input file\n");
590 goto end;
591 } else if (memcmp(mbuf, magic, sizeof magic - 1)) {
592 BIO_printf(bio_err, "bad magic number\n");
593 goto end;
594 }
595 sptr = salt;
596 }
597 if (cfg.pbkdf2 == 1 || cfg.iter > 0) {
598 /*
599 * derive key and default iv
600 * concatenated into a temporary buffer
601 */
602 unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH];
603 int iklen = EVP_CIPHER_key_length(cfg.cipher);
604 int ivlen = EVP_CIPHER_iv_length(cfg.cipher);
605 /* not needed if HASH_UPDATE() is fixed : */
606 int islen = (sptr != NULL ? sizeof(salt) : 0);
607
608 if (cfg.iter == 0)
609 cfg.iter = 10000;
610
611 if (!PKCS5_PBKDF2_HMAC(cfg.keystr,
612 strlen(cfg.keystr), sptr, islen,
613 cfg.iter, dgst, iklen+ivlen, tmpkeyiv)) {
614 BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
615 goto end;
616 }
617 /* split and move data back to global buffer */
618 memcpy(key, tmpkeyiv, iklen);
619 memcpy(iv, tmpkeyiv + iklen, ivlen);
620 explicit_bzero(tmpkeyiv, sizeof tmpkeyiv);
621 } else {
622 EVP_BytesToKey(cfg.cipher, dgst, sptr,
623 (unsigned char *)cfg.keystr,
624 strlen(cfg.keystr), 1, key, iv);
625 }
626
627 /*
628 * zero the complete buffer or the string passed from
629 * the command line bug picked up by Larry J. Hughes
630 * Jr. <hughes@indiana.edu>
631 */
632 if (cfg.keystr == strbuf)
633 explicit_bzero(cfg.keystr, SIZE);
634 else
635 explicit_bzero(cfg.keystr,
636 strlen(cfg.keystr));
637 }
638 if (cfg.hiv != NULL && !set_hex(cfg.hiv, iv, sizeof iv)) {
639 BIO_printf(bio_err, "invalid hex iv value\n");
640 goto end;
641 }
642 if (cfg.hiv == NULL && cfg.keystr == NULL &&
643 EVP_CIPHER_iv_length(cfg.cipher) != 0) {
644 /*
645 * No IV was explicitly set and no IV was generated
646 * during EVP_BytesToKey. Hence the IV is undefined,
647 * making correct decryption impossible.
648 */
649 BIO_printf(bio_err, "iv undefined\n");
650 goto end;
651 }
652 if (cfg.hkey != NULL && !set_hex(cfg.hkey, key, sizeof key)) {
653 BIO_printf(bio_err, "invalid hex key value\n");
654 goto end;
655 }
656 if ((benc = BIO_new(BIO_f_cipher())) == NULL)
657 goto end;
658
659 /*
660 * Since we may be changing parameters work on the encryption
661 * context rather than calling BIO_set_cipher().
662 */
663
664 BIO_get_cipher_ctx(benc, &ctx);
665
666 if (!EVP_CipherInit_ex(ctx, cfg.cipher, NULL, NULL,
667 NULL, cfg.enc)) {
668 BIO_printf(bio_err, "Error setting cipher %s\n",
669 EVP_CIPHER_name(cfg.cipher));
670 ERR_print_errors(bio_err);
671 goto end;
672 }
673 if (cfg.nopad)
674 EVP_CIPHER_CTX_set_padding(ctx, 0);
675
676 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, cfg.enc)) {
677 BIO_printf(bio_err, "Error setting cipher %s\n",
678 EVP_CIPHER_name(cfg.cipher));
679 ERR_print_errors(bio_err);
680 goto end;
681 }
682 if (cfg.debug) {
683 BIO_set_callback(benc, BIO_debug_callback);
684 BIO_set_callback_arg(benc, (char *) bio_err);
685 }
686 if (cfg.printkey) {
687 int key_len, iv_len;
688
689 if (!cfg.nosalt) {
690 printf("salt=");
691 for (i = 0; i < (int) sizeof(salt); i++)
692 printf("%02X", salt[i]);
693 printf("\n");
694 }
695 key_len = EVP_CIPHER_key_length(cfg.cipher);
696 if (key_len > 0) {
697 printf("key=");
698 for (i = 0; i < key_len; i++)
699 printf("%02X", key[i]);
700 printf("\n");
701 }
702 iv_len = EVP_CIPHER_iv_length(cfg.cipher);
703 if (iv_len > 0) {
704 printf("iv =");
705 for (i = 0; i < iv_len; i++)
706 printf("%02X", iv[i]);
707 printf("\n");
708 }
709 if (cfg.printkey == 2) {
710 ret = 0;
711 goto end;
712 }
713 }
714 }
715 /* Only encrypt/decrypt as we write the file */
716 if (benc != NULL)
717 wbio = BIO_push(benc, wbio);
718
719 for (;;) {
720 inl = BIO_read(rbio, (char *) buff, bsize);
721 if (inl <= 0)
722 break;
723 if (BIO_write(wbio, (char *) buff, inl) != inl) {
724 BIO_printf(bio_err, "error writing output file\n");
725 goto end;
726 }
727 }
728 if (!BIO_flush(wbio)) {
729 BIO_printf(bio_err, "bad decrypt\n");
730 goto end;
731 }
732 ret = 0;
733 if (cfg.verbose) {
734 BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in));
735 BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
736 }
737 end:
738 ERR_print_errors(bio_err);
739 free(strbuf);
740 free(buff);
741 BIO_free(in);
742 BIO_free_all(out);
743 BIO_free(benc);
744 BIO_free(b64);
745 free(pass);
746
747 return (ret);
748}
749
750int
751set_hex(char *in, unsigned char *out, int size)
752{
753 int i, n;
754 unsigned char j;
755
756 n = strlen(in);
757 if (n > (size * 2)) {
758 BIO_printf(bio_err, "hex string is too long\n");
759 return (0);
760 }
761 memset(out, 0, size);
762 for (i = 0; i < n; i++) {
763 j = (unsigned char) *in;
764 *(in++) = '\0';
765 if (j == 0)
766 break;
767 if (j >= '0' && j <= '9')
768 j -= '0';
769 else if (j >= 'A' && j <= 'F')
770 j = j - 'A' + 10;
771 else if (j >= 'a' && j <= 'f')
772 j = j - 'a' + 10;
773 else {
774 BIO_printf(bio_err, "non-hex digit\n");
775 return (0);
776 }
777 if (i & 1)
778 out[i / 2] |= j;
779 else
780 out[i / 2] = (j << 4);
781 }
782 return (1);
783}
diff --git a/src/usr.bin/openssl/errstr.c b/src/usr.bin/openssl/errstr.c
deleted file mode 100644
index d4ffd70c39..0000000000
--- a/src/usr.bin/openssl/errstr.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/* $OpenBSD: errstr.c,v 1.11 2023/07/23 11:20:11 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <limits.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63
64#include "apps.h"
65
66#include <openssl/bio.h>
67#include <openssl/err.h>
68#include <openssl/lhash.h>
69#include <openssl/ssl.h>
70
71static const struct option errstr_options[] = {
72 { NULL },
73};
74
75static void
76errstr_usage(void)
77{
78 fprintf(stderr, "usage: errstr errno ...\n");
79}
80
81int
82errstr_main(int argc, char **argv)
83{
84 unsigned long ulval;
85 char *ularg, *ep;
86 int argsused, i;
87 char buf[256];
88 int ret = 0;
89
90 if (pledge("stdio rpath", NULL) == -1) {
91 perror("pledge");
92 exit(1);
93 }
94
95 if (options_parse(argc, argv, errstr_options, NULL, &argsused) != 0) {
96 errstr_usage();
97 return (1);
98 }
99
100 for (i = argsused; i < argc; i++) {
101 errno = 0;
102 ularg = argv[i];
103 ulval = strtoul(ularg, &ep, 16);
104 if (strchr(ularg, '-') != NULL ||
105 (ularg[0] == '\0' || *ep != '\0') ||
106 (errno == ERANGE && ulval == ULONG_MAX)) {
107 printf("%s: bad error code\n", ularg);
108 ret++;
109 continue;
110 }
111
112 ERR_error_string_n(ulval, buf, sizeof(buf));
113 printf("%s\n", buf);
114 }
115
116 return (ret);
117}
diff --git a/src/usr.bin/openssl/gendh.c b/src/usr.bin/openssl/gendh.c
deleted file mode 100644
index b9dde3c773..0000000000
--- a/src/usr.bin/openssl/gendh.c
+++ /dev/null
@@ -1,219 +0,0 @@
1/* $OpenBSD: gendh.c,v 1.14 2023/03/06 14:32:06 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h>
60
61/* Until the key-gen callbacks are modified to use newer prototypes, we allow
62 * deprecated functions for openssl-internal code */
63#ifdef OPENSSL_NO_DEPRECATED
64#undef OPENSSL_NO_DEPRECATED
65#endif
66
67#ifndef OPENSSL_NO_DH
68
69#include <sys/types.h>
70#include <sys/stat.h>
71
72#include <limits.h>
73#include <stdio.h>
74#include <string.h>
75
76#include "apps.h"
77
78#include <openssl/bio.h>
79#include <openssl/bn.h>
80#include <openssl/dh.h>
81#include <openssl/err.h>
82#include <openssl/pem.h>
83#include <openssl/x509.h>
84
85#define DEFBITS 512
86
87static int dh_cb(int p, int n, BN_GENCB *cb);
88
89static struct {
90 int g;
91 char *outfile;
92} cfg;
93
94static const struct option gendh_options[] = {
95 {
96 .name = "2",
97 .desc = "Generate DH parameters with a generator value of 2 "
98 "(default)",
99 .type = OPTION_VALUE,
100 .value = 2,
101 .opt.value = &cfg.g,
102 },
103 {
104 .name = "5",
105 .desc = "Generate DH parameters with a generator value of 5",
106 .type = OPTION_VALUE,
107 .value = 5,
108 .opt.value = &cfg.g,
109 },
110 {
111 .name = "out",
112 .argname = "file",
113 .desc = "Output file (default stdout)",
114 .type = OPTION_ARG,
115 .opt.arg = &cfg.outfile,
116 },
117 { NULL },
118};
119
120static void
121gendh_usage(void)
122{
123 fprintf(stderr,
124 "usage: gendh [-2 | -5] [-out file] [numbits]\n\n");
125 options_usage(gendh_options);
126}
127
128int
129gendh_main(int argc, char **argv)
130{
131 BN_GENCB *cb = NULL;
132 DH *dh = NULL;
133 int ret = 1, numbits = DEFBITS;
134 BIO *out = NULL;
135 char *strbits = NULL;
136
137 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
138 perror("pledge");
139 exit(1);
140 }
141
142 if ((cb = BN_GENCB_new()) == NULL) {
143 BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
144 goto end;
145 }
146
147 BN_GENCB_set(cb, dh_cb, bio_err);
148
149 memset(&cfg, 0, sizeof(cfg));
150
151 cfg.g = 2;
152
153 if (options_parse(argc, argv, gendh_options, &strbits, NULL) != 0) {
154 gendh_usage();
155 goto end;
156 }
157
158 if (strbits != NULL) {
159 const char *errstr;
160 numbits = strtonum(strbits, 0, INT_MAX, &errstr);
161 if (errstr) {
162 fprintf(stderr, "Invalid number of bits: %s\n", errstr);
163 goto end;
164 }
165 }
166
167 out = BIO_new(BIO_s_file());
168 if (out == NULL) {
169 ERR_print_errors(bio_err);
170 goto end;
171 }
172 if (cfg.outfile == NULL) {
173 BIO_set_fp(out, stdout, BIO_NOCLOSE);
174 } else {
175 if (BIO_write_filename(out, cfg.outfile) <= 0) {
176 perror(cfg.outfile);
177 goto end;
178 }
179 }
180
181 BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime,"
182 " generator %d\n", numbits, cfg.g);
183 BIO_printf(bio_err, "This is going to take a long time\n");
184
185 if (((dh = DH_new()) == NULL) ||
186 !DH_generate_parameters_ex(dh, numbits, cfg.g, cb))
187 goto end;
188
189 if (!PEM_write_bio_DHparams(out, dh))
190 goto end;
191 ret = 0;
192 end:
193 if (ret != 0)
194 ERR_print_errors(bio_err);
195 BIO_free_all(out);
196 BN_GENCB_free(cb);
197 DH_free(dh);
198
199 return (ret);
200}
201
202static int
203dh_cb(int p, int n, BN_GENCB *cb)
204{
205 char c = '*';
206
207 if (p == 0)
208 c = '.';
209 if (p == 1)
210 c = '+';
211 if (p == 2)
212 c = '*';
213 if (p == 3)
214 c = '\n';
215 BIO_write(BN_GENCB_get_arg(cb), &c, 1);
216 (void) BIO_flush(BN_GENCB_get_arg(cb));
217 return 1;
218}
219#endif
diff --git a/src/usr.bin/openssl/gendsa.c b/src/usr.bin/openssl/gendsa.c
deleted file mode 100644
index 00635c4551..0000000000
--- a/src/usr.bin/openssl/gendsa.c
+++ /dev/null
@@ -1,296 +0,0 @@
1/* $OpenBSD: gendsa.c,v 1.17 2023/03/06 14:32:06 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
60
61
62#include <sys/types.h>
63#include <sys/stat.h>
64
65#include <stdio.h>
66#include <string.h>
67
68#include "apps.h"
69
70#include <openssl/bio.h>
71#include <openssl/bn.h>
72#include <openssl/dsa.h>
73#include <openssl/err.h>
74#include <openssl/pem.h>
75#include <openssl/x509.h>
76
77static struct {
78 const EVP_CIPHER *enc;
79 char *outfile;
80 char *passargout;
81} cfg;
82
83static const EVP_CIPHER *get_cipher_by_name(char *name)
84{
85 if (name == NULL || strcmp(name, "") == 0)
86 return (NULL);
87#ifndef OPENSSL_NO_AES
88 else if (strcmp(name, "aes128") == 0)
89 return EVP_aes_128_cbc();
90 else if (strcmp(name, "aes192") == 0)
91 return EVP_aes_192_cbc();
92 else if (strcmp(name, "aes256") == 0)
93 return EVP_aes_256_cbc();
94#endif
95#ifndef OPENSSL_NO_CAMELLIA
96 else if (strcmp(name, "camellia128") == 0)
97 return EVP_camellia_128_cbc();
98 else if (strcmp(name, "camellia192") == 0)
99 return EVP_camellia_192_cbc();
100 else if (strcmp(name, "camellia256") == 0)
101 return EVP_camellia_256_cbc();
102#endif
103#ifndef OPENSSL_NO_DES
104 else if (strcmp(name, "des") == 0)
105 return EVP_des_cbc();
106 else if (strcmp(name, "des3") == 0)
107 return EVP_des_ede3_cbc();
108#endif
109#ifndef OPENSSL_NO_IDEA
110 else if (strcmp(name, "idea") == 0)
111 return EVP_idea_cbc();
112#endif
113 else
114 return (NULL);
115}
116
117static int
118set_enc(int argc, char **argv, int *argsused)
119{
120 char *name = argv[0];
121
122 if (*name++ != '-')
123 return (1);
124
125 if ((cfg.enc = get_cipher_by_name(name)) == NULL)
126 return (1);
127
128 *argsused = 1;
129 return (0);
130}
131
132static const struct option gendsa_options[] = {
133#ifndef OPENSSL_NO_AES
134 {
135 .name = "aes128",
136 .desc = "Encrypt PEM output with CBC AES",
137 .type = OPTION_ARGV_FUNC,
138 .opt.argvfunc = set_enc,
139 },
140 {
141 .name = "aes192",
142 .desc = "Encrypt PEM output with CBC AES",
143 .type = OPTION_ARGV_FUNC,
144 .opt.argvfunc = set_enc,
145 },
146 {
147 .name = "aes256",
148 .desc = "Encrypt PEM output with CBC AES",
149 .type = OPTION_ARGV_FUNC,
150 .opt.argvfunc = set_enc,
151 },
152#endif
153#ifndef OPENSSL_NO_CAMELLIA
154 {
155 .name = "camellia128",
156 .desc = "Encrypt PEM output with CBC Camellia",
157 .type = OPTION_ARGV_FUNC,
158 .opt.argvfunc = set_enc,
159 },
160 {
161 .name = "camellia192",
162 .desc = "Encrypt PEM output with CBC Camellia",
163 .type = OPTION_ARGV_FUNC,
164 .opt.argvfunc = set_enc,
165 },
166 {
167 .name = "camellia256",
168 .desc = "Encrypt PEM output with CBC Camellia",
169 .type = OPTION_ARGV_FUNC,
170 .opt.argvfunc = set_enc,
171 },
172#endif
173#ifndef OPENSSL_NO_DES
174 {
175 .name = "des",
176 .desc = "Encrypt the generated key with DES in CBC mode",
177 .type = OPTION_ARGV_FUNC,
178 .opt.argvfunc = set_enc,
179 },
180 {
181 .name = "des3",
182 .desc = "Encrypt the generated key with DES in EDE CBC mode (168 bit key)",
183 .type = OPTION_ARGV_FUNC,
184 .opt.argvfunc = set_enc,
185 },
186#endif
187#ifndef OPENSSL_NO_IDEA
188 {
189 .name = "idea",
190 .desc = "Encrypt the generated key with IDEA in CBC mode",
191 .type = OPTION_ARGV_FUNC,
192 .opt.argvfunc = set_enc,
193 },
194#endif
195 {
196 .name = "out",
197 .argname = "file",
198 .desc = "Output the key to 'file'",
199 .type = OPTION_ARG,
200 .opt.arg = &cfg.outfile,
201 },
202 {
203 .name = "passout",
204 .argname = "src",
205 .desc = "Output file passphrase source",
206 .type = OPTION_ARG,
207 .opt.arg = &cfg.passargout,
208 },
209 { NULL },
210};
211
212static void
213gendsa_usage(void)
214{
215 fprintf(stderr, "usage: gendsa [-aes128 | -aes192 | -aes256 |\n");
216 fprintf(stderr, " -camellia128 | -camellia192 | -camellia256 |\n");
217 fprintf(stderr, " -des | -des3 | -idea] [-out file] [-passout src]");
218 fprintf(stderr, " paramfile\n\n");
219 options_usage(gendsa_options);
220 fprintf(stderr, "\n");
221}
222
223int
224gendsa_main(int argc, char **argv)
225{
226 DSA *dsa = NULL;
227 int ret = 1;
228 char *dsaparams = NULL;
229 char *passout = NULL;
230 BIO *out = NULL, *in = NULL;
231
232 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
233 perror("pledge");
234 exit(1);
235 }
236
237 memset(&cfg, 0, sizeof(cfg));
238
239 if (options_parse(argc, argv, gendsa_options, &dsaparams, NULL) != 0) {
240 gendsa_usage();
241 goto end;
242 }
243
244 if (dsaparams == NULL) {
245 gendsa_usage();
246 goto end;
247 }
248 if (!app_passwd(bio_err, NULL, cfg.passargout, NULL,
249 &passout)) {
250 BIO_printf(bio_err, "Error getting password\n");
251 goto end;
252 }
253 in = BIO_new(BIO_s_file());
254 if (!(BIO_read_filename(in, dsaparams))) {
255 perror(dsaparams);
256 goto end;
257 }
258 if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) {
259 BIO_printf(bio_err, "unable to load DSA parameter file\n");
260 goto end;
261 }
262 BIO_free(in);
263 in = NULL;
264
265 out = BIO_new(BIO_s_file());
266 if (out == NULL)
267 goto end;
268
269 if (cfg.outfile == NULL) {
270 BIO_set_fp(out, stdout, BIO_NOCLOSE);
271 } else {
272 if (BIO_write_filename(out, cfg.outfile) <= 0) {
273 perror(cfg.outfile);
274 goto end;
275 }
276 }
277
278 BIO_printf(bio_err, "Generating DSA key, %d bits\n",
279 BN_num_bits(DSA_get0_p(dsa)));
280 if (!DSA_generate_key(dsa))
281 goto end;
282
283 if (!PEM_write_bio_DSAPrivateKey(out, dsa, cfg.enc, NULL, 0,
284 NULL, passout))
285 goto end;
286 ret = 0;
287 end:
288 if (ret != 0)
289 ERR_print_errors(bio_err);
290 BIO_free(in);
291 BIO_free_all(out);
292 DSA_free(dsa);
293 free(passout);
294
295 return (ret);
296}
diff --git a/src/usr.bin/openssl/genpkey.c b/src/usr.bin/openssl/genpkey.c
deleted file mode 100644
index 10c5b0f662..0000000000
--- a/src/usr.bin/openssl/genpkey.c
+++ /dev/null
@@ -1,418 +0,0 @@
1/* $OpenBSD: genpkey.c,v 1.17 2023/07/23 11:39:29 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include "apps.h"
63
64#include <openssl/err.h>
65#include <openssl/evp.h>
66#include <openssl/pem.h>
67
68static int init_keygen_file(BIO * err, EVP_PKEY_CTX **pctx, const char *file);
69static int genpkey_cb(EVP_PKEY_CTX * ctx);
70
71static struct {
72 const EVP_CIPHER *cipher;
73 EVP_PKEY_CTX **ctx;
74 int do_param;
75 char *outfile;
76 int outformat;
77 char *passarg;
78 int text;
79} cfg;
80
81static int
82genpkey_opt_algorithm(char *arg)
83{
84 if (!init_gen_str(bio_err, cfg.ctx, arg,
85 cfg.do_param))
86 return (1);
87
88 return (0);
89}
90
91static int
92genpkey_opt_cipher(int argc, char **argv, int *argsused)
93{
94 char *name = argv[0];
95
96 if (*name++ != '-')
97 return (1);
98
99 if (cfg.do_param == 1)
100 return (1);
101
102 if (strcmp(name, "none") == 0) {
103 cfg.cipher = NULL;
104 *argsused = 1;
105 return (0);
106 }
107
108 if ((cfg.cipher = EVP_get_cipherbyname(name)) != NULL) {
109 *argsused = 1;
110 return (0);
111 }
112
113 return (1);
114}
115
116static int
117genpkey_opt_paramfile(char *arg)
118{
119 if (cfg.do_param == 1)
120 return (1);
121 if (!init_keygen_file(bio_err, cfg.ctx, arg))
122 return (1);
123
124 return (0);
125}
126
127static int
128genpkey_opt_pkeyopt(char *arg)
129{
130 if (*cfg.ctx == NULL) {
131 BIO_puts(bio_err, "No keytype specified\n");
132 return (1);
133 }
134
135 if (pkey_ctrl_string(*cfg.ctx, arg) <= 0) {
136 BIO_puts(bio_err, "parameter setting error\n");
137 ERR_print_errors(bio_err);
138 return (1);
139 }
140
141 return (0);
142}
143
144static const struct option genpkey_options[] = {
145 {
146 .name = "algorithm",
147 .argname = "name",
148 .desc = "Public key algorithm to use (must precede -pkeyopt)",
149 .type = OPTION_ARG_FUNC,
150 .opt.argfunc = genpkey_opt_algorithm,
151 },
152 {
153 .name = "genparam",
154 .desc = "Generate a set of parameters instead of a private key",
155 .type = OPTION_FLAG,
156 .opt.flag = &cfg.do_param,
157 },
158 {
159 .name = "out",
160 .argname = "file",
161 .desc = "Output file to write to (default stdout)",
162 .type = OPTION_ARG,
163 .opt.arg = &cfg.outfile,
164 },
165 {
166 .name = "outform",
167 .argname = "format",
168 .desc = "Output format (DER or PEM)",
169 .type = OPTION_ARG_FORMAT,
170 .opt.value = &cfg.outformat,
171 },
172 {
173 .name = "paramfile",
174 .argname = "file",
175 .desc = "File to load public key algorithm parameters from\n"
176 "(must precede -pkeyopt)",
177 .type = OPTION_ARG_FUNC,
178 .opt.argfunc = genpkey_opt_paramfile,
179 },
180 {
181 .name = "pass",
182 .argname = "arg",
183 .desc = "Output file password source",
184 .type = OPTION_ARG,
185 .opt.arg = &cfg.passarg,
186 },
187 {
188 .name = "pkeyopt",
189 .argname = "opt:value",
190 .desc = "Set public key algorithm option to the given value",
191 .type = OPTION_ARG_FUNC,
192 .opt.argfunc = genpkey_opt_pkeyopt,
193 },
194 {
195 .name = "text",
196 .desc = "Print the private/public key in human readable form",
197 .type = OPTION_FLAG,
198 .opt.flag = &cfg.text,
199 },
200 {
201 .name = NULL,
202 .type = OPTION_ARGV_FUNC,
203 .opt.argvfunc = genpkey_opt_cipher,
204 },
205 {NULL},
206};
207
208static void
209genpkey_usage(void)
210{
211 fprintf(stderr,
212 "usage: genpkey [-algorithm alg] [cipher] [-genparam] [-out file]\n"
213 " [-outform der | pem] [-paramfile file] [-pass arg]\n"
214 " [-pkeyopt opt:value] [-text]\n\n");
215 options_usage(genpkey_options);
216}
217
218int
219genpkey_main(int argc, char **argv)
220{
221 BIO *in = NULL, *out = NULL;
222 EVP_PKEY_CTX *ctx = NULL;
223 EVP_PKEY *pkey = NULL;
224 char *pass = NULL;
225 int ret = 1, rv;
226
227 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
228 perror("pledge");
229 exit(1);
230 }
231
232 memset(&cfg, 0, sizeof(cfg));
233 cfg.ctx = &ctx;
234 cfg.outformat = FORMAT_PEM;
235
236 if (options_parse(argc, argv, genpkey_options, NULL, NULL) != 0) {
237 genpkey_usage();
238 goto end;
239 }
240
241 if (ctx == NULL) {
242 genpkey_usage();
243 goto end;
244 }
245
246 if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) {
247 BIO_puts(bio_err, "Error getting password\n");
248 goto end;
249 }
250 if (cfg.outfile != NULL) {
251 if ((out = BIO_new_file(cfg.outfile, "wb")) ==
252 NULL) {
253 BIO_printf(bio_err, "Can't open output file %s\n",
254 cfg.outfile);
255 goto end;
256 }
257 } else {
258 out = BIO_new_fp(stdout, BIO_NOCLOSE);
259 }
260
261 EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
262 EVP_PKEY_CTX_set_app_data(ctx, bio_err);
263
264 if (cfg.do_param) {
265 if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
266 BIO_puts(bio_err, "Error generating parameters\n");
267 ERR_print_errors(bio_err);
268 goto end;
269 }
270 } else {
271 if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
272 BIO_puts(bio_err, "Error generating key\n");
273 ERR_print_errors(bio_err);
274 goto end;
275 }
276 }
277
278 if (cfg.do_param)
279 rv = PEM_write_bio_Parameters(out, pkey);
280 else if (cfg.outformat == FORMAT_PEM)
281 rv = PEM_write_bio_PrivateKey(out, pkey, cfg.cipher,
282 NULL, 0, NULL, pass);
283 else if (cfg.outformat == FORMAT_ASN1)
284 rv = i2d_PrivateKey_bio(out, pkey);
285 else {
286 BIO_printf(bio_err, "Bad format specified for key\n");
287 goto end;
288 }
289
290 if (rv <= 0) {
291 BIO_puts(bio_err, "Error writing key\n");
292 ERR_print_errors(bio_err);
293 }
294 if (cfg.text) {
295 if (cfg.do_param)
296 rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
297 else
298 rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
299
300 if (rv <= 0) {
301 BIO_puts(bio_err, "Error printing key\n");
302 ERR_print_errors(bio_err);
303 }
304 }
305 ret = 0;
306
307 end:
308 EVP_PKEY_free(pkey);
309 EVP_PKEY_CTX_free(ctx);
310 BIO_free_all(out);
311 BIO_free(in);
312 free(pass);
313
314 return ret;
315}
316
317static int
318init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, const char *file)
319{
320 BIO *pbio;
321 EVP_PKEY *pkey = NULL;
322 EVP_PKEY_CTX *ctx = NULL;
323 if (*pctx) {
324 BIO_puts(err, "Parameters already set!\n");
325 return 0;
326 }
327 pbio = BIO_new_file(file, "r");
328 if (!pbio) {
329 BIO_printf(err, "Can't open parameter file %s\n", file);
330 return 0;
331 }
332 pkey = PEM_read_bio_Parameters(pbio, NULL);
333 BIO_free(pbio);
334
335 if (!pkey) {
336 BIO_printf(bio_err, "Error reading parameter file %s\n", file);
337 return 0;
338 }
339 ctx = EVP_PKEY_CTX_new(pkey, NULL);
340 if (!ctx)
341 goto err;
342 if (EVP_PKEY_keygen_init(ctx) <= 0)
343 goto err;
344 EVP_PKEY_free(pkey);
345 *pctx = ctx;
346 return 1;
347
348 err:
349 BIO_puts(err, "Error initializing context\n");
350 ERR_print_errors(err);
351 EVP_PKEY_CTX_free(ctx);
352 EVP_PKEY_free(pkey);
353 return 0;
354
355}
356
357int
358init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, const char *algname, int do_param)
359{
360 const EVP_PKEY_ASN1_METHOD *ameth;
361 EVP_PKEY_CTX *ctx = NULL;
362 int pkey_id;
363
364 if (*pctx) {
365 BIO_puts(err, "Algorithm already set!\n");
366 return 0;
367 }
368 ameth = EVP_PKEY_asn1_find_str(NULL, algname, -1);
369
370 if (!ameth) {
371 BIO_printf(bio_err, "Algorithm %s not found\n", algname);
372 return 0;
373 }
374 ERR_clear_error();
375
376 EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
377 ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL);
378
379 if (!ctx)
380 goto err;
381 if (do_param) {
382 if (EVP_PKEY_paramgen_init(ctx) <= 0)
383 goto err;
384 } else {
385 if (EVP_PKEY_keygen_init(ctx) <= 0)
386 goto err;
387 }
388
389 *pctx = ctx;
390 return 1;
391
392 err:
393 BIO_printf(err, "Error initializing %s context\n", algname);
394 ERR_print_errors(err);
395 EVP_PKEY_CTX_free(ctx);
396 return 0;
397
398}
399
400static int
401genpkey_cb(EVP_PKEY_CTX * ctx)
402{
403 char c = '*';
404 BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
405 int p;
406 p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
407 if (p == 0)
408 c = '.';
409 if (p == 1)
410 c = '+';
411 if (p == 2)
412 c = '*';
413 if (p == 3)
414 c = '\n';
415 BIO_write(b, &c, 1);
416 (void) BIO_flush(b);
417 return 1;
418}
diff --git a/src/usr.bin/openssl/genrsa.c b/src/usr.bin/openssl/genrsa.c
deleted file mode 100644
index 0b5323fa5f..0000000000
--- a/src/usr.bin/openssl/genrsa.c
+++ /dev/null
@@ -1,389 +0,0 @@
1/* $OpenBSD: genrsa.c,v 1.22 2023/03/06 14:32:06 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h>
60
61/* Until the key-gen callbacks are modified to use newer prototypes, we allow
62 * deprecated functions for openssl-internal code */
63#ifdef OPENSSL_NO_DEPRECATED
64#undef OPENSSL_NO_DEPRECATED
65#endif
66
67
68#include <sys/types.h>
69#include <sys/stat.h>
70
71#include <stdio.h>
72#include <string.h>
73
74#include "apps.h"
75
76#include <openssl/bio.h>
77#include <openssl/bn.h>
78#include <openssl/err.h>
79#include <openssl/evp.h>
80#include <openssl/pem.h>
81#include <openssl/rsa.h>
82#include <openssl/x509.h>
83
84#define DEFBITS 2048
85
86static int genrsa_cb(int p, int n, BN_GENCB *cb);
87
88static struct {
89 const EVP_CIPHER *enc;
90 unsigned long f4;
91 char *outfile;
92 char *passargout;
93} cfg;
94
95static int
96set_public_exponent(int argc, char **argv, int *argsused)
97{
98 char *option = argv[0];
99
100 if (strcmp(option, "-3") == 0)
101 cfg.f4 = 3;
102 else if (strcmp(option, "-f4") == 0 || strcmp(option, "-F4") == 0)
103 cfg.f4 = RSA_F4;
104 else
105 return (1);
106
107 *argsused = 1;
108 return (0);
109}
110
111static const EVP_CIPHER *get_cipher_by_name(char *name)
112{
113 if (name == NULL || strcmp(name, "") == 0)
114 return (NULL);
115#ifndef OPENSSL_NO_AES
116 else if (strcmp(name, "aes128") == 0)
117 return EVP_aes_128_cbc();
118 else if (strcmp(name, "aes192") == 0)
119 return EVP_aes_192_cbc();
120 else if (strcmp(name, "aes256") == 0)
121 return EVP_aes_256_cbc();
122#endif
123#ifndef OPENSSL_NO_CAMELLIA
124 else if (strcmp(name, "camellia128") == 0)
125 return EVP_camellia_128_cbc();
126 else if (strcmp(name, "camellia192") == 0)
127 return EVP_camellia_192_cbc();
128 else if (strcmp(name, "camellia256") == 0)
129 return EVP_camellia_256_cbc();
130#endif
131#ifndef OPENSSL_NO_DES
132 else if (strcmp(name, "des") == 0)
133 return EVP_des_cbc();
134 else if (strcmp(name, "des3") == 0)
135 return EVP_des_ede3_cbc();
136#endif
137#ifndef OPENSSL_NO_IDEA
138 else if (strcmp(name, "idea") == 0)
139 return EVP_idea_cbc();
140#endif
141 else
142 return (NULL);
143}
144
145static int
146set_enc(int argc, char **argv, int *argsused)
147{
148 char *name = argv[0];
149
150 if (*name++ != '-')
151 return (1);
152
153 if ((cfg.enc = get_cipher_by_name(name)) == NULL)
154 return (1);
155
156 *argsused = 1;
157 return (0);
158}
159
160static const struct option genrsa_options[] = {
161 {
162 .name = "3",
163 .desc = "Use 3 for the E value",
164 .type = OPTION_ARGV_FUNC,
165 .opt.argvfunc = set_public_exponent,
166 },
167 {
168 .name = "f4",
169 .desc = "Use F4 (0x10001) for the E value",
170 .type = OPTION_ARGV_FUNC,
171 .opt.argvfunc = set_public_exponent,
172 },
173 {
174 .name = "F4",
175 .desc = "Use F4 (0x10001) for the E value",
176 .type = OPTION_ARGV_FUNC,
177 .opt.argvfunc = set_public_exponent,
178 },
179#ifndef OPENSSL_NO_AES
180 {
181 .name = "aes128",
182 .desc = "Encrypt PEM output with CBC AES",
183 .type = OPTION_ARGV_FUNC,
184 .opt.argvfunc = set_enc,
185 },
186 {
187 .name = "aes192",
188 .desc = "Encrypt PEM output with CBC AES",
189 .type = OPTION_ARGV_FUNC,
190 .opt.argvfunc = set_enc,
191 },
192 {
193 .name = "aes256",
194 .desc = "Encrypt PEM output with CBC AES",
195 .type = OPTION_ARGV_FUNC,
196 .opt.argvfunc = set_enc,
197 },
198#endif
199#ifndef OPENSSL_NO_CAMELLIA
200 {
201 .name = "camellia128",
202 .desc = "Encrypt PEM output with CBC Camellia",
203 .type = OPTION_ARGV_FUNC,
204 .opt.argvfunc = set_enc,
205 },
206 {
207 .name = "camellia192",
208 .desc = "Encrypt PEM output with CBC Camellia",
209 .type = OPTION_ARGV_FUNC,
210 .opt.argvfunc = set_enc,
211 },
212 {
213 .name = "camellia256",
214 .desc = "Encrypt PEM output with CBC Camellia",
215 .type = OPTION_ARGV_FUNC,
216 .opt.argvfunc = set_enc,
217 },
218#endif
219#ifndef OPENSSL_NO_DES
220 {
221 .name = "des",
222 .desc = "Encrypt the generated key with DES in CBC mode",
223 .type = OPTION_ARGV_FUNC,
224 .opt.argvfunc = set_enc,
225 },
226 {
227 .name = "des3",
228 .desc = "Encrypt the generated key with DES in EDE CBC mode (168 bit key)",
229 .type = OPTION_ARGV_FUNC,
230 .opt.argvfunc = set_enc,
231 },
232#endif
233#ifndef OPENSSL_NO_IDEA
234 {
235 .name = "idea",
236 .desc = "Encrypt the generated key with IDEA in CBC mode",
237 .type = OPTION_ARGV_FUNC,
238 .opt.argvfunc = set_enc,
239 },
240#endif
241 {
242 .name = "out",
243 .argname = "file",
244 .desc = "Output the key to 'file'",
245 .type = OPTION_ARG,
246 .opt.arg = &cfg.outfile,
247 },
248 {
249 .name = "passout",
250 .argname = "arg",
251 .desc = "Output file passphrase source",
252 .type = OPTION_ARG,
253 .opt.arg = &cfg.passargout,
254 },
255 { NULL },
256};
257
258static void
259genrsa_usage(void)
260{
261 fprintf(stderr, "usage: genrsa [-3 | -f4] [-aes128 | -aes192 |");
262 fprintf(stderr, " -aes256 |\n");
263 fprintf(stderr, " -camellia128 | -camellia192 | -camellia256 |");
264 fprintf(stderr, " -des | -des3 | -idea]\n");
265 fprintf(stderr, " [-out file] [-passout arg] [numbits]\n\n");
266 options_usage(genrsa_options);
267 fprintf(stderr, "\n");
268}
269
270int
271genrsa_main(int argc, char **argv)
272{
273 BN_GENCB *cb = NULL;
274 int ret = 1;
275 int num = DEFBITS;
276 char *numbits = NULL;
277 char *passout = NULL;
278 BIO *out = NULL;
279 BIGNUM *bn = NULL;
280 RSA *rsa = NULL;
281 char *rsa_e_hex = NULL, *rsa_e_dec = NULL;
282
283 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
284 perror("pledge");
285 exit(1);
286 }
287
288 if ((bn = BN_new()) == NULL)
289 goto err;
290
291 if ((cb = BN_GENCB_new()) == NULL) {
292 BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
293 goto err;
294 }
295
296 BN_GENCB_set(cb, genrsa_cb, bio_err);
297
298 if ((out = BIO_new(BIO_s_file())) == NULL) {
299 BIO_printf(bio_err, "unable to create BIO for output\n");
300 goto err;
301 }
302
303 memset(&cfg, 0, sizeof(cfg));
304 cfg.f4 = RSA_F4;
305
306 if (options_parse(argc, argv, genrsa_options, &numbits, NULL) != 0) {
307 genrsa_usage();
308 goto err;
309 }
310
311 if ((numbits != NULL) &&
312 ((sscanf(numbits, "%d", &num) == 0) || (num < 0))) {
313 genrsa_usage();
314 goto err;
315 }
316
317 if (!app_passwd(bio_err, NULL, cfg.passargout, NULL,
318 &passout)) {
319 BIO_printf(bio_err, "Error getting password\n");
320 goto err;
321 }
322
323 if (cfg.outfile == NULL) {
324 BIO_set_fp(out, stdout, BIO_NOCLOSE);
325 } else {
326 if (BIO_write_filename(out, cfg.outfile) <= 0) {
327 perror(cfg.outfile);
328 goto err;
329 }
330 }
331
332 BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
333 num);
334 rsa = RSA_new();
335 if (!rsa)
336 goto err;
337
338 if (!BN_set_word(bn, cfg.f4) ||
339 !RSA_generate_key_ex(rsa, num, bn, cb))
340 goto err;
341
342 if ((rsa_e_hex = BN_bn2hex(RSA_get0_e(rsa))) == NULL)
343 goto err;
344 if ((rsa_e_dec = BN_bn2dec(RSA_get0_e(rsa))) == NULL)
345 goto err;
346
347 BIO_printf(bio_err, "e is %s (0x%s)\n", rsa_e_dec, rsa_e_hex);
348 {
349 PW_CB_DATA cb_data;
350 cb_data.password = passout;
351 cb_data.prompt_info = cfg.outfile;
352 if (!PEM_write_bio_RSAPrivateKey(out, rsa, cfg.enc,
353 NULL, 0, password_callback, &cb_data))
354 goto err;
355 }
356
357 ret = 0;
358 err:
359 BN_free(bn);
360 BN_GENCB_free(cb);
361 RSA_free(rsa);
362 BIO_free_all(out);
363 free(rsa_e_dec);
364 free(rsa_e_hex);
365 free(passout);
366
367 if (ret != 0)
368 ERR_print_errors(bio_err);
369
370 return (ret);
371}
372
373static int
374genrsa_cb(int p, int n, BN_GENCB *cb)
375{
376 char c = '*';
377
378 if (p == 0)
379 c = '.';
380 if (p == 1)
381 c = '+';
382 if (p == 2)
383 c = '*';
384 if (p == 3)
385 c = '\n';
386 BIO_write(BN_GENCB_get_arg(cb), &c, 1);
387 (void) BIO_flush(BN_GENCB_get_arg(cb));
388 return 1;
389}
diff --git a/src/usr.bin/openssl/ocsp.c b/src/usr.bin/openssl/ocsp.c
deleted file mode 100644
index d35940a7ae..0000000000
--- a/src/usr.bin/openssl/ocsp.c
+++ /dev/null
@@ -1,1584 +0,0 @@
1/* $OpenBSD: ocsp.c,v 1.26 2024/08/31 18:39:25 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58#ifndef OPENSSL_NO_OCSP
59
60#include <sys/types.h>
61
62#include <stdio.h>
63#include <stdlib.h>
64#include <limits.h>
65#include <string.h>
66#include <poll.h>
67#include <time.h>
68
69/* Needs to be included before the openssl headers! */
70#include "apps.h"
71
72#include <openssl/bn.h>
73#include <openssl/conf.h>
74#include <openssl/crypto.h>
75#include <openssl/err.h>
76#include <openssl/evp.h>
77#include <openssl/ssl.h>
78#include <openssl/x509v3.h>
79
80/* Maximum leeway in validity period: default 5 minutes */
81#define MAX_VALIDITY_PERIOD (5 * 60)
82
83static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
84 const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids);
85static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
86 const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids);
87static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
88 STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec,
89 long maxage);
90
91static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
92 CA_DB *db, X509 *ca, X509 *rcert, EVP_PKEY *rkey, STACK_OF(X509) *rother,
93 unsigned long flags, int nmin, int ndays);
94
95static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
96static BIO *init_responder(char *port);
97static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
98 char *port);
99static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
100static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
101 STACK_OF(CONF_VALUE) *headers, const char *host, OCSP_REQUEST *req,
102 int req_timeout);
103
104static struct {
105 int accept_count;
106 int add_nonce;
107 char *CAfile;
108 char *CApath;
109 X509 *cert;
110 const EVP_MD *cert_id_md;
111 STACK_OF(CONF_VALUE) *headers;
112 char *host;
113 STACK_OF(OCSP_CERTID) *ids;
114 int ignore_err;
115 X509 *issuer;
116 char *keyfile;
117 long maxage;
118 int ndays;
119 int nmin;
120 int no_usage;
121 int noverify;
122 long nsec;
123 char *outfile;
124 char *path;
125 char *port;
126 char *rca_filename;
127 char *rcertfile;
128 OCSP_REQUEST *req;
129 int req_text;
130 int req_timeout;
131 char *reqin;
132 STACK_OF(OPENSSL_STRING) *reqnames;
133 char *reqout;
134 int resp_text;
135 char *respin;
136 char *respout;
137 unsigned long rflags;
138 char *ridx_filename;
139 char *rkeyfile;
140 char *rsignfile;
141 char *sign_certfile;
142 unsigned long sign_flags;
143 char *signfile;
144 int use_ssl;
145 char *verify_certfile;
146 unsigned long verify_flags;
147} cfg;
148
149static int
150ocsp_opt_cert(char *arg)
151{
152 X509_free(cfg.cert);
153 cfg.cert = load_cert(bio_err, arg, FORMAT_PEM, NULL,
154 "certificate");
155 if (cfg.cert == NULL) {
156 cfg.no_usage = 1;
157 return (1);
158 }
159 if (cfg.cert_id_md == NULL)
160 cfg.cert_id_md = EVP_sha1();
161 if (!add_ocsp_cert(&cfg.req, cfg.cert,
162 cfg.cert_id_md, cfg.issuer, cfg.ids)) {
163 cfg.no_usage = 1;
164 return (1);
165 }
166 if (!sk_OPENSSL_STRING_push(cfg.reqnames, arg)) {
167 cfg.no_usage = 1;
168 return (1);
169 }
170 return (0);
171}
172
173static int
174ocsp_opt_cert_id_md(int argc, char **argv, int *argsused)
175{
176 char *name = argv[0];
177
178 if (*name++ != '-')
179 return (1);
180
181 if ((cfg.cert_id_md = EVP_get_digestbyname(name)) == NULL)
182 return (1);
183
184 *argsused = 1;
185 return (0);
186}
187
188static int
189x509v3_add_value(const char *name, const char *value,
190 STACK_OF(CONF_VALUE) **out_extlist)
191{
192 STACK_OF(CONF_VALUE) *extlist = NULL;
193 CONF_VALUE *conf_value = NULL;
194 int ret = 0;
195
196 if ((conf_value = calloc(1, sizeof(*conf_value))) == NULL) {
197 X509V3error(ERR_R_MALLOC_FAILURE);
198 goto err;
199 }
200 if (name != NULL) {
201 if ((conf_value->name = strdup(name)) == NULL) {
202 X509V3error(ERR_R_MALLOC_FAILURE);
203 goto err;
204 }
205 }
206 if (value != NULL) {
207 if ((conf_value->value = strdup(value)) == NULL) {
208 X509V3error(ERR_R_MALLOC_FAILURE);
209 goto err;
210 }
211 }
212
213 if ((extlist = *out_extlist) == NULL)
214 extlist = sk_CONF_VALUE_new_null();
215 if (extlist == NULL) {
216 X509V3error(ERR_R_MALLOC_FAILURE);
217 goto err;
218 }
219
220 if (!sk_CONF_VALUE_push(extlist, conf_value)) {
221 X509V3error(ERR_R_MALLOC_FAILURE);
222 goto err;
223 }
224 conf_value = NULL;
225
226 *out_extlist = extlist;
227 extlist = NULL;
228
229 ret = 1;
230
231 err:
232 if (extlist != *out_extlist)
233 sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free);
234 X509V3_conf_free(conf_value);
235
236 return ret;
237}
238
239static int
240ocsp_opt_header(int argc, char **argv, int *argsused)
241{
242 if (argc < 3 || argv[1] == NULL || argv[2] == NULL)
243 return (1);
244
245 if (!x509v3_add_value(argv[1], argv[2], &cfg.headers)) {
246 cfg.no_usage = 1;
247 return (1);
248 }
249
250 *argsused = 3;
251 return (0);
252}
253
254static int
255ocsp_opt_host(char *arg)
256{
257 if (cfg.use_ssl != -1)
258 return (1);
259
260 cfg.host = arg;
261 return (0);
262}
263
264static int
265ocsp_opt_issuer(char *arg)
266{
267 X509_free(cfg.issuer);
268 cfg.issuer = load_cert(bio_err, arg, FORMAT_PEM, NULL,
269 "issuer certificate");
270 if (cfg.issuer == NULL) {
271 cfg.no_usage = 1;
272 return (1);
273 }
274 return (0);
275}
276
277static int
278ocsp_opt_ndays(char *arg)
279{
280 const char *errstr = NULL;
281
282 cfg.ndays = strtonum(arg, 0, INT_MAX, &errstr);
283 if (errstr != NULL) {
284 BIO_printf(bio_err, "Illegal update period %s: %s\n",
285 arg, errstr);
286 return (1);
287 }
288 return (0);
289}
290
291static int
292ocsp_opt_nmin(char *arg)
293{
294 const char *errstr = NULL;
295
296 cfg.nmin = strtonum(arg, 0, INT_MAX, &errstr);
297 if (errstr != NULL) {
298 BIO_printf(bio_err, "Illegal update period %s: %s\n",
299 arg, errstr);
300 return (1);
301 }
302
303 if (cfg.ndays != -1)
304 return (1);
305
306 cfg.ndays = 0;
307 return (0);
308}
309
310static int
311ocsp_opt_nrequest(char *arg)
312{
313 const char *errstr = NULL;
314
315 cfg.accept_count = strtonum(arg, 0, INT_MAX, &errstr);
316 if (errstr != NULL) {
317 BIO_printf(bio_err, "Illegal accept count %s: %s\n",
318 arg, errstr);
319 return (1);
320 }
321 return (0);
322}
323
324static int
325ocsp_opt_port(char *arg)
326{
327 if (cfg.use_ssl != -1)
328 return (1);
329
330 cfg.port = arg;
331 return (0);
332}
333
334static int
335ocsp_opt_serial(char *arg)
336{
337 if (cfg.cert_id_md == NULL)
338 cfg.cert_id_md = EVP_sha1();
339 if (!add_ocsp_serial(&cfg.req, arg, cfg.cert_id_md,
340 cfg.issuer, cfg.ids)) {
341 cfg.no_usage = 1;
342 return (1);
343 }
344 if (!sk_OPENSSL_STRING_push(cfg.reqnames, arg)) {
345 cfg.no_usage = 1;
346 return (1);
347 }
348 return (0);
349}
350
351static int
352ocsp_opt_status_age(char *arg)
353{
354 const char *errstr = NULL;
355
356 cfg.maxage = strtonum(arg, 0, LONG_MAX, &errstr);
357 if (errstr != NULL) {
358 BIO_printf(bio_err, "Illegal validity age %s: %s\n",
359 arg, errstr);
360 return (1);
361 }
362 return (0);
363}
364
365static int
366ocsp_opt_text(void)
367{
368 cfg.req_text = 1;
369 cfg.resp_text = 1;
370 return (0);
371}
372
373static int
374ocsp_opt_timeout(char *arg)
375{
376 const char *errstr = NULL;
377
378 cfg.req_timeout = strtonum(arg, 0, INT_MAX, &errstr);
379 if (errstr != NULL) {
380 BIO_printf(bio_err, "Illegal timeout value %s: %s\n",
381 arg, errstr);
382 return (1);
383 }
384 return (0);
385}
386
387static int
388ocsp_opt_url(char *arg)
389{
390 if (cfg.host == NULL && cfg.port == NULL &&
391 cfg.path == NULL) {
392 if (!OCSP_parse_url(arg, &cfg.host, &cfg.port,
393 &cfg.path, &cfg.use_ssl)) {
394 BIO_printf(bio_err, "Error parsing URL\n");
395 return (1);
396 }
397 }
398 return (0);
399}
400
401static int
402ocsp_opt_vafile(char *arg)
403{
404 cfg.verify_certfile = arg;
405 cfg.verify_flags |= OCSP_TRUSTOTHER;
406 return (0);
407}
408
409static int
410ocsp_opt_validity_period(char *arg)
411{
412 const char *errstr = NULL;
413
414 cfg.nsec = strtonum(arg, 0, LONG_MAX, &errstr);
415 if (errstr != NULL) {
416 BIO_printf(bio_err, "Illegal validity period %s: %s\n",
417 arg, errstr);
418 return (1);
419 }
420 return (0);
421}
422
423static const struct option ocsp_options[] = {
424 {
425 .name = "CA",
426 .argname = "file",
427 .desc = "CA certificate corresponding to the revocation information",
428 .type = OPTION_ARG,
429 .opt.arg = &cfg.rca_filename,
430 },
431 {
432 .name = "CAfile",
433 .argname = "file",
434 .desc = "Trusted certificates file",
435 .type = OPTION_ARG,
436 .opt.arg = &cfg.CAfile,
437 },
438 {
439 .name = "CApath",
440 .argname = "directory",
441 .desc = "Trusted certificates directory",
442 .type = OPTION_ARG,
443 .opt.arg = &cfg.CApath,
444 },
445 {
446 .name = "cert",
447 .argname = "file",
448 .desc = "Certificate to check",
449 .type = OPTION_ARG_FUNC,
450 .opt.argfunc = ocsp_opt_cert,
451 },
452 {
453 .name = "header",
454 .argname = "name value",
455 .desc = "Add the header name with the value to the request",
456 .type = OPTION_ARGV_FUNC,
457 .opt.argvfunc = ocsp_opt_header,
458 },
459 {
460 .name = "host",
461 .argname = "hostname:port",
462 .desc = "Send OCSP request to host on port",
463 .type = OPTION_ARG_FUNC,
464 .opt.argfunc = ocsp_opt_host,
465 },
466 {
467 .name = "ignore_err",
468 .desc = "Ignore the invalid response",
469 .type = OPTION_FLAG,
470 .opt.flag = &cfg.ignore_err,
471 },
472 {
473 .name = "index",
474 .argname = "indexfile",
475 .desc = "Certificate status index file",
476 .type = OPTION_ARG,
477 .opt.arg = &cfg.ridx_filename,
478 },
479 {
480 .name = "issuer",
481 .argname = "file",
482 .desc = "Issuer certificate",
483 .type = OPTION_ARG_FUNC,
484 .opt.argfunc = ocsp_opt_issuer,
485 },
486 {
487 .name = "ndays",
488 .argname = "days",
489 .desc = "Number of days before next update",
490 .type = OPTION_ARG_FUNC,
491 .opt.argfunc = ocsp_opt_ndays,
492 },
493 {
494 .name = "nmin",
495 .argname = "minutes",
496 .desc = "Number of minutes before next update",
497 .type = OPTION_ARG_FUNC,
498 .opt.argfunc = ocsp_opt_nmin,
499 },
500 {
501 .name = "no_cert_checks",
502 .desc = "Don't do additional checks on signing certificate",
503 .type = OPTION_UL_VALUE_OR,
504 .opt.ulvalue = &cfg.verify_flags,
505 .ulvalue = OCSP_NOCHECKS,
506 },
507 {
508 .name = "no_cert_verify",
509 .desc = "Don't check signing certificate",
510 .type = OPTION_UL_VALUE_OR,
511 .opt.ulvalue = &cfg.verify_flags,
512 .ulvalue = OCSP_NOVERIFY,
513 },
514 {
515 .name = "no_certs",
516 .desc = "Don't include any certificates in signed request",
517 .type = OPTION_UL_VALUE_OR,
518 .opt.ulvalue = &cfg.sign_flags,
519 .ulvalue = OCSP_NOCERTS,
520 },
521 {
522 .name = "no_chain",
523 .desc = "Don't use certificates in the response",
524 .type = OPTION_UL_VALUE_OR,
525 .opt.ulvalue = &cfg.verify_flags,
526 .ulvalue = OCSP_NOCHAIN,
527 },
528 {
529 .name = "no_explicit",
530 .desc = "Don't check the explicit trust for OCSP signing",
531 .type = OPTION_UL_VALUE_OR,
532 .opt.ulvalue = &cfg.verify_flags,
533 .ulvalue = OCSP_NOEXPLICIT,
534 },
535 {
536 .name = "no_intern",
537 .desc = "Don't search certificates contained in response for signer",
538 .type = OPTION_UL_VALUE_OR,
539 .opt.ulvalue = &cfg.verify_flags,
540 .ulvalue = OCSP_NOINTERN,
541 },
542 {
543 .name = "no_nonce",
544 .desc = "Don't add OCSP nonce to request",
545 .type = OPTION_VALUE,
546 .opt.value = &cfg.add_nonce,
547 .value = 0,
548 },
549 {
550 .name = "no_signature_verify",
551 .desc = "Don't check signature on response",
552 .type = OPTION_UL_VALUE_OR,
553 .opt.ulvalue = &cfg.verify_flags,
554 .ulvalue = OCSP_NOSIGS,
555 },
556 {
557 .name = "nonce",
558 .desc = "Add OCSP nonce to request",
559 .type = OPTION_VALUE,
560 .opt.value = &cfg.add_nonce,
561 .value = 2,
562 },
563 {
564 .name = "noverify",
565 .desc = "Don't verify response at all",
566 .type = OPTION_FLAG,
567 .opt.flag = &cfg.noverify,
568 },
569 {
570 .name = "nrequest",
571 .argname = "number",
572 .desc = "Number of requests to accept (default unlimited)",
573 .type = OPTION_ARG_FUNC,
574 .opt.argfunc = ocsp_opt_nrequest,
575 },
576 {
577 .name = "out",
578 .argname = "file",
579 .desc = "Output filename",
580 .type = OPTION_ARG,
581 .opt.arg = &cfg.outfile,
582 },
583 {
584 .name = "path",
585 .argname = "path",
586 .desc = "Path to use in OCSP request",
587 .type = OPTION_ARG,
588 .opt.arg = &cfg.path,
589 },
590 {
591 .name = "port",
592 .argname = "portnum",
593 .desc = "Port to run responder on",
594 .type = OPTION_ARG_FUNC,
595 .opt.argfunc = ocsp_opt_port,
596 },
597 {
598 .name = "req_text",
599 .desc = "Print text form of request",
600 .type = OPTION_FLAG,
601 .opt.flag = &cfg.req_text,
602 },
603 {
604 .name = "reqin",
605 .argname = "file",
606 .desc = "Read DER encoded OCSP request from \"file\"",
607 .type = OPTION_ARG,
608 .opt.arg = &cfg.reqin,
609 },
610 {
611 .name = "reqout",
612 .argname = "file",
613 .desc = "Write DER encoded OCSP request to \"file\"",
614 .type = OPTION_ARG,
615 .opt.arg = &cfg.reqout,
616 },
617 {
618 .name = "resp_key_id",
619 .desc = "Identify response by signing certificate key ID",
620 .type = OPTION_UL_VALUE_OR,
621 .opt.ulvalue = &cfg.rflags,
622 .ulvalue = OCSP_RESPID_KEY,
623 },
624 {
625 .name = "resp_no_certs",
626 .desc = "Don't include any certificates in response",
627 .type = OPTION_UL_VALUE_OR,
628 .opt.ulvalue = &cfg.rflags,
629 .ulvalue = OCSP_NOCERTS,
630 },
631 {
632 .name = "resp_text",
633 .desc = "Print text form of response",
634 .type = OPTION_FLAG,
635 .opt.flag = &cfg.resp_text,
636 },
637 {
638 .name = "respin",
639 .argname = "file",
640 .desc = "Read DER encoded OCSP response from \"file\"",
641 .type = OPTION_ARG,
642 .opt.arg = &cfg.respin,
643 },
644 {
645 .name = "respout",
646 .argname = "file",
647 .desc = "Write DER encoded OCSP response to \"file\"",
648 .type = OPTION_ARG,
649 .opt.arg = &cfg.respout,
650 },
651 {
652 .name = "rkey",
653 .argname = "file",
654 .desc = "Responder key to sign responses with",
655 .type = OPTION_ARG,
656 .opt.arg = &cfg.rkeyfile,
657 },
658 {
659 .name = "rother",
660 .argname = "file",
661 .desc = "Other certificates to include in response",
662 .type = OPTION_ARG,
663 .opt.arg = &cfg.rcertfile,
664 },
665 {
666 .name = "rsigner",
667 .argname = "file",
668 .desc = "Responder certificate to sign responses with",
669 .type = OPTION_ARG,
670 .opt.arg = &cfg.rsignfile,
671 },
672 {
673 .name = "serial",
674 .argname = "num",
675 .desc = "Serial number to check",
676 .type = OPTION_ARG_FUNC,
677 .opt.argfunc = ocsp_opt_serial,
678 },
679 {
680 .name = "sign_other",
681 .argname = "file",
682 .desc = "Additional certificates to include in signed request",
683 .type = OPTION_ARG,
684 .opt.arg = &cfg.sign_certfile,
685 },
686 {
687 .name = "signer",
688 .argname = "file",
689 .desc = "Certificate to sign OCSP request with",
690 .type = OPTION_ARG,
691 .opt.arg = &cfg.signfile,
692 },
693 {
694 .name = "signkey",
695 .argname = "file",
696 .desc = "Private key to sign OCSP request with",
697 .type = OPTION_ARG,
698 .opt.arg = &cfg.keyfile,
699 },
700 {
701 .name = "status_age",
702 .argname = "age",
703 .desc = "Maximum status age in seconds",
704 .type = OPTION_ARG_FUNC,
705 .opt.argfunc = ocsp_opt_status_age,
706 },
707 {
708 .name = "text",
709 .desc = "Print text form of request and response",
710 .type = OPTION_FUNC,
711 .opt.func = ocsp_opt_text,
712 },
713 {
714 .name = "timeout",
715 .argname = "seconds",
716 .desc = "Connection timeout to the OCSP responder in seconds",
717 .type = OPTION_ARG_FUNC,
718 .opt.argfunc = ocsp_opt_timeout,
719 },
720 {
721 .name = "trust_other",
722 .desc = "Don't verify additional certificates",
723 .type = OPTION_UL_VALUE_OR,
724 .opt.ulvalue = &cfg.verify_flags,
725 .ulvalue = OCSP_TRUSTOTHER,
726 },
727 {
728 .name = "url",
729 .argname = "responder_url",
730 .desc = "OCSP responder URL",
731 .type = OPTION_ARG_FUNC,
732 .opt.argfunc = ocsp_opt_url,
733 },
734 {
735 .name = "VAfile",
736 .argname = "file",
737 .desc = "Explicitly trusted responder certificates",
738 .type = OPTION_ARG_FUNC,
739 .opt.argfunc = ocsp_opt_vafile,
740 },
741 {
742 .name = "validity_period",
743 .argname = "n",
744 .desc = "Maximum validity discrepancy in seconds",
745 .type = OPTION_ARG_FUNC,
746 .opt.argfunc = ocsp_opt_validity_period,
747 },
748 {
749 .name = "verify_other",
750 .argname = "file",
751 .desc = "Additional certificates to search for signer",
752 .type = OPTION_ARG,
753 .opt.arg = &cfg.verify_certfile,
754 },
755 {
756 .name = NULL,
757 .desc = "",
758 .type = OPTION_ARGV_FUNC,
759 .opt.argvfunc = ocsp_opt_cert_id_md,
760 },
761 { NULL },
762};
763
764static void
765ocsp_usage(void)
766{
767 fprintf(stderr, "usage: ocsp "
768 "[-CA file] [-CAfile file] [-CApath directory] [-cert file]\n"
769 " [-dgst alg] [-header name value] [-host hostname:port]\n"
770 " [-ignore_err] [-index indexfile] [-issuer file]\n"
771 " [-ndays days] [-nmin minutes] [-no_cert_checks]\n"
772 " [-no_cert_verify] [-no_certs] [-no_chain] [-no_explicit]\n"
773 " [-no_intern] [-no_nonce] [-no_signature_verify] [-nonce]\n"
774 " [-noverify] [-nrequest number] [-out file] [-path path]\n"
775 " [-port portnum] [-req_text] [-reqin file] [-reqout file]\n"
776 " [-resp_key_id] [-resp_no_certs] [-resp_text] [-respin file]\n"
777 " [-respout file] [-rkey file] [-rother file] [-rsigner file]\n"
778 " [-serial num] [-sign_other file] [-signer file]\n"
779 " [-signkey file] [-status_age age] [-text]\n"
780 " [-timeout seconds] [-trust_other] [-url responder_url]\n"
781 " [-VAfile file] [-validity_period nsec] [-verify_other file]\n");
782 fprintf(stderr, "\n");
783 options_usage(ocsp_options);
784 fprintf(stderr, "\n");
785}
786
787int
788ocsp_main(int argc, char **argv)
789{
790 OCSP_RESPONSE *resp = NULL;
791 OCSP_BASICRESP *bs = NULL;
792 X509 *signer = NULL, *rsigner = NULL;
793 EVP_PKEY *key = NULL, *rkey = NULL;
794 BIO *acbio = NULL, *cbio = NULL;
795 BIO *derbio = NULL;
796 BIO *out = NULL;
797 X509_STORE *store = NULL;
798 STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
799 int ret = 1;
800 int badarg = 0;
801 int i;
802 X509 *rca_cert = NULL;
803 CA_DB *rdb = NULL;
804
805 if (pledge("stdio cpath wpath rpath inet dns tty", NULL) == -1) {
806 perror("pledge");
807 exit(1);
808 }
809
810 memset(&cfg, 0, sizeof(cfg));
811 cfg.accept_count = -1;
812 cfg.add_nonce = 1;
813 if ((cfg.ids = sk_OCSP_CERTID_new_null()) == NULL)
814 goto end;
815 cfg.maxage = -1;
816 cfg.ndays = -1;
817 cfg.nsec = MAX_VALIDITY_PERIOD;
818 cfg.req_timeout = -1;
819 if ((cfg.reqnames = sk_OPENSSL_STRING_new_null()) == NULL)
820 goto end;
821 cfg.use_ssl = -1;
822
823 if (options_parse(argc, argv, ocsp_options, NULL, NULL) != 0) {
824 if (cfg.no_usage)
825 goto end;
826 else
827 badarg = 1;
828 }
829
830 /* Have we anything to do? */
831 if (!cfg.req && !cfg.reqin && !cfg.respin &&
832 !(cfg.port && cfg.ridx_filename))
833 badarg = 1;
834
835 if (badarg) {
836 ocsp_usage();
837 goto end;
838 }
839 if (cfg.outfile)
840 out = BIO_new_file(cfg.outfile, "w");
841 else
842 out = BIO_new_fp(stdout, BIO_NOCLOSE);
843
844 if (!out) {
845 BIO_printf(bio_err, "Error opening output file\n");
846 goto end;
847 }
848 if (!cfg.req && (cfg.add_nonce != 2))
849 cfg.add_nonce = 0;
850
851 if (!cfg.req && cfg.reqin) {
852 derbio = BIO_new_file(cfg.reqin, "rb");
853 if (!derbio) {
854 BIO_printf(bio_err,
855 "Error Opening OCSP request file\n");
856 goto end;
857 }
858 cfg.req = d2i_OCSP_REQUEST_bio(derbio, NULL);
859 BIO_free(derbio);
860 if (!cfg.req) {
861 BIO_printf(bio_err, "Error reading OCSP request\n");
862 goto end;
863 }
864 }
865 if (!cfg.req && cfg.port) {
866 acbio = init_responder(cfg.port);
867 if (!acbio)
868 goto end;
869 }
870 if (cfg.rsignfile && !rdb) {
871 if (!cfg.rkeyfile)
872 cfg.rkeyfile = cfg.rsignfile;
873 rsigner = load_cert(bio_err, cfg.rsignfile, FORMAT_PEM,
874 NULL, "responder certificate");
875 if (!rsigner) {
876 BIO_printf(bio_err,
877 "Error loading responder certificate\n");
878 goto end;
879 }
880 rca_cert = load_cert(bio_err, cfg.rca_filename,
881 FORMAT_PEM, NULL, "CA certificate");
882 if (cfg.rcertfile) {
883 rother = load_certs(bio_err, cfg.rcertfile,
884 FORMAT_PEM, NULL, "responder other certificates");
885 if (!rother)
886 goto end;
887 }
888 rkey = load_key(bio_err, cfg.rkeyfile, FORMAT_PEM, 0,
889 NULL, "responder private key");
890 if (!rkey)
891 goto end;
892 }
893 if (acbio)
894 BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
895
896 redo_accept:
897
898 if (acbio) {
899 if (!do_responder(&cfg.req, &cbio, acbio,
900 cfg.port))
901 goto end;
902 if (!cfg.req) {
903 resp = OCSP_response_create(
904 OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
905 send_ocsp_response(cbio, resp);
906 goto done_resp;
907 }
908 }
909 if (!cfg.req &&
910 (cfg.signfile || cfg.reqout || cfg.host ||
911 cfg.add_nonce || cfg.ridx_filename)) {
912 BIO_printf(bio_err,
913 "Need an OCSP request for this operation!\n");
914 goto end;
915 }
916 if (cfg.req && cfg.add_nonce)
917 OCSP_request_add1_nonce(cfg.req, NULL, -1);
918
919 if (cfg.signfile) {
920 if (!cfg.keyfile)
921 cfg.keyfile = cfg.signfile;
922 signer = load_cert(bio_err, cfg.signfile, FORMAT_PEM,
923 NULL, "signer certificate");
924 if (!signer) {
925 BIO_printf(bio_err,
926 "Error loading signer certificate\n");
927 goto end;
928 }
929 if (cfg.sign_certfile) {
930 sign_other = load_certs(bio_err,
931 cfg.sign_certfile, FORMAT_PEM, NULL,
932 "signer certificates");
933 if (!sign_other)
934 goto end;
935 }
936 key = load_key(bio_err, cfg.keyfile, FORMAT_PEM, 0,
937 NULL, "signer private key");
938 if (!key)
939 goto end;
940
941 if (!OCSP_request_sign(cfg.req, signer, key, NULL,
942 sign_other, cfg.sign_flags)) {
943 BIO_printf(bio_err, "Error signing OCSP request\n");
944 goto end;
945 }
946 }
947 if (cfg.req_text && cfg.req)
948 OCSP_REQUEST_print(out, cfg.req, 0);
949
950 if (cfg.reqout) {
951 derbio = BIO_new_file(cfg.reqout, "wb");
952 if (!derbio) {
953 BIO_printf(bio_err, "Error opening file %s\n",
954 cfg.reqout);
955 goto end;
956 }
957 i2d_OCSP_REQUEST_bio(derbio, cfg.req);
958 BIO_free(derbio);
959 }
960 if (cfg.ridx_filename && (!rkey || !rsigner || !rca_cert)) {
961 BIO_printf(bio_err,
962 "Need a responder certificate, key and CA for this operation!\n");
963 goto end;
964 }
965 if (cfg.ridx_filename && !rdb) {
966 rdb = load_index(cfg.ridx_filename, NULL);
967 if (!rdb)
968 goto end;
969 if (!index_index(rdb))
970 goto end;
971 }
972 if (rdb) {
973 i = make_ocsp_response(&resp, cfg.req, rdb, rca_cert,
974 rsigner, rkey, rother, cfg.rflags,
975 cfg.nmin, cfg.ndays);
976 if (cbio)
977 send_ocsp_response(cbio, resp);
978 } else if (cfg.host) {
979 resp = process_responder(bio_err, cfg.req,
980 cfg.host,
981 cfg.path ? cfg.path : "/",
982 cfg.port, cfg.use_ssl, cfg.headers,
983 cfg.req_timeout);
984 if (!resp)
985 goto end;
986 } else if (cfg.respin) {
987 derbio = BIO_new_file(cfg.respin, "rb");
988 if (!derbio) {
989 BIO_printf(bio_err,
990 "Error Opening OCSP response file\n");
991 goto end;
992 }
993 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
994 BIO_free(derbio);
995 if (!resp) {
996 BIO_printf(bio_err, "Error reading OCSP response\n");
997 goto end;
998 }
999 } else {
1000 ret = 0;
1001 goto end;
1002 }
1003
1004 done_resp:
1005
1006 if (cfg.respout) {
1007 derbio = BIO_new_file(cfg.respout, "wb");
1008 if (!derbio) {
1009 BIO_printf(bio_err, "Error opening file %s\n",
1010 cfg.respout);
1011 goto end;
1012 }
1013 i2d_OCSP_RESPONSE_bio(derbio, resp);
1014 BIO_free(derbio);
1015 }
1016 i = OCSP_response_status(resp);
1017
1018 if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
1019 BIO_printf(bio_err, "Responder Error: %s (%d)\n",
1020 OCSP_response_status_str(i), i);
1021 if (cfg.ignore_err)
1022 goto redo_accept;
1023 ret = 1;
1024 goto end;
1025 }
1026 if (cfg.resp_text)
1027 OCSP_RESPONSE_print(out, resp, 0);
1028
1029 /* If running as responder don't verify our own response */
1030 if (cbio) {
1031 if (cfg.accept_count > 0)
1032 cfg.accept_count--;
1033 /* Redo if more connections needed */
1034 if (cfg.accept_count) {
1035 BIO_free_all(cbio);
1036 cbio = NULL;
1037 OCSP_REQUEST_free(cfg.req);
1038 cfg.req = NULL;
1039 OCSP_RESPONSE_free(resp);
1040 resp = NULL;
1041 goto redo_accept;
1042 }
1043 goto end;
1044 }
1045 if (!store)
1046 store = setup_verify(bio_err, cfg.CAfile,
1047 cfg.CApath);
1048 if (!store)
1049 goto end;
1050 if (cfg.verify_certfile) {
1051 verify_other = load_certs(bio_err, cfg.verify_certfile,
1052 FORMAT_PEM, NULL, "validator certificate");
1053 if (!verify_other)
1054 goto end;
1055 }
1056 bs = OCSP_response_get1_basic(resp);
1057
1058 if (!bs) {
1059 BIO_printf(bio_err, "Error parsing response\n");
1060 goto end;
1061 }
1062 if (!cfg.noverify) {
1063 if (cfg.req &&
1064 ((i = OCSP_check_nonce(cfg.req, bs)) <= 0)) {
1065 if (i == -1) {
1066 BIO_printf(bio_err,
1067 "WARNING: no nonce in response\n");
1068 } else {
1069 BIO_printf(bio_err, "Nonce Verify error\n");
1070 goto end;
1071 }
1072 }
1073 i = OCSP_basic_verify(bs, verify_other, store,
1074 cfg.verify_flags);
1075 if (i < 0)
1076 i = OCSP_basic_verify(bs, NULL, store, 0);
1077
1078 if (i <= 0) {
1079 BIO_printf(bio_err, "Response Verify Failure\n");
1080 ERR_print_errors(bio_err);
1081 } else {
1082 BIO_printf(bio_err, "Response verify OK\n");
1083 }
1084 }
1085 if (!print_ocsp_summary(out, bs, cfg.req, cfg.reqnames,
1086 cfg.ids, cfg.nsec, cfg.maxage))
1087 goto end;
1088
1089 ret = 0;
1090
1091 end:
1092 ERR_print_errors(bio_err);
1093 X509_free(signer);
1094 X509_STORE_free(store);
1095 EVP_PKEY_free(key);
1096 EVP_PKEY_free(rkey);
1097 X509_free(cfg.issuer);
1098 X509_free(cfg.cert);
1099 X509_free(rsigner);
1100 X509_free(rca_cert);
1101 free_index(rdb);
1102 BIO_free_all(cbio);
1103 BIO_free_all(acbio);
1104 BIO_free(out);
1105 OCSP_REQUEST_free(cfg.req);
1106 OCSP_RESPONSE_free(resp);
1107 OCSP_BASICRESP_free(bs);
1108 sk_OPENSSL_STRING_free(cfg.reqnames);
1109 sk_OCSP_CERTID_free(cfg.ids);
1110 sk_X509_pop_free(sign_other, X509_free);
1111 sk_X509_pop_free(verify_other, X509_free);
1112 sk_CONF_VALUE_pop_free(cfg.headers, X509V3_conf_free);
1113
1114 if (cfg.use_ssl != -1) {
1115 free(cfg.host);
1116 free(cfg.port);
1117 free(cfg.path);
1118 }
1119 return (ret);
1120}
1121
1122static int
1123add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,
1124 X509 *issuer, STACK_OF(OCSP_CERTID) *ids)
1125{
1126 OCSP_CERTID *id;
1127
1128 if (!issuer) {
1129 BIO_printf(bio_err, "No issuer certificate specified\n");
1130 return 0;
1131 }
1132 if (!*req)
1133 *req = OCSP_REQUEST_new();
1134 if (!*req)
1135 goto err;
1136 id = OCSP_cert_to_id(cert_id_md, cert, issuer);
1137 if (!id || !sk_OCSP_CERTID_push(ids, id))
1138 goto err;
1139 if (!OCSP_request_add0_id(*req, id))
1140 goto err;
1141 return 1;
1142
1143 err:
1144 BIO_printf(bio_err, "Error Creating OCSP request\n");
1145 return 0;
1146}
1147
1148static int
1149add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD *cert_id_md,
1150 X509 *issuer, STACK_OF(OCSP_CERTID) *ids)
1151{
1152 OCSP_CERTID *id;
1153 X509_NAME *iname;
1154 ASN1_BIT_STRING *ikey;
1155 ASN1_INTEGER *sno;
1156
1157 if (!issuer) {
1158 BIO_printf(bio_err, "No issuer certificate specified\n");
1159 return 0;
1160 }
1161 if (!*req)
1162 *req = OCSP_REQUEST_new();
1163 if (!*req)
1164 goto err;
1165 iname = X509_get_subject_name(issuer);
1166 ikey = X509_get0_pubkey_bitstr(issuer);
1167 sno = s2i_ASN1_INTEGER(NULL, serial);
1168 if (!sno) {
1169 BIO_printf(bio_err, "Error converting serial number %s\n",
1170 serial);
1171 return 0;
1172 }
1173 id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
1174 ASN1_INTEGER_free(sno);
1175 if (!id || !sk_OCSP_CERTID_push(ids, id))
1176 goto err;
1177 if (!OCSP_request_add0_id(*req, id))
1178 goto err;
1179 return 1;
1180
1181 err:
1182 BIO_printf(bio_err, "Error Creating OCSP request\n");
1183 return 0;
1184}
1185
1186static int
1187print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
1188 STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec,
1189 long maxage)
1190{
1191 OCSP_CERTID *id;
1192 char *name;
1193 int i;
1194 int status, reason;
1195
1196 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
1197
1198 if (!bs || !req || !sk_OPENSSL_STRING_num(names) ||
1199 !sk_OCSP_CERTID_num(ids))
1200 return 1;
1201
1202 for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) {
1203 id = sk_OCSP_CERTID_value(ids, i);
1204 name = sk_OPENSSL_STRING_value(names, i);
1205 BIO_printf(out, "%s: ", name);
1206
1207 if (!OCSP_resp_find_status(bs, id, &status, &reason,
1208 &rev, &thisupd, &nextupd)) {
1209 BIO_puts(out, "ERROR: No Status found.\n");
1210 continue;
1211 }
1212 /*
1213 * Check validity: if invalid write to output BIO so we know
1214 * which response this refers to.
1215 */
1216 if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) {
1217 BIO_puts(out, "WARNING: Status times invalid.\n");
1218 ERR_print_errors(out);
1219 }
1220 BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
1221
1222 BIO_puts(out, "\tThis Update: ");
1223 ASN1_GENERALIZEDTIME_print(out, thisupd);
1224 BIO_puts(out, "\n");
1225
1226 if (nextupd) {
1227 BIO_puts(out, "\tNext Update: ");
1228 ASN1_GENERALIZEDTIME_print(out, nextupd);
1229 BIO_puts(out, "\n");
1230 }
1231 if (status != V_OCSP_CERTSTATUS_REVOKED)
1232 continue;
1233
1234 if (reason != -1)
1235 BIO_printf(out, "\tReason: %s\n",
1236 OCSP_crl_reason_str(reason));
1237
1238 BIO_puts(out, "\tRevocation Time: ");
1239 ASN1_GENERALIZEDTIME_print(out, rev);
1240 BIO_puts(out, "\n");
1241 }
1242
1243 return 1;
1244}
1245
1246
1247static int
1248make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
1249 X509 *ca, X509 *rcert, EVP_PKEY *rkey, STACK_OF(X509) *rother,
1250 unsigned long flags, int nmin, int ndays)
1251{
1252 ASN1_TIME *thisupd = NULL, *nextupd = NULL;
1253 OCSP_CERTID *cid, *ca_id = NULL;
1254 OCSP_BASICRESP *bs = NULL;
1255 int i, id_count, ret = 1;
1256
1257 id_count = OCSP_request_onereq_count(req);
1258
1259 if (id_count <= 0) {
1260 *resp = OCSP_response_create(
1261 OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
1262 goto end;
1263 }
1264 bs = OCSP_BASICRESP_new();
1265 thisupd = X509_gmtime_adj(NULL, 0);
1266 if (ndays != -1)
1267 nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24);
1268
1269 /* Examine each certificate id in the request */
1270 for (i = 0; i < id_count; i++) {
1271 OCSP_ONEREQ *one;
1272 ASN1_INTEGER *serial;
1273 char **inf;
1274 ASN1_OBJECT *cert_id_md_oid;
1275 const EVP_MD *cert_id_md;
1276 one = OCSP_request_onereq_get0(req, i);
1277 cid = OCSP_onereq_get0_id(one);
1278
1279 OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid);
1280
1281 cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
1282 if (!cert_id_md) {
1283 *resp = OCSP_response_create(
1284 OCSP_RESPONSE_STATUS_INTERNALERROR, NULL);
1285 goto end;
1286 }
1287 OCSP_CERTID_free(ca_id);
1288 ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
1289
1290 /* Is this request about our CA? */
1291 if (OCSP_id_issuer_cmp(ca_id, cid)) {
1292 OCSP_basic_add1_status(bs, cid,
1293 V_OCSP_CERTSTATUS_UNKNOWN, 0, NULL,
1294 thisupd, nextupd);
1295 continue;
1296 }
1297 OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
1298 inf = lookup_serial(db, serial);
1299 if (!inf) {
1300 OCSP_basic_add1_status(bs, cid,
1301 V_OCSP_CERTSTATUS_UNKNOWN, 0, NULL,
1302 thisupd, nextupd);
1303 } else if (inf[DB_type][0] == DB_TYPE_VAL) {
1304 OCSP_basic_add1_status(bs, cid,
1305 V_OCSP_CERTSTATUS_GOOD, 0, NULL,
1306 thisupd, nextupd);
1307 } else if (inf[DB_type][0] == DB_TYPE_REV) {
1308 ASN1_OBJECT *inst = NULL;
1309 ASN1_TIME *revtm = NULL;
1310 ASN1_GENERALIZEDTIME *invtm = NULL;
1311 OCSP_SINGLERESP *single;
1312 int reason = -1;
1313
1314 unpack_revinfo(&revtm, &reason, &inst, &invtm,
1315 inf[DB_rev_date]);
1316 single = OCSP_basic_add1_status(bs, cid,
1317 V_OCSP_CERTSTATUS_REVOKED,
1318 reason, revtm,
1319 thisupd, nextupd);
1320 if (invtm)
1321 OCSP_SINGLERESP_add1_ext_i2d(single,
1322 NID_invalidity_date, invtm, 0, 0);
1323 else if (inst)
1324 OCSP_SINGLERESP_add1_ext_i2d(single,
1325 NID_hold_instruction_code, inst, 0, 0);
1326 ASN1_OBJECT_free(inst);
1327 ASN1_TIME_free(revtm);
1328 ASN1_GENERALIZEDTIME_free(invtm);
1329 }
1330 }
1331
1332 OCSP_copy_nonce(bs, req);
1333
1334 OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
1335
1336 *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
1337
1338 end:
1339 ASN1_TIME_free(thisupd);
1340 ASN1_TIME_free(nextupd);
1341 OCSP_CERTID_free(ca_id);
1342 OCSP_BASICRESP_free(bs);
1343 return ret;
1344}
1345
1346static char **
1347lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
1348{
1349 int i;
1350 BIGNUM *bn = NULL;
1351 char *itmp, *row[DB_NUMBER], **rrow;
1352
1353 for (i = 0; i < DB_NUMBER; i++)
1354 row[i] = NULL;
1355 bn = ASN1_INTEGER_to_BN(ser, NULL);
1356 OPENSSL_assert(bn); /* FIXME: should report an error at this
1357 * point and abort */
1358 if (BN_is_zero(bn))
1359 itmp = strdup("00");
1360 else
1361 itmp = BN_bn2hex(bn);
1362 row[DB_serial] = itmp;
1363 BN_free(bn);
1364 rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
1365 free(itmp);
1366 return rrow;
1367}
1368
1369/* Quick and dirty OCSP server: read in and parse input request */
1370
1371static BIO *
1372init_responder(char *port)
1373{
1374 BIO *acbio = NULL, *bufbio = NULL;
1375
1376 bufbio = BIO_new(BIO_f_buffer());
1377 if (!bufbio)
1378 goto err;
1379 acbio = BIO_new_accept(port);
1380 if (!acbio)
1381 goto err;
1382 BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR);
1383 BIO_set_accept_bios(acbio, bufbio);
1384 bufbio = NULL;
1385
1386 if (BIO_do_accept(acbio) <= 0) {
1387 BIO_printf(bio_err, "Error setting up accept BIO\n");
1388 ERR_print_errors(bio_err);
1389 goto err;
1390 }
1391 return acbio;
1392
1393 err:
1394 BIO_free_all(acbio);
1395 BIO_free(bufbio);
1396 return NULL;
1397}
1398
1399static int
1400do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port)
1401{
1402 int have_post = 0, len;
1403 OCSP_REQUEST *req = NULL;
1404 char inbuf[1024];
1405 BIO *cbio = NULL;
1406
1407 if (BIO_do_accept(acbio) <= 0) {
1408 BIO_printf(bio_err, "Error accepting connection\n");
1409 ERR_print_errors(bio_err);
1410 return 0;
1411 }
1412 cbio = BIO_pop(acbio);
1413 *pcbio = cbio;
1414
1415 for (;;) {
1416 len = BIO_gets(cbio, inbuf, sizeof inbuf);
1417 if (len <= 0)
1418 return 1;
1419 /* Look for "POST" signalling start of query */
1420 if (!have_post) {
1421 if (strncmp(inbuf, "POST", 4)) {
1422 BIO_printf(bio_err, "Invalid request\n");
1423 return 1;
1424 }
1425 have_post = 1;
1426 }
1427 /* Look for end of headers */
1428 if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
1429 break;
1430 }
1431
1432 /* Try to read OCSP request */
1433
1434 req = d2i_OCSP_REQUEST_bio(cbio, NULL);
1435
1436 if (!req) {
1437 BIO_printf(bio_err, "Error parsing OCSP request\n");
1438 ERR_print_errors(bio_err);
1439 }
1440 *preq = req;
1441
1442 return 1;
1443}
1444
1445static int
1446send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
1447{
1448 static const char http_resp[] =
1449 "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
1450 "Content-Length: %d\r\n\r\n";
1451
1452 if (!cbio)
1453 return 0;
1454 BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
1455 i2d_OCSP_RESPONSE_bio(cbio, resp);
1456 (void) BIO_flush(cbio);
1457 return 1;
1458}
1459
1460static OCSP_RESPONSE *
1461query_responder(BIO *err, BIO *cbio, char *path, STACK_OF(CONF_VALUE) *headers,
1462 const char *host, OCSP_REQUEST *req, int req_timeout)
1463{
1464 int fd;
1465 int rv;
1466 int i;
1467 int have_host = 0;
1468 OCSP_REQ_CTX *ctx = NULL;
1469 OCSP_RESPONSE *rsp = NULL;
1470 struct pollfd pfd[1];
1471
1472 if (req_timeout != -1)
1473 BIO_set_nbio(cbio, 1);
1474
1475 rv = BIO_do_connect(cbio);
1476
1477 if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) {
1478 BIO_puts(err, "Error connecting BIO\n");
1479 return NULL;
1480 }
1481 if (BIO_get_fd(cbio, &fd) < 0) {
1482 BIO_puts(err, "Can't get connection fd\n");
1483 goto err;
1484 }
1485 if (req_timeout != -1 && rv <= 0) {
1486 pfd[0].fd = fd;
1487 pfd[0].events = POLLOUT;
1488 rv = poll(pfd, 1, req_timeout * 1000);
1489 if (rv == 0) {
1490 BIO_puts(err, "Timeout on connect\n");
1491 return NULL;
1492 }
1493 if (rv == -1) {
1494 BIO_puts(err, "Poll error\n");
1495 return NULL;
1496 }
1497 }
1498 ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
1499 if (!ctx)
1500 return NULL;
1501
1502 for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
1503 CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
1504 if (strcasecmp("host", hdr->name) == 0)
1505 have_host = 1;
1506 if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
1507 goto err;
1508 }
1509
1510 if (!have_host) {
1511 if (!OCSP_REQ_CTX_add1_header(ctx, "Host", host))
1512 goto err;
1513 }
1514
1515 if (!OCSP_REQ_CTX_set1_req(ctx, req))
1516 goto err;
1517
1518 for (;;) {
1519 rv = OCSP_sendreq_nbio(&rsp, ctx);
1520 if (rv != -1)
1521 break;
1522 if (req_timeout == -1)
1523 continue;
1524 pfd[0].fd = fd;
1525 if (BIO_should_read(cbio)) {
1526 pfd[0].events = POLLIN;
1527 } else if (BIO_should_write(cbio)) {
1528 pfd[0].events = POLLOUT;
1529 } else {
1530 BIO_puts(err, "Unexpected retry condition\n");
1531 goto err;
1532 }
1533 rv = poll(pfd, 1, req_timeout * 1000);
1534 if (rv == 0) {
1535 BIO_puts(err, "Timeout on request\n");
1536 break;
1537 }
1538 if (rv == -1 || (pfd[0].revents & (POLLERR|POLLNVAL))) {
1539 BIO_puts(err, "Poll error\n");
1540 break;
1541 }
1542 }
1543
1544 err:
1545 OCSP_REQ_CTX_free(ctx);
1546 return rsp;
1547}
1548
1549OCSP_RESPONSE *
1550process_responder(BIO *err, OCSP_REQUEST *req, char *host, char *path,
1551 char *port, int use_ssl, STACK_OF(CONF_VALUE) *headers, int req_timeout)
1552{
1553 BIO *cbio = NULL;
1554 SSL_CTX *ctx = NULL;
1555 OCSP_RESPONSE *resp = NULL;
1556
1557 cbio = BIO_new_connect(host);
1558 if (!cbio) {
1559 BIO_printf(err, "Error creating connect BIO\n");
1560 goto end;
1561 }
1562 if (port)
1563 BIO_set_conn_port(cbio, port);
1564 if (use_ssl == 1) {
1565 BIO *sbio;
1566 ctx = SSL_CTX_new(TLS_client_method());
1567 if (ctx == NULL) {
1568 BIO_printf(err, "Error creating SSL context.\n");
1569 goto end;
1570 }
1571 SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
1572 sbio = BIO_new_ssl(ctx, 1);
1573 cbio = BIO_push(sbio, cbio);
1574 }
1575 resp = query_responder(err, cbio, path, headers, host, req, req_timeout);
1576 if (!resp)
1577 BIO_printf(bio_err, "Error querying OCSP responder\n");
1578
1579 end:
1580 BIO_free_all(cbio);
1581 SSL_CTX_free(ctx);
1582 return resp;
1583}
1584#endif
diff --git a/src/usr.bin/openssl/openssl.1 b/src/usr.bin/openssl/openssl.1
deleted file mode 100644
index a095c01f0a..0000000000
--- a/src/usr.bin/openssl/openssl.1
+++ /dev/null
@@ -1,6827 +0,0 @@
1.\" $OpenBSD: openssl.1,v 1.163 2025/04/14 08:40:10 tb Exp $
2.\" ====================================================================
3.\" Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\"
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\"
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in
14.\" the documentation and/or other materials provided with the
15.\" distribution.
16.\"
17.\" 3. All advertising materials mentioning features or use of this
18.\" software must display the following acknowledgment:
19.\" "This product includes software developed by the OpenSSL Project
20.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21.\"
22.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23.\" endorse or promote products derived from this software without
24.\" prior written permission. For written permission, please contact
25.\" openssl-core@openssl.org.
26.\"
27.\" 5. Products derived from this software may not be called "OpenSSL"
28.\" nor may "OpenSSL" appear in their names without prior written
29.\" permission of the OpenSSL Project.
30.\"
31.\" 6. Redistributions of any form whatsoever must retain the following
32.\" acknowledgment:
33.\" "This product includes software developed by the OpenSSL Project
34.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35.\"
36.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47.\" OF THE POSSIBILITY OF SUCH DAMAGE.
48.\" ====================================================================
49.\"
50.\" This product includes cryptographic software written by Eric Young
51.\" (eay@cryptsoft.com). This product includes software written by Tim
52.\" Hudson (tjh@cryptsoft.com).
53.\"
54.\"
55.\" Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
56.\" All rights reserved.
57.\"
58.\" This package is an SSL implementation written
59.\" by Eric Young (eay@cryptsoft.com).
60.\" The implementation was written so as to conform with Netscapes SSL.
61.\"
62.\" This library is free for commercial and non-commercial use as long as
63.\" the following conditions are aheared to. The following conditions
64.\" apply to all code found in this distribution, be it the RC4, RSA,
65.\" lhash, DES, etc., code; not just the SSL code. The SSL documentation
66.\" included with this distribution is covered by the same copyright terms
67.\" except that the holder is Tim Hudson (tjh@cryptsoft.com).
68.\"
69.\" Copyright remains Eric Young's, and as such any Copyright notices in
70.\" the code are not to be removed.
71.\" If this package is used in a product, Eric Young should be given attribution
72.\" as the author of the parts of the library used.
73.\" This can be in the form of a textual message at program startup or
74.\" in documentation (online or textual) provided with the package.
75.\"
76.\" Redistribution and use in source and binary forms, with or without
77.\" modification, are permitted provided that the following conditions
78.\" are met:
79.\" 1. Redistributions of source code must retain the copyright
80.\" notice, this list of conditions and the following disclaimer.
81.\" 2. Redistributions in binary form must reproduce the above copyright
82.\" notice, this list of conditions and the following disclaimer in the
83.\" documentation and/or other materials provided with the distribution.
84.\" 3. All advertising materials mentioning features or use of this software
85.\" must display the following acknowledgement:
86.\" "This product includes cryptographic software written by
87.\" Eric Young (eay@cryptsoft.com)"
88.\" The word 'cryptographic' can be left out if the rouines from the library
89.\" being used are not cryptographic related :-).
90.\" 4. If you include any Windows specific code (or a derivative thereof) from
91.\" the apps directory (application code) you must include an
92.\" acknowledgement:
93.\" "This product includes software written by Tim Hudson
94.\" (tjh@cryptsoft.com)"
95.\"
96.\" THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
97.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
98.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
99.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
100.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
101.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
102.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
103.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
104.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
105.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
106.\" SUCH DAMAGE.
107.\"
108.\" The licence and distribution terms for any publically available version or
109.\" derivative of this code cannot be changed. i.e. this code cannot simply be
110.\" copied and put under another distribution licence
111.\" [including the GNU Public Licence.]
112.\"
113.Dd $Mdocdate: April 14 2025 $
114.Dt OPENSSL 1
115.Os
116.Sh NAME
117.Nm openssl
118.Nd OpenSSL command line tool
119.Sh SYNOPSIS
120.Nm
121.Ar command
122.Op Ar command_opt ...
123.Op Ar command_arg ...
124.Pp
125.Nm
126.Cm list-standard-commands |
127.Cm list-message-digest-commands |
128.Cm list-cipher-commands |
129.Cm list-cipher-algorithms |
130.Cm list-message-digest-algorithms |
131.Cm list-public-key-algorithms
132.Pp
133.Nm
134.Cm no- Ns Ar command
135.Sh DESCRIPTION
136.Nm OpenSSL
137is a cryptography toolkit implementing the
138Transport Layer Security
139.Pq TLS
140network protocol,
141as well as related cryptography standards.
142.Pp
143The
144.Nm
145program is a command line tool for using the various
146cryptography functions of
147.Nm openssl Ns 's
148crypto library from the shell.
149.Pp
150The pseudo-commands
151.Cm list-standard-commands , list-message-digest-commands ,
152and
153.Cm list-cipher-commands
154output a list
155.Pq one entry per line
156of the names of all standard commands, message digest commands,
157or cipher commands, respectively, that are available in the present
158.Nm
159utility.
160.Pp
161The pseudo-commands
162.Cm list-cipher-algorithms
163and
164.Cm list-message-digest-algorithms
165list all cipher and message digest names,
166one entry per line.
167Aliases are listed as:
168.Pp
169.D1 from => to
170.Pp
171The pseudo-command
172.Cm list-public-key-algorithms
173lists all supported public key algorithms.
174.Pp
175The pseudo-command
176.Cm no- Ns Ar command
177tests whether a command of the
178specified name is available.
179If
180.Ar command
181does not exist,
182it returns 0
183and prints
184.Cm no- Ns Ar command ;
185otherwise it returns 1 and prints
186.Ar command .
187In both cases, the output goes to stdout and nothing is printed to stderr.
188Additional command line arguments are always ignored.
189Since for each cipher there is a command of the same name,
190this provides an easy way for shell scripts to test for the
191availability of ciphers in the
192.Nm
193program.
194.Pp
195.Sy Note :
196.Cm no- Ns Ar command
197is not able to detect pseudo-commands such as
198.Cm quit ,
199.Cm list- Ns Ar ... Ns Cm -commands ,
200or
201.Cm no- Ns Ar command
202itself.
203.Tg asn1parse
204.Sh ASN1PARSE
205.Bl -hang -width "openssl asn1parse"
206.It Nm openssl asn1parse
207.Bk -words
208.Op Fl i
209.Op Fl dlimit Ar number
210.Op Fl dump
211.Op Fl genconf Ar file
212.Op Fl genstr Ar str
213.Op Fl in Ar file
214.Op Fl inform Cm der | pem | txt
215.Op Fl length Ar number
216.Op Fl noout
217.Op Fl offset Ar number
218.Op Fl oid Ar file
219.Op Fl out Ar file
220.Op Fl strparse Ar offset
221.Ek
222.El
223.Pp
224The
225.Nm asn1parse
226command is a diagnostic utility that can parse ASN.1 structures.
227It can also be used to extract data from ASN.1 formatted data.
228.Pp
229The options are as follows:
230.Bl -tag -width Ds
231.It Fl dlimit Ar number
232Dump the first
233.Ar number
234bytes of unknown data in hex form.
235.It Fl dump
236Dump unknown data in hex form.
237.It Fl genconf Ar file , Fl genstr Ar str
238Generate encoded data based on string
239.Ar str ,
240file
241.Ar file ,
242or both, using the format described in
243.Xr ASN1_generate_nconf 3 .
244If only
245.Ar file
246is present then the string is obtained from the default section
247using the name
248.Dq asn1 .
249The encoded data is passed through the ASN.1 parser and printed out as
250though it came from a file;
251the contents can thus be examined and written to a file using the
252.Fl out
253option.
254.It Fl i
255Indent the output according to the
256.Qq depth
257of the structures.
258.It Fl in Ar file
259The input file to read from, or standard input if not specified.
260.It Fl inform Cm der | pem | txt
261The input format.
262.It Fl length Ar number
263Number of bytes to parse; the default is until end of file.
264.It Fl noout
265Do not output the parsed version of the input file.
266.It Fl offset Ar number
267Starting offset to begin parsing; the default is start of file.
268.It Fl oid Ar file
269A file containing additional object identifiers
270.Pq OIDs .
271If an OID
272.Pq object identifier
273is not part of
274.Nm openssl Ns 's
275internal table, it will be represented in
276numerical form
277.Pq for example 1.2.3.4 .
278.Pp
279Each line consists of three columns:
280the first column is the OID in numerical format and should be followed by
281whitespace.
282The second column is the
283.Qq short name ,
284which is a single word followed by whitespace.
285The final column is the rest of the line and is the
286.Qq long name .
287.Nm asn1parse
288displays the long name.
289.It Fl out Ar file
290The DER-encoded output file; the default is no encoded output
291(useful when combined with
292.Fl strparse ) .
293.It Fl strparse Ar offset
294Parse the content octets of the ASN.1 object starting at
295.Ar offset .
296This option can be used multiple times to
297.Qq drill down
298into a nested structure.
299.El
300.Tg ca
301.Sh CA
302.Bl -hang -width "openssl ca"
303.It Nm openssl ca
304.Bk -words
305.Op Fl batch
306.Op Fl cert Ar file
307.Op Fl config Ar file
308.Op Fl create_serial
309.Op Fl crl_CA_compromise Ar time
310.Op Fl crl_compromise Ar time
311.Op Fl crl_hold Ar instruction
312.Op Fl crl_reason Ar reason
313.Op Fl crldays Ar days
314.Op Fl crlexts Ar section
315.Op Fl crlhours Ar hours
316.Op Fl crlsec Ar seconds
317.Op Fl days Ar arg
318.Op Fl enddate Ar date
319.Op Fl extensions Ar section
320.Op Fl extfile Ar file
321.Op Fl gencrl
322.Op Fl in Ar file
323.Op Fl infiles
324.Op Fl key Ar password
325.Op Fl keyfile Ar file
326.Op Fl keyform Cm pem | der
327.Op Fl md Ar alg
328.Op Fl multivalue-rdn
329.Op Fl name Ar section
330.Op Fl noemailDN
331.Op Fl notext
332.Op Fl out Ar file
333.Op Fl outdir Ar directory
334.Op Fl passin Ar arg
335.Op Fl policy Ar arg
336.Op Fl preserveDN
337.Op Fl revoke Ar file
338.Op Fl selfsign
339.Op Fl sigopt Ar nm:v
340.Op Fl ss_cert Ar file
341.Op Fl startdate Ar date
342.Op Fl status Ar serial
343.Op Fl subj Ar arg
344.Op Fl updatedb
345.Op Fl utf8
346.Op Fl verbose
347.Ek
348.El
349.Pp
350The
351.Nm ca
352command is a minimal certificate authority (CA) application.
353It can be used to sign certificate requests in a variety of forms
354and generate certificate revocation lists (CRLs).
355It also maintains a text database of issued certificates and their status.
356.Pp
357The options relevant to CAs are as follows:
358.Bl -tag -width "XXXX"
359.It Fl batch
360Batch mode.
361In this mode no questions will be asked
362and all certificates will be certified automatically.
363.It Fl cert Ar file
364The CA certificate file.
365.It Fl config Ar file
366Specify an alternative configuration file.
367.It Fl create_serial
368If reading the serial from the text file as specified in the
369configuration fails, create a new random serial to be used as the
370next serial number.
371.It Fl days Ar arg
372The number of days to certify the certificate for.
373.It Fl enddate Ar date
374Set the expiry date.
375The format of the date is [YY]YYMMDDHHMMSSZ,
376with all four year digits required for dates from 2050 onwards.
377.It Fl extensions Ar section
378The section of the configuration file containing certificate extensions
379to be added when a certificate is issued (defaults to
380.Cm x509_extensions
381unless the
382.Fl extfile
383option is used).
384If no extension section is present, a V1 certificate is created.
385If the extension section is present
386.Pq even if it is empty ,
387then a V3 certificate is created.
388See the
389.Xr x509v3.cnf 5
390manual page for details of the extension section format.
391.It Fl extfile Ar file
392An additional configuration
393.Ar file
394to read certificate extensions from
395(using the default section unless the
396.Fl extensions
397option is also used).
398.It Fl in Ar file
399An input
400.Ar file
401containing a single certificate request to be signed by the CA.
402.It Fl infiles
403If present, this should be the last option; all subsequent arguments
404are assumed to be the names of files containing certificate requests.
405.It Fl key Ar password
406The
407.Fa password
408used to encrypt the private key.
409Since on some systems the command line arguments are visible,
410this option should be used with caution.
411.It Fl keyfile Ar file
412The private key to sign requests with.
413.It Fl keyform Cm pem | der
414Private key file format.
415The default is
416.Cm pem .
417.It Fl md Ar alg
418The message digest to use.
419Possible values include
420.Ar md5
421and
422.Ar sha1 .
423This option also applies to CRLs.
424.It Fl multivalue-rdn
425This option causes the
426.Fl subj
427argument to be interpreted with full support for multivalued RDNs,
428for example
429.Qq "/DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe" .
430If
431.Fl multivalue-rdn
432is not used, the UID value is set to
433.Qq "123456+CN=John Doe" .
434.It Fl name Ar section
435Specifies the configuration file
436.Ar section
437to use (overrides
438.Cm default_ca
439in the
440.Cm ca
441section).
442.It Fl noemailDN
443The DN of a certificate can contain the EMAIL field if present in the
444request DN, however it is good policy just having the email set into
445the
446.Cm altName
447extension of the certificate.
448When this option is set, the EMAIL field is removed from the certificate's
449subject and set only in the, eventually present, extensions.
450The
451.Ar email_in_dn
452keyword can be used in the configuration file to enable this behaviour.
453.It Fl notext
454Don't output the text form of a certificate to the output file.
455.It Fl out Ar file
456The output file to output certificates to.
457The default is standard output.
458The certificate details will also be printed out to this file in
459PEM format.
460.It Fl outdir Ar directory
461The
462.Ar directory
463to output certificates to.
464The certificate will be written to a file consisting of the
465serial number in hex with
466.Qq .pem
467appended.
468.It Fl passin Ar arg
469The key password source.
470.It Fl policy Ar arg
471Define the CA
472.Qq policy
473to use.
474The policy section in the configuration file
475consists of a set of variables corresponding to certificate DN fields.
476The values may be one of
477.Qq match
478(the value must match the same field in the CA certificate),
479.Qq supplied
480(the value must be present), or
481.Qq optional
482(the value may be present).
483Any fields not mentioned in the policy section
484are silently deleted, unless the
485.Fl preserveDN
486option is set,
487but this can be regarded more of a quirk than intended behaviour.
488.It Fl preserveDN
489Normally, the DN order of a certificate is the same as the order of the
490fields in the relevant policy section.
491When this option is set, the order is the same as the request.
492This is largely for compatibility with the older IE enrollment control
493which would only accept certificates if their DNs matched the order of the
494request.
495This is not needed for Xenroll.
496.It Fl selfsign
497Indicates the issued certificates are to be signed with the key the
498certificate requests were signed with, given with
499.Fl keyfile .
500Certificate requests signed with a different key are ignored.
501If
502.Fl gencrl
503or
504.Fl ss_cert
505are given,
506.Fl selfsign
507is ignored.
508.Pp
509A consequence of using
510.Fl selfsign
511is that the self-signed certificate appears among the entries in
512the certificate database (see the configuration option
513.Cm database )
514and uses the same serial number counter as all other certificates
515signed with the self-signed certificate.
516.It Fl sigopt Ar nm:v
517Pass options to the signature algorithm during sign or certify operations.
518The names and values of these options are algorithm-specific.
519.It Fl ss_cert Ar file
520A single self-signed certificate to be signed by the CA.
521.It Fl startdate Ar date
522Set the start date.
523The format of the date is [YY]YYMMDDHHMMSSZ,
524with all four year digits required for dates from 2050 onwards.
525.It Fl subj Ar arg
526Supersedes the subject name given in the request.
527The
528.Ar arg
529must be formatted as
530.Sm off
531.Pf / Ar type0 Ns = Ar value0 Ns / Ar type 1 Ns = Ar value 1 Ns /
532.Ar type2 Ns = Ar ... ;
533.Sm on
534characters may be escaped by
535.Sq \e
536.Pq backslash ,
537no spaces are skipped.
538.It Fl utf8
539Interpret field values read from a terminal or obtained from a
540configuration file as UTF-8 strings.
541By default, they are interpreted as ASCII.
542.It Fl verbose
543Print extra details about the operations being performed.
544.El
545.Pp
546The options relevant to CRLs are as follows:
547.Bl -tag -width "XXXX"
548.It Fl crl_CA_compromise Ar time
549This is the same as
550.Fl crl_compromise ,
551except the revocation reason is set to CACompromise.
552.It Fl crl_compromise Ar time
553Set the revocation reason to keyCompromise and the compromise time to
554.Ar time .
555.Ar time
556should be in GeneralizedTime format, i.e. YYYYMMDDHHMMSSZ.
557.It Fl crl_hold Ar instruction
558Set the CRL revocation reason code to certificateHold and the hold
559instruction to
560.Ar instruction
561which must be an OID.
562Although any OID can be used, only holdInstructionNone
563(the use of which is discouraged by RFC 2459), holdInstructionCallIssuer or
564holdInstructionReject will normally be used.
565.It Fl crl_reason Ar reason
566Revocation reason, where
567.Ar reason
568is one of:
569unspecified, keyCompromise, CACompromise, affiliationChanged, superseded,
570cessationOfOperation, certificateHold or removeFromCRL.
571The matching of
572.Ar reason
573is case insensitive.
574Setting any revocation reason will make the CRL v2.
575In practice, removeFromCRL is not particularly useful because it is only used
576in delta CRLs which are not currently implemented.
577.It Fl crldays Ar days
578The number of days before the next CRL is due.
579This is the days from now to place in the CRL
580.Cm nextUpdate
581field.
582.It Fl crlexts Ar section
583The
584.Ar section
585of the configuration file containing CRL extensions to include.
586If no CRL extension section is present then a V1 CRL is created;
587if the CRL extension section is present
588(even if it is empty)
589then a V2 CRL is created.
590The CRL extensions specified are CRL extensions and not CRL entry extensions.
591It should be noted that some software can't handle V2 CRLs.
592See the
593.Xr x509v3.cnf 5
594manual page for details of the extension section format.
595.It Fl crlhours Ar hours
596The number of hours before the next CRL is due.
597.It Fl crlsec Ar seconds
598The number of seconds before the next CRL is due.
599.It Fl gencrl
600Generate a CRL based on information in the index file.
601.It Fl revoke Ar file
602A
603.Ar file
604containing a certificate to revoke.
605.It Fl status Ar serial
606Show the status of the certificate with serial number
607.Ar serial .
608.It Fl updatedb
609Update the database index to purge expired certificates.
610.El
611.Pp
612Many of the options can be set in the
613.Cm ca
614section of the configuration file
615(or in the default section of the configuration file),
616specified using
617.Cm default_ca
618or
619.Fl name .
620The
621.Cm preserve
622option is read directly from the
623.Cm ca
624section.
625.Pp
626Many of the configuration file options are identical to command line
627options.
628Where the option is present in the configuration file and the command line,
629the command line value is used.
630Where an option is described as mandatory, then it must be present in
631the configuration file or the command line equivalent
632.Pq if any
633used.
634.Bl -tag -width "XXXX"
635.It Cm certificate
636The same as
637.Fl cert .
638It gives the file containing the CA certificate.
639Mandatory.
640.It Cm copy_extensions
641Determines how extensions in certificate requests should be handled.
642If set to
643.Cm none
644or this option is not present, then extensions are
645ignored and not copied to the certificate.
646If set to
647.Cm copy ,
648then any extensions present in the request that are not already present
649are copied to the certificate.
650If set to
651.Cm copyall ,
652then all extensions in the request are copied to the certificate:
653if the extension is already present in the certificate it is deleted first.
654.Pp
655The
656.Cm copy_extensions
657option should be used with caution.
658If care is not taken, it can be a security risk.
659For example, if a certificate request contains a
660.Cm basicConstraints
661extension with CA:TRUE and the
662.Cm copy_extensions
663value is set to
664.Cm copyall
665and the user does not spot
666this when the certificate is displayed, then this will hand the requester
667a valid CA certificate.
668.Pp
669This situation can be avoided by setting
670.Cm copy_extensions
671to
672.Cm copy
673and including
674.Cm basicConstraints
675with CA:FALSE in the configuration file.
676Then if the request contains a
677.Cm basicConstraints
678extension, it will be ignored.
679.Pp
680The main use of this option is to allow a certificate request to supply
681values for certain extensions such as
682.Cm subjectAltName .
683.It Cm crl_extensions
684The same as
685.Fl crlexts .
686.It Cm crlnumber
687A text file containing the next CRL number to use in hex.
688The CRL number will be inserted in the CRLs only if this file exists.
689If this file is present, it must contain a valid CRL number.
690.It Cm database
691The text database file to use.
692Mandatory.
693This file must be present, though initially it will be empty.
694.It Cm default_crl_hours , default_crl_days
695The same as the
696.Fl crlhours
697and
698.Fl crldays
699options.
700These will only be used if neither command line option is present.
701At least one of these must be present to generate a CRL.
702.It Cm default_days
703The same as the
704.Fl days
705option.
706The number of days to certify a certificate for.
707.It Cm default_enddate
708The same as the
709.Fl enddate
710option.
711Either this option or
712.Cm default_days
713.Pq or the command line equivalents
714must be present.
715.It Cm default_md
716The same as the
717.Fl md
718option.
719The message digest to use.
720Mandatory.
721.It Cm default_startdate
722The same as the
723.Fl startdate
724option.
725The start date to certify a certificate for.
726If not set, the current time is used.
727.It Cm email_in_dn
728The same as
729.Fl noemailDN .
730If the EMAIL field is to be removed from the DN of the certificate,
731simply set this to
732.Qq no .
733If not present, the default is to allow for the EMAIL field in the
734certificate's DN.
735.It Cm name_opt , cert_opt
736These options allow the format used to display the certificate details
737when asking the user to confirm signing.
738All the options supported by the
739.Nm x509
740utilities'
741.Fl nameopt
742and
743.Fl certopt
744switches can be used here, except that
745.Cm no_signame
746and
747.Cm no_sigdump
748are permanently set and cannot be disabled
749(this is because the certificate signature cannot be displayed because
750the certificate has not been signed at this point).
751.Pp
752For convenience, the value
753.Cm ca_default
754is accepted by both to produce a reasonable output.
755.Pp
756If neither option is present, the format used in earlier versions of
757.Nm openssl
758is used.
759Use of the old format is strongly discouraged
760because it only displays fields mentioned in the
761.Cm policy
762section,
763mishandles multicharacter string types and does not display extensions.
764.It Cm new_certs_dir
765The same as the
766.Fl outdir
767command line option.
768It specifies the directory where new certificates will be placed.
769Mandatory.
770.It Cm oid_file
771This specifies a file containing additional object identifiers.
772Each line of the file should consist of the numerical form of the
773object identifier followed by whitespace, then the short name followed
774by whitespace and finally the long name.
775.It Cm oid_section
776This specifies a section in the configuration file containing extra
777object identifiers.
778Each line should consist of the short name of the object identifier
779followed by
780.Sq =
781and the numerical form.
782The short and long names are the same when this option is used.
783.It Cm policy
784The same as
785.Fl policy .
786Mandatory.
787.It Cm preserve
788The same as
789.Fl preserveDN .
790.It Cm private_key
791Same as the
792.Fl keyfile
793option.
794The file containing the CA private key.
795Mandatory.
796.It Cm serial
797A text file containing the next serial number to use in hex.
798Mandatory.
799This file must be present and contain a valid serial number.
800.It Cm unique_subject
801If the value
802.Cm yes
803is given, the valid certificate entries in the
804database must have unique subjects.
805If the value
806.Cm no
807is given,
808several valid certificate entries may have the exact same subject.
809The default value is
810.Cm yes .
811.Pp
812Note that it is valid in some circumstances for certificates to be created
813without any subject.
814In cases where there are multiple certificates without
815subjects this does not count as a duplicate.
816.It Cm x509_extensions
817The same as
818.Fl extensions .
819.El
820.Tg certhash
821.Sh CERTHASH
822.Bl -hang -width "openssl certhash"
823.It Nm openssl certhash
824.Bk -words
825.Op Fl nv
826.Ar dir ...
827.Ek
828.El
829.Pp
830The
831.Nm certhash
832command calculates a hash value of
833.Qq .pem
834file in the specified directory list and creates symbolic links for each file,
835where the name of the link is the hash value.
836See the
837.Xr SSL_CTX_load_verify_locations 3
838manual page for how hash links are used.
839.Pp
840The links created are of the form
841.Qq HHHHHHHH.D ,
842where each
843.Sq H
844is a hexadecimal character and
845.Sq D
846is a single decimal digit.
847The hashes for CRLs look similar, except the letter
848.Sq r
849appears after the period, like this:
850.Qq HHHHHHHH.rD .
851When processing a directory,
852.Nm certhash
853will first remove all links that have a name in that syntax and invalid
854reference.
855.Pp
856Multiple objects may have the same hash; they will be indicated by
857incrementing the
858.Sq D
859value.
860Duplicates are found by comparing the full SHA256 fingerprint.
861A warning will be displayed if a duplicate is found.
862.Pp
863A warning will also be displayed if there are files that cannot be parsed as
864either a certificate or a CRL.
865.Pp
866The options are as follows:
867.Bl -tag -width Ds
868.It Fl n
869Perform a dry-run, and do not make any changes.
870.It Fl v
871Print extra details about the processing.
872.It Ar dir ...
873Specify the directories to process.
874.El
875.Tg ciphers
876.Sh CIPHERS
877.Nm openssl ciphers
878.Op Fl hsVv
879.Op Fl tls1_2
880.Op Fl tls1_3
881.Op Ar control
882.Pp
883The
884.Nm ciphers
885command converts the
886.Ar control
887string from the format documented in
888.Xr SSL_CTX_set_cipher_list 3
889into an ordered SSL cipher suite preference list.
890If no
891.Ar control
892string is specified, the
893.Cm DEFAULT
894list is printed.
895.Pp
896The options are as follows:
897.Bl -tag -width Ds
898.It Fl h , \&?
899Print a brief usage message.
900.It Fl s
901Only list ciphers that are supported by the TLS method.
902.It Fl tls1_2 | tls1_3
903In combination with the
904.Fl s
905option, list the ciphers which could be used
906if the specified protocol version were negotiated.
907.It Fl V
908Verbose.
909List ciphers with cipher suite code in hex format,
910cipher name, and a complete description of protocol version,
911key exchange, authentication, encryption, and mac algorithms.
912.It Fl v
913Like
914.Fl V ,
915but without cipher suite codes.
916.El
917.Tg cms
918.Sh CMS
919.Bl -hang -width "openssl cms"
920.It Nm openssl cms
921.Bk -words
922.Oo
923.Fl aes128 | aes192 | aes256 | camellia128 |
924.Fl camellia192 | camellia256 | des | des3 |
925.Fl rc2-40 | rc2-64 | rc2-128
926.Oc
927.Op Fl CAfile Ar file
928.Op Fl CApath Ar directory
929.Op Fl CRLfile Ar file
930.Op Fl binary
931.Op Fl certfile Ar file
932.Op Fl certsout Ar file
933.Op Fl cmsout
934.Op Fl compress
935.Op Fl content Ar file
936.Op Fl crlfeol
937.Op Fl data_create
938.Op Fl data_out
939.Op Fl debug_decrypt
940.Op Fl decrypt
941.Op Fl digest_create
942.Op Fl digest_verify
943.Op Fl econtent_type Ar type
944.Op Fl encrypt
945.Op Fl EncryptedData_decrypt
946.Op Fl EncryptedData_encrypt
947.Op Fl from Ar addr
948.Op Fl in Ar file
949.Op Fl inform Cm der | pem | smime
950.Op Fl inkey Ar file
951.Op Fl keyform Cm der | pem
952.Op Fl keyid
953.Op Fl keyopt Ar nm:v
954.Op Fl md Ar digest
955.Op Fl no_attr_verify
956.Op Fl no_content_verify
957.Op Fl no_signer_cert_verify
958.Op Fl noattr
959.Op Fl nocerts
960.Op Fl nodetach
961.Op Fl nointern
962.Op Fl nooldmime
963.Op Fl noout
964.Op Fl nosigs
965.Op Fl nosmimecap
966.Op Fl noverify
967.Op Fl out Ar file
968.Op Fl outform Cm der | pem | smime
969.Op Fl passin Ar src
970.Op Fl print
971.Op Fl pwri_password Ar arg
972.Op Fl rctform Cm der | pem | smime
973.Op Fl receipt_request_all | receipt_request_first
974.Op Fl receipt_request_from Ar addr
975.Op Fl receipt_request_print
976.Op Fl receipt_request_to Ar addr
977.Op Fl recip Ar file
978.Op Fl resign
979.Op Fl secretkey Ar key
980.Op Fl secretkeyid Ar id
981.Op Fl sign
982.Op Fl sign_receipt
983.Op Fl signer Ar file
984.Op Fl stream | indef | noindef
985.Op Fl subject Ar s
986.Op Fl text
987.Op Fl to Ar addr
988.Op Fl uncompress
989.Op Fl verify
990.Op Fl verify_receipt Ar file
991.Op Fl verify_retcode
992.Op Ar cert.pem ...
993.Ek
994.El
995.Pp
996The
997.Nm cms
998command handles S/MIME v3.1 mail.
999It can encrypt, decrypt, sign and verify, compress and uncompress S/MIME
1000messages.
1001.Pp
1002The MIME message must be sent without any blank lines between the headers and
1003the output.
1004Some mail programs will automatically add a blank line.
1005Piping the mail directly to sendmail is one way to achieve the correct format.
1006.Pp
1007The supplied message to be signed or encrypted must include the necessary MIME
1008headers or many S/MIME clients won't display it properly (if at all).
1009You can use the
1010.Fl text
1011option to automatically add plain text headers.
1012.Pp
1013A "signed and encrypted" message is one where a signed message is then
1014encrypted.
1015This can be produced by encrypting an already signed message.
1016.Pp
1017There are various operation options that set the type of operation to be
1018performed.
1019The meaning of the other options varies according to the operation type.
1020.Bl -tag -width "XXXX"
1021.It Fl encrypt
1022Encrypt mail for the given recipient certificates.
1023Input file is the message to be encrypted.
1024The output file is the encrypted mail in MIME format.
1025The actual CMS type is EnvelopedData.
1026Note that no revocation check is done for the recipient cert, so if that
1027key has been compromised, others may be able to decrypt the text.
1028.It Fl decrypt
1029Decrypt mail using the supplied certificate and private key.
1030Expects an encrypted mail message in MIME format for the input file.
1031The decrypted mail is written to the output file.
1032.It Fl sign
1033Sign mail using the supplied certificate and private key.
1034Input file is the message to be signed.
1035The signed message in MIME format is written to the output file.
1036.It Fl verify
1037Verify signed mail.
1038Expects a signed mail message on input and outputs the signed data.
1039Both clear text and opaque signing are supported.
1040.It Fl cmsout
1041Take an input message and write out a PEM encoded CMS structure.
1042.It Fl resign
1043Resign a message.
1044Take an existing message and one or more new signers.
1045This operation uses an existing message digest when adding a new signer.
1046This means that attributes must be present in at least one existing
1047signer using the same message digest or this operation will fail.
1048.It Fl data_create
1049Create a CMS Data type.
1050.It Fl data_out
1051Output a content from the input CMS Data type.
1052.It Fl digest_create
1053Create a CMS DigestedData type.
1054.It Fl digest_verify
1055Verify a CMS DigestedData type and output the content.
1056.It Fl compress
1057Create a CMS CompressedData type.
1058Must be compiled with zlib support for this option to work.
1059.It Fl uncompress
1060Uncompress a CMS CompressedData type and output the content.
1061Must be compiled with zlib support for this option to work.
1062.It Fl EncryptedData_encrypt
1063Encrypt a content using supplied symmetric key and algorithm using a
1064CMS EncryptedData type.
1065.It Fl EncryptedData_decrypt
1066Decrypt a CMS EncryptedData type using supplied symmetric key.
1067.It Fl sign_receipt
1068Generate and output a signed receipt for the supplied message.
1069The input message must contain a signed receipt request.
1070Functionality is otherwise similar to the
1071.Fl sign
1072operation.
1073.It Xo
1074.Fl verify_receipt Ar file
1075.Xc
1076Verify a signed receipt in file.
1077The input message must contain the original receipt request.
1078Functionality is otherwise similar to the
1079.Fl verify
1080operation.
1081.El
1082.Pp
1083The remaining options are as follows:
1084.Bl -tag -width "XXXX"
1085.It Xo
1086.Fl aes128 | aes192 | aes256 | camellia128 |
1087.Fl camellia192 | camellia256 | des | des3 |
1088.Fl rc2-40 | rc2-64 | rc2-128
1089.Xc
1090The encryption algorithm to use.
1091128-, 192-, or 256-bit AES, 128-, 192-, or 256-bit CAMELLIA,
1092DES (56 bits), triple DES (168 bits),
1093or 40-, 64-, or 128-bit RC2, respectively;
1094if not specified, triple DES is
1095used.
1096Only used with
1097.Fl encrypt
1098and
1099.Fl EncryptedData_encrypt
1100commands.
1101.It Fl binary
1102Normally the input message is converted to "canonical" format which is
1103effectively using CR/LF as end of line, as required by the S/MIME specification.
1104When this option is present, no translation occurs.
1105This is useful when handling binary data which may not be in MIME format.
1106.It Fl CAfile Ar file
1107A file containing trusted CA certificates, used with
1108.Fl verify
1109and
1110.Fl verify_receipt .
1111.It Fl CApath Ar directory
1112A directory containing trusted CA certificates, used with
1113.Fl verify
1114and
1115.Fl verify_receipt .
1116This directory must be a standard certificate directory: that is a hash
1117of each subject name (using
1118.Nm x509 Fl hash )
1119should be linked to each certificate.
1120.It Fl CRLfile Ar file
1121Allows additional certificate revocation lists to be specified for verification.
1122The CRLs should be in PEM format.
1123.It Ar cert.pem ...
1124One or more certificates of message recipients: used when encrypting a message.
1125.It Fl certfile Ar file
1126Allows additional certificates to be specified.
1127When signing, these will be included with the message.
1128When verifying, these will be searched for the signer's certificates.
1129The certificates should be in PEM format.
1130.It Fl certsout Ar file
1131A file that any certificates contained in the message are written to.
1132.It Xo
1133.Fl check_ss_sig ,
1134.Fl crl_check ,
1135.Fl crl_check_all ,
1136.Fl extended_crl ,
1137.Fl ignore_critical ,
1138.Fl issuer_checks ,
1139.Fl policy ,
1140.Fl policy_check ,
1141.Fl purpose ,
1142.Fl x509_strict
1143.Xc
1144Set various certificate chain validation options.
1145See the
1146.Nm verify
1147command for details.
1148.It Fl content Ar file
1149A file containing the detached content.
1150This is only useful with the
1151.Fl verify
1152command.
1153This is only usable if the CMS structure is using the detached signature
1154form where the content is not included.
1155This option will override any content if the input format is S/MIME and
1156it uses the multipart/signed MIME content type.
1157.It Fl crlfeol
1158Output a S/MIME message with CR/LF end of line.
1159.It Fl debug_decrypt
1160Set the CMS_DEBUG_DECRYPT flag when decrypting.
1161This option should be used with caution, since this can be used to disable
1162the MMA attack protection and return an error if no recipient can be found.
1163See the
1164.Xr CMS_decrypt 3
1165manual page for details of the flag.
1166.It Xo
1167.Fl from Ar addr ,
1168.Fl subject Ar s ,
1169.Fl to Ar addr
1170.Xc
1171The relevant mail headers.
1172These are included outside the signed portion of a message so they may
1173be included manually.
1174If signing then many S/MIME mail clients check the signer's certificate's
1175email address matches that specified in the From: address.
1176.It Fl econtent_type Ar type
1177Set the encapsulated content type, used with
1178.Fl sign .
1179If not supplied, the Data type is used.
1180The type argument can be any valid OID name in either text or numerical format.
1181.It Fl in Ar file
1182The input message to be encrypted or signed or the message to be decrypted or
1183verified.
1184.It Fl inform Cm der | pem | smime
1185The input format for the CMS structure.
1186The default is
1187.Cm smime ,
1188which reads an S/MIME format message.
1189.Cm pem
1190and
1191.Cm der
1192format change this to expect PEM and DER format CMS structures instead.
1193This currently only affects the input format of the CMS structure; if no
1194CMS structure is being input (for example with
1195.Fl encrypt
1196or
1197.Fl sign )
1198this option has no effect.
1199.It Fl inkey Ar file
1200The private key to use when signing or decrypting.
1201This must match the corresponding certificate.
1202If this option is not specified then the private key must be included in
1203the certificate file specified with the
1204.Fl recip
1205or
1206.Fl signer
1207file.
1208When signing, this option can be used multiple times to specify successive keys.
1209.It Fl keyform Cm der | pem
1210Input private key format.
1211The default is
1212.Cm pem .
1213.It Fl keyid
1214Use subject key identifier to identify certificates instead of issuer
1215name and serial number.
1216The supplied certificate must include a subject key identifier extension.
1217Supported by
1218.Fl sign
1219and
1220.Fl encrypt
1221operations.
1222.It Fl keyopt Ar nm:v
1223Set customised parameters for the preceding key or certificate
1224for encryption and signing.
1225It can currently be used to set RSA-PSS for signing, RSA-OAEP for
1226encryption or to modify default parameters for ECDH.
1227This option can be used multiple times.
1228.It Fl md Ar digest
1229The digest algorithm to use when signing or resigning.
1230If not present then the default digest algorithm for the signing key
1231will be used (usually SHA1).
1232.It Fl no_attr_verify
1233Do not verify the signer's attribute of a signature.
1234.It Fl no_content_verify
1235Do not verify the content of a signed message.
1236.It Fl no_signer_cert_verify
1237Do not verify the signer's certificate of a signed message.
1238.It Fl noattr
1239Do not include attributes.
1240Normally when a message is signed a set of attributes are included which
1241include the signing time and supported symmetric algorithms.
1242With this option they are not included.
1243.It Fl nocerts
1244Do not include the signer's certificate.
1245This will reduce the size of the signed message but the verifier must
1246have a copy of the signer's certificate available locally (passed using
1247the
1248.Fl certfile
1249option for example).
1250.It Fl nodetach
1251When signing a message, use opaque signing.
1252This form is more resistant to translation by mail relays but it cannot be
1253read by mail agents that do not support S/MIME.
1254Without this option cleartext signing with the MIME type multipart/signed is
1255used.
1256.It Fl nointern
1257Only the certificates specified in the
1258.Fl certfile
1259option are used.
1260When verifying a message, normally certificates (if any) included in the
1261message are searched for the signing certificate.
1262The supplied certificates can still be used as untrusted CAs however.
1263.It Fl nooldmime
1264Output an old S/MIME content type like "application/x-pkcs7-".
1265.It Fl noout
1266Do not output the parsed CMS structure for the
1267.Fl cmsout
1268operation.
1269This is useful when combined with the
1270.Fl print
1271option or if the syntax of the CMS structure is being checked.
1272.It Fl nosigs
1273Do not try to verify the signatures on the message.
1274.It Fl nosmimecap
1275Exclude the list of supported algorithms from signed attributes; other
1276options such as signing time and content type are still included.
1277.It Fl noverify
1278Do not verify the signer's certificate of a signed message.
1279.It Fl out Ar file
1280The message text that has been decrypted or verified or the output MIME
1281format message that has been signed or verified.
1282.It Fl outform Cm der | pem | smime
1283This specifies the output format for the CMS structure.
1284The default is
1285.Cm smime ,
1286which writes an S/MIME format message.
1287.Cm pem
1288and
1289.Cm der
1290format change this to write PEM and DER format CMS structures instead.
1291This currently only affects the output format of the CMS structure; if
1292no CMS structure is being output (for example with
1293.Fl verify
1294or
1295.Fl decrypt )
1296this option has no effect.
1297.It Fl passin Ar src
1298The private key password source.
1299.It Fl print
1300Print out all fields of the CMS structure for the
1301.Fl cmsout
1302operation.
1303This is mainly useful for testing purposes.
1304.It Fl pwri_password Ar arg
1305Specify PasswordRecipientInfo (PWRI) password to use.
1306Supported by the
1307.Fl encrypt
1308and
1309.Fl decrypt
1310operations.
1311.It Fl rctform Cm der | pem | smime
1312Specify the format for a signed receipt for use with the
1313.Fl receipt_verify
1314operation.
1315The default is
1316.Cm smime .
1317.It Fl receipt_request_all | receipt_request_first
1318Indicate requests should be provided by all recipient or first tier
1319recipients (those mailed directly and not from a mailing list), for the
1320.Fl sign
1321operation to include a signed receipt request.
1322Ignored if
1323.Fl receipt_request_from
1324is included.
1325.It Fl receipt_request_from Ar addr
1326Add an explicit email address where receipts should be supplied.
1327.It Fl receipt_request_print
1328Print out the contents of any signed receipt requests for the
1329.Fl verify
1330operation.
1331.It Fl receipt_request_to Ar addr
1332Add an explicit email address where signed receipts should be sent to.
1333This option must be supplied if a signed receipt is requested.
1334.It Fl recip Ar file
1335When decrypting a message, this specifies the recipient's certificate.
1336The certificate must match one of the recipients of the message or an
1337error occurs.
1338When encrypting a message, this option may be used multiple times to
1339specify each recipient.
1340This form must be used if customised parameters are required (for example to
1341specify RSA-OAEP).
1342Only certificates carrying RSA, Diffie-Hellman or EC keys are supported
1343by this option.
1344.It Fl secretkey Ar key
1345Specify symmetric key to use.
1346The key must be supplied in hex format and be consistent with the
1347algorithm used.
1348Supported by the
1349.Fl EncryptedData_encrypt ,
1350.Fl EncryptedData_decrypt ,
1351.Fl encrypt
1352and
1353.Fl decrypt
1354operations.
1355When used with
1356.Fl encrypt
1357or
1358.Fl decrypt ,
1359the supplied key is used to wrap or unwrap the content encryption key
1360using an AES key in the KEKRecipientInfo type.
1361.It Fl secretkeyid Ar id
1362The key identifier for the supplied symmetric key for KEKRecipientInfo type.
1363This option must be present if the
1364.Fl secretkey
1365option is used with
1366.Fl encrypt .
1367With
1368.Fl decrypt
1369operations the id is used to locate the relevant key; if it is not supplied
1370then an attempt is used to decrypt any KEKRecipientInfo structures.
1371.It Fl signer Ar file
1372A signing certificate when signing or resigning a message; this option
1373can be used multiple times if more than one signer is required.
1374If a message is being verified then the signers certificates will be
1375written to this file if the verification was successful.
1376.It Xo
1377.Fl stream |
1378.Fl indef |
1379.Fl noindef
1380.Xc
1381The
1382.Fl stream
1383and
1384.Fl indef
1385options are equivalent and enable streaming I/O for encoding operations.
1386This permits single pass processing of data without the need to hold the
1387entire contents in memory, potentially supporting very large files.
1388Streaming is automatically set for S/MIME signing with detached data if
1389the output format is
1390.Cm smime ;
1391it is currently off by default for all other operations.
1392.Fl noindef
1393disable streaming I/O where it would produce an indefinite length
1394constructed encoding.
1395This option currently has no effect.
1396.It Fl text
1397Add plain text (text/plain) MIME headers to the supplied message if
1398encrypting or signing.
1399If decrypting or verifying, it strips off text headers: if the decrypted
1400or verified message is not of MIME type text/plain then an error occurs.
1401.It Fl verify_retcode
1402Set verification error code to exit code to indicate what verification error
1403has occurred.
1404Supported by
1405.Fl verify
1406operation only.
1407Exit code value minus 32 shows verification error code.
1408See
1409.Nm verify
1410command for the list of verification error code.
1411.El
1412.Pp
1413The exit codes for
1414.Nm cms
1415are as follows:
1416.Pp
1417.Bl -tag -width "XXXX" -offset 3n -compact
1418.It 0
1419The operation was completely successful.
1420.It 1
1421An error occurred parsing the command options.
1422.It 2
1423One of the input files could not be read.
1424.It 3
1425An error occurred creating the CMS file or when reading the MIME message.
1426.It 4
1427An error occurred decrypting or verifying the message.
1428.It 5
1429The message was verified correctly but an error occurred writing out the
1430signer's certificates.
1431.It 6
1432An error occurred writing the output file.
1433.It 32+
1434A verify error occurred while
1435.Fl verify_retcode
1436is specified.
1437.El
1438.Tg crl
1439.Sh CRL
1440.Bl -hang -width "openssl crl"
1441.It Nm openssl crl
1442.Bk -words
1443.Op Fl CAfile Ar file
1444.Op Fl CApath Ar dir
1445.Op Fl crlnumber
1446.Op Fl fingerprint
1447.Op Fl hash
1448.Op Fl hash_old
1449.Op Fl in Ar file
1450.Op Fl inform Cm der | pem
1451.Op Fl issuer
1452.Op Fl lastupdate
1453.Op Fl nameopt Ar option
1454.Op Fl nextupdate
1455.Op Fl noout
1456.Op Fl out Ar file
1457.Op Fl outform Cm der | pem
1458.Op Fl text
1459.Op Fl verify
1460.Ek
1461.El
1462.Pp
1463The
1464.Nm crl
1465command processes CRL files in DER or PEM format.
1466.Pp
1467The options are as follows:
1468.Bl -tag -width Ds
1469.It Fl CAfile Ar file
1470Verify the signature on a CRL by looking up the issuing certificate in
1471.Ar file .
1472.It Fl CApath Ar directory
1473Verify the signature on a CRL by looking up the issuing certificate in
1474.Ar dir .
1475This directory must be a standard certificate directory,
1476i.e. a hash of each subject name (using
1477.Cm x509 Fl hash )
1478should be linked to each certificate.
1479.It Fl crlnumber
1480Print the CRL number.
1481.It Fl fingerprint
1482Print the CRL fingerprint.
1483.It Fl hash
1484Output a hash of the issuer name.
1485This can be used to look up CRLs in a directory by issuer name.
1486.It Fl hash_old
1487Output an old-style (MD5) hash of the issuer name.
1488.It Fl in Ar file
1489The input file to read from, or standard input if not specified.
1490.It Fl inform Cm der | pem
1491The input format.
1492.It Fl issuer
1493Output the issuer name.
1494.It Fl lastupdate
1495Output the
1496.Cm thisUpdate
1497field.
1498This option is misnamed for historical reasons.
1499.It Fl nameopt Ar option
1500Specify certificate name options.
1501.It Fl nextupdate
1502Output the
1503.Cm nextUpdate
1504field.
1505.It Fl noout
1506Do not output the encoded version of the CRL.
1507.It Fl out Ar file
1508The output file to write to, or standard output if not specified.
1509.It Fl outform Cm der | pem
1510The output format.
1511.It Fl text
1512Print the CRL in plain text.
1513.It Fl verify
1514Verify the signature on the CRL.
1515.El
1516.Tg crl2pkcs7
1517.Sh CRL2PKCS7
1518.Bl -hang -width "openssl crl2pkcs7"
1519.It Nm openssl crl2pkcs7
1520.Bk -words
1521.Op Fl certfile Ar file
1522.Op Fl in Ar file
1523.Op Fl inform Cm der | pem
1524.Op Fl nocrl
1525.Op Fl out Ar file
1526.Op Fl outform Cm der | pem
1527.Ek
1528.El
1529.Pp
1530The
1531.Nm crl2pkcs7
1532command takes an optional CRL and one or more
1533certificates and converts them into a PKCS#7 degenerate
1534.Qq certificates only
1535structure.
1536.Pp
1537The options are as follows:
1538.Bl -tag -width Ds
1539.It Fl certfile Ar file
1540Add the certificates in PEM
1541.Ar file
1542to the PKCS#7 structure.
1543This option can be used more than once
1544to read certificates from multiple files.
1545.It Fl in Ar file
1546Read the CRL from
1547.Ar file ,
1548or standard input if not specified.
1549.It Fl inform Cm der | pem
1550The input format.
1551.It Fl nocrl
1552Normally, a CRL is included in the output file.
1553With this option, no CRL is
1554included in the output file and a CRL is not read from the input file.
1555.It Fl out Ar file
1556Write the PKCS#7 structure to
1557.Ar file ,
1558or standard output if not specified.
1559.It Fl outform Cm der | pem
1560The output format.
1561.El
1562.Tg dgst
1563.Sh DGST
1564.Bl -hang -width "openssl dgst"
1565.It Nm openssl dgst
1566.Bk -words
1567.Op Fl cdr
1568.Op Fl binary
1569.Op Fl Ar digest
1570.Op Fl hex
1571.Op Fl hmac Ar key
1572.Op Fl keyform Cm pem
1573.Op Fl mac Ar algorithm
1574.Op Fl macopt Ar nm : Ns Ar v
1575.Op Fl out Ar file
1576.Op Fl passin Ar arg
1577.Op Fl prverify Ar file
1578.Op Fl sign Ar file
1579.Op Fl signature Ar file
1580.Op Fl sigopt Ar nm : Ns Ar v
1581.Op Fl verify Ar file
1582.Op Ar
1583.Ek
1584.El
1585.Pp
1586The digest functions output the message digest of a supplied
1587.Ar file
1588or
1589.Ar files
1590in hexadecimal form.
1591They can also be used for digital signing and verification.
1592.Pp
1593The options are as follows:
1594.Bl -tag -width Ds
1595.It Fl binary
1596Output the digest or signature in binary form.
1597.It Fl c
1598Print the digest in two-digit groups separated by colons.
1599.It Fl d
1600Print BIO debugging information.
1601.It Fl Ar digest
1602Use the specified message
1603.Ar digest .
1604The default is SHA256.
1605The available digests can be displayed using
1606.Nm openssl
1607.Cm list-message-digest-commands .
1608The following are equivalent:
1609.Nm openssl dgst
1610.Fl sha256
1611and
1612.Nm openssl
1613.Cm sha256 .
1614.It Fl hex
1615Digest is to be output as a hex dump.
1616This is the default case for a
1617.Qq normal
1618digest as opposed to a digital signature.
1619.It Fl hmac Ar key
1620Create a hashed MAC using
1621.Ar key .
1622.It Fl keyform Cm pem
1623Specifies the key format to sign the digest with.
1624.It Fl mac Ar algorithm
1625Create a keyed Message Authentication Code (MAC).
1626The most popular MAC algorithm is HMAC (hash-based MAC),
1627but there are other MAC algorithms which are not based on hash.
1628MAC keys and other options should be set via the
1629.Fl macopt
1630parameter.
1631.It Fl macopt Ar nm : Ns Ar v
1632Passes options to the MAC algorithm, specified by
1633.Fl mac .
1634The following options are supported by HMAC:
1635.Bl -tag -width Ds
1636.It Cm key : Ns Ar string
1637Specifies the MAC key as an alphanumeric string
1638(use if the key contain printable characters only).
1639String length must conform to any restrictions of the MAC algorithm.
1640.It Cm hexkey : Ns Ar string
1641Specifies the MAC key in hexadecimal form (two hex digits per byte).
1642Key length must conform to any restrictions of the MAC algorithm.
1643.El
1644.It Fl out Ar file
1645The output file to write to,
1646or standard output if not specified.
1647.It Fl passin Ar arg
1648The key password source.
1649.It Fl prverify Ar file
1650Verify the signature using the private key in
1651.Ar file .
1652The output is either
1653.Qq Verification OK
1654or
1655.Qq Verification Failure .
1656.It Fl r
1657Print the digest in coreutils format.
1658.It Fl sign Ar file
1659Digitally sign the digest using the private key in
1660.Ar file .
1661.It Fl signature Ar file
1662The actual signature to verify.
1663.It Fl sigopt Ar nm : Ns Ar v
1664Pass options to the signature algorithm during sign or verify operations.
1665The names and values of these options are algorithm-specific.
1666.It Fl verify Ar file
1667Verify the signature using the public key in
1668.Ar file .
1669The output is either
1670.Qq Verification OK
1671or
1672.Qq Verification Failure .
1673.It Ar
1674File or files to digest.
1675If no files are specified then standard input is used.
1676.El
1677.Tg dhparam
1678.Sh DHPARAM
1679.Bl -hang -width "openssl dhparam"
1680.It Nm openssl dhparam
1681.Bk -words
1682.Op Fl 2 | 5
1683.Op Fl check
1684.Op Fl dsaparam
1685.Op Fl in Ar file
1686.Op Fl inform Cm der | pem
1687.Op Fl noout
1688.Op Fl out Ar file
1689.Op Fl outform Cm der | pem
1690.Op Fl text
1691.Op Ar numbits
1692.Ek
1693.El
1694.Pp
1695The
1696.Nm dhparam
1697command is used to manipulate DH parameter files.
1698Only the older PKCS#3 DH is supported,
1699not the newer X9.42 DH.
1700.Pp
1701The options are as follows:
1702.Bl -tag -width Ds
1703.It Fl 2 , 5
1704The generator to use;
17052 is the default.
1706If present, the input file is ignored and parameters are generated instead.
1707.It Fl check
1708Check the DH parameters.
1709.It Fl dsaparam
1710Read or create DSA parameters,
1711converted to DH format on output.
1712Otherwise,
1713.Qq strong
1714primes
1715.Pq such that (p-1)/2 is also prime
1716will be used for DH parameter generation.
1717.Pp
1718DH parameter generation with the
1719.Fl dsaparam
1720option is much faster,
1721and the recommended exponent length is shorter,
1722which makes DH key exchange more efficient.
1723Beware that with such DSA-style DH parameters,
1724a fresh DH key should be created for each use to
1725avoid small-subgroup attacks that may be possible otherwise.
1726.It Fl in Ar file
1727The input file to read from,
1728or standard input if not specified.
1729.It Fl inform Cm der | pem
1730The input format.
1731.It Fl noout
1732Do not output the encoded version of the parameters.
1733.It Fl out Ar file
1734The output file to write to,
1735or standard output if not specified.
1736.It Fl outform Cm der | pem
1737The output format.
1738.It Fl text
1739Print the DH parameters in plain text.
1740.It Ar numbits
1741Generate a parameter set of size
1742.Ar numbits .
1743It must be the last option.
1744If not present, a value of 2048 is used.
1745If this value is present, the input file is ignored and
1746parameters are generated instead.
1747.El
1748.Tg dsa
1749.Sh DSA
1750.Bl -hang -width "openssl dsa"
1751.It Nm openssl dsa
1752.Bk -words
1753.Oo
1754.Fl aes128 | aes192 | aes256 |
1755.Fl des | des3
1756.Oc
1757.Op Fl in Ar file
1758.Op Fl inform Cm der | pem | pvk
1759.Op Fl modulus
1760.Op Fl noout
1761.Op Fl out Ar file
1762.Op Fl outform Cm der | pem | pvk
1763.Op Fl passin Ar arg
1764.Op Fl passout Ar arg
1765.Op Fl pubin
1766.Op Fl pubout
1767.Op Fl pvk-none | pvk-strong | pvk-weak
1768.Op Fl text
1769.Ek
1770.El
1771.Pp
1772The
1773.Nm dsa
1774command processes DSA keys.
1775They can be converted between various forms and their components printed out.
1776.Pp
1777.Sy Note :
1778This command uses the traditional
1779.Nm SSLeay
1780compatible format for private key encryption:
1781newer applications should use the more secure PKCS#8 format using the
1782.Nm pkcs8
1783command.
1784.Pp
1785The options are as follows:
1786.Bl -tag -width Ds
1787.It Xo
1788.Fl aes128 | aes192 | aes256 |
1789.Fl des | des3
1790.Xc
1791Encrypt the private key with the AES, DES, or the triple DES
1792ciphers, respectively, before outputting it.
1793A pass phrase is prompted for.
1794If none of these options are specified, the key is written in plain text.
1795This means that using the
1796.Nm dsa
1797utility to read an encrypted key with no encryption option can be used to
1798remove the pass phrase from a key,
1799or by setting the encryption options it can be used to add or change
1800the pass phrase.
1801These options can only be used with PEM format output files.
1802.It Fl in Ar file
1803The input file to read from,
1804or standard input if not specified.
1805If the key is encrypted, a pass phrase will be prompted for.
1806.It Fl inform Cm der | pem | pvk
1807The input format.
1808.It Fl modulus
1809Print the value of the public key component of the key.
1810.It Fl noout
1811Do not output the encoded version of the key.
1812.It Fl out Ar file
1813The output file to write to,
1814or standard output if not specified.
1815If any encryption options are set then a pass phrase will be
1816prompted for.
1817.It Fl outform Cm der | pem | pvk
1818The output format.
1819.It Fl passin Ar arg
1820The key password source.
1821.It Fl passout Ar arg
1822The output file password source.
1823.It Fl pubin
1824Read in a public key, not a private key.
1825.It Fl pubout
1826Output a public key, not a private key.
1827Automatically set if the input is a public key.
1828.It Xo
1829.Fl pvk-none | pvk-strong | pvk-weak
1830.Xc
1831Enable or disable PVK encoding.
1832The default is
1833.Fl pvk-strong .
1834.It Fl text
1835Print the public/private key in plain text.
1836.El
1837.Tg dsaparam
1838.Sh DSAPARAM
1839.Bl -hang -width "openssl dsaparam"
1840.It Nm openssl dsaparam
1841.Bk -words
1842.Op Fl genkey
1843.Op Fl in Ar file
1844.Op Fl inform Cm der | pem
1845.Op Fl noout
1846.Op Fl out Ar file
1847.Op Fl outform Cm der | pem
1848.Op Fl text
1849.Op Ar numbits
1850.Ek
1851.El
1852.Pp
1853The
1854.Nm dsaparam
1855command is used to manipulate or generate DSA parameter files.
1856.Pp
1857The options are as follows:
1858.Bl -tag -width Ds
1859.It Fl genkey
1860Generate a DSA key either using the specified or generated
1861parameters.
1862.It Fl in Ar file
1863The input file to read from,
1864or standard input if not specified.
1865If the
1866.Ar numbits
1867parameter is included, then this option is ignored.
1868.It Fl inform Cm der | pem
1869The input format.
1870.It Fl noout
1871Do not output the encoded version of the parameters.
1872.It Fl out Ar file
1873The output file to write to,
1874or standard output if not specified.
1875.It Fl outform Cm der | pem
1876The output format.
1877.It Fl text
1878Print the DSA parameters in plain text.
1879.It Ar numbits
1880Generate a parameter set of size
1881.Ar numbits .
1882If this option is included, the input file is ignored.
1883.El
1884.Tg ec
1885.Sh EC
1886.Bl -hang -width "openssl ec"
1887.It Nm openssl ec
1888.Bk -words
1889.Op Fl conv_form Ar arg
1890.Op Fl des
1891.Op Fl des3
1892.Op Fl in Ar file
1893.Op Fl inform Cm der | pem
1894.Op Fl noout
1895.Op Fl out Ar file
1896.Op Fl outform Cm der | pem
1897.Op Fl param_enc Ar arg
1898.Op Fl param_out
1899.Op Fl passin Ar arg
1900.Op Fl passout Ar arg
1901.Op Fl pubin
1902.Op Fl pubout
1903.Op Fl text
1904.Ek
1905.El
1906.Pp
1907The
1908.Nm ec
1909command processes EC keys.
1910They can be converted between various
1911forms and their components printed out.
1912.Nm openssl
1913uses the private key format specified in
1914.Dq SEC 1: Elliptic Curve Cryptography
1915.Pq Lk https://www.secg.org/ .
1916To convert an
1917EC private key into the PKCS#8 private key format use the
1918.Nm pkcs8
1919command.
1920.Pp
1921The options are as follows:
1922.Bl -tag -width Ds
1923.It Fl conv_form Ar arg
1924Specify how the points on the elliptic curve are converted
1925into octet strings.
1926Possible values are:
1927.Cm compressed ,
1928.Cm uncompressed
1929(the default),
1930and
1931.Cm hybrid .
1932For more information regarding
1933the point conversion forms see the X9.62 standard.
1934Note:
1935Due to patent issues the
1936.Cm compressed
1937option is disabled by default for binary curves
1938and can be enabled by defining the preprocessor macro
1939.Dv OPENSSL_EC_BIN_PT_COMP
1940at compile time.
1941.It Fl des | des3
1942Encrypt the private key with DES, triple DES, or
1943any other cipher supported by
1944.Nm openssl .
1945A pass phrase is prompted for.
1946If none of these options are specified, the key is written in plain text.
1947This means that using the
1948.Nm ec
1949utility to read in an encrypted key with no
1950encryption option can be used to remove the pass phrase from a key,
1951or by setting the encryption options
1952it can be used to add or change the pass phrase.
1953These options can only be used with PEM format output files.
1954.It Fl in Ar file
1955The input file to read a key from,
1956or standard input if not specified.
1957If the key is encrypted, a pass phrase will be prompted for.
1958.It Fl inform Cm der | pem
1959The input format.
1960.It Fl noout
1961Do not output the encoded version of the key.
1962.It Fl out Ar file
1963The output filename to write to,
1964or standard output if not specified.
1965If any encryption options are set then a pass phrase will be prompted for.
1966.It Fl outform Cm der | pem
1967The output format.
1968.It Fl param_enc Ar arg
1969Specify how the elliptic curve parameters are encoded.
1970Possible value are:
1971.Cm named_curve ,
1972i.e. the EC parameters are specified by an OID; or
1973.Cm explicit ,
1974where the EC parameters are explicitly given
1975(see RFC 3279 for the definition of the EC parameter structures).
1976The default value is
1977.Cm named_curve .
1978Note: the
1979.Cm implicitlyCA
1980alternative,
1981as specified in RFC 3279,
1982is currently not implemented.
1983.It Fl param_out
1984Print the elliptic curve parameters.
1985.It Fl passin Ar arg
1986The key password source.
1987.It Fl passout Ar arg
1988The output file password source.
1989.It Fl pubin
1990Read in a public key, not a private key.
1991.It Fl pubout
1992Output a public key, not a private key.
1993Automatically set if the input is a public key.
1994.It Fl text
1995Print the public/private key in plain text.
1996.El
1997.Tg ecparam
1998.Sh ECPARAM
1999.Bl -hang -width "openssl ecparam"
2000.It Nm openssl ecparam
2001.Bk -words
2002.Op Fl check
2003.Op Fl conv_form Ar arg
2004.Op Fl genkey
2005.Op Fl in Ar file
2006.Op Fl inform Cm der | pem
2007.Op Fl list_curves
2008.Op Fl name Ar arg
2009.Op Fl no_seed
2010.Op Fl noout
2011.Op Fl out Ar file
2012.Op Fl outform Cm der | pem
2013.Op Fl param_enc Ar arg
2014.Op Fl text
2015.Ek
2016.El
2017.Pp
2018The
2019.Nm ecparam
2020command is used to manipulate or generate EC parameter files.
2021.Nm openssl
2022is not able to generate new groups so
2023.Nm ecparam
2024can only create EC parameters from known (named) curves.
2025.Pp
2026The options are as follows:
2027.Bl -tag -width Ds
2028.It Fl check
2029Validate the elliptic curve parameters.
2030.It Fl conv_form Ar arg
2031Specify how the points on the elliptic curve are converted
2032into octet strings.
2033Possible values are:
2034.Cm compressed ,
2035.Cm uncompressed
2036(the default),
2037and
2038.Cm hybrid .
2039For more information regarding
2040the point conversion forms see the X9.62 standard.
2041Note:
2042Due to patent issues the
2043.Cm compressed
2044option is disabled by default for binary curves
2045and can be enabled by defining the preprocessor macro
2046.Dv OPENSSL_EC_BIN_PT_COMP
2047at compile time.
2048.It Fl genkey
2049Generate an EC private key using the specified parameters.
2050.It Fl in Ar file
2051The input file to read from,
2052or standard input if not specified.
2053.It Fl inform Cm der | pem
2054The input format.
2055.It Fl list_curves
2056Print a list of all
2057currently implemented EC parameter names and exit.
2058.It Fl name Ar arg
2059Use the EC parameters with the specified "short" name.
2060.It Fl no_seed
2061Do not include the seed for the parameter generation
2062in the ECParameters structure (see RFC 3279).
2063.It Fl noout
2064Do not output the encoded version of the parameters.
2065.It Fl out Ar file
2066The output file to write to,
2067or standard output if not specified.
2068.It Fl outform Cm der | pem
2069The output format.
2070.It Fl param_enc Ar arg
2071Specify how the elliptic curve parameters are encoded.
2072Possible value are:
2073.Cm named_curve ,
2074i.e. the EC parameters are specified by an OID, or
2075.Cm explicit ,
2076where the EC parameters are explicitly given
2077(see RFC 3279 for the definition of the EC parameter structures).
2078The default value is
2079.Cm named_curve .
2080Note: the
2081.Cm implicitlyCA
2082alternative, as specified in RFC 3279,
2083is currently not implemented.
2084.It Fl text
2085Print the EC parameters in plain text.
2086.El
2087.Tg enc
2088.Sh ENC
2089.Bl -hang -width "openssl enc"
2090.It Nm openssl enc
2091.Bk -words
2092.Fl ciphername
2093.Op Fl AadePpv
2094.Op Fl base64
2095.Op Fl bufsize Ar number
2096.Op Fl debug
2097.Op Fl in Ar file
2098.Op Fl iter Ar iterations
2099.Op Fl iv Ar IV
2100.Op Fl K Ar key
2101.Op Fl k Ar password
2102.Op Fl kfile Ar file
2103.Op Fl md Ar digest
2104.Op Fl none
2105.Op Fl nopad
2106.Op Fl nosalt
2107.Op Fl out Ar file
2108.Op Fl pass Ar arg
2109.Op Fl pbkdf2
2110.Op Fl S Ar salt
2111.Op Fl salt
2112.Ek
2113.El
2114.Pp
2115The symmetric cipher commands allow data to be encrypted or decrypted
2116using various block and stream ciphers using keys based on passwords
2117or explicitly provided.
2118Base64 encoding or decoding can also be performed either by itself
2119or in addition to the encryption or decryption.
2120The program can be called either as
2121.Nm openssl Ar ciphername
2122or
2123.Nm openssl enc - Ns Ar ciphername .
2124.Pp
2125Some of the ciphers do not have large keys and others have security
2126implications if not used correctly.
2127All the block ciphers normally use PKCS#5 padding,
2128also known as standard block padding.
2129If padding is disabled, the input data must be a multiple of the cipher
2130block length.
2131.Pp
2132The options are as follows:
2133.Bl -tag -width Ds
2134.It Fl A
2135If the
2136.Fl a
2137option is set, then base64 process the data on one line.
2138.It Fl a , base64
2139Base64 process the data.
2140This means that if encryption is taking place, the data is base64-encoded
2141after encryption.
2142If decryption is set, the input data is base64-decoded before
2143being decrypted.
2144.It Fl bufsize Ar number
2145Set the buffer size for I/O.
2146.It Fl d
2147Decrypt the input data.
2148.It Fl debug
2149Debug the BIOs used for I/O.
2150.It Fl e
2151Encrypt the input data.
2152This is the default.
2153.It Fl in Ar file
2154The input file to read from,
2155or standard input if not specified.
2156.It Fl iter Ar iterations
2157Use the pbkdf2 key derivation function, with
2158.Ar iterations
2159as the number of iterations.
2160.It Fl iv Ar IV
2161The actual
2162.Ar IV
2163.Pq initialisation vector
2164to use:
2165this must be represented as a string comprised only of hex digits.
2166When only the
2167.Ar key
2168is specified using the
2169.Fl K
2170option,
2171the IV must explicitly be defined.
2172When a password is being specified using one of the other options,
2173the IV is generated from this password.
2174.It Fl K Ar key
2175The actual
2176.Ar key
2177to use:
2178this must be represented as a string comprised only of hex digits.
2179If only the key is specified,
2180the IV must also be specified using the
2181.Fl iv
2182option.
2183When both a
2184.Ar key
2185and a
2186.Ar password
2187are specified, the
2188.Ar key
2189given with the
2190.Fl K
2191option will be used and the IV generated from the password will be taken.
2192It probably does not make much sense to specify both
2193.Ar key
2194and
2195.Ar password .
2196.It Fl k Ar password
2197The
2198.Ar password
2199to derive the key from.
2200Superseded by the
2201.Fl pass
2202option.
2203.It Fl kfile Ar file
2204Read the password to derive the key from the first line of
2205.Ar file .
2206Superseded by the
2207.Fl pass
2208option.
2209.It Fl md Ar digest
2210Use
2211.Ar digest
2212to create a key from a pass phrase.
2213Currently, the default value is
2214.Cm sha256 .
2215.It Fl none
2216Use NULL cipher (no encryption or decryption of input).
2217.It Fl nopad
2218Disable standard block padding.
2219.It Fl nosalt
2220Don't use a salt in the key derivation routines.
2221This option should never be used
2222since it makes it possible to perform efficient dictionary
2223attacks on the password and to attack stream cipher encrypted data.
2224.It Fl out Ar file
2225The output file to write to,
2226or standard output if not specified.
2227.It Fl P
2228Print out the salt, key, and IV used, then immediately exit;
2229don't do any encryption or decryption.
2230.It Fl p
2231Print out the salt, key, and IV used.
2232.It Fl pass Ar arg
2233The password source.
2234.It Fl pbkdf2
2235Use the pbkdf2 key derivation function, with
2236the default of 10000 iterations.
2237.It Fl S Ar salt
2238The actual
2239.Ar salt
2240to use:
2241this must be represented as a string comprised only of hex digits.
2242.It Fl salt
2243Use a salt in the key derivation routines (the default).
2244When the salt is being used,
2245the first eight bytes of the encrypted data are reserved for the salt:
2246it is randomly generated when encrypting a file and read from the
2247encrypted file when it is decrypted.
2248.It Fl v
2249Print extra details about the processing.
2250.El
2251.Tg errstr
2252.Sh ERRSTR
2253.Nm openssl errstr
2254.Ar errno ...
2255.Pp
2256The
2257.Nm errstr
2258command performs error number to error string conversion,
2259generating a human-readable string representing the error code
2260.Ar errno .
2261The string is obtained through the
2262.Xr ERR_error_string_n 3
2263function and has the following format:
2264.Pp
2265.Dl error:[error code]:[library name]:[function name]:[reason string]
2266.Pp
2267.Bq error code
2268is an 8-digit hexadecimal number.
2269The remaining fields
2270.Bq library name ,
2271.Bq function name ,
2272and
2273.Bq reason string
2274are all ASCII text.
2275.Tg gendsa
2276.Sh GENDSA
2277.Bl -hang -width "openssl gendsa"
2278.It Nm openssl gendsa
2279.Bk -words
2280.Oo
2281.Fl aes128 | aes192 | aes256 | camellia128 |
2282.Fl camellia192 | camellia256 | des | des3 | idea
2283.Oc
2284.Op Fl out Ar file
2285.Op Fl passout Ar arg
2286.Ar paramfile
2287.Ek
2288.El
2289.Pp
2290The
2291.Nm gendsa
2292command generates a DSA private key from a DSA parameter file
2293(typically generated by the
2294.Nm openssl dsaparam
2295command).
2296DSA key generation is little more than random number generation so it is
2297much quicker than,
2298for example,
2299RSA key generation.
2300.Pp
2301The options are as follows:
2302.Bl -tag -width Ds
2303.It Xo
2304.Fl aes128 | aes192 | aes256 |
2305.Fl camellia128 | camellia192 | camellia256 |
2306.Fl des | des3 |
2307.Fl idea
2308.Xc
2309Encrypt the private key with the AES, CAMELLIA, DES, triple DES
2310or the IDEA ciphers, respectively, before outputting it.
2311A pass phrase is prompted for.
2312If none of these options are specified, no encryption is used.
2313.It Fl out Ar file
2314The output file to write to,
2315or standard output if not specified.
2316.It Fl passout Ar arg
2317The output file password source.
2318.It Ar paramfile
2319Specify the DSA parameter file to use.
2320The parameters in this file determine the size of the private key.
2321.El
2322.Tg genpkey
2323.Sh GENPKEY
2324.Bl -hang -width "openssl genpkey"
2325.It Nm openssl genpkey
2326.Bk -words
2327.Op Fl algorithm Ar alg
2328.Op Ar cipher
2329.Op Fl genparam
2330.Op Fl out Ar file
2331.Op Fl outform Cm der | pem
2332.Op Fl paramfile Ar file
2333.Op Fl pass Ar arg
2334.Op Fl pkeyopt Ar opt : Ns Ar value
2335.Op Fl text
2336.Ek
2337.El
2338.Pp
2339The
2340.Nm genpkey
2341command generates private keys.
2342The use of this
2343program is encouraged over the algorithm specific utilities
2344because additional algorithm options can be used.
2345.Pp
2346The options are as follows:
2347.Bl -tag -width Ds
2348.It Fl algorithm Ar alg
2349The public key algorithm to use,
2350such as RSA, DSA, or DH.
2351This option must precede any
2352.Fl pkeyopt
2353options.
2354The options
2355.Fl paramfile
2356and
2357.Fl algorithm
2358are mutually exclusive.
2359.It Ar cipher
2360Encrypt the private key with the supplied cipher.
2361Any algorithm name accepted by
2362.Xr EVP_get_cipherbyname 3
2363is acceptable.
2364.It Fl genparam
2365Generate a set of parameters instead of a private key.
2366This option must precede any
2367.Fl algorithm ,
2368.Fl paramfile ,
2369or
2370.Fl pkeyopt
2371options.
2372.It Fl out Ar file
2373The output file to write to,
2374or standard output if not specified.
2375.It Fl outform Cm der | pem
2376The output format.
2377.It Fl paramfile Ar file
2378Some public key algorithms generate a private key based on a set of parameters,
2379which can be supplied using this option.
2380If this option is used, the public key
2381algorithm used is determined by the parameters.
2382This option must precede any
2383.Fl pkeyopt
2384options.
2385The options
2386.Fl paramfile
2387and
2388.Fl algorithm
2389are mutually exclusive.
2390.It Fl pass Ar arg
2391The output file password source.
2392.It Fl pkeyopt Ar opt : Ns Ar value
2393Set the public key algorithm option
2394.Ar opt
2395to
2396.Ar value ,
2397as follows:
2398.Bl -tag -width Ds -offset indent
2399.It rsa_keygen_bits : Ns Ar numbits
2400(RSA)
2401The number of bits in the generated key.
2402The default is 2048.
2403.It rsa_keygen_pubexp : Ns Ar value
2404(RSA)
2405The RSA public exponent value.
2406This can be a large decimal or hexadecimal value if preceded by 0x.
2407The default is 65537.
2408.It dsa_paramgen_bits : Ns Ar numbits
2409(DSA)
2410The number of bits in the generated parameters.
2411The default is 1024.
2412.It dh_paramgen_prime_len : Ns Ar numbits
2413(DH)
2414The number of bits in the prime parameter
2415.Ar p .
2416.It dh_paramgen_generator : Ns Ar value
2417(DH)
2418The value to use for the generator
2419.Ar g .
2420.It ec_paramgen_curve : Ns Ar curve
2421(EC)
2422The elliptic curve to use.
2423.El
2424.It Fl text
2425Print the private/public key in plain text.
2426.El
2427.Tg genrsa
2428.Sh GENRSA
2429.Bl -hang -width "openssl genrsa"
2430.It Nm openssl genrsa
2431.Bk -words
2432.Op Fl 3 | f4
2433.Oo
2434.Fl aes128 | aes192 | aes256 | camellia128 |
2435.Fl camellia192 | camellia256 | des | des3 | idea
2436.Oc
2437.Op Fl out Ar file
2438.Op Fl passout Ar arg
2439.Op Ar numbits
2440.Ek
2441.El
2442.Pp
2443The
2444.Nm genrsa
2445command generates an RSA private key,
2446which essentially involves the generation of two prime numbers.
2447When generating the key,
2448various symbols will be output to indicate the progress of the generation.
2449A
2450.Sq \&.
2451represents each number which has passed an initial sieve test;
2452.Sq +
2453means a number has passed a single round of the Miller-Rabin primality test;
2454.Sq *
2455means the number has failed primality testing
2456and needs to be generated afresh.
2457A newline means that the number has passed all the prime tests
2458(the actual number depends on the key size).
2459.Pp
2460The options are as follows:
2461.Bl -tag -width Ds
2462.It Fl 3 | f4
2463The public exponent to use, either 3 or 65537.
2464The default is 65537.
2465.It Xo
2466.Fl aes128 | aes192 | aes256 |
2467.Fl camellia128 | camellia192 | camellia256 |
2468.Fl des | des3 |
2469.Fl idea
2470.Xc
2471Encrypt the private key with the AES, CAMELLIA, DES, triple DES
2472or the IDEA ciphers, respectively, before outputting it.
2473If none of these options are specified, no encryption is used.
2474If encryption is used, a pass phrase is prompted for,
2475if it is not supplied via the
2476.Fl passout
2477option.
2478.It Fl out Ar file
2479The output file to write to,
2480or standard output if not specified.
2481.It Fl passout Ar arg
2482The output file password source.
2483.It Ar numbits
2484The size of the private key to generate in bits.
2485This must be the last option specified.
2486The default is 2048.
2487.El
2488.Tg ocsp
2489.Sh OCSP
2490.Bl -hang -width "openssl ocsp"
2491.It Nm openssl ocsp
2492.Bk -words
2493.Op Fl CA Ar file
2494.Op Fl CAfile Ar file
2495.Op Fl CApath Ar directory
2496.Op Fl cert Ar file
2497.Op Fl dgst Ar alg
2498.Op Fl header Ar name value
2499.Op Fl host Ar hostname : Ns Ar port
2500.Op Fl ignore_err
2501.Op Fl index Ar indexfile
2502.Op Fl issuer Ar file
2503.Op Fl ndays Ar days
2504.Op Fl nmin Ar minutes
2505.Op Fl no_cert_checks
2506.Op Fl no_cert_verify
2507.Op Fl no_certs
2508.Op Fl no_chain
2509.Op Fl no_explicit
2510.Op Fl no_intern
2511.Op Fl no_nonce
2512.Op Fl no_signature_verify
2513.Op Fl nonce
2514.Op Fl noverify
2515.Op Fl nrequest Ar number
2516.Op Fl out Ar file
2517.Op Fl path Ar path
2518.Op Fl port Ar portnum
2519.Op Fl req_text
2520.Op Fl reqin Ar file
2521.Op Fl reqout Ar file
2522.Op Fl resp_key_id
2523.Op Fl resp_no_certs
2524.Op Fl resp_text
2525.Op Fl respin Ar file
2526.Op Fl respout Ar file
2527.Op Fl rkey Ar file
2528.Op Fl rother Ar file
2529.Op Fl rsigner Ar file
2530.Op Fl serial Ar num
2531.Op Fl sign_other Ar file
2532.Op Fl signer Ar file
2533.Op Fl signkey Ar file
2534.Op Fl status_age Ar age
2535.Op Fl text
2536.Op Fl timeout Ar seconds
2537.Op Fl trust_other
2538.Op Fl url Ar responder_url
2539.Op Fl VAfile Ar file
2540.Op Fl validity_period Ar nsec
2541.Op Fl verify_other Ar file
2542.Ek
2543.El
2544.Pp
2545The Online Certificate Status Protocol (OCSP)
2546enables applications to determine the (revocation) state
2547of an identified certificate (RFC 2560).
2548.Pp
2549The
2550.Nm ocsp
2551command performs many common OCSP tasks.
2552It can be used to print out requests and responses,
2553create requests and send queries to an OCSP responder,
2554and behave like a mini OCSP server itself.
2555.Pp
2556The options are as follows:
2557.Bl -tag -width Ds
2558.It Fl CAfile Ar file , Fl CApath Ar directory
2559A file or path containing trusted CA certificates,
2560used to verify the signature on the OCSP response.
2561.It Fl cert Ar file
2562Add the certificate
2563.Ar file
2564to the request.
2565The issuer certificate is taken from the previous
2566.Fl issuer
2567option, or an error occurs if no issuer certificate is specified.
2568.It Fl dgst Ar alg
2569Use the digest algorithm
2570.Ar alg
2571for certificate identification in the OCSP request.
2572By default SHA1 is used.
2573.It Xo
2574.Fl host Ar hostname : Ns Ar port ,
2575.Fl path Ar path
2576.Xc
2577Send
2578the OCSP request to
2579.Ar hostname
2580on
2581.Ar port .
2582.Fl path
2583specifies the HTTP path name to use, or
2584.Pa /
2585by default.
2586.It Fl header Ar name value
2587Add the header name with the specified value to the OCSP request that is sent
2588to the responder.
2589This may be repeated.
2590.It Fl issuer Ar file
2591The current issuer certificate, in PEM format.
2592Can be used multiple times and must come before any
2593.Fl cert
2594options.
2595.It Fl no_cert_checks
2596Don't perform any additional checks on the OCSP response signer's certificate.
2597That is, do not make any checks to see if the signer's certificate is
2598authorised to provide the necessary status information:
2599as a result this option should only be used for testing purposes.
2600.It Fl no_cert_verify
2601Don't verify the OCSP response signer's certificate at all.
2602Since this option allows the OCSP response to be signed by any certificate,
2603it should only be used for testing purposes.
2604.It Fl no_certs
2605Don't include any certificates in the signed request.
2606.It Fl no_chain
2607Do not use certificates in the response as additional untrusted CA
2608certificates.
2609.It Fl no_explicit
2610Don't check the explicit trust for OCSP signing in the root CA certificate.
2611.It Fl no_intern
2612Ignore certificates contained in the OCSP response
2613when searching for the signer's certificate.
2614The signer's certificate must be specified with either the
2615.Fl verify_other
2616or
2617.Fl VAfile
2618options.
2619.It Fl no_signature_verify
2620Don't check the signature on the OCSP response.
2621Since this option tolerates invalid signatures on OCSP responses,
2622it will normally only be used for testing purposes.
2623.It Fl nonce , no_nonce
2624Add an OCSP nonce extension to a request,
2625or disable an OCSP nonce addition.
2626Normally, if an OCSP request is input using the
2627.Fl respin
2628option no nonce is added:
2629using the
2630.Fl nonce
2631option will force the addition of a nonce.
2632If an OCSP request is being created (using the
2633.Fl cert
2634and
2635.Fl serial
2636options),
2637a nonce is automatically added; specifying
2638.Fl no_nonce
2639overrides this.
2640.It Fl noverify
2641Don't attempt to verify the OCSP response signature or the nonce values.
2642This is normally only be used for debugging
2643since it disables all verification of the responder's certificate.
2644.It Fl out Ar file
2645Specify the output file to write to,
2646or standard output if not specified.
2647.It Fl req_text , resp_text , text
2648Print out the text form of the OCSP request, response, or both, respectively.
2649.It Fl reqin Ar file , Fl respin Ar file
2650Read an OCSP request or response file from
2651.Ar file .
2652These options are ignored
2653if an OCSP request or response creation is implied by other options
2654(for example with the
2655.Fl serial , cert ,
2656and
2657.Fl host
2658options).
2659.It Fl reqout Ar file , Fl respout Ar file
2660Write out the DER-encoded certificate request or response to
2661.Ar file .
2662.It Fl serial Ar num
2663Same as the
2664.Fl cert
2665option except the certificate with serial number
2666.Ar num
2667is added to the request.
2668The serial number is interpreted as a decimal integer unless preceded by
2669.Sq 0x .
2670Negative integers can also be specified
2671by preceding the value with a minus sign.
2672.It Fl sign_other Ar file
2673Additional certificates to include in the signed request.
2674.It Fl signer Ar file , Fl signkey Ar file
2675Sign the OCSP request using the certificate specified in the
2676.Fl signer
2677option and the private key specified by the
2678.Fl signkey
2679option.
2680If the
2681.Fl signkey
2682option is not present, then the private key is read from the same file
2683as the certificate.
2684If neither option is specified, the OCSP request is not signed.
2685.It Fl timeout Ar seconds
2686Connection timeout to the OCSP responder in seconds.
2687.It Fl trust_other
2688The certificates specified by the
2689.Fl verify_other
2690option should be explicitly trusted and no additional checks will be
2691performed on them.
2692This is useful when the complete responder certificate chain is not available
2693or trusting a root CA is not appropriate.
2694.It Fl url Ar responder_url
2695Specify the responder URL.
2696Both HTTP and HTTPS
2697.Pq SSL/TLS
2698URLs can be specified.
2699.It Fl VAfile Ar file
2700A file containing explicitly trusted responder certificates.
2701Equivalent to the
2702.Fl verify_other
2703and
2704.Fl trust_other
2705options.
2706.It Fl validity_period Ar nsec , Fl status_age Ar age
2707The range of times, in seconds, which will be tolerated in an OCSP response.
2708Each certificate status response includes a notBefore time
2709and an optional notAfter time.
2710The current time should fall between these two values,
2711but the interval between the two times may be only a few seconds.
2712In practice the OCSP responder and clients' clocks may not be precisely
2713synchronised and so such a check may fail.
2714To avoid this the
2715.Fl validity_period
2716option can be used to specify an acceptable error range in seconds,
2717the default value being 5 minutes.
2718.Pp
2719If the notAfter time is omitted from a response,
2720it means that new status information is immediately available.
2721In this case the age of the notBefore field is checked
2722to see it is not older than
2723.Ar age
2724seconds old.
2725By default, this additional check is not performed.
2726.It Fl verify_other Ar file
2727A file containing additional certificates to search
2728when attempting to locate the OCSP response signing certificate.
2729Some responders omit the actual signer's certificate from the response,
2730so this can be used to supply the necessary certificate.
2731.El
2732.Pp
2733The options for the OCSP server are as follows:
2734.Bl -tag -width "XXXX"
2735.It Fl CA Ar file
2736CA certificate corresponding to the revocation information in
2737.Ar indexfile .
2738.It Fl ignore_err
2739Ignore the invalid response.
2740.It Fl index Ar indexfile
2741.Ar indexfile
2742is a text index file in ca format
2743containing certificate revocation information.
2744.Pp
2745If this option is specified,
2746.Nm ocsp
2747is in responder mode, otherwise it is in client mode.
2748The requests the responder processes can be either specified on
2749the command line (using the
2750.Fl issuer
2751and
2752.Fl serial
2753options), supplied in a file (using the
2754.Fl respin
2755option), or via external OCSP clients (if
2756.Ar port
2757or
2758.Ar url
2759is specified).
2760.Pp
2761If this option is present, then the
2762.Fl CA
2763and
2764.Fl rsigner
2765options must also be present.
2766.It Fl nmin Ar minutes , Fl ndays Ar days
2767Number of
2768.Ar minutes
2769or
2770.Ar days
2771when fresh revocation information is available:
2772used in the nextUpdate field.
2773If neither option is present,
2774the nextUpdate field is omitted,
2775meaning fresh revocation information is immediately available.
2776.It Fl nrequest Ar number
2777Exit after receiving
2778.Ar number
2779requests (the default is unlimited).
2780.It Fl port Ar portnum
2781Port to listen for OCSP requests on.
2782May also be specified using the
2783.Fl url
2784option.
2785.It Fl resp_key_id
2786Identify the signer certificate using the key ID;
2787the default is to use the subject name.
2788.It Fl resp_no_certs
2789Don't include any certificates in the OCSP response.
2790.It Fl rkey Ar file
2791The private key to sign OCSP responses with;
2792if not present, the file specified in the
2793.Fl rsigner
2794option is used.
2795.It Fl rother Ar file
2796Additional certificates to include in the OCSP response.
2797.It Fl rsigner Ar file
2798The certificate to sign OCSP responses with.
2799.El
2800.Pp
2801Initially the OCSP responder certificate is located and the signature on
2802the OCSP request checked using the responder certificate's public key.
2803Then a normal certificate verify is performed on the OCSP responder certificate
2804building up a certificate chain in the process.
2805The locations of the trusted certificates used to build the chain can be
2806specified by the
2807.Fl CAfile
2808and
2809.Fl CApath
2810options or they will be looked for in the standard
2811.Nm openssl
2812certificates directory.
2813.Pp
2814If the initial verify fails, the OCSP verify process halts with an error.
2815Otherwise the issuing CA certificate in the request is compared to the OCSP
2816responder certificate: if there is a match then the OCSP verify succeeds.
2817.Pp
2818Otherwise the OCSP responder certificate's CA is checked against the issuing
2819CA certificate in the request.
2820If there is a match and the OCSPSigning extended key usage is present
2821in the OCSP responder certificate, then the OCSP verify succeeds.
2822.Pp
2823Otherwise the root CA of the OCSP responder's CA is checked to see if it
2824is trusted for OCSP signing.
2825If it is, the OCSP verify succeeds.
2826.Pp
2827If none of these checks is successful, the OCSP verify fails.
2828What this effectively means is that if the OCSP responder certificate is
2829authorised directly by the CA it is issuing revocation information about
2830(and it is correctly configured),
2831then verification will succeed.
2832.Pp
2833If the OCSP responder is a global responder,
2834which can give details about multiple CAs
2835and has its own separate certificate chain,
2836then its root CA can be trusted for OCSP signing.
2837Alternatively, the responder certificate itself can be explicitly trusted
2838with the
2839.Fl VAfile
2840option.
2841.Tg passwd
2842.Sh PASSWD
2843.Bl -hang -width "openssl passwd"
2844.It Nm openssl passwd
2845.Bk -words
2846.Op Fl 1 | apr1 | crypt
2847.Op Fl in Ar file
2848.Op Fl noverify
2849.Op Fl quiet
2850.Op Fl reverse
2851.Op Fl salt Ar string
2852.Op Fl stdin
2853.Op Fl table
2854.Op Ar password
2855.Ek
2856.El
2857.Pp
2858The
2859.Nm passwd
2860command computes the hash of a password.
2861.Pp
2862The options are as follows:
2863.Bl -tag -width Ds
2864.It Fl 1
2865Use the MD5 based
2866.Bx
2867password algorithm
2868.Qq 1 .
2869.It Fl apr1
2870Use the
2871.Qq apr1
2872algorithm
2873.Po
2874Apache variant of the
2875.Bx
2876algorithm
2877.Pc .
2878.It Fl crypt
2879Use the
2880.Qq crypt
2881algorithm (the default).
2882.It Fl in Ar file
2883Read passwords from
2884.Ar file .
2885.It Fl noverify
2886Don't verify when reading a password from the terminal.
2887.It Fl quiet
2888Don't output warnings when passwords given on the command line are truncated.
2889.It Fl reverse
2890Switch table columns.
2891This only makes sense in conjunction with the
2892.Fl table
2893option.
2894.It Fl salt Ar string
2895Use the salt specified by
2896.Ar string .
2897When reading a password from the terminal, this implies
2898.Fl noverify .
2899.It Fl stdin
2900Read passwords from standard input.
2901.It Fl table
2902In the output list, prepend the cleartext password and a TAB character
2903to each password hash.
2904.El
2905.Tg pkcs7
2906.Sh PKCS7
2907.Bl -hang -width "openssl pkcs7"
2908.It Nm openssl pkcs7
2909.Bk -words
2910.Op Fl in Ar file
2911.Op Fl inform Cm der | pem
2912.Op Fl noout
2913.Op Fl out Ar file
2914.Op Fl outform Cm der | pem
2915.Op Fl print
2916.Op Fl print_certs
2917.Op Fl text
2918.Ek
2919.El
2920.Pp
2921The
2922.Nm pkcs7
2923command processes PKCS#7 files in DER or PEM format.
2924The PKCS#7 routines only understand PKCS#7 v 1.5 as specified in RFC 2315.
2925.Pp
2926The options are as follows:
2927.Bl -tag -width Ds
2928.It Fl in Ar file
2929The input file to read from,
2930or standard input if not specified.
2931.It Fl inform Cm der | pem
2932The input format.
2933.It Fl noout
2934Don't output the encoded version of the PKCS#7 structure
2935(or certificates if
2936.Fl print_certs
2937is set).
2938.It Fl out Ar file
2939The output to write to,
2940or standard output if not specified.
2941.It Fl outform Cm der | pem
2942The output format.
2943.It Fl print
2944Print the ASN.1 representation of PKCS#7 structure.
2945.It Fl print_certs
2946Print any certificates or CRLs contained in the file,
2947preceded by their subject and issuer names in a one-line format.
2948.It Fl text
2949Print certificate details in full rather than just subject and issuer names.
2950.El
2951.Tg pkcs8
2952.Sh PKCS8
2953.Bl -hang -width "openssl pkcs8"
2954.It Nm openssl pkcs8
2955.Bk -words
2956.Op Fl in Ar file
2957.Op Fl inform Cm der | pem
2958.Op Fl nocrypt
2959.Op Fl noiter
2960.Op Fl out Ar file
2961.Op Fl outform Cm der | pem
2962.Op Fl passin Ar arg
2963.Op Fl passout Ar arg
2964.Op Fl topk8
2965.Op Fl v1 Ar alg
2966.Op Fl v2 Ar alg
2967.Ek
2968.El
2969.Pp
2970The
2971.Nm pkcs8
2972command processes private keys
2973(both encrypted and unencrypted)
2974in PKCS#8 format
2975with a variety of PKCS#5 (v1.5 and v2.0) and PKCS#12 algorithms.
2976The default encryption is only 56 bits;
2977keys encrypted using PKCS#5 v2.0 algorithms and high iteration counts
2978are more secure.
2979.Pp
2980The options are as follows:
2981.Bl -tag -width Ds
2982.It Fl in Ar file
2983The input file to read from,
2984or standard input if not specified.
2985If the key is encrypted, a pass phrase will be prompted for.
2986.It Fl inform Cm der | pem
2987The input format.
2988.It Fl nocrypt
2989Generate an unencrypted PrivateKeyInfo structure.
2990This option does not encrypt private keys at all
2991and should only be used when absolutely necessary.
2992.It Fl noiter
2993Use an iteration count of 1.
2994See the
2995.Sx PKCS12
2996section below for a detailed explanation of this option.
2997.It Fl out Ar file
2998The output file to write to,
2999or standard output if none is specified.
3000If any encryption options are set, a pass phrase will be prompted for.
3001.It Fl outform Cm der | pem
3002The output format.
3003.It Fl passin Ar arg
3004The key password source.
3005.It Fl passout Ar arg
3006The output file password source.
3007.It Fl topk8
3008Read a traditional format private key and write a PKCS#8 format key.
3009.It Fl v1 Ar alg
3010Specify a PKCS#5 v1.5 or PKCS#12 algorithm to use.
3011.Pp
3012.Bl -tag -width "XXXX" -compact
3013.It PBE-MD5-DES
301456-bit DES.
3015.It PBE-SHA1-RC2-64 | PBE-MD5-RC2-64 | PBE-SHA1-DES
301664-bit RC2 or 56-bit DES.
3017.It PBE-SHA1-RC4-128 | PBE-SHA1-RC4-40 | PBE-SHA1-3DES
3018.It PBE-SHA1-2DES | PBE-SHA1-RC2-128 | PBE-SHA1-RC2-40
3019PKCS#12 password-based encryption algorithm,
3020which allow strong encryption algorithms like triple DES or 128-bit RC2.
3021.El
3022.It Fl v2 Ar alg
3023Use PKCS#5 v2.0 algorithms.
3024Supports algorithms such as 168-bit triple DES or 128-bit RC2,
3025however not many implementations support PKCS#5 v2.0 yet
3026(if using private keys with
3027.Nm openssl
3028this doesn't matter).
3029.Pp
3030.Ar alg
3031is the encryption algorithm to use;
3032valid values include des, des3, and rc2.
3033It is recommended that des3 is used.
3034.El
3035.Tg pkcs12
3036.Sh PKCS12
3037.Bl -hang -width "openssl pkcs12"
3038.It Nm openssl pkcs12
3039.Bk -words
3040.Oo
3041.Fl aes128 | aes192 | aes256 | camellia128 |
3042.Fl camellia192 | camellia256 | des | des3 | idea
3043.Oc
3044.Op Fl cacerts
3045.Op Fl CAfile Ar file
3046.Op Fl caname Ar name
3047.Op Fl CApath Ar directory
3048.Op Fl certfile Ar file
3049.Op Fl certpbe Ar alg
3050.Op Fl chain
3051.Op Fl clcerts
3052.Op Fl descert
3053.Op Fl export
3054.Op Fl in Ar file
3055.Op Fl info
3056.Op Fl inkey Ar file
3057.Op Fl keyex
3058.Op Fl keypbe Ar alg
3059.Op Fl keysig
3060.Op Fl macalg Ar alg
3061.Op Fl maciter
3062.Op Fl name Ar name
3063.Op Fl nocerts
3064.Op Fl nodes
3065.Op Fl noiter
3066.Op Fl nokeys
3067.Op Fl nomac
3068.Op Fl nomaciter
3069.Op Fl nomacver
3070.Op Fl noout
3071.Op Fl out Ar file
3072.Op Fl passin Ar arg
3073.Op Fl passout Ar arg
3074.Op Fl password Ar arg
3075.Op Fl twopass
3076.Ek
3077.El
3078.Pp
3079The
3080.Nm pkcs12
3081command allows PKCS#12 files
3082.Pq sometimes referred to as PFX files
3083to be created and parsed.
3084By default, a PKCS#12 file is parsed;
3085a PKCS#12 file can be created by using the
3086.Fl export
3087option.
3088.Pp
3089The options for parsing a PKCS12 file are as follows:
3090.Bl -tag -width "XXXX"
3091.It Xo
3092.Fl aes128 | aes192 | aes256 |
3093.Fl camellia128 | camellia192 | camellia256 |
3094.Fl des | des3 |
3095.Fl idea
3096.Xc
3097Encrypt private keys using AES, CAMELLIA, DES, triple DES
3098or the IDEA ciphers, respectively.
3099The default is triple DES.
3100.It Fl cacerts
3101Only output CA certificates
3102.Pq not client certificates .
3103.It Fl clcerts
3104Only output client certificates
3105.Pq not CA certificates .
3106.It Fl in Ar file
3107The input file to read from,
3108or standard input if not specified.
3109.It Fl info
3110Output additional information about the PKCS#12 file structure,
3111algorithms used, and iteration counts.
3112.It Fl nocerts
3113Do not output certificates.
3114.It Fl nodes
3115Do not encrypt private keys.
3116.It Fl nokeys
3117Do not output private keys.
3118.It Fl nomacver
3119Do not attempt to verify the integrity MAC before reading the file.
3120.It Fl noout
3121Do not output the keys and certificates to the output file
3122version of the PKCS#12 file.
3123.It Fl out Ar file
3124The output file to write to,
3125or standard output if not specified.
3126.It Fl passin Ar arg
3127The key password source.
3128.It Fl passout Ar arg
3129The output file password source.
3130.It Fl twopass
3131Prompt for separate integrity and encryption passwords: most software
3132always assumes these are the same so this option will render such
3133PKCS#12 files unreadable.
3134.El
3135.Pp
3136The options for PKCS12 file creation are as follows:
3137.Bl -tag -width "XXXX"
3138.It Fl CAfile Ar file
3139CA storage as a file.
3140.It Fl CApath Ar directory
3141CA storage as a directory.
3142The directory must be a standard certificate directory:
3143that is, a hash of each subject name (using
3144.Nm x509 Fl hash )
3145should be linked to each certificate.
3146.It Fl caname Ar name
3147Specify the
3148.Qq friendly name
3149for other certificates.
3150May be used multiple times to specify names for all certificates
3151in the order they appear.
3152.It Fl certfile Ar file
3153A file to read additional certificates from.
3154.It Fl certpbe Ar alg , Fl keypbe Ar alg
3155Specify the algorithm used to encrypt the private key and
3156certificates to be selected.
3157Any PKCS#5 v1.5 or PKCS#12 PBE algorithm name can be used.
3158If a cipher name
3159(as output by the
3160.Cm list-cipher-algorithms
3161command) is specified then it
3162is used with PKCS#5 v2.0.
3163For interoperability reasons it is advisable to only use PKCS#12 algorithms.
3164.It Fl chain
3165Include the entire certificate chain of the user certificate.
3166The standard CA store is used for this search.
3167If the search fails, it is considered a fatal error.
3168.It Fl descert
3169Encrypt the certificate using triple DES; this may render the PKCS#12
3170file unreadable by some
3171.Qq export grade
3172software.
3173By default, the private key is encrypted using triple DES and the
3174certificate using 40-bit RC2.
3175.It Fl export
3176Create a PKCS#12 file (rather than parsing one).
3177.It Fl in Ar file
3178The input file to read from,
3179or standard input if not specified.
3180The order doesn't matter but one private key and its corresponding
3181certificate should be present.
3182If additional certificates are present, they will also be included
3183in the PKCS#12 file.
3184.It Fl inkey Ar file
3185File to read a private key from.
3186If not present, a private key must be present in the input file.
3187.It Fl keyex | keysig
3188Specify whether the private key is to be used for key exchange or just signing.
3189Normally,
3190.Qq export grade
3191software will only allow 512-bit RSA keys to be
3192used for encryption purposes, but arbitrary length keys for signing.
3193The
3194.Fl keysig
3195option marks the key for signing only.
3196Signing only keys can be used for S/MIME signing, authenticode
3197(ActiveX control signing)
3198and SSL client authentication.
3199.It Fl macalg Ar alg
3200Specify the MAC digest algorithm.
3201The default is SHA1.
3202.It Fl maciter
3203Included for compatibility only:
3204it used to be needed to use MAC iterations counts
3205but they are now used by default.
3206.It Fl name Ar name
3207Specify the
3208.Qq friendly name
3209for the certificate and private key.
3210This name is typically displayed in list boxes by software importing the file.
3211.It Fl nomac
3212Don't attempt to provide the MAC integrity.
3213.It Fl nomaciter , noiter
3214Affect the iteration counts on the MAC and key algorithms.
3215.Pp
3216To discourage attacks by using large dictionaries of common passwords,
3217the algorithm that derives keys from passwords can have an iteration count
3218applied to it: this causes a certain part of the algorithm to be repeated
3219and slows it down.
3220The MAC is used to check the file integrity but since it will normally
3221have the same password as the keys and certificates it could also be attacked.
3222By default, both MAC and encryption iteration counts are set to 2048;
3223using these options the MAC and encryption iteration counts can be set to 1.
3224Since this reduces the file security, you should not use these options
3225unless you really have to.
3226Most software supports both MAC and key iteration counts.
3227.It Fl out Ar file
3228The output file to write to,
3229or standard output if not specified.
3230.It Fl passin Ar arg
3231The key password source.
3232.It Fl passout Ar arg
3233The output file password source.
3234.It Fl password Ar arg
3235With
3236.Fl export ,
3237.Fl password
3238is equivalent to
3239.Fl passout .
3240Otherwise,
3241.Fl password
3242is equivalent to
3243.Fl passin .
3244.El
3245.Tg pkey
3246.Sh PKEY
3247.Bl -hang -width "openssl pkey"
3248.It Nm openssl pkey
3249.Bk -words
3250.Op Ar cipher
3251.Op Fl in Ar file
3252.Op Fl inform Cm der | pem
3253.Op Fl noout
3254.Op Fl out Ar file
3255.Op Fl outform Cm der | pem
3256.Op Fl passin Ar arg
3257.Op Fl passout Ar arg
3258.Op Fl pubin
3259.Op Fl pubout
3260.Op Fl text
3261.Op Fl text_pub
3262.Ek
3263.El
3264.Pp
3265The
3266.Nm pkey
3267command processes public or private keys.
3268They can be converted between various forms
3269and their components printed out.
3270.Pp
3271The options are as follows:
3272.Bl -tag -width Ds
3273.It Ar cipher
3274Encrypt the private key with the specified cipher.
3275Any algorithm name accepted by
3276.Xr EVP_get_cipherbyname 3
3277is acceptable, such as
3278.Cm des3 .
3279.It Fl in Ar file
3280The input file to read from,
3281or standard input if not specified.
3282If the key is encrypted, a pass phrase will be prompted for.
3283.It Fl inform Cm der | pem
3284The input format.
3285.It Fl noout
3286Do not output the encoded version of the key.
3287.It Fl out Ar file
3288The output file to write to,
3289or standard output if not specified.
3290If any encryption options are set then a pass phrase
3291will be prompted for.
3292.It Fl outform Cm der | pem
3293The output format.
3294.It Fl passin Ar arg
3295The key password source.
3296.It Fl passout Ar arg
3297The output file password source.
3298.It Fl pubin
3299Read in a public key, not a private key.
3300.It Fl pubout
3301Output a public key, not a private key.
3302Automatically set if the input is a public key.
3303.It Fl text
3304Print the public/private key in plain text.
3305.It Fl text_pub
3306Print out only public key components
3307even if a private key is being processed.
3308.El
3309.Tg pkeyparam
3310.Sh PKEYPARAM
3311.Cm openssl pkeyparam
3312.Op Fl in Ar file
3313.Op Fl noout
3314.Op Fl out Ar file
3315.Op Fl text
3316.Pp
3317The
3318.Nm pkeyparam
3319command processes public or private keys.
3320The key type is determined by the PEM headers.
3321.Pp
3322The options are as follows:
3323.Bl -tag -width Ds
3324.It Fl in Ar file
3325The input file to read from,
3326or standard input if not specified.
3327.It Fl noout
3328Do not output the encoded version of the parameters.
3329.It Fl out Ar file
3330The output file to write to,
3331or standard output if not specified.
3332.It Fl text
3333Print the parameters in plain text.
3334.El
3335.Tg pkeyutl
3336.Sh PKEYUTL
3337.Bl -hang -width "openssl pkeyutl"
3338.It Nm openssl pkeyutl
3339.Bk -words
3340.Op Fl asn1parse
3341.Op Fl certin
3342.Op Fl decrypt
3343.Op Fl derive
3344.Op Fl encrypt
3345.Op Fl hexdump
3346.Op Fl in Ar file
3347.Op Fl inkey Ar file
3348.Op Fl keyform Cm der | pem
3349.Op Fl out Ar file
3350.Op Fl passin Ar arg
3351.Op Fl peerform Cm der | pem
3352.Op Fl peerkey Ar file
3353.Op Fl pkeyopt Ar opt : Ns Ar value
3354.Op Fl pubin
3355.Op Fl rev
3356.Op Fl sigfile Ar file
3357.Op Fl sign
3358.Op Fl verify
3359.Op Fl verifyrecover
3360.Ek
3361.El
3362.Pp
3363The
3364.Nm pkeyutl
3365command can be used to perform public key operations using
3366any supported algorithm.
3367.Pp
3368The options are as follows:
3369.Bl -tag -width Ds
3370.It Fl asn1parse
3371ASN.1 parse the output data.
3372This is useful when combined with the
3373.Fl verifyrecover
3374option when an ASN.1 structure is signed.
3375.It Fl certin
3376The input is a certificate containing a public key.
3377.It Fl decrypt
3378Decrypt the input data using a private key.
3379.It Fl derive
3380Derive a shared secret using the peer key.
3381.It Fl encrypt
3382Encrypt the input data using a public key.
3383.It Fl hexdump
3384Hex dump the output data.
3385.It Fl in Ar file
3386The input file to read from,
3387or standard input if not specified.
3388.It Fl inkey Ar file
3389The input key file.
3390By default it should be a private key.
3391.It Fl keyform Cm der | pem
3392The key format.
3393.It Fl out Ar file
3394The output file to write to,
3395or standard output if not specified.
3396.It Fl passin Ar arg
3397The key password source.
3398.It Fl peerform Cm der | pem
3399The peer key format.
3400.It Fl peerkey Ar file
3401The peer key file, used by key derivation (agreement) operations.
3402.It Fl pkeyopt Ar opt : Ns Ar value
3403Set the public key algorithm option
3404.Ar opt
3405to
3406.Ar value .
3407Unless otherwise mentioned, all algorithms support the format
3408.Ar digest : Ns Ar alg ,
3409which specifies the digest to use
3410for sign, verify, and verifyrecover operations.
3411The value
3412.Ar alg
3413should represent a digest name as used in the
3414.Xr EVP_get_digestbyname 3
3415function.
3416.Pp
3417The RSA algorithm supports the
3418encrypt, decrypt, sign, verify, and verifyrecover operations in general.
3419Some padding modes only support some of these
3420operations however.
3421.Bl -tag -width Ds
3422.It rsa_padding_mode : Ns Ar mode
3423This sets the RSA padding mode.
3424Acceptable values for
3425.Ar mode
3426are
3427.Cm pkcs1
3428for PKCS#1 padding;
3429.Cm none
3430for no padding;
3431.Cm oaep
3432for OAEP mode;
3433.Cm x931
3434for X9.31 mode;
3435and
3436.Cm pss
3437for PSS.
3438.Pp
3439In PKCS#1 padding if the message digest is not set then the supplied data is
3440signed or verified directly instead of using a DigestInfo structure.
3441If a digest is set then a DigestInfo
3442structure is used and its length
3443must correspond to the digest type.
3444For oeap mode only encryption and decryption is supported.
3445For x931 if the digest type is set it is used to format the block data;
3446otherwise the first byte is used to specify the X9.31 digest ID.
3447Sign, verify, and verifyrecover can be performed in this mode.
3448For pss mode only sign and verify are supported and the digest type must be
3449specified.
3450.It rsa_pss_saltlen : Ns Ar len
3451For pss
3452mode only this option specifies the salt length.
3453Two special values are supported:
3454-1 sets the salt length to the digest length.
3455When signing, -2 sets the salt length to the maximum permissible value.
3456When verifying, -2 causes the salt length to be automatically determined
3457based on the PSS block structure.
3458.El
3459.Pp
3460The DSA algorithm supports the sign and verify operations.
3461Currently there are no additional options other than
3462.Ar digest .
3463Only the SHA1 digest can be used and this digest is assumed by default.
3464.Pp
3465The DH algorithm supports the derive operation
3466and no additional options.
3467.Pp
3468The EC algorithm supports the sign, verify, and derive operations.
3469The sign and verify operations use ECDSA and derive uses ECDH.
3470Currently there are no additional options other than
3471.Ar digest .
3472Only the SHA1 digest can be used and this digest is assumed by default.
3473.It Fl pubin
3474The input file is a public key.
3475.It Fl rev
3476Reverse the order of the input buffer.
3477.It Fl sigfile Ar file
3478Signature file (verify operation only).
3479.It Fl sign
3480Sign the input data and output the signed result.
3481This requires a private key.
3482.It Fl verify
3483Verify the input data against the signature file and indicate if the
3484verification succeeded or failed.
3485.It Fl verifyrecover
3486Verify the input data and output the recovered data.
3487.El
3488.Tg prime
3489.Sh PRIME
3490.Cm openssl prime
3491.Op Fl bits Ar n
3492.Op Fl checks Ar n
3493.Op Fl generate
3494.Op Fl hex
3495.Op Fl safe
3496.Ar p
3497.Pp
3498The
3499.Nm prime
3500command is used to generate prime numbers,
3501or to check numbers for primality.
3502Results are probabilistic:
3503they have an exceedingly high likelihood of being correct,
3504but are not guaranteed.
3505.Pp
3506The options are as follows:
3507.Bl -tag -width Ds
3508.It Fl bits Ar n
3509Specify the number of bits in the generated prime number.
3510Must be used in conjunction with
3511.Fl generate .
3512.It Fl checks Ar n
3513Perform a Miller-Rabin probabilistic primality test with
3514.Ar n
3515iterations.
3516The default is 20.
3517.It Fl generate
3518Generate a pseudo-random prime number.
3519Must be used in conjunction with
3520.Fl bits .
3521.It Fl hex
3522Output in hex format.
3523.It Fl safe
3524Generate only
3525.Qq safe
3526prime numbers
3527(i.e. a prime p so that (p-1)/2 is also prime).
3528.It Ar p
3529Test if number
3530.Ar p
3531is prime.
3532.El
3533.Tg rand
3534.Sh RAND
3535.Bl -hang -width "openssl rand"
3536.It Nm openssl rand
3537.Bk -words
3538.Op Fl base64
3539.Op Fl hex
3540.Op Fl out Ar file
3541.Ar num
3542.Ek
3543.El
3544.Pp
3545The
3546.Nm rand
3547command outputs
3548.Ar num
3549pseudo-random bytes.
3550.Pp
3551The options are as follows:
3552.Bl -tag -width Ds
3553.It Fl base64
3554Perform base64 encoding on the output.
3555.It Fl hex
3556Specify hexadecimal output.
3557.It Fl out Ar file
3558The output file to write to,
3559or standard output if not specified.
3560.El
3561.Tg req
3562.Sh REQ
3563.Bl -hang -width "openssl req"
3564.It Nm openssl req
3565.Bk -words
3566.Op Fl addext Ar ext
3567.Op Fl batch
3568.Op Fl config Ar file
3569.Op Fl days Ar n
3570.Op Fl extensions Ar section
3571.Op Fl in Ar file
3572.Op Fl inform Cm der | pem
3573.Op Fl key Ar keyfile
3574.Op Fl keyform Cm der | pem
3575.Op Fl keyout Ar file
3576.Op Fl md4 | md5 | sha1
3577.Op Fl modulus
3578.Op Fl multivalue-rdn
3579.Op Fl nameopt Ar option
3580.Op Fl new
3581.Op Fl newhdr
3582.Op Fl newkey Ar arg
3583.Op Fl nodes
3584.Op Fl noout
3585.Op Fl out Ar file
3586.Op Fl outform Cm der | pem
3587.Op Fl passin Ar arg
3588.Op Fl passout Ar arg
3589.Op Fl pkeyopt Ar opt:value
3590.Op Fl pubkey
3591.Op Fl reqexts Ar section
3592.Op Fl reqopt Ar option
3593.Op Fl set_serial Ar n
3594.Op Fl sigopt Ar nm:v
3595.Op Fl subj Ar arg
3596.Op Fl subject
3597.Op Fl text
3598.Op Fl utf8
3599.Op Fl verbose
3600.Op Fl verify
3601.Op Fl x509
3602.Ek
3603.El
3604.Pp
3605The
3606.Nm req
3607command primarily creates and processes certificate requests
3608in PKCS#10 format.
3609It can additionally create self-signed certificates,
3610for use as root CAs, for example.
3611.Pp
3612The options are as follows:
3613.Bl -tag -width Ds
3614.It Fl addext Ar ext
3615Add a specific extension to the certificate (if the
3616.Fl x509
3617option is present) or certificate request.
3618The argument must have the form of a key=value pair as it would appear in a
3619config file.
3620This option can be given multiple times.
3621.It Fl batch
3622Non-interactive mode.
3623.It Fl config Ar file
3624Specify an alternative configuration file.
3625.It Fl days Ar n
3626Specify the number of days to certify the certificate for.
3627The default is 30 days.
3628Used with the
3629.Fl x509
3630option.
3631.It Fl extensions Ar section , Fl reqexts Ar section
3632Specify alternative sections to include certificate
3633extensions (with
3634.Fl x509 )
3635or certificate request extensions,
3636allowing several different sections to be used in the same configuration file.
3637.It Fl in Ar file
3638The input file to read a request from,
3639or standard input if not specified.
3640A request is only read if the creation options
3641.Fl new
3642and
3643.Fl newkey
3644are not specified.
3645.It Fl inform Cm der | pem
3646The input format.
3647.It Fl key Ar keyfile
3648The file to read the private key from.
3649It also accepts PKCS#8 format private keys for PEM format files.
3650.It Fl keyform Cm der | pem
3651The format of the private key file specified in the
3652.Fl key
3653argument.
3654The default is
3655.Cm pem .
3656.It Fl keyout Ar file
3657The file to write the newly created private key to.
3658If this option is not specified,
3659the filename present in the configuration file is used.
3660.It Fl md5 | sha1 | sha256
3661The message digest to sign the request with.
3662This overrides the digest algorithm specified in the configuration file.
3663.Pp
3664Some public key algorithms may override this choice.
3665For instance, DSA signatures always use SHA1.
3666.It Fl modulus
3667Print the value of the modulus of the public key contained in the request.
3668.It Fl multivalue-rdn
3669This option causes the
3670.Fl subj
3671argument to be interpreted with full support for multivalued RDNs,
3672for example
3673.Qq "/DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe" .
3674If
3675.Fl multivalue-rdn
3676is not used, the UID value is set to
3677.Qq "123456+CN=John Doe" .
3678.It Fl nameopt Ar option , Fl reqopt Ar option
3679Determine how the subject or issuer names are displayed.
3680.Ar option
3681can be a single option or multiple options separated by commas.
3682Alternatively, these options may be used more than once to set multiple options.
3683See the
3684.Sx X509
3685section below for details.
3686.It Fl new
3687Generate a new certificate request.
3688The user is prompted for the relevant field values.
3689The actual fields prompted for and their maximum and minimum sizes
3690are specified in the configuration file and any requested extensions.
3691.Pp
3692If the
3693.Fl key
3694option is not used, it will generate a new RSA private
3695key using information specified in the configuration file.
3696.It Fl newhdr
3697Add the word NEW to the PEM file header and footer lines
3698on the outputted request.
3699Some software and CAs need this.
3700.It Fl newkey Ar arg
3701Create a new certificate request and a new private key.
3702The argument takes one of several forms.
3703.Pp
3704.No rsa : Ns Ar nbits
3705generates an RSA key
3706.Ar nbits
3707in size.
3708If
3709.Ar nbits
3710is omitted,
3711the default key size is used.
3712.Pp
3713.No dsa : Ns Ar file
3714generates a DSA key using the parameters in
3715.Ar file .
3716.Pp
3717.No param : Ns Ar file
3718generates a key using the parameters or certificate in
3719.Ar file .
3720.Pp
3721All other algorithms support the form
3722.Ar algorithm : Ns Ar file ,
3723where file may be an algorithm parameter file,
3724created by the
3725.Cm genpkey -genparam
3726command or an X.509 certificate for a key with appropriate algorithm.
3727.Ar file
3728can be omitted,
3729in which case any parameters can be specified via the
3730.Fl pkeyopt
3731option.
3732.It Fl nodes
3733Do not encrypt the private key.
3734.It Fl noout
3735Do not output the encoded version of the request.
3736.It Fl out Ar file
3737The output file to write to,
3738or standard output if not specified.
3739.It Fl outform Cm der | pem
3740The output format.
3741.It Fl passin Ar arg
3742The key password source.
3743.It Fl passout Ar arg
3744The output file password source.
3745.It Fl pkeyopt Ar opt:value
3746Set the public key algorithm option
3747.Ar opt
3748to
3749.Ar value .
3750.It Fl pubkey
3751Output the public key.
3752.It Fl reqopt Ar option
3753Customise the output format used with
3754.Fl text .
3755The
3756.Ar option
3757argument can be a single option or multiple options separated by commas.
3758See also the discussion of
3759.Fl certopt
3760in the
3761.Nm x509
3762command.
3763.It Fl set_serial Ar n
3764Serial number to use when outputting a self-signed certificate.
3765This may be specified as a decimal value or a hex value if preceded by
3766.Sq 0x .
3767It is possible to use negative serial numbers but this is not recommended.
3768.It Fl sigopt Ar nm:v
3769Pass options to the signature algorithm during sign operation.
3770The names and values of these options are algorithm-specific.
3771.It Fl subj Ar arg
3772Replaces the subject field of an input request
3773with the specified data and output the modified request.
3774.Ar arg
3775must be formatted as /type0=value0/type1=value1/type2=...;
3776characters may be escaped by
3777.Sq \e
3778(backslash);
3779no spaces are skipped.
3780.It Fl subject
3781Print the request subject (or certificate subject if
3782.Fl x509
3783is specified).
3784.It Fl text
3785Print the certificate request in plain text.
3786.It Fl utf8
3787Interpret field values as UTF8 strings, not ASCII.
3788.It Fl verbose
3789Print extra details about the operations being performed.
3790.It Fl verify
3791Verify the signature on the request.
3792.It Fl x509
3793Output a self-signed certificate instead of a certificate request.
3794This is typically used to generate a test certificate or a self-signed root CA.
3795The extensions added to the certificate (if any)
3796are specified in the configuration file.
3797Unless specified using the
3798.Fl set_serial
3799option, 0 is used for the serial number.
3800.El
3801.Pp
3802The configuration options are specified in the
3803.Qq req
3804section of the configuration file.
3805The options available are as follows:
3806.Bl -tag -width "XXXX"
3807.It Cm attributes
3808The section containing any request attributes: its format
3809is the same as
3810.Cm distinguished_name .
3811Typically these may contain the challengePassword or unstructuredName types.
3812They are currently ignored by the
3813.Nm openssl
3814request signing utilities, but some CAs might want them.
3815.It Cm default_bits
3816The default key size, in bits.
3817The default is 2048.
3818It is used if the
3819.Fl new
3820option is used and can be overridden by using the
3821.Fl newkey
3822option.
3823.It Cm default_keyfile
3824The default file to write a private key to,
3825or standard output if not specified.
3826It can be overridden by the
3827.Fl keyout
3828option.
3829.It Cm default_md
3830The digest algorithm to use.
3831Possible values include
3832.Cm md5 ,
3833.Cm sha1
3834and
3835.Cm sha256
3836(the default).
3837It can be overridden on the command line.
3838.It Cm distinguished_name
3839The section containing the distinguished name fields to
3840prompt for when generating a certificate or certificate request.
3841The format is described below.
3842.It Cm encrypt_key
3843If set to
3844.Qq no
3845and a private key is generated, it is not encrypted.
3846It is equivalent to the
3847.Fl nodes
3848option.
3849For compatibility,
3850.Cm encrypt_rsa_key
3851is an equivalent option.
3852.It Cm input_password | output_password
3853The passwords for the input private key file (if present)
3854and the output private key file (if one will be created).
3855The command line options
3856.Fl passin
3857and
3858.Fl passout
3859override the configuration file values.
3860.It Cm oid_file
3861A file containing additional OBJECT IDENTIFIERS.
3862Each line of the file should consist of the numerical form of the
3863object identifier, followed by whitespace, then the short name followed
3864by whitespace and finally the long name.
3865.It Cm oid_section
3866Specify a section in the configuration file containing extra
3867object identifiers.
3868Each line should consist of the short name of the
3869object identifier followed by
3870.Sq =
3871and the numerical form.
3872The short and long names are the same when this option is used.
3873.It Cm prompt
3874If set to
3875.Qq no ,
3876it disables prompting of certificate fields
3877and just takes values from the config file directly.
3878It also changes the expected format of the
3879.Cm distinguished_name
3880and
3881.Cm attributes
3882sections.
3883.It Cm req_extensions
3884The configuration file section containing a list of
3885extensions to add to the certificate request.
3886It can be overridden by the
3887.Fl reqexts
3888option.
3889.It Cm string_mask
3890Limit the string types for encoding certain fields.
3891The following values may be used, limiting strings to the indicated types:
3892.Bl -tag -width "MASK:number"
3893.It Cm utf8only
3894UTF8String.
3895This is the default, as recommended by PKIX in RFC 2459.
3896.It Cm default
3897PrintableString, IA5String, T61String, BMPString, UTF8String.
3898.It Cm pkix
3899PrintableString, IA5String, BMPString, UTF8String.
3900Inspired by the PKIX recommendation in RFC 2459 for certificates
3901generated before 2004, but differs by also permitting IA5String.
3902.It Cm nombstr
3903PrintableString, IA5String, T61String, UniversalString.
3904A workaround for some ancient software that had problems
3905with the variable-sized BMPString and UTF8String types.
3906.It Cm MASK : Ns Ar number
3907An explicit bitmask of permitted types, where
3908.Ar number
3909is a C-style hex, decimal, or octal number that's a bit-wise OR of
3910.Dv B_ASN1_*
3911values from
3912.In openssl/asn1.h .
3913.El
3914.It Cm utf8
3915If set to
3916.Qq yes ,
3917field values are interpreted as UTF8 strings.
3918.It Cm x509_extensions
3919The configuration file section containing a list of
3920extensions to add to a certificate generated when the
3921.Fl x509
3922switch is used.
3923It can be overridden by the
3924.Fl extensions
3925command line switch.
3926.El
3927.Pp
3928There are two separate formats for the distinguished name and attribute
3929sections.
3930If the
3931.Fl prompt
3932option is set to
3933.Qq no ,
3934then these sections just consist of field names and values.
3935If the
3936.Fl prompt
3937option is absent or not set to
3938.Qq no ,
3939then the file contains field prompting information of the form:
3940.Bd -unfilled -offset indent
3941fieldName="prompt"
3942fieldName_default="default field value"
3943fieldName_min= 2
3944fieldName_max= 4
3945.Ed
3946.Pp
3947.Qq fieldName
3948is the field name being used, for example
3949.Cm commonName
3950(or CN).
3951The
3952.Qq prompt
3953string is used to ask the user to enter the relevant details.
3954If the user enters nothing, the default value is used;
3955if no default value is present, the field is omitted.
3956A field can still be omitted if a default value is present,
3957if the user just enters the
3958.Sq \&.
3959character.
3960.Pp
3961The number of characters entered must be between the
3962fieldName_min and fieldName_max limits:
3963there may be additional restrictions based on the field being used
3964(for example
3965.Cm countryName
3966can only ever be two characters long and must fit in a
3967.Cm PrintableString ) .
3968.Pp
3969Some fields (such as
3970.Cm organizationName )
3971can be used more than once in a DN.
3972This presents a problem because configuration files will
3973not recognize the same name occurring twice.
3974To avoid this problem, if the
3975.Cm fieldName
3976contains some characters followed by a full stop, they will be ignored.
3977So, for example, a second
3978.Cm organizationName
3979can be input by calling it
3980.Qq 1.organizationName .
3981.Pp
3982The actual permitted field names are any object identifier short or
3983long names.
3984These are compiled into
3985.Nm openssl
3986and include the usual values such as
3987.Cm commonName , countryName , localityName , organizationName ,
3988.Cm organizationalUnitName , stateOrProvinceName .
3989Additionally,
3990.Cm emailAddress
3991is included as well as
3992.Cm name , surname , givenName , initials
3993and
3994.Cm dnQualifier .
3995.Pp
3996Additional object identifiers can be defined with the
3997.Cm oid_file
3998or
3999.Cm oid_section
4000options in the configuration file.
4001Any additional fields will be treated as though they were a
4002.Cm DirectoryString .
4003.Tg rsa
4004.Sh RSA
4005.Bl -hang -width "openssl rsa"
4006.It Nm openssl rsa
4007.Bk -words
4008.Op Fl aes128 | aes192 | aes256 | des | des3
4009.Op Fl check
4010.Op Fl in Ar file
4011.Op Fl inform Cm der | net | pem | pvk
4012.Op Fl modulus
4013.Op Fl noout
4014.Op Fl out Ar file
4015.Op Fl outform Cm der | net | pem | pvk
4016.Op Fl passin Ar arg
4017.Op Fl passout Ar arg
4018.Op Fl pubin
4019.Op Fl pubout
4020.Op Fl pvk-none | pvk-strong | pvk-weak
4021.Op Fl RSAPublicKey_in
4022.Op Fl RSAPublicKey_out
4023.Op Fl text
4024.Ek
4025.El
4026.Pp
4027The
4028.Nm rsa
4029command processes RSA keys.
4030They can be converted between various forms and their components printed out.
4031.Nm rsa
4032uses the traditional
4033.Nm SSLeay
4034compatible format for private key encryption:
4035newer applications should use the more secure PKCS#8 format using the
4036.Nm pkcs8
4037utility.
4038.Pp
4039The options are as follows:
4040.Bl -tag -width Ds
4041.It Fl aes128 | aes192 | aes256 | des | des3
4042Encrypt the private key with the AES, DES,
4043or the triple DES ciphers, respectively, before outputting it.
4044A pass phrase is prompted for.
4045If none of these options are specified, the key is written in plain text.
4046This means that using the
4047.Nm rsa
4048utility to read in an encrypted key with no encryption option can be used
4049to remove the pass phrase from a key, or by setting the encryption options
4050it can be used to add or change the pass phrase.
4051These options can only be used with PEM format output files.
4052.It Fl check
4053Check the consistency of an RSA private key.
4054.It Fl in Ar file
4055The input file to read from,
4056or standard input if not specified.
4057If the key is encrypted, a pass phrase will be prompted for.
4058.It Fl inform Cm der | net | pem | pvk
4059The input format.
4060.It Fl noout
4061Do not output the encoded version of the key.
4062.It Fl modulus
4063Print the value of the modulus of the key.
4064.It Fl out Ar file
4065The output file to write to,
4066or standard output if not specified.
4067.It Fl outform Cm der | net | pem | pvk
4068The output format.
4069.It Fl passin Ar arg
4070The key password source.
4071.It Fl passout Ar arg
4072The output file password source.
4073.It Fl pubin
4074Read in a public key,
4075not a private key.
4076.It Fl pubout
4077Output a public key,
4078not a private key.
4079Automatically set if the input is a public key.
4080.It Xo
4081.Fl pvk-none | pvk-strong | pvk-weak
4082.Xc
4083Enable or disable PVK encoding.
4084The default is
4085.Fl pvk-strong .
4086.It Fl RSAPublicKey_in , RSAPublicKey_out
4087Same as
4088.Fl pubin
4089and
4090.Fl pubout
4091except
4092.Cm RSAPublicKey
4093format is used instead.
4094.It Fl text
4095Print the public/private key components in plain text.
4096.El
4097.Tg rsautl
4098.Sh RSAUTL
4099.Bl -hang -width "openssl rsautl"
4100.It Nm openssl rsautl
4101.Bk -words
4102.Op Fl asn1parse
4103.Op Fl certin
4104.Op Fl decrypt
4105.Op Fl encrypt
4106.Op Fl hexdump
4107.Op Fl in Ar file
4108.Op Fl inkey Ar file
4109.Op Fl keyform Cm der | pem
4110.Op Fl oaep | pkcs | raw | x931
4111.Op Fl out Ar file
4112.Op Fl passin Ar arg
4113.Op Fl pubin
4114.Op Fl rev
4115.Op Fl sign
4116.Op Fl verify
4117.Ek
4118.El
4119.Pp
4120The
4121.Nm rsautl
4122command can be used to sign, verify, encrypt and decrypt
4123data using the RSA algorithm.
4124.Pp
4125The options are as follows:
4126.Bl -tag -width Ds
4127.It Fl asn1parse
4128Asn1parse the output data; this is useful when combined with the
4129.Fl verify
4130option.
4131.It Fl certin
4132The input is a certificate containing an RSA public key.
4133.It Fl decrypt
4134Decrypt the input data using an RSA private key.
4135.It Fl encrypt
4136Encrypt the input data using an RSA public key.
4137.It Fl hexdump
4138Hex dump the output data.
4139.It Fl in Ar file
4140The input to read from,
4141or standard input if not specified.
4142.It Fl inkey Ar file
4143The input key file; by default an RSA private key.
4144.It Fl keyform Cm der | pem
4145The private key format.
4146The default is
4147.Cm pem .
4148.It Fl oaep | pkcs | raw | x931
4149The padding to use:
4150PKCS#1 OAEP, PKCS#1 v1.5 (the default), no padding, or ANSI X9.31,
4151respectively.
4152For signatures, only
4153.Fl pkcs
4154and
4155.Fl raw
4156can be used.
4157.It Fl out Ar file
4158The output file to write to,
4159or standard output if not specified.
4160.It Fl passin Ar arg
4161The key password source.
4162.It Fl pubin
4163The input file is an RSA public key.
4164.It Fl rev
4165Reverse the order of the input buffer.
4166.It Fl sign
4167Sign the input data and output the signed result.
4168This requires an RSA private key.
4169.It Fl verify
4170Verify the input data and output the recovered data.
4171.El
4172.Tg s_client
4173.Sh S_CLIENT
4174.Bl -hang -width "openssl s_client"
4175.It Nm openssl s_client
4176.Bk -words
4177.Op Fl 4 | 6
4178.Op Fl alpn Ar protocols
4179.Op Fl bugs
4180.Op Fl CAfile Ar file
4181.Op Fl CApath Ar directory
4182.Op Fl cert Ar file
4183.Op Fl certform Cm der | pem
4184.Op Fl check_ss_sig
4185.Op Fl cipher Ar cipherlist
4186.Op Fl connect Ar host Ns Op : Ns Ar port
4187.Op Fl crl_check
4188.Op Fl crl_check_all
4189.Op Fl crlf
4190.Op Fl debug
4191.Op Fl dtls
4192.Op Fl dtls1_2
4193.Op Fl extended_crl
4194.Op Fl groups Ar list
4195.Op Fl host Ar host
4196.Op Fl ign_eof
4197.Op Fl ignore_critical
4198.Op Fl issuer_checks
4199.Op Fl key Ar keyfile
4200.Op Fl keyform Cm der | pem
4201.Op Fl keymatexport Ar label
4202.Op Fl keymatexportlen Ar len
4203.Op Fl legacy_server_connect
4204.Op Fl msg
4205.Op Fl mtu Ar mtu
4206.Op Fl nbio
4207.Op Fl nbio_test
4208.Op Fl no_comp
4209.Op Fl no_ign_eof
4210.Op Fl no_legacy_server_connect
4211.Op Fl no_ticket
4212.Op Fl no_tls1_2
4213.Op Fl no_tls1_3
4214.Op Fl pass Ar arg
4215.Op Fl policy_check
4216.Op Fl port Ar port
4217.Op Fl prexit
4218.Op Fl proxy Ar host : Ns Ar port
4219.Op Fl quiet
4220.Op Fl reconnect
4221.Op Fl servername Ar name
4222.Op Fl serverpref
4223.Op Fl sess_in Ar file
4224.Op Fl sess_out Ar file
4225.Op Fl showcerts
4226.Op Fl starttls Ar protocol
4227.Op Fl state
4228.Op Fl status
4229.Op Fl timeout
4230.Op Fl tls1_2
4231.Op Fl tls1_3
4232.Op Fl tlsextdebug
4233.Op Fl use_srtp Ar profiles
4234.Op Fl verify Ar depth
4235.Op Fl verify_return_error
4236.Op Fl x509_strict
4237.Op Fl xmpphost Ar host
4238.Ek
4239.El
4240.Pp
4241The
4242.Nm s_client
4243command implements a generic SSL/TLS client which connects
4244to a remote host using SSL/TLS.
4245.Pp
4246If a connection is established with an SSL server, any data received
4247from the server is displayed and any key presses will be sent to the
4248server.
4249When used interactively (which means neither
4250.Fl quiet
4251nor
4252.Fl ign_eof
4253have been given), the session will be renegotiated if the line begins with an
4254.Cm R ;
4255if the line begins with a
4256.Cm Q
4257or if end of file is reached, the connection will be closed down.
4258.Pp
4259The options are as follows:
4260.Bl -tag -width Ds
4261.It Fl 4
4262Attempt connections using IPv4 only.
4263.It Fl 6
4264Attempt connections using IPv6 only.
4265.It Fl alpn Ar protocols
4266Enable the Application-Layer Protocol Negotiation.
4267.Ar protocols
4268is a comma-separated list of protocol names that the client should advertise
4269support for.
4270.It Fl bugs
4271Enable various workarounds for buggy implementations.
4272.It Fl CAfile Ar file
4273A
4274.Ar file
4275containing trusted certificates to use during server authentication
4276and to use when attempting to build the client certificate chain.
4277.It Fl CApath Ar directory
4278The
4279.Ar directory
4280to use for server certificate verification.
4281This directory must be in
4282.Qq hash format ;
4283see
4284.Fl verify
4285for more information.
4286These are also used when building the client certificate chain.
4287.It Fl cert Ar file
4288The certificate to use, if one is requested by the server.
4289The default is not to use a certificate.
4290.It Fl certform Cm der | pem
4291The certificate format.
4292The default is
4293.Cm pem .
4294.It Xo
4295.Fl check_ss_sig ,
4296.Fl crl_check ,
4297.Fl crl_check_all ,
4298.Fl extended_crl ,
4299.Fl ignore_critical ,
4300.Fl issuer_checks ,
4301.Fl policy_check ,
4302.Fl x509_strict
4303.Xc
4304Set various certificate chain validation options.
4305See the
4306.Nm verify
4307command for details.
4308.It Fl cipher Ar cipherlist
4309Modify the cipher list sent by the client.
4310Although the server determines which cipher suite is used, it should take
4311the first supported cipher in the list sent by the client.
4312See the
4313.Nm ciphers
4314command for more information.
4315.It Fl connect Ar host Ns Op : Ns Ar port
4316The
4317.Ar host
4318and
4319.Ar port
4320to connect to.
4321If not specified, an attempt is made to connect to the local host
4322on port 4433.
4323Alternatively, the host and port pair may be separated using a forward-slash
4324character,
4325which is useful for numeric IPv6 addresses.
4326.It Fl crlf
4327Translate a line feed from the terminal into CR+LF,
4328as required by some servers.
4329.It Fl debug
4330Print extensive debugging information, including a hex dump of all traffic.
4331.It Fl dtls
4332Permit any version of DTLS.
4333.It Fl dtls1_2
4334Permit only DTLS1.2.
4335.It Fl groups Ar list
4336Set the supported elliptic curve groups to the colon separated
4337.Ar list
4338of group NIDs or names as documented in
4339.Xr SSL_CTX_set1_groups_list 3 .
4340.It Fl host Ar host
4341The
4342.Ar host
4343to connect to.
4344The default is localhost.
4345.It Fl ign_eof
4346Inhibit shutting down the connection when end of file is reached in the input.
4347.It Fl key Ar keyfile
4348The private key to use.
4349If not specified, the certificate file will be used.
4350.It Fl keyform Cm der | pem
4351The private key format.
4352The default is
4353.Cm pem .
4354.It Fl keymatexport Ar label
4355Export keying material using label.
4356.It Fl keymatexportlen Ar len
4357Export len bytes of keying material (default 20).
4358.It Fl legacy_server_connect , no_legacy_server_connect
4359Allow or disallow initial connection to servers that don't support RI.
4360.It Fl msg
4361Show all protocol messages with hex dump.
4362.It Fl mtu Ar mtu
4363Set the link layer MTU.
4364.It Fl nbio
4365Turn on non-blocking I/O.
4366.It Fl nbio_test
4367Test non-blocking I/O.
4368.It Fl no_ign_eof
4369Shut down the connection when end of file is reached in the input.
4370Can be used to override the implicit
4371.Fl ign_eof
4372after
4373.Fl quiet .
4374.It Fl no_tls1_2 | no_tls1_3
4375Disable the use of TLS1.2 and 1.3, respectively.
4376.It Fl no_ticket
4377Disable RFC 4507 session ticket support.
4378.It Fl pass Ar arg
4379The private key password source.
4380.It Fl port Ar port
4381The
4382.Ar port
4383to connect to.
4384The default is 4433.
4385.It Fl prexit
4386Print session information when the program exits.
4387This will always attempt
4388to print out information even if the connection fails.
4389Normally, information will only be printed out once if the connection succeeds.
4390This option is useful because the cipher in use may be renegotiated
4391or the connection may fail because a client certificate is required or is
4392requested only after an attempt is made to access a certain URL.
4393Note that the output produced by this option is not always accurate
4394because a connection might never have been established.
4395.It Fl proxy Ar host : Ns Ar port
4396Use the HTTP proxy at
4397.Ar host
4398and
4399.Ar port .
4400The connection to the proxy is done in cleartext and the
4401.Fl connect
4402argument is given to the proxy.
4403If not specified, localhost is used as final destination.
4404After that, switch the connection through the proxy to the destination
4405to TLS.
4406.It Fl quiet
4407Inhibit printing of session and certificate information.
4408This implicitly turns on
4409.Fl ign_eof
4410as well.
4411.It Fl reconnect
4412Reconnect to the same server 5 times using the same session ID; this can
4413be used as a test that session caching is working.
4414.It Fl servername Ar name
4415Include the TLS Server Name Indication (SNI) extension in the ClientHello
4416message, using the specified server
4417.Ar name .
4418.It Fl showcerts
4419Display the whole server certificate chain: normally only the server
4420certificate itself is displayed.
4421.It Fl serverpref
4422Use the server's cipher preferences.
4423.It Fl sess_in Ar file
4424Load TLS session from file.
4425The client will attempt to resume a connection from this session.
4426.It Fl sess_out Ar file
4427Output TLS session to file.
4428.It Fl starttls Ar protocol
4429Send the protocol-specific messages to switch to TLS for communication.
4430.Ar protocol
4431is a keyword for the intended protocol.
4432Currently, the supported keywords are
4433.Qq ftp ,
4434.Qq imap ,
4435.Qq smtp ,
4436.Qq pop3 ,
4437and
4438.Qq xmpp .
4439.It Fl state
4440Print the SSL session states.
4441.It Fl status
4442Send a certificate status request to the server (OCSP stapling).
4443The server response (if any) is printed out.
4444.It Fl timeout
4445Enable send/receive timeout on DTLS connections.
4446.It Fl tls1_2 | tls1_3
4447Permit only TLS1.2 or 1.3 respectively.
4448.It Fl tlsextdebug
4449Print a hex dump of any TLS extensions received from the server.
4450.It Fl use_srtp Ar profiles
4451Offer SRTP key management with a colon-separated profile list.
4452.It Fl verify Ar depth
4453Turn on server certificate verification,
4454with a maximum length of
4455.Ar depth .
4456Currently the verify operation continues after errors so all the problems
4457with a certificate chain can be seen.
4458As a side effect the connection will never fail due to a server
4459certificate verify failure.
4460.It Fl verify_return_error
4461Return verification error.
4462.It Fl xmpphost Ar hostname
4463When used with
4464.Fl starttls Ar xmpp ,
4465specify the host for the "to" attribute of the stream element.
4466If this option is not specified then the host specified with
4467.Fl connect
4468will be used.
4469.El
4470.Tg s_server
4471.Sh S_SERVER
4472.Bl -hang -width "openssl s_server"
4473.It Nm openssl s_server
4474.Bk -words
4475.Op Fl accept Ar port
4476.Op Fl alpn Ar protocols
4477.Op Fl bugs
4478.Op Fl CAfile Ar file
4479.Op Fl CApath Ar directory
4480.Op Fl cert Ar file
4481.Op Fl cert2 Ar file
4482.Op Fl certform Cm der | pem
4483.Op Fl cipher Ar cipherlist
4484.Op Fl context Ar id
4485.Op Fl crl_check
4486.Op Fl crl_check_all
4487.Op Fl crlf
4488.Op Fl dcert Ar file
4489.Op Fl dcertform Cm der | pem
4490.Op Fl debug
4491.Op Fl dhparam Ar file
4492.Op Fl dkey Ar file
4493.Op Fl dkeyform Cm der | pem
4494.Op Fl dpass Ar arg
4495.Op Fl dtls
4496.Op Fl dtls1
4497.Op Fl dtls1_2
4498.Op Fl groups Ar list
4499.Op Fl HTTP
4500.Op Fl id_prefix Ar arg
4501.Op Fl key Ar keyfile
4502.Op Fl key2 Ar keyfile
4503.Op Fl keyform Cm der | pem
4504.Op Fl keymatexport Ar label
4505.Op Fl keymatexportlen Ar len
4506.Op Fl msg
4507.Op Fl mtu Ar mtu
4508.Op Fl naccept Ar num
4509.Op Fl named_curve Ar arg
4510.Op Fl nbio
4511.Op Fl nbio_test
4512.Op Fl no_cache
4513.Op Fl no_dhe
4514.Op Fl no_ecdhe
4515.Op Fl no_ticket
4516.Op Fl no_tls1_2
4517.Op Fl no_tls1_3
4518.Op Fl no_tmp_rsa
4519.Op Fl nocert
4520.Op Fl pass Ar arg
4521.Op Fl quiet
4522.Op Fl servername Ar name
4523.Op Fl servername_fatal
4524.Op Fl serverpref
4525.Op Fl state
4526.Op Fl status
4527.Op Fl status_timeout Ar nsec
4528.Op Fl status_url Ar url
4529.Op Fl status_verbose
4530.Op Fl timeout
4531.Op Fl tls1_2
4532.Op Fl tls1_3
4533.Op Fl tlsextdebug
4534.Op Fl use_srtp Ar profiles
4535.Op Fl Verify Ar depth
4536.Op Fl verify Ar depth
4537.Op Fl verify_return_error
4538.Op Fl WWW
4539.Op Fl www
4540.Ek
4541.El
4542.Pp
4543The
4544.Nm s_server
4545command implements a generic SSL/TLS server which listens
4546for connections on a given port using SSL/TLS.
4547.Pp
4548If a connection request is established with a client and neither the
4549.Fl www
4550nor the
4551.Fl WWW
4552option has been used, then any data received
4553from the client is displayed and any key presses are sent to the client.
4554Certain single letter commands perform special operations:
4555.Pp
4556.Bl -tag -width "XXXX" -compact
4557.It Ic P
4558Send plain text, which should cause the client to disconnect.
4559.It Ic Q
4560End the current SSL connection and exit.
4561.It Ic q
4562End the current SSL connection, but still accept new connections.
4563.It Ic R
4564Renegotiate the SSL session and request a client certificate.
4565.It Ic r
4566Renegotiate the SSL session.
4567.It Ic S
4568Print out some session cache status information.
4569.El
4570.Pp
4571The options are as follows:
4572.Bl -tag -width Ds
4573.It Fl accept Ar port
4574Listen on TCP
4575.Ar port
4576for connections.
4577The default is port 4433.
4578.It Fl alpn Ar protocols
4579Enable the Application-Layer Protocol Negotiation.
4580.Ar protocols
4581is a comma-separated list of supported protocol names.
4582.It Fl bugs
4583Enable various workarounds for buggy implementations.
4584.It Fl CAfile Ar file
4585A
4586.Ar file
4587containing trusted certificates to use during client authentication
4588and to use when attempting to build the server certificate chain.
4589The list is also used in the list of acceptable client CAs passed to the
4590client when a certificate is requested.
4591.It Fl CApath Ar directory
4592The
4593.Ar directory
4594to use for client certificate verification.
4595This directory must be in
4596.Qq hash format ;
4597see
4598.Fl verify
4599for more information.
4600These are also used when building the server certificate chain.
4601.It Fl cert Ar file
4602The certificate to use: most server's cipher suites require the use of a
4603certificate and some require a certificate with a certain public key type.
4604For example, the DSS cipher suites require a certificate containing a DSS
4605(DSA) key.
4606If not specified, the file
4607.Pa server.pem
4608will be used.
4609.It Fl cert2 Ar file
4610The certificate to use for servername.
4611.It Fl certform Cm der | pem
4612The certificate format.
4613The default is
4614.Cm pem .
4615.It Fl cipher Ar cipherlist
4616Modify the cipher list used by the server.
4617This allows the cipher list used by the server to be modified.
4618When the client sends a list of supported ciphers, the first client cipher
4619also included in the server list is used.
4620Because the client specifies the preference order, the order of the server
4621cipherlist is irrelevant.
4622See the
4623.Nm ciphers
4624command for more information.
4625.It Fl context Ar id
4626Set the SSL context ID.
4627It can be given any string value.
4628.It Fl crl_check , crl_check_all
4629Check the peer certificate has not been revoked by its CA.
4630The CRLs are appended to the certificate file.
4631.Fl crl_check_all
4632checks all CRLs of all CAs in the chain.
4633.It Fl crlf
4634Translate a line feed from the terminal into CR+LF.
4635.It Fl dcert Ar file , Fl dkey Ar file
4636Specify an additional certificate and private key; these behave in the
4637same manner as the
4638.Fl cert
4639and
4640.Fl key
4641options except there is no default if they are not specified
4642(no additional certificate or key is used).
4643By using RSA and DSS certificates and keys,
4644a server can support clients which only support RSA or DSS cipher suites
4645by using an appropriate certificate.
4646.It Fl dcertform Cm der | pem , Fl dkeyform Cm der | pem , Fl dpass Ar arg
4647Additional certificate and private key format, and private key password source,
4648respectively.
4649.It Fl debug
4650Print extensive debugging information, including a hex dump of all traffic.
4651.It Fl dhparam Ar file
4652The DH parameter file to use.
4653The ephemeral DH cipher suites generate keys
4654using a set of DH parameters.
4655If not specified, an attempt is made to
4656load the parameters from the server certificate file.
4657If this fails, a static set of parameters hard coded into the
4658.Nm s_server
4659program will be used.
4660.It Fl dtls
4661Permit any version of DTLS.
4662.It Fl dtls1_2
4663Permit only DTLS1.2.
4664.It Fl groups Ar list
4665Set the supported elliptic curve groups to the colon separated
4666.Ar list
4667of group NIDs or names as documented in
4668.Xr SSL_CTX_set1_groups_list 3 .
4669.It Fl HTTP
4670Emulate a simple web server.
4671Pages are resolved relative to the current directory.
4672For example if the URL
4673.Pa https://myhost/page.html
4674is requested, the file
4675.Pa ./page.html
4676will be loaded.
4677The files loaded are assumed to contain a complete and correct HTTP
4678response (lines that are part of the HTTP response line and headers
4679must end with CRLF).
4680.It Fl id_prefix Ar arg
4681Generate SSL/TLS session IDs prefixed by
4682.Ar arg .
4683This is mostly useful for testing any SSL/TLS code
4684that wish to deal with multiple servers,
4685when each of which might be generating a unique range of session IDs.
4686.It Fl key Ar keyfile
4687The private key to use.
4688If not specified, the certificate file will be used.
4689.It Fl key2 Ar keyfile
4690The private key to use for servername.
4691.It Fl keyform Cm der | pem
4692The private key format.
4693The default is
4694.Cm pem .
4695.It Fl keymatexport Ar label
4696Export keying material using label.
4697.It Fl keymatexportlen Ar len
4698Export len bytes of keying material (default 20).
4699.It Fl msg
4700Show all protocol messages with hex dump.
4701.It Fl mtu Ar mtu
4702Set the link layer MTU.
4703.It Fl naccept Ar num
4704Terminate server after
4705.Ar num
4706connections.
4707.It Fl named_curve Ar arg
4708Specify the elliptic curve name to use for ephemeral ECDH keys.
4709This option is deprecated; use
4710.Fl groups
4711instead.
4712.It Fl nbio
4713Turn on non-blocking I/O.
4714.It Fl nbio_test
4715Test non-blocking I/O.
4716.It Fl no_cache
4717Disable session caching.
4718.It Fl no_dhe
4719Disable ephemeral DH cipher suites.
4720.It Fl no_ecdhe
4721Disable ephemeral ECDH cipher suites.
4722.It Fl no_ticket
4723Disable RFC 4507 session ticket support.
4724.It Fl no_tls1_2 | no_tls1_3
4725Disable the use of TLS1.2 and 1.3, respectively.
4726.It Fl no_tmp_rsa
4727Disable temporary RSA key generation.
4728.It Fl nocert
4729Do not use a certificate.
4730This restricts the cipher suites available to the anonymous ones
4731(currently just anonymous DH).
4732.It Fl pass Ar arg
4733The private key password source.
4734.It Fl quiet
4735Inhibit printing of session and certificate information.
4736.It Fl servername Ar name
4737Set the TLS Server Name Indication (SNI) extension with
4738.Ar name .
4739.It Fl servername_fatal
4740Send fatal alert if servername does not match.
4741The default is warning alert.
4742.It Fl serverpref
4743Use server's cipher preferences.
4744.It Fl state
4745Print the SSL session states.
4746.It Fl status
4747Enables certificate status request support (OCSP stapling).
4748.It Fl status_timeout Ar nsec
4749Sets the timeout for OCSP response in seconds.
4750.It Fl status_url Ar url
4751Sets a fallback responder URL to use if no responder URL is present in the
4752server certificate.
4753Without this option, an error is returned if the server certificate does not
4754contain a responder address.
4755.It Fl status_verbose
4756Enables certificate status request support (OCSP stapling) and gives a verbose
4757printout of the OCSP response.
4758.It Fl timeout
4759Enable send/receive timeout on DTLS connections.
4760.It Fl tls1_2 | tls1_3
4761Permit only TLS1.2, or 1.3, respectively.
4762.It Fl tlsextdebug
4763Print a hex dump of any TLS extensions received from the server.
4764.It Fl use_srtp Ar profiles
4765Offer SRTP key management with a colon-separated profile list.
4766.It Fl verify_return_error
4767Return verification error.
4768.It Fl WWW
4769Emulate a simple web server.
4770Pages are resolved relative to the current directory.
4771For example if the URL
4772.Pa https://myhost/page.html
4773is requested, the file
4774.Pa ./page.html
4775will be loaded.
4776.It Fl www
4777Send a status message to the client when it connects,
4778including information about the ciphers used and various session parameters.
4779The output is in HTML format so this option will normally be used with a
4780web browser.
4781.It Fl Verify Ar depth , Fl verify Ar depth
4782Request a certificate chain from the client,
4783with a maximum length of
4784.Ar depth .
4785With
4786.Fl Verify ,
4787the client must supply a certificate or an error occurs;
4788with
4789.Fl verify ,
4790a certificate is requested but the client does not have to send one.
4791.El
4792.Tg s_time
4793.Sh S_TIME
4794.Bl -hang -width "openssl s_time"
4795.It Nm openssl s_time
4796.Bk -words
4797.Op Fl bugs
4798.Op Fl CAfile Ar file
4799.Op Fl CApath Ar directory
4800.Op Fl cert Ar file
4801.Op Fl cipher Ar cipherlist
4802.Op Fl connect Ar host Ns Op : Ns Ar port
4803.Op Fl key Ar keyfile
4804.Op Fl nbio
4805.Op Fl new
4806.Op Fl no_shutdown
4807.Op Fl reuse
4808.Op Fl time Ar seconds
4809.Op Fl verify Ar depth
4810.Op Fl www Ar page
4811.Ek
4812.El
4813.Pp
4814The
4815.Nm s_time
4816command implements a generic SSL/TLS client which connects to a
4817remote host using SSL/TLS.
4818It can request a page from the server and includes
4819the time to transfer the payload data in its timing measurements.
4820It measures the number of connections within a given timeframe,
4821the amount of data transferred
4822.Pq if any ,
4823and calculates the average time spent for one connection.
4824.Pp
4825The options are as follows:
4826.Bl -tag -width Ds
4827.It Fl bugs
4828Enable various workarounds for buggy implementations.
4829.It Fl CAfile Ar file
4830A
4831.Ar file
4832containing trusted certificates to use during server authentication
4833and to use when attempting to build the client certificate chain.
4834.It Fl CApath Ar directory
4835The directory to use for server certificate verification.
4836This directory must be in
4837.Qq hash format ;
4838see
4839.Nm verify
4840for more information.
4841These are also used when building the client certificate chain.
4842.It Fl cert Ar file
4843The certificate to use, if one is requested by the server.
4844The default is not to use a certificate.
4845.It Fl cipher Ar cipherlist
4846Modify the cipher list sent by the client.
4847Although the server determines which cipher suite is used,
4848it should take the first supported cipher in the list sent by the client.
4849See the
4850.Nm ciphers
4851command for more information.
4852.It Fl connect Ar host Ns Op : Ns Ar port
4853The host and port to connect to.
4854.It Fl key Ar keyfile
4855The private key to use.
4856If not specified, the certificate file will be used.
4857.It Fl nbio
4858Turn on non-blocking I/O.
4859.It Fl new
4860Perform the timing test using a new session ID for each connection.
4861If neither
4862.Fl new
4863nor
4864.Fl reuse
4865are specified,
4866they are both on by default and executed in sequence.
4867.It Fl no_shutdown
4868Shut down the connection without sending a
4869.Qq close notify
4870shutdown alert to the server.
4871.It Fl reuse
4872Perform the timing test using the same session ID for each connection.
4873If neither
4874.Fl new
4875nor
4876.Fl reuse
4877are specified,
4878they are both on by default and executed in sequence.
4879.It Fl time Ar seconds
4880Limit
4881.Nm s_time
4882benchmarks to the number of
4883.Ar seconds .
4884The default is 30 seconds.
4885.It Fl verify Ar depth
4886Turn on server certificate verification,
4887with a maximum length of
4888.Ar depth .
4889Currently the verify operation continues after errors, so all the problems
4890with a certificate chain can be seen.
4891As a side effect,
4892the connection will never fail due to a server certificate verify failure.
4893.It Fl www Ar page
4894The page to GET from the server.
4895A value of
4896.Sq /
4897gets the index.htm[l] page.
4898If this parameter is not specified,
4899.Nm s_time
4900will only perform the handshake to establish SSL connections
4901but not transfer any payload data.
4902.El
4903.Tg sess_id
4904.Sh SESS_ID
4905.Bl -hang -width "openssl sess_id"
4906.It Nm openssl sess_id
4907.Bk -words
4908.Op Fl cert
4909.Op Fl context Ar ID
4910.Op Fl in Ar file
4911.Op Fl inform Cm der | pem
4912.Op Fl noout
4913.Op Fl out Ar file
4914.Op Fl outform Cm der | pem
4915.Op Fl text
4916.Ek
4917.El
4918.Pp
4919The
4920.Nm sess_id
4921program processes the encoded version of the SSL session structure and
4922optionally prints out SSL session details
4923(for example the SSL session master key)
4924in human-readable format.
4925.Pp
4926The options are as follows:
4927.Bl -tag -width Ds
4928.It Fl cert
4929If a certificate is present in the session,
4930it will be output using this option;
4931if the
4932.Fl text
4933option is also present, then it will be printed out in text form.
4934.It Fl context Ar ID
4935Set the session
4936.Ar ID .
4937The ID can be any string of characters.
4938.It Fl in Ar file
4939The input file to read from,
4940or standard input if not specified.
4941.It Fl inform Cm der | pem
4942The input format.
4943.Cm der
4944uses an ASN.1 DER-encoded format containing session details.
4945The precise format can vary from one version to the next.
4946.Cm pem
4947is the default format: it consists of the DER
4948format base64-encoded with additional header and footer lines.
4949.It Fl noout
4950Do not output the encoded version of the session.
4951.It Fl out Ar file
4952The output file to write to,
4953or standard output if not specified.
4954.It Fl outform Cm der | pem
4955The output format.
4956.It Fl text
4957Print the various public or private key components in plain text,
4958in addition to the encoded version.
4959.El
4960.Pp
4961The output of
4962.Nm sess_id
4963is composed as follows:
4964.Pp
4965.Bl -tag -width "Verify return code " -offset 3n -compact
4966.It Protocol
4967The protocol in use.
4968.It Cipher
4969The actual raw SSL or TLS cipher code.
4970.It Session-ID
4971The SSL session ID, in hex format.
4972.It Session-ID-ctx
4973The session ID context, in hex format.
4974.It Master-Key
4975The SSL session master key.
4976.It Key-Arg
4977The key argument; this is only used in SSL v2.
4978.It Start Time
4979The session start time.
4980.Ux
4981format.
4982.It Timeout
4983The timeout, in seconds.
4984.It Verify return code
4985The return code when a certificate is verified.
4986.El
4987.Pp
4988Since the SSL session output contains the master key, it is possible to read
4989the contents of an encrypted session using this information.
4990Therefore appropriate security precautions
4991should be taken if the information is being output by a
4992.Qq real
4993application.
4994This is, however, strongly discouraged and should only be used for
4995debugging purposes.
4996.Tg smime
4997.Sh SMIME
4998.Bl -hang -width "openssl smime"
4999.It Nm openssl smime
5000.Bk -words
5001.Oo
5002.Fl aes128 | aes192 | aes256 | des |
5003.Fl des3 | rc2-40 | rc2-64 | rc2-128
5004.Oc
5005.Op Fl binary
5006.Op Fl CAfile Ar file
5007.Op Fl CApath Ar directory
5008.Op Fl certfile Ar file
5009.Op Fl check_ss_sig
5010.Op Fl content Ar file
5011.Op Fl crl_check
5012.Op Fl crl_check_all
5013.Op Fl decrypt
5014.Op Fl encrypt
5015.Op Fl extended_crl
5016.Op Fl from Ar addr
5017.Op Fl ignore_critical
5018.Op Fl in Ar file
5019.Op Fl indef
5020.Op Fl inform Cm der | pem | smime
5021.Op Fl inkey Ar file
5022.Op Fl issuer_checks
5023.Op Fl keyform Cm der | pem
5024.Op Fl md Ar digest
5025.Op Fl noattr
5026.Op Fl nocerts
5027.Op Fl nochain
5028.Op Fl nodetach
5029.Op Fl noindef
5030.Op Fl nointern
5031.Op Fl nosigs
5032.Op Fl nosmimecap
5033.Op Fl noverify
5034.Op Fl out Ar file
5035.Op Fl outform Cm der | pem | smime
5036.Op Fl passin Ar arg
5037.Op Fl pk7out
5038.Op Fl policy_check
5039.Op Fl recip Ar file
5040.Op Fl resign
5041.Op Fl sign
5042.Op Fl signer Ar file
5043.Op Fl stream
5044.Op Fl subject Ar s
5045.Op Fl text
5046.Op Fl to Ar addr
5047.Op Fl verify
5048.Op Fl x509_strict
5049.Op Ar cert.pem ...
5050.Ek
5051.El
5052.Pp
5053The
5054.Nm smime
5055command handles S/MIME mail.
5056It can encrypt, decrypt, sign, and verify S/MIME messages.
5057.Pp
5058The MIME message must be sent without any blank lines between the
5059headers and the output.
5060Some mail programs will automatically add a blank line.
5061Piping the mail directly to an MTA is one way to
5062achieve the correct format.
5063.Pp
5064The supplied message to be signed or encrypted must include the necessary
5065MIME headers or many S/MIME clients won't display it properly (if at all).
5066Use the
5067.Fl text
5068option to automatically add plain text headers.
5069.Pp
5070A
5071.Qq signed and encrypted
5072message is one where a signed message is then encrypted.
5073This can be produced by encrypting an already signed message.
5074.Pp
5075There are a number of operations that can be performed, as follows:
5076.Bl -tag -width "XXXX"
5077.It Fl decrypt
5078Decrypt mail using the supplied certificate and private key.
5079The input file is an encrypted mail message in MIME format.
5080The decrypted mail is written to the output file.
5081.It Fl encrypt
5082Encrypt mail for the given recipient certificates.
5083The input is the message to be encrypted.
5084The output file is the encrypted mail, in MIME format.
5085.It Fl pk7out
5086Take an input message and write out a PEM-encoded PKCS#7 structure.
5087.It Fl resign
5088Resign a message: take an existing message and one or more new signers.
5089.It Fl sign
5090Sign mail using the supplied certificate and private key.
5091The input file is the message to be signed.
5092The signed message, in MIME format, is written to the output file.
5093.It Fl verify
5094Verify signed mail.
5095The input is a signed mail message and the output is the signed data.
5096Both clear text and opaque signing is supported.
5097.El
5098.Pp
5099The remaining options are as follows:
5100.Bl -tag -width "XXXX"
5101.It Xo
5102.Fl aes128 | aes192 | aes256 | des |
5103.Fl des3 | rc2-40 | rc2-64 | rc2-128
5104.Xc
5105The encryption algorithm to use.
5106128-, 192-, or 256-bit AES, DES (56 bits), triple DES (168 bits),
5107or 40-, 64-, or 128-bit RC2, respectively;
5108if not specified, 40-bit RC2 is
5109used.
5110Only used with
5111.Fl encrypt .
5112.It Fl binary
5113Normally, the input message is converted to
5114.Qq canonical
5115format which uses CR/LF as end of line,
5116as required by the S/MIME specification.
5117When this option is present, no translation occurs.
5118This is useful when handling binary data which may not be in MIME format.
5119.It Fl CAfile Ar file
5120A
5121.Ar file
5122containing trusted CA certificates; only used with
5123.Fl verify .
5124.It Fl CApath Ar directory
5125A
5126.Ar directory
5127containing trusted CA certificates; only used with
5128.Fl verify .
5129This directory must be a standard certificate directory:
5130that is, a hash of each subject name (using
5131.Nm x509 -hash )
5132should be linked to each certificate.
5133.It Ar cert.pem ...
5134One or more certificates of message recipients: used when encrypting
5135a message.
5136.It Fl certfile Ar file
5137Allows additional certificates to be specified.
5138When signing, these will be included with the message.
5139When verifying, these will be searched for the signers' certificates.
5140The certificates should be in PEM format.
5141.It Xo
5142.Fl check_ss_sig ,
5143.Fl crl_check ,
5144.Fl crl_check_all ,
5145.Fl extended_crl ,
5146.Fl ignore_critical ,
5147.Fl issuer_checks ,
5148.Fl policy_check ,
5149.Fl x509_strict
5150.Xc
5151Set various certificate chain validation options.
5152See the
5153.Nm verify
5154command for details.
5155.It Fl content Ar file
5156A file containing the detached content.
5157This is only useful with the
5158.Fl verify
5159option,
5160and only usable if the PKCS#7 structure is using the detached
5161signature form where the content is not included.
5162This option will override any content if the input format is S/MIME
5163and it uses the multipart/signed MIME content type.
5164.It Xo
5165.Fl from Ar addr ,
5166.Fl subject Ar s ,
5167.Fl to Ar addr
5168.Xc
5169The relevant mail headers.
5170These are included outside the signed
5171portion of a message so they may be included manually.
5172When signing, many S/MIME
5173mail clients check that the signer's certificate email
5174address matches the From: address.
5175.It Fl in Ar file
5176The input file to read from.
5177.It Fl indef
5178Enable streaming I/O for encoding operations.
5179This permits single pass processing of data without
5180the need to hold the entire contents in memory,
5181potentially supporting very large files.
5182Streaming is automatically set for S/MIME signing with detached
5183data if the output format is SMIME;
5184it is currently off by default for all other operations.
5185.It Fl inform Cm der | pem | smime
5186The input format.
5187.It Fl inkey Ar file
5188The private key to use when signing or decrypting,
5189which must match the corresponding certificate.
5190If this option is not specified, the private key must be included
5191in the certificate file specified with
5192the
5193.Fl recip
5194or
5195.Fl signer
5196file.
5197When signing,
5198this option can be used multiple times to specify successive keys.
5199.It Fl keyform Cm der | pem
5200Input private key format.
5201The default is
5202.Cm pem .
5203.It Fl md Ar digest
5204The digest algorithm to use when signing or resigning.
5205If not present then the default digest algorithm for the signing key is used
5206(usually SHA1).
5207.It Fl noattr
5208Do not include attributes.
5209.It Fl nocerts
5210Do not include the signer's certificate.
5211This will reduce the size of the signed message but the verifier must
5212have a copy of the signer's certificate available locally (passed using the
5213.Fl certfile
5214option, for example).
5215.It Fl nochain
5216Do not do chain verification of signers' certificates: that is,
5217don't use the certificates in the signed message as untrusted CAs.
5218.It Fl nodetach
5219When signing a message, use opaque signing: this form is more resistant
5220to translation by mail relays but it cannot be read by mail agents that
5221do not support S/MIME.
5222Without this option cleartext signing with the MIME type
5223multipart/signed is used.
5224.It Fl noindef
5225Disable streaming I/O where it would produce an encoding of indefinite length
5226(currently has no effect).
5227.It Fl nointern
5228Only use certificates specified in the
5229.Fl certfile .
5230The supplied certificates can still be used as untrusted CAs.
5231.It Fl nosigs
5232Do not try to verify the signatures on the message.
5233.It Fl nosmimecap
5234Exclude the list of supported algorithms from signed attributes,
5235other options such as signing time and content type are still included.
5236.It Fl noverify
5237Do not verify the signer's certificate of a signed message.
5238.It Fl out Ar file
5239The output file to write to.
5240.It Fl outform Cm der | pem | smime
5241The output format.
5242The default is smime, which writes an S/MIME format message.
5243.Cm pem
5244and
5245.Cm der
5246change this to write PEM and DER format PKCS#7 structures instead.
5247This currently only affects the output format of the PKCS#7
5248structure; if no PKCS#7 structure is being output (for example with
5249.Fl verify
5250or
5251.Fl decrypt )
5252this option has no effect.
5253.It Fl passin Ar arg
5254The key password source.
5255.It Fl recip Ar file
5256The recipients certificate when decrypting a message.
5257This certificate
5258must match one of the recipients of the message or an error occurs.
5259.It Fl signer Ar file
5260A signing certificate when signing or resigning a message;
5261this option can be used multiple times if more than one signer is required.
5262If a message is being verified, the signer's certificates will be
5263written to this file if the verification was successful.
5264.It Fl stream
5265The same as
5266.Fl indef .
5267.It Fl text
5268Add plain text (text/plain) MIME
5269headers to the supplied message if encrypting or signing.
5270If decrypting or verifying, it strips off text headers:
5271if the decrypted or verified message is not of MIME type text/plain
5272then an error occurs.
5273.El
5274.Pp
5275The exit codes for
5276.Nm smime
5277are as follows:
5278.Pp
5279.Bl -tag -width "XXXX" -offset 3n -compact
5280.It 0
5281The operation was completely successful.
5282.It 1
5283An error occurred parsing the command options.
5284.It 2
5285One of the input files could not be read.
5286.It 3
5287An error occurred creating the file or when reading the message.
5288.It 4
5289An error occurred decrypting or verifying the message.
5290.It 5
5291An error occurred writing certificates.
5292.El
5293.Tg speed
5294.Sh SPEED
5295.Bl -hang -width "openssl speed"
5296.It Nm openssl speed
5297.Bk -words
5298.Op Ar algorithm
5299.Op Fl decrypt
5300.Op Fl elapsed
5301.Op Fl evp Ar algorithm
5302.Op Fl mr
5303.Op Fl multi Ar number
5304.Op Fl unaligned Ar number
5305.Ek
5306.El
5307.Pp
5308The
5309.Nm speed
5310command is used to test the performance of cryptographic algorithms.
5311.Bl -tag -width "XXXX"
5312.It Ar algorithm
5313Perform the test using
5314.Ar algorithm .
5315The default is to test all algorithms.
5316.It Fl decrypt
5317Time decryption instead of encryption;
5318must be used with
5319.Fl evp .
5320.It Fl elapsed
5321Measure time in real time instead of CPU user time.
5322.It Fl evp Ar algorithm
5323Perform the test using one of the algorithms accepted by
5324.Xr EVP_get_cipherbyname 3 .
5325.It Fl mr
5326Produce machine readable output.
5327.It Fl multi Ar number
5328Run
5329.Ar number
5330benchmarks in parallel.
5331.It Fl unaligned Ar number
5332Use allocated buffers with an offset of
5333.Ar number
5334bytes from the alignment provided by
5335.Xr malloc 3 .
5336.Ar number
5337should be between 0 and 16.
5338.El
5339.Tg ts
5340.Sh TS
5341.Bk -words
5342.Bl -hang -width "openssl ts"
5343.It Nm openssl ts
5344.Fl query
5345.Op Fl md4 | md5 | ripemd160 | sha1
5346.Op Fl cert
5347.Op Fl config Ar configfile
5348.Op Fl data Ar file_to_hash
5349.Op Fl digest Ar digest_bytes
5350.Op Fl in Ar request.tsq
5351.Op Fl no_nonce
5352.Op Fl out Ar request.tsq
5353.Op Fl policy Ar object_id
5354.Op Fl text
5355.It Nm openssl ts
5356.Fl reply
5357.Op Fl chain Ar certs_file.pem
5358.Op Fl config Ar configfile
5359.Op Fl in Ar response.tsr
5360.Op Fl inkey Ar private.pem
5361.Op Fl out Ar response.tsr
5362.Op Fl passin Ar arg
5363.Op Fl policy Ar object_id
5364.Op Fl queryfile Ar request.tsq
5365.Op Fl section Ar tsa_section
5366.Op Fl signer Ar tsa_cert.pem
5367.Op Fl text
5368.Op Fl token_in
5369.Op Fl token_out
5370.It Nm openssl ts
5371.Fl verify
5372.Op Fl CAfile Ar trusted_certs.pem
5373.Op Fl CApath Ar trusted_cert_path
5374.Op Fl data Ar file_to_hash
5375.Op Fl digest Ar digest_bytes
5376.Op Fl in Ar response.tsr
5377.Op Fl queryfile Ar request.tsq
5378.Op Fl token_in
5379.Op Fl untrusted Ar cert_file.pem
5380.El
5381.Ek
5382.Pp
5383The
5384.Nm ts
5385command is a basic Time Stamping Authority (TSA) client and server
5386application as specified in RFC 3161 (Time-Stamp Protocol, TSP).
5387A TSA can be part of a PKI deployment and its role is to provide long
5388term proof of the existence of specific data.
5389Here is a brief description of the protocol:
5390.Bl -enum
5391.It
5392The TSA client computes a one-way hash value for a data file and sends
5393the hash to the TSA.
5394.It
5395The TSA attaches the current date and time to the received hash value,
5396signs them and sends the time stamp token back to the client.
5397By creating this token the TSA certifies the existence of the original
5398data file at the time of response generation.
5399.It
5400The TSA client receives the time stamp token and verifies the
5401signature on it.
5402It also checks if the token contains the same hash
5403value that it had sent to the TSA.
5404.El
5405.Pp
5406There is one DER-encoded protocol data unit defined for transporting a time
5407stamp request to the TSA and one for sending the time stamp response
5408back to the client.
5409The
5410.Nm ts
5411command has three main functions:
5412creating a time stamp request based on a data file;
5413creating a time stamp response based on a request;
5414and verifying if a response corresponds
5415to a particular request or a data file.
5416.Pp
5417There is no support for sending the requests/responses automatically
5418over HTTP or TCP yet as suggested in RFC 3161.
5419Users must send the requests either by FTP or email.
5420.Pp
5421The
5422.Fl query
5423switch can be used for creating and printing a time stamp
5424request with the following options:
5425.Bl -tag -width Ds
5426.It Fl cert
5427Expect the TSA to include its signing certificate in the response.
5428.It Fl config Ar configfile
5429Specify an alternative configuration file.
5430Only the OID section is used.
5431.It Fl data Ar file_to_hash
5432The data file for which the time stamp request needs to be created.
5433The default is standard input.
5434.It Fl digest Ar digest_bytes
5435Specify the message imprint explicitly without the data file.
5436The imprint must be specified in a hexadecimal format,
5437two characters per byte,
5438the bytes optionally separated by colons.
5439The number of bytes must match the message digest algorithm in use.
5440.It Fl in Ar request.tsq
5441A previously created time stamp request in DER
5442format that will be printed into the output file.
5443Useful for examining the content of a request in human-readable format.
5444.It Fl md4 | md5 | ripemd160 | sha | sha1
5445The message digest to apply to the data file.
5446It supports all the message digest algorithms that are supported by the
5447.Nm dgst
5448command.
5449The default is SHA1.
5450.It Fl no_nonce
5451Specify no nonce in the request.
5452The default, to include a 64-bit long pseudo-random nonce,
5453is recommended to protect against replay attacks.
5454.It Fl out Ar request.tsq
5455The output file to write to,
5456or standard output if not specified.
5457.It Fl policy Ar object_id
5458The policy that the client expects the TSA to use for creating the
5459time stamp token.
5460Either dotted OID notation or OID names defined
5461in the config file can be used.
5462If no policy is requested, the TSA uses its own default policy.
5463.It Fl text
5464Output in human-readable text format instead of DER.
5465.El
5466.Pp
5467A time stamp response (TimeStampResp) consists of a response status
5468and the time stamp token itself (ContentInfo),
5469if the token generation was successful.
5470The
5471.Fl reply
5472command is for creating a time stamp
5473response or time stamp token based on a request and printing the
5474response/token in human-readable format.
5475If
5476.Fl token_out
5477is not specified the output is always a time stamp response (TimeStampResp),
5478otherwise it is a time stamp token (ContentInfo).
5479.Bl -tag -width Ds
5480.It Fl chain Ar certs_file.pem
5481The collection of PEM certificates
5482that will be included in the response
5483in addition to the signer certificate if the
5484.Fl cert
5485option was used for the request.
5486This file is supposed to contain the certificate chain
5487for the signer certificate from its issuer upwards.
5488The
5489.Fl reply
5490command does not build a certificate chain automatically.
5491.It Fl config Ar configfile
5492Specify an alternative configuration file.
5493.It Fl in Ar response.tsr
5494Specify a previously created time stamp response (or time stamp token, if
5495.Fl token_in
5496is also specified)
5497in DER format that will be written to the output file.
5498This option does not require a request;
5499it is useful, for example,
5500to examine the content of a response or token
5501or to extract the time stamp token from a response.
5502If the input is a token and the output is a time stamp response, a default
5503.Qq granted
5504status info is added to the token.
5505.It Fl inkey Ar private.pem
5506The signer private key of the TSA in PEM format.
5507Overrides the
5508.Cm signer_key
5509config file option.
5510.It Fl out Ar response.tsr
5511The response is written to this file.
5512The format and content of the file depends on other options (see
5513.Fl text
5514and
5515.Fl token_out ) .
5516The default is stdout.
5517.It Fl passin Ar arg
5518The key password source.
5519.It Fl policy Ar object_id
5520The default policy to use for the response.
5521Either dotted OID notation or OID names defined
5522in the config file can be used.
5523If no policy is requested, the TSA uses its own default policy.
5524.It Fl queryfile Ar request.tsq
5525The file containing a DER-encoded time stamp request.
5526.It Fl section Ar tsa_section
5527The config file section containing the settings for response generation.
5528.It Fl signer Ar tsa_cert.pem
5529The PEM signer certificate of the TSA.
5530The TSA signing certificate must have exactly one extended key usage
5531assigned to it: timeStamping.
5532The extended key usage must also be critical,
5533otherwise the certificate is going to be refused.
5534Overrides the
5535.Cm signer_cert
5536variable of the config file.
5537.It Fl text
5538Output in human-readable text format instead of DER.
5539.It Fl token_in
5540The input is a DER-encoded time stamp token (ContentInfo)
5541instead of a time stamp response (TimeStampResp).
5542.It Fl token_out
5543The output is a time stamp token (ContentInfo)
5544instead of a time stamp response (TimeStampResp).
5545.El
5546.Pp
5547The
5548.Fl verify
5549command is for verifying if a time stamp response or time stamp token
5550is valid and matches a particular time stamp request or data file.
5551The
5552.Fl verify
5553command does not use the configuration file.
5554.Bl -tag -width Ds
5555.It Fl CAfile Ar trusted_certs.pem
5556The file containing a set of trusted self-signed PEM CA certificates.
5557See
5558.Nm verify
5559for additional details.
5560Either this option or
5561.Fl CApath
5562must be specified.
5563.It Fl CApath Ar trusted_cert_path
5564The directory containing the trusted CA certificates of the client.
5565See
5566.Nm verify
5567for additional details.
5568Either this option or
5569.Fl CAfile
5570must be specified.
5571.It Fl data Ar file_to_hash
5572The response or token must be verified against
5573.Ar file_to_hash .
5574The file is hashed with the message digest algorithm specified in the token.
5575The
5576.Fl digest
5577and
5578.Fl queryfile
5579options must not be specified with this one.
5580.It Fl digest Ar digest_bytes
5581The response or token must be verified against the message digest specified
5582with this option.
5583The number of bytes must match the message digest algorithm
5584specified in the token.
5585The
5586.Fl data
5587and
5588.Fl queryfile
5589options must not be specified with this one.
5590.It Fl in Ar response.tsr
5591The time stamp response that needs to be verified, in DER format.
5592This option in mandatory.
5593.It Fl queryfile Ar request.tsq
5594The original time stamp request, in DER format.
5595The
5596.Fl data
5597and
5598.Fl digest
5599options must not be specified with this one.
5600.It Fl token_in
5601The input is a DER-encoded time stamp token (ContentInfo)
5602instead of a time stamp response (TimeStampResp).
5603.It Fl untrusted Ar cert_file.pem
5604Additional untrusted PEM certificates which may be needed
5605when building the certificate chain for the TSA's signing certificate.
5606This file must contain the TSA signing certificate and
5607all intermediate CA certificates unless the response includes them.
5608.El
5609.Pp
5610Options specified on the command line always override
5611the settings in the config file:
5612.Bl -tag -width Ds
5613.It Cm tsa Ar section , Cm default_tsa
5614This is the main section and it specifies the name of another section
5615that contains all the options for the
5616.Fl reply
5617option.
5618This section can be overridden with the
5619.Fl section
5620command line switch.
5621.It Cm oid_file
5622See
5623.Nm ca
5624for a description.
5625.It Cm oid_section
5626See
5627.Nm ca
5628for a description.
5629.It Cm serial
5630The file containing the hexadecimal serial number of the
5631last time stamp response created.
5632This number is incremented by 1 for each response.
5633If the file does not exist at the time of response generation,
5634a new file is created with serial number 1.
5635This parameter is mandatory.
5636.It Cm signer_cert
5637TSA signing certificate, in PEM format.
5638The same as the
5639.Fl signer
5640command line option.
5641.It Cm certs
5642A set of PEM-encoded certificates that need to be
5643included in the response.
5644The same as the
5645.Fl chain
5646command line option.
5647.It Cm signer_key
5648The private key of the TSA, in PEM format.
5649The same as the
5650.Fl inkey
5651command line option.
5652.It Cm default_policy
5653The default policy to use when the request does not mandate any policy.
5654The same as the
5655.Fl policy
5656command line option.
5657.It Cm other_policies
5658Comma separated list of policies that are also acceptable by the TSA
5659and used only if the request explicitly specifies one of them.
5660.It Cm digests
5661The list of message digest algorithms that the TSA accepts.
5662At least one algorithm must be specified.
5663This parameter is mandatory.
5664.It Cm accuracy
5665The accuracy of the time source of the TSA in seconds, milliseconds
5666and microseconds.
5667For example, secs:1, millisecs:500, microsecs:100.
5668If any of the components is missing,
5669zero is assumed for that field.
5670.It Cm clock_precision_digits
5671The maximum number of digits, which represent the fraction of seconds,
5672that need to be included in the time field.
5673The trailing zeroes must be removed from the time,
5674so there might actually be fewer digits
5675or no fraction of seconds at all.
5676The maximum value is 6;
5677the default is 0.
5678.It Cm ordering
5679If this option is yes,
5680the responses generated by this TSA can always be ordered,
5681even if the time difference between two responses is less
5682than the sum of their accuracies.
5683The default is no.
5684.It Cm tsa_name
5685Set this option to yes if the subject name of the TSA must be included in
5686the TSA name field of the response.
5687The default is no.
5688.It Cm ess_cert_id_chain
5689The SignedData objects created by the TSA always contain the
5690certificate identifier of the signing certificate in a signed
5691attribute (see RFC 2634, Enhanced Security Services).
5692If this option is set to yes and either the
5693.Cm certs
5694variable or the
5695.Fl chain
5696option is specified then the certificate identifiers of the chain will also
5697be included in the SigningCertificate signed attribute.
5698If this variable is set to no,
5699only the signing certificate identifier is included.
5700The default is no.
5701.El
5702.Tg verify
5703.Sh VERIFY
5704.Bl -hang -width "openssl verify"
5705.It Nm openssl verify
5706.Bk -words
5707.Op Fl CAfile Ar file
5708.Op Fl CApath Ar directory
5709.Op Fl check_ss_sig
5710.Op Fl CRLfile Ar file
5711.Op Fl crl_check
5712.Op Fl crl_check_all
5713.Op Fl explicit_policy
5714.Op Fl extended_crl
5715.Op Fl help
5716.Op Fl ignore_critical
5717.Op Fl inhibit_any
5718.Op Fl inhibit_map
5719.Op Fl issuer_checks
5720.Op Fl legacy_verify
5721.Op Fl policy_check
5722.Op Fl purpose Ar purpose
5723.Op Fl trusted Ar file
5724.Op Fl untrusted Ar file
5725.Op Fl verbose
5726.Op Fl x509_strict
5727.Op Ar certificates
5728.Ek
5729.El
5730.Pp
5731The
5732.Nm verify
5733command verifies certificate chains.
5734.Pp
5735The options are as follows:
5736.Bl -tag -width Ds
5737.It Fl CAfile Ar file
5738A
5739.Ar file
5740of trusted certificates.
5741The
5742.Ar file
5743should contain multiple certificates in PEM format, concatenated together.
5744.It Fl CApath Ar directory
5745A
5746.Ar directory
5747of trusted certificates.
5748The certificates, or symbolic links to them,
5749should have names of the form
5750.Ar hash Ns .0 ,
5751where
5752.Ar hash
5753is the hashed certificate subject name
5754(see the
5755.Fl hash
5756option of the
5757.Nm x509
5758utility).
5759.It Fl check_ss_sig
5760Verify the signature on the self-signed root CA.
5761This is disabled by default
5762because it doesn't add any security.
5763.It Fl CRLfile Ar file
5764The
5765.Ar file
5766should contain one or more CRLs in PEM format.
5767.It Fl crl_check
5768Check end entity certificate validity by attempting to look up a valid CRL.
5769If a valid CRL cannot be found, an error occurs.
5770.It Fl crl_check_all
5771Check the validity of all certificates in the chain by attempting
5772to look up valid CRLs.
5773.It Fl explicit_policy
5774Set policy variable require-explicit-policy (RFC 3280).
5775.It Fl extended_crl
5776Enable extended CRL features such as indirect CRLs and alternate CRL
5777signing keys.
5778.It Fl help
5779Print a usage message.
5780.It Fl ignore_critical
5781Ignore critical extensions instead of rejecting the certificate.
5782.It Fl inhibit_any
5783Set policy variable inhibit-any-policy (RFC 3280).
5784.It Fl inhibit_map
5785Set policy variable inhibit-policy-mapping (RFC 3280).
5786.It Fl issuer_checks
5787Print diagnostics relating to searches for the issuer certificate
5788of the current certificate
5789showing why each candidate issuer certificate was rejected.
5790The presence of rejection messages
5791does not itself imply that anything is wrong:
5792during the normal verify process several rejections may take place.
5793.It Fl legacy_verify
5794Use the legacy X.509 certificate chain verification code.
5795.It Fl policy_check
5796Enable certificate policy processing.
5797.It Fl purpose Ar purpose
5798The intended use for the certificate.
5799Without this option no chain verification will be done.
5800Currently accepted uses are
5801.Cm sslclient , sslserver ,
5802.Cm nssslserver , smimesign ,
5803.Cm smimeencrypt , crlsign ,
5804.Cm any ,
5805and
5806.Cm ocsphelper .
5807.It Fl trusted Ar file
5808A
5809.Ar file
5810of trusted certificates.
5811The
5812.Ar file
5813should contain multiple certificates.
5814.It Fl untrusted Ar file
5815A
5816.Ar file
5817of untrusted certificates.
5818The
5819.Ar file
5820should contain multiple certificates.
5821.It Fl verbose
5822Print extra information about the operations being performed.
5823.It Fl x509_strict
5824Disable workarounds for broken certificates which have to be disabled
5825for strict X.509 compliance.
5826.It Ar certificates
5827One or more PEM
5828.Ar certificates
5829to verify.
5830If no certificate files are included, an attempt is made to read
5831a certificate from standard input.
5832If the first certificate filename begins with a dash,
5833use a lone dash to mark the last option.
5834.El
5835.Pp
5836The
5837.Nm verify
5838program uses the same functions as the internal SSL and S/MIME verification,
5839with one crucial difference:
5840wherever possible an attempt is made to continue after an error,
5841whereas normally the verify operation would halt on the first error.
5842This allows all the problems with a certificate chain to be determined.
5843.Pp
5844The verify operation consists of a number of separate steps.
5845Firstly a certificate chain is built up starting from the supplied certificate
5846and ending in the root CA.
5847It is an error if the whole chain cannot be built up.
5848The chain is built up by looking up the issuer's certificate of the current
5849certificate.
5850If a certificate is found which is its own issuer, it is assumed
5851to be the root CA.
5852.Pp
5853All certificates whose subject name matches the issuer name
5854of the current certificate are subject to further tests.
5855The relevant authority key identifier components of the current certificate
5856(if present) must match the subject key identifier (if present)
5857and issuer and serial number of the candidate issuer;
5858in addition the
5859.Cm keyUsage
5860extension of the candidate issuer (if present) must permit certificate signing.
5861.Pp
5862The lookup first looks in the list of untrusted certificates and if no match
5863is found the remaining lookups are from the trusted certificates.
5864The root CA is always looked up in the trusted certificate list:
5865if the certificate to verify is a root certificate,
5866then an exact match must be found in the trusted list.
5867.Pp
5868The second operation is to check every untrusted certificate's extensions for
5869consistency with the supplied purpose.
5870If the
5871.Fl purpose
5872option is not included, then no checks are done.
5873The supplied or
5874.Qq leaf
5875certificate must have extensions compatible with the supplied purpose
5876and all other certificates must also be valid CA certificates.
5877The precise extensions required are described in more detail in
5878the
5879.Nm X509
5880section below.
5881.Pp
5882The third operation is to check the trust settings on the root CA.
5883The root CA should be trusted for the supplied purpose.
5884A certificate with no trust settings is considered to be valid for
5885all purposes.
5886.Pp
5887The final operation is to check the validity of the certificate chain.
5888The validity period is checked against the current system time and the
5889.Cm notBefore
5890and
5891.Cm notAfter
5892dates in the certificate.
5893The certificate signatures are also checked at this point.
5894.Pp
5895If all operations complete successfully, the certificate is considered
5896valid.
5897If any operation fails then the certificate is not valid.
5898When a verify operation fails, the output messages can be somewhat cryptic.
5899The general form of the error message is:
5900.Bd -literal
5901server.pem: /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024-bit)
5902error 24 at 1 depth lookup:invalid CA certificate
5903.Ed
5904.Pp
5905The first line contains the name of the certificate being verified, followed by
5906the subject name of the certificate.
5907The second line contains the error number as defined by the
5908.Dv X509_V_ERR_*
5909constants in
5910.In openssl/x509_vfy.h ,
5911the associated error message documented in
5912.Xr X509_STORE_CTX_get_error 3 ,
5913and the depth.
5914The depth is the number of the certificate being verified when a
5915problem was detected starting with zero for the certificate being verified
5916itself, then 1 for the CA that signed the certificate and so on.
5917.Tg version
5918.Sh VERSION
5919.Nm openssl version
5920.Op Fl abdfpv
5921.Pp
5922The
5923.Nm version
5924command is used to print out version information about
5925.Nm openssl .
5926.Pp
5927The options are as follows:
5928.Bl -tag -width Ds
5929.It Fl a
5930All information: this is the same as setting all the other flags.
5931.It Fl b
5932The date the current version of
5933.Nm openssl
5934was built.
5935.It Fl d
5936.Ev OPENSSLDIR
5937setting.
5938.It Fl f
5939Compilation flags.
5940.It Fl p
5941Platform setting.
5942.It Fl v
5943The current
5944.Nm openssl
5945version.
5946.El
5947.Tg x509
5948.Sh X509
5949.Bl -hang -width "openssl x509"
5950.It Nm openssl x509
5951.Bk -words
5952.Op Fl addreject Ar arg
5953.Op Fl addtrust Ar arg
5954.Op Fl alias
5955.Op Fl CA Ar file
5956.Op Fl CAcreateserial
5957.Op Fl CAform Cm der | pem
5958.Op Fl CAkey Ar file
5959.Op Fl CAkeyform Cm der | pem
5960.Op Fl CAserial Ar file
5961.Op Fl certopt Ar option
5962.Op Fl checkend Ar arg
5963.Op Fl clrext
5964.Op Fl clrreject
5965.Op Fl clrtrust
5966.Op Fl dates
5967.Op Fl days Ar arg
5968.Op Fl email
5969.Op Fl enddate
5970.Op Fl extensions Ar section
5971.Op Fl extfile Ar file
5972.Op Fl fingerprint
5973.Op Fl force_pubkey Ar key
5974.Op Fl hash
5975.Op Fl in Ar file
5976.Op Fl inform Cm der | net | pem
5977.Op Fl issuer
5978.Op Fl issuer_hash
5979.Op Fl issuer_hash_old
5980.Op Fl keyform Cm der | pem
5981.Op Fl md5 | sha1
5982.Op Fl modulus
5983.Op Fl multivalue-rdn
5984.Op Fl nameopt Ar option
5985.Op Fl new
5986.Op Fl next_serial
5987.Op Fl noout
5988.Op Fl ocsp_uri
5989.Op Fl ocspid
5990.Op Fl out Ar file
5991.Op Fl outform Cm der | net | pem
5992.Op Fl passin Ar arg
5993.Op Fl pubkey
5994.Op Fl purpose
5995.Op Fl req
5996.Op Fl serial
5997.Op Fl set_issuer Ar name
5998.Op Fl set_serial Ar n
5999.Op Fl set_subject Ar name
6000.Op Fl setalias Ar arg
6001.Op Fl signkey Ar file
6002.Op Fl sigopt Ar nm:v
6003.Op Fl startdate
6004.Op Fl subject
6005.Op Fl subject_hash
6006.Op Fl subject_hash_old
6007.Op Fl text
6008.Op Fl trustout
6009.Op Fl utf8
6010.Op Fl x509toreq
6011.Ek
6012.El
6013.Pp
6014The
6015.Nm x509
6016command is a multi-purpose certificate utility.
6017It can be used to display certificate information, convert certificates to
6018various forms, sign certificate requests like a
6019.Qq mini CA ,
6020or edit certificate trust settings.
6021.Pp
6022The following are x509 input, output, and general purpose options:
6023.Bl -tag -width "XXXX"
6024.It Fl in Ar file
6025The input file to read from,
6026or standard input if not specified.
6027This option cannot be used with
6028.Fl new .
6029.It Fl inform Cm der | net | pem
6030The input format.
6031Normally, the command will expect an X.509 certificate,
6032but this can change if other options such as
6033.Fl in
6034or
6035.Fl req
6036are present.
6037.It Fl md5 | sha1
6038The digest to use.
6039This affects any signing or display option that uses a message digest,
6040such as the
6041.Fl fingerprint , signkey ,
6042and
6043.Fl CA
6044options.
6045If not specified, MD5 is used.
6046SHA1 is always used with DSA keys.
6047.It Fl out Ar file
6048The output file to write to,
6049or standard output if none is specified.
6050.It Fl outform Cm der | net | pem
6051The output format.
6052.It Fl passin Ar arg
6053The key password source.
6054.El
6055.Pp
6056The following are x509 display options:
6057.Bl -tag -width "XXXX"
6058.It Fl certopt Ar option
6059Customise the output format used with
6060.Fl text ,
6061either using a list of comma-separated options or by specifying
6062.Fl certopt
6063multiple times.
6064The default behaviour is to print all fields.
6065The options are as follows:
6066.Pp
6067.Bl -tag -width "no_extensions" -offset indent -compact
6068.It Cm ca_default
6069Equivalent to
6070.Cm no_issuer , no_pubkey , no_header ,
6071.Cm no_version , no_sigdump ,
6072and
6073.Cm no_signame .
6074.It Cm compatible
6075Equivalent to no output options at all.
6076.It Cm ext_default
6077Print unsupported certificate extensions.
6078.It Cm ext_dump
6079Hex dump unsupported extensions.
6080.It Cm ext_error
6081Print an error message for unsupported certificate extensions.
6082.It Cm ext_parse
6083ASN.1 parse unsupported extensions.
6084.It Cm no_aux
6085Do not print certificate trust information.
6086.It Cm no_extensions
6087Do not print X509V3 extensions.
6088.It Cm no_header
6089Do not print header (Certificate and Data) information.
6090.It Cm no_issuer
6091Do not print the issuer name.
6092.It Cm no_pubkey
6093Do not print the public key.
6094.It Cm no_serial
6095Do not print the serial number.
6096.It Cm no_sigdump
6097Do not give a hexadecimal dump of the certificate signature.
6098.It Cm no_signame
6099Do not print the signature algorithm used.
6100.It Cm no_subject
6101Do not print the subject name.
6102.It Cm no_validity
6103Do not print the
6104.Cm notBefore
6105and
6106.Cm notAfter
6107(validity) fields.
6108.It Cm no_version
6109Do not print the version number.
6110.El
6111.It Fl dates
6112Print the start and expiry date of a certificate.
6113.It Fl email
6114Output the email addresses, if any.
6115.It Fl enddate
6116Print the expiry date of the certificate; that is, the
6117.Cm notAfter
6118date.
6119.It Fl fingerprint
6120Print the digest of the DER-encoded version of the whole certificate.
6121.It Fl hash
6122A synonym for
6123.Fl subject_hash .
6124.It Fl issuer
6125Print the issuer name.
6126.It Fl issuer_hash
6127Print the hash of the certificate issuer name.
6128.It Fl issuer_hash_old
6129Print the hash of the certificate issuer name
6130using the older algorithm as used by
6131.Nm openssl
6132versions before 1.0.0.
6133.It Fl modulus
6134Print the value of the modulus of the public key contained in the certificate.
6135.It Fl multivalue-rdn
6136This option causes the
6137.Fl subj
6138argument to be interpreted with full support for multivalued RDNs,
6139for example
6140.Qq "/DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe" .
6141If
6142.Fl multivalue-rdn
6143is not used, the UID value is set to
6144.Qq "123456+CN=John Doe" .
6145.It Fl nameopt Ar option
6146Customise how the subject or issuer names are displayed,
6147either using a list of comma-separated options or by specifying
6148.Fl nameopt
6149multiple times.
6150The default behaviour is to use the
6151.Cm oneline
6152format.
6153The options,
6154which can be preceded by a dash to turn them off,
6155are as follows:
6156.Bl -tag -width "XXXX"
6157.It Cm align
6158Align field values for a more readable output.
6159Only usable with
6160.Ar sep_multiline .
6161.It Cm compat
6162Use the old format,
6163equivalent to specifying no options at all.
6164.It Cm dn_rev
6165Reverse the fields of the DN, as required by RFC 2253.
6166As a side effect, this also reverses the order of multiple AVAs.
6167.It Cm dump_all
6168Dump all fields.
6169When used with
6170.Ar dump_der ,
6171it allows the DER encoding of the structure to be unambiguously determined.
6172.It Cm dump_der
6173Any fields that need to be hexdumped are
6174dumped using the DER encoding of the field.
6175Otherwise just the content octets will be displayed.
6176Both options use the RFC 2253 #XXXX... format.
6177.It Cm dump_nostr
6178Dump non-character string types
6179(for example OCTET STRING);
6180usually, non-character string types are displayed
6181as though each content octet represents a single character.
6182.It Cm dump_unknown
6183Dump any field whose OID is not recognised by
6184.Nm openssl .
6185.It Cm esc_2253
6186Escape the
6187.Qq special
6188characters required by RFC 2253 in a field that is
6189.Dq \& ,+"<>; .
6190Additionally,
6191.Sq #
6192is escaped at the beginning of a string
6193and a space character at the beginning or end of a string.
6194.It Cm esc_ctrl
6195Escape control characters.
6196That is, those with ASCII values less than 0x20 (space)
6197and the delete (0x7f) character.
6198They are escaped using the RFC 2253 \eXX notation (where XX are two hex
6199digits representing the character value).
6200.It Cm esc_msb
6201Escape characters with the MSB set; that is, with ASCII values larger than
6202127.
6203.It Cm multiline
6204A multiline format.
6205Equivalent to
6206.Cm esc_ctrl , esc_msb , sep_multiline ,
6207.Cm space_eq , lname ,
6208and
6209.Cm align .
6210.It Cm no_type
6211Do not attempt to interpret multibyte characters.
6212That is, content octets are merely dumped as though one octet
6213represents each character.
6214This is useful for diagnostic purposes
6215but results in rather odd looking output.
6216.It Cm nofname , sname , lname , oid
6217Alter how the field name is displayed:
6218.Cm nofname
6219does not display the field at all;
6220.Cm sname
6221uses the short name form (CN for
6222.Cm commonName ,
6223for example);
6224.Cm lname
6225uses the long form.
6226.Cm oid
6227represents the OID in numerical form and is useful for diagnostic purpose.
6228.It Cm oneline
6229A one line format which is more readable than
6230.Cm RFC2253 .
6231Equivalent to
6232.Cm esc_2253 , esc_ctrl , esc_msb , utf8 ,
6233.Cm dump_nostr , dump_der , use_quote , sep_comma_plus_spc ,
6234.Cm space_eq ,
6235and
6236.Cm sname .
6237.It Cm RFC2253
6238Displays names compatible with RFC 2253.
6239Equivalent to
6240.Cm esc_2253 , esc_ctrl ,
6241.Cm esc_msb , utf8 , dump_nostr , dump_unknown ,
6242.Cm dump_der , sep_comma_plus , dn_rev ,
6243and
6244.Cm sname .
6245.It Cm sep_comma_plus , sep_comma_plus_space , sep_semi_plus_space , sep_multiline
6246Determine the field separators:
6247the first character is between RDNs and the second between multiple AVAs
6248(multiple AVAs are very rare and their use is discouraged).
6249The options ending in
6250.Qq space
6251additionally place a space after the separator to make it more readable.
6252.Cm sep_multiline
6253uses a linefeed character for the RDN separator and a spaced
6254.Sq +
6255for the AVA separator,
6256as well as indenting the fields by four characters.
6257If no field separator is specified then
6258.Cm sep_comma_plus_space
6259is used by default.
6260.It Cm show_type
6261Show the type of the ASN.1 character string.
6262The type precedes the field contents.
6263For example
6264.Qq BMPSTRING: Hello World .
6265.It Cm space_eq
6266Place spaces round the
6267.Sq =
6268character which follows the field name.
6269.It Cm use_quote
6270Escape some characters by surrounding the whole string with
6271.Sq \&"
6272characters.
6273Without the option, all escaping is done with the
6274.Sq \e
6275character.
6276.It Cm utf8
6277Convert all strings to UTF8 format first, as required by RFC 2253.
6278On a UTF8 compatible terminal,
6279the use of this option (and not setting
6280.Cm esc_msb )
6281may result in the correct display of multibyte characters.
6282Usually, multibyte characters larger than 0xff
6283are represented using the format \eUXXXX for 16 bits and \eWXXXXXXXX
6284for 32 bits,
6285and any UTF8Strings are converted to their character form first.
6286.El
6287.It Fl next_serial
6288Print the next serial number.
6289.It Fl noout
6290Do not output the encoded version of the request.
6291.It Fl ocsp_uri
6292Print the OCSP responder addresses, if any.
6293.It Fl ocspid
6294Print OCSP hash values for the subject name and public key.
6295.It Fl pubkey
6296Print the public key.
6297.It Fl serial
6298Print the certificate serial number.
6299.It Fl sigopt Ar nm:v
6300Pass options to the signature algorithm during sign or certify operations.
6301The names and values of these options are algorithm-specific.
6302.It Fl startdate
6303Print the start date of the certificate; that is, the
6304.Cm notBefore
6305date.
6306.It Fl subject
6307Print the subject name.
6308.It Fl subject_hash
6309Print the hash of the certificate subject name.
6310This is used in
6311.Nm openssl
6312to form an index to allow certificates in a directory to be looked up
6313by subject name.
6314.It Fl subject_hash_old
6315Print the hash of the certificate subject name
6316using the older algorithm as used by
6317.Nm openssl
6318versions before 1.0.0.
6319.It Fl text
6320Print the full certificate in text form.
6321.El
6322.Pp
6323A trusted certificate is a certificate which has several
6324additional pieces of information attached to it such as the permitted
6325and prohibited uses of the certificate and an alias.
6326When a certificate is being verified, at least one certificate must be trusted.
6327By default, a trusted certificate must be stored locally and be a root CA.
6328The following are x509 trust settings options:
6329.Bl -tag -width "XXXX"
6330.It Fl addreject Ar arg
6331Add a prohibited use.
6332Accepts the same values as the
6333.Fl addtrust
6334option.
6335.It Fl addtrust Ar arg
6336Add a trusted certificate use.
6337Any object name can be used here, but currently only
6338.Cm clientAuth
6339(SSL client use),
6340.Cm serverAuth
6341(SSL server use),
6342and
6343.Cm emailProtection
6344(S/MIME email) are used.
6345.It Fl alias
6346Output the certificate alias.
6347.It Fl clrreject
6348Clear all the prohibited or rejected uses of the certificate.
6349.It Fl clrtrust
6350Clear all the permitted or trusted uses of the certificate.
6351.It Fl purpose
6352Perform tests on the certificate extensions.
6353The same code is used when verifying untrusted certificates in chains,
6354so this section is useful if a chain is rejected by the verify code.
6355.Pp
6356The
6357.Cm basicConstraints
6358extension CA flag is used to determine whether the
6359certificate can be used as a CA.
6360If the CA flag is true, it is a CA;
6361if the CA flag is false, it is not a CA.
6362All CAs should have the CA flag set to true.
6363.Pp
6364If the
6365.Cm basicConstraints
6366extension is absent, then the certificate is
6367considered to be a possible CA;
6368other extensions are checked according to the intended use of the certificate.
6369A warning is given in this case because the certificate should really not
6370be regarded as a CA.
6371However it is allowed to be a CA to work around some broken software.
6372.Pp
6373If the certificate is a V1 certificate
6374(and thus has no extensions) and it is self-signed,
6375it is also assumed to be a CA but a warning is again given.
6376This is to work around the problem of Verisign roots
6377which are V1 self-signed certificates.
6378.Pp
6379If the
6380.Cm keyUsage
6381extension is present, then additional restraints are
6382made on the uses of the certificate.
6383A CA certificate must have the
6384.Cm keyCertSign
6385bit set if the
6386.Cm keyUsage
6387extension is present.
6388.Pp
6389The extended key usage extension places additional restrictions on the
6390certificate uses.
6391If this extension is present, whether critical or not,
6392the key can only be used for the purposes specified.
6393.Pp
6394A complete description of each test is given below.
6395The comments about
6396.Cm basicConstraints
6397and
6398.Cm keyUsage
6399and V1 certificates above apply to all CA certificates.
6400.Bl -tag -width "XXXX"
6401.It SSL Client
6402The extended key usage extension must be absent or include the
6403web client authentication OID.
6404.Cm keyUsage
6405must be absent or it must have the
6406.Cm digitalSignature
6407bit set.
6408The Netscape certificate type must be absent
6409or it must have the SSL client bit set.
6410.It SSL Client CA
6411The extended key usage extension must be absent or include the
6412web client authentication OID.
6413The Netscape certificate type must be absent
6414or it must have the SSL CA bit set:
6415this is used as a workaround if the
6416.Cm basicConstraints
6417extension is absent.
6418.It SSL Server
6419The extended key usage extension must be absent or include the
6420web server authentication and/or one of the SGC OIDs.
6421.Cm keyUsage
6422must be absent or it must have the
6423.Cm digitalSignature
6424set, the
6425.Cm keyEncipherment
6426set, or both bits set.
6427The Netscape certificate type must be absent or have the SSL server bit set.
6428.It SSL Server CA
6429The extended key usage extension must be absent or include the
6430web server authentication and/or one of the SGC OIDs.
6431The Netscape certificate type must be absent or the SSL CA bit must be set:
6432this is used as a workaround if the
6433.Cm basicConstraints
6434extension is absent.
6435.It Netscape SSL Server
6436For Netscape SSL clients to connect to an SSL server; it must have the
6437.Cm keyEncipherment
6438bit set if the
6439.Cm keyUsage
6440extension is present.
6441This isn't always valid because some cipher suites use the key for
6442digital signing.
6443Otherwise it is the same as a normal SSL server.
6444.It Common S/MIME Client Tests
6445The extended key usage extension must be absent or include the
6446email protection OID.
6447The Netscape certificate type must be absent or should have the S/MIME bit set.
6448If the S/MIME bit is not set in Netscape certificate type, then the SSL
6449client bit is tolerated as an alternative but a warning is shown:
6450this is because some Verisign certificates don't set the S/MIME bit.
6451.It S/MIME Signing
6452In addition to the common S/MIME client tests, the
6453.Cm digitalSignature
6454bit must be set if the
6455.Cm keyUsage
6456extension is present.
6457.It S/MIME Encryption
6458In addition to the common S/MIME tests, the
6459.Cm keyEncipherment
6460bit must be set if the
6461.Cm keyUsage
6462extension is present.
6463.It S/MIME CA
6464The extended key usage extension must be absent or include the
6465email protection OID.
6466The Netscape certificate type must be absent
6467or must have the S/MIME CA bit set:
6468this is used as a workaround if the
6469.Cm basicConstraints
6470extension is absent.
6471.It CRL Signing
6472The
6473.Cm keyUsage
6474extension must be absent or it must have the CRL signing bit set.
6475.It CRL Signing CA
6476The normal CA tests apply, except the
6477.Cm basicConstraints
6478extension must be present.
6479.El
6480.It Fl setalias Ar arg
6481Set the alias of the certificate,
6482allowing the certificate to be referred to using a nickname,
6483such as
6484.Qq Steve's Certificate .
6485.It Fl trustout
6486Output a trusted certificate
6487(the default if any trust settings are modified).
6488An ordinary or trusted certificate can be input, but by default an ordinary
6489certificate is output and any trust settings are discarded.
6490.El
6491.Pp
6492The
6493.Nm x509
6494utility can be used to sign certificates and requests:
6495it can thus behave like a mini CA.
6496The following are x509 signing options:
6497.Bl -tag -width "XXXX"
6498.It Fl CA Ar file
6499The CA certificate to be used for signing.
6500When this option is present,
6501.Nm x509
6502behaves like a mini CA.
6503The input file is signed by the CA using this option;
6504that is, its issuer name is set to the subject name of the CA and it is
6505digitally signed using the CA's private key.
6506.Pp
6507This option is normally combined with the
6508.Fl req
6509option.
6510Without the
6511.Fl req
6512option, the input is a certificate which must be self-signed.
6513.It Fl CAcreateserial
6514Create the CA serial number file if it does not exist
6515instead of generating an error.
6516The file will contain the serial number
6517.Sq 02
6518and the certificate being signed will have
6519.Sq 1
6520as its serial number.
6521.It Fl CAform Cm der | pem
6522The format of the CA certificate file.
6523The default is
6524.Cm pem .
6525.It Fl CAkey Ar file
6526Set the CA private key to sign a certificate with.
6527Otherwise it is assumed that the CA private key is present
6528in the CA certificate file.
6529.It Fl CAkeyform Cm der | pem
6530The format of the CA private key.
6531The default is
6532.Cm pem .
6533.It Fl CAserial Ar file
6534Use the serial number in
6535.Ar file
6536to sign a certificate.
6537The file should consist of one line containing an even number of hex digits
6538with the serial number to use.
6539After each use the serial number is incremented and written out
6540to the file again.
6541.Pp
6542The default filename consists of the CA certificate file base name with
6543.Pa .srl
6544appended.
6545For example, if the CA certificate file is called
6546.Pa mycacert.pem ,
6547it expects to find a serial number file called
6548.Pa mycacert.srl .
6549.It Fl checkend Ar arg
6550Check whether the certificate expires in the next
6551.Ar arg
6552seconds.
6553If so, exit with return value 1;
6554otherwise exit with return value 0.
6555.It Fl clrext
6556Delete any extensions from a certificate.
6557This option is used when a certificate is being created from another
6558certificate (for example with the
6559.Fl signkey
6560or the
6561.Fl CA
6562options).
6563Normally, all extensions are retained.
6564.It Fl days Ar arg
6565The number of days to make a certificate valid for.
6566The default is 30 days.
6567.It Fl extensions Ar section
6568The section to add certificate extensions from.
6569If this option is not specified, the extensions should either be
6570contained in the unnamed (default) section
6571or the default section should contain a variable called
6572.Qq extensions
6573which contains the section to use.
6574.It Fl extfile Ar file
6575File containing certificate extensions to use.
6576If not specified, no extensions are added to the certificate.
6577.It Fl force_pubkey Ar key
6578Set the public key of the certificate to the public key contained in
6579.Ar key .
6580.It Fl keyform Cm der | pem
6581The format of the key file used in the
6582.Fl force_pubkey
6583and
6584.Fl signkey
6585options.
6586.It Fl new
6587Generate a new certificate using the subject given by
6588.Fl set_subject
6589and signed by
6590.Fl signkey .
6591If no public key is provided with
6592.Fl force_pubkey ,
6593the resulting certificate is self-signed.
6594This option cannot be used with
6595.Fl in
6596or
6597.Fl req .
6598.It Fl req
6599Expect a certificate request on input instead of a certificate.
6600This option cannot be used with
6601.Fl new .
6602.It Fl set_issuer Ar name
6603The issuer name to use.
6604.Ar name
6605must be formatted as /type0=value0/type1=value1/type2=...;
6606characters may be escaped by
6607.Sq \e
6608(backslash);
6609no spaces are skipped.
6610.It Fl set_serial Ar n
6611The serial number to use.
6612This option can be used with either the
6613.Fl signkey
6614or
6615.Fl CA
6616options.
6617If used in conjunction with the
6618.Fl CA
6619option, the serial number file (as specified by the
6620.Fl CAserial
6621or
6622.Fl CAcreateserial
6623options) is not used.
6624.Pp
6625The serial number can be decimal or hex (if preceded by
6626.Sq 0x ) .
6627Negative serial numbers can also be specified but their use is not recommended.
6628.It Fl set_subject Ar name
6629The subject name to use.
6630.Ar name
6631must be formatted as /type0=value0/type1=value1/type2=...;
6632characters may be escaped by
6633.Sq \e
6634(backslash);
6635no spaces are skipped.
6636.It Fl signkey Ar file
6637Self-sign
6638.Ar file
6639using the supplied private key.
6640.Pp
6641If the input file is a certificate, it sets the issuer name to the
6642subject name (i.e. makes it self-signed),
6643changes the public key to the supplied value,
6644and changes the start and end dates.
6645The start date is set to the current time and the end date is set to
6646a value determined by the
6647.Fl days
6648option.
6649Any certificate extensions are retained unless the
6650.Fl clrext
6651option is supplied.
6652.Pp
6653If the input is a certificate request, a self-signed certificate
6654is created using the supplied private key using the subject name in
6655the request.
6656.It Fl utf8
6657Interpret field values read from a terminal or obtained from a configuration
6658file as UTF-8 strings.
6659By default, they are interpreted as ASCII.
6660.It Fl x509toreq
6661Convert a certificate into a certificate request.
6662The
6663.Fl signkey
6664option is used to pass the required private key.
6665.El
6666.Sh COMMON NOTATION
6667Several commands share a common syntax,
6668as detailed below.
6669.Pp
6670Password arguments, typically specified using
6671.Fl passin
6672and
6673.Fl passout
6674for input and output passwords,
6675allow passwords to be obtained from a variety of sources.
6676Both of these options take a single argument, described below.
6677If no password argument is given and a password is required,
6678then the user is prompted to enter one:
6679this will typically be read from the current terminal with echoing turned off.
6680.Bl -tag -width "pass:password" -offset indent
6681.It Cm pass : Ns Ar password
6682The actual password is
6683.Ar password .
6684Since the password is visible to utilities,
6685this form should only be used where security is not important.
6686.It Cm env : Ns Ar var
6687Obtain the password from the environment variable
6688.Ar var .
6689Since the environment of other processes is visible,
6690this option should be used with caution.
6691.It Cm file : Ns Ar path
6692The first line of
6693.Ar path
6694is the password.
6695If the same
6696.Ar path
6697argument is supplied to
6698.Fl passin
6699and
6700.Fl passout ,
6701then the first line will be used for the input password and the next line
6702for the output password.
6703.Ar path
6704need not refer to a regular file:
6705it could, for example, refer to a device or named pipe.
6706.It Cm fd : Ns Ar number
6707Read the password from the file descriptor
6708.Ar number .
6709This can be used to send the data via a pipe, for example.
6710.It Cm stdin
6711Read the password from standard input.
6712.El
6713.Pp
6714Input/output formats,
6715typically specified using
6716.Fl inform
6717and
6718.Fl outform ,
6719indicate the format being read from or written to.
6720The argument is case insensitive.
6721.Pp
6722.Bl -tag -width Ds -offset indent -compact
6723.It Cm der
6724Distinguished Encoding Rules (DER)
6725is a binary format.
6726.It Cm net
6727Insecure legacy format.
6728.It Cm pem
6729Privacy Enhanced Mail (PEM)
6730is base64-encoded.
6731.It Cm pvk
6732Private Key format.
6733.It Cm smime
6734An SMIME format message.
6735.It Cm txt
6736Plain ASCII text.
6737.El
6738.Sh ENVIRONMENT
6739The following environment variables affect the execution of
6740.Nm openssl :
6741.Bl -tag -width "/etc/ssl/openssl.cnf"
6742.It Ev OPENSSL_CONF
6743The location of the master configuration file.
6744.El
6745.Sh FILES
6746.Bl -tag -width "/etc/ssl/openssl.cnf" -compact
6747.It Pa /etc/ssl/
6748Default config directory for
6749.Nm openssl .
6750.It Pa /etc/ssl/lib/
6751Unused.
6752.It Pa /etc/ssl/private/
6753Default private key directory.
6754.It Pa /etc/ssl/openssl.cnf
6755Default configuration file for
6756.Nm openssl .
6757.It Pa /etc/ssl/x509v3.cnf
6758Default configuration file for
6759.Nm x509
6760certificates.
6761.El
6762.Sh SEE ALSO
6763.Xr acme-client 1 ,
6764.Xr nc 1 ,
6765.Xr openssl.cnf 5 ,
6766.Xr x509v3.cnf 5 ,
6767.Xr ssl 8 ,
6768.Xr starttls 8
6769.Sh STANDARDS
6770.Rs
6771.%A T. Dierks
6772.%A C. Allen
6773.%D January 1999
6774.%R RFC 2246
6775.%T The TLS Protocol Version 1.0
6776.Re
6777.Pp
6778.Rs
6779.%A M. Wahl
6780.%A S. Killie
6781.%A T. Howes
6782.%D December 1997
6783.%R RFC 2253
6784.%T Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names
6785.Re
6786.Pp
6787.Rs
6788.%A B. Kaliski
6789.%D March 1998
6790.%R RFC 2315
6791.%T PKCS #7: Cryptographic Message Syntax Version 1.5
6792.Re
6793.Pp
6794.Rs
6795.%A R. Housley
6796.%A W. Ford
6797.%A W. Polk
6798.%A D. Solo
6799.%D January 1999
6800.%R RFC 2459
6801.%T Internet X.509 Public Key Infrastructure Certificate and CRL Profile
6802.Re
6803.Pp
6804.Rs
6805.%A M. Myers
6806.%A R. Ankney
6807.%A A. Malpani
6808.%A S. Galperin
6809.%A C. Adams
6810.%D June 1999
6811.%R RFC 2560
6812.%T X.509 Internet Public Key Infrastructure Online Certificate Status Protocol \(en OCSP
6813.Re
6814.Pp
6815.Rs
6816.%A R. Housley
6817.%D June 1999
6818.%R RFC 2630
6819.%T Cryptographic Message Syntax
6820.Re
6821.Pp
6822.Rs
6823.%A P. Chown
6824.%D June 2002
6825.%R RFC 3268
6826.%T Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS)
6827.Re
diff --git a/src/usr.bin/openssl/openssl.c b/src/usr.bin/openssl/openssl.c
deleted file mode 100644
index 75a0e4d266..0000000000
--- a/src/usr.bin/openssl/openssl.c
+++ /dev/null
@@ -1,724 +0,0 @@
1/* $OpenBSD: openssl.c,v 1.39 2025/01/02 13:10:03 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <err.h>
113#include <signal.h>
114#include <stdio.h>
115#include <string.h>
116#include <stdlib.h>
117#include <unistd.h>
118
119#include "apps.h"
120
121#include <openssl/bio.h>
122#include <openssl/conf.h>
123#include <openssl/crypto.h>
124#include <openssl/err.h>
125#include <openssl/lhash.h>
126#include <openssl/pem.h>
127#include <openssl/ssl.h>
128#include <openssl/x509.h>
129
130#define FUNC_TYPE_GENERAL 1
131#define FUNC_TYPE_MD 2
132#define FUNC_TYPE_CIPHER 3
133#define FUNC_TYPE_PKEY 4
134#define FUNC_TYPE_MD_ALG 5
135#define FUNC_TYPE_CIPHER_ALG 6
136
137typedef struct {
138 int type;
139 const char *name;
140 int (*func)(int argc, char **argv);
141} FUNCTION;
142
143DECLARE_LHASH_OF(FUNCTION);
144
145FUNCTION functions[] = {
146
147 /* General functions. */
148 { FUNC_TYPE_GENERAL, "asn1parse", asn1parse_main },
149 { FUNC_TYPE_GENERAL, "ca", ca_main },
150 { FUNC_TYPE_GENERAL, "certhash", certhash_main },
151 { FUNC_TYPE_GENERAL, "ciphers", ciphers_main },
152#ifndef OPENSSL_NO_CMS
153 { FUNC_TYPE_GENERAL, "cms", cms_main },
154#endif
155 { FUNC_TYPE_GENERAL, "crl2pkcs7", crl2pkcs7_main },
156 { FUNC_TYPE_GENERAL, "crl", crl_main },
157 { FUNC_TYPE_GENERAL, "dgst", dgst_main },
158 { FUNC_TYPE_GENERAL, "enc", enc_main },
159 { FUNC_TYPE_GENERAL, "errstr", errstr_main },
160 { FUNC_TYPE_GENERAL, "genpkey", genpkey_main },
161#ifndef OPENSSL_NO_OCSP
162 { FUNC_TYPE_GENERAL, "ocsp", ocsp_main },
163#endif
164 { FUNC_TYPE_GENERAL, "passwd", passwd_main },
165 { FUNC_TYPE_GENERAL, "pkcs7", pkcs7_main },
166 { FUNC_TYPE_GENERAL, "pkcs8", pkcs8_main },
167#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
168 { FUNC_TYPE_GENERAL, "pkcs12", pkcs12_main },
169#endif
170 { FUNC_TYPE_GENERAL, "pkey", pkey_main },
171 { FUNC_TYPE_GENERAL, "pkeyparam", pkeyparam_main },
172 { FUNC_TYPE_GENERAL, "pkeyutl", pkeyutl_main },
173 { FUNC_TYPE_GENERAL, "prime", prime_main },
174 { FUNC_TYPE_GENERAL, "rand", rand_main },
175 { FUNC_TYPE_GENERAL, "req", req_main },
176 { FUNC_TYPE_GENERAL, "s_client", s_client_main },
177 { FUNC_TYPE_GENERAL, "s_server", s_server_main },
178 { FUNC_TYPE_GENERAL, "s_time", s_time_main },
179 { FUNC_TYPE_GENERAL, "sess_id", sess_id_main },
180 { FUNC_TYPE_GENERAL, "smime", smime_main },
181#ifndef OPENSSL_NO_SPEED
182 { FUNC_TYPE_GENERAL, "speed", speed_main },
183#endif
184 { FUNC_TYPE_GENERAL, "ts", ts_main },
185 { FUNC_TYPE_GENERAL, "verify", verify_main },
186 { FUNC_TYPE_GENERAL, "version", version_main },
187 { FUNC_TYPE_GENERAL, "x509", x509_main },
188
189#ifndef OPENSSL_NO_DH
190 { FUNC_TYPE_GENERAL, "dh", dh_main },
191 { FUNC_TYPE_GENERAL, "dhparam", dhparam_main },
192 { FUNC_TYPE_GENERAL, "gendh", gendh_main },
193#endif
194#ifndef OPENSSL_NO_DSA
195 { FUNC_TYPE_GENERAL, "dsa", dsa_main },
196 { FUNC_TYPE_GENERAL, "dsaparam", dsaparam_main },
197 { FUNC_TYPE_GENERAL, "gendsa", gendsa_main },
198#endif
199#ifndef OPENSSL_NO_EC
200 { FUNC_TYPE_GENERAL, "ec", ec_main },
201 { FUNC_TYPE_GENERAL, "ecparam", ecparam_main },
202#endif
203#ifndef OPENSSL_NO_RSA
204 { FUNC_TYPE_GENERAL, "genrsa", genrsa_main },
205 { FUNC_TYPE_GENERAL, "rsa", rsa_main },
206 { FUNC_TYPE_GENERAL, "rsautl", rsautl_main },
207#endif
208
209 /* Message Digests. */
210#ifndef OPENSSL_NO_MD4
211 { FUNC_TYPE_MD, "md4", dgst_main },
212#endif
213#ifndef OPENSSL_NO_MD5
214 { FUNC_TYPE_MD, "md5", dgst_main },
215#endif
216#ifndef OPENSSL_NO_RIPEMD160
217 { FUNC_TYPE_MD, "ripemd160", dgst_main },
218#endif
219#ifndef OPENSSL_NO_SHA1
220 { FUNC_TYPE_MD, "sha1", dgst_main },
221#endif
222#ifndef OPENSSL_NO_SHA224
223 { FUNC_TYPE_MD, "sha224", dgst_main },
224#endif
225#ifndef OPENSSL_NO_SHA256
226 { FUNC_TYPE_MD, "sha256", dgst_main },
227#endif
228#ifndef OPENSSL_NO_SHA384
229 { FUNC_TYPE_MD, "sha384", dgst_main },
230#endif
231#ifndef OPENSSL_NO_SHA512
232 { FUNC_TYPE_MD, "sha512", dgst_main },
233#endif
234#ifndef OPENSSL_NO_SM3
235 { FUNC_TYPE_MD, "sm3", dgst_main },
236 { FUNC_TYPE_MD, "sm3WithRSAEncryption", dgst_main },
237#endif
238#ifndef OPENSSL_NO_WHIRLPOOL
239 { FUNC_TYPE_MD, "whirlpool", dgst_main },
240#endif
241
242 /* Ciphers. */
243 { FUNC_TYPE_CIPHER, "base64", enc_main },
244#ifndef OPENSSL_NO_AES
245 { FUNC_TYPE_CIPHER, "aes-128-cbc", enc_main },
246 { FUNC_TYPE_CIPHER, "aes-128-ecb", enc_main },
247 { FUNC_TYPE_CIPHER, "aes-192-cbc", enc_main },
248 { FUNC_TYPE_CIPHER, "aes-192-ecb", enc_main },
249 { FUNC_TYPE_CIPHER, "aes-256-cbc", enc_main },
250 { FUNC_TYPE_CIPHER, "aes-256-ecb", enc_main },
251#endif
252#ifndef OPENSSL_NO_BF
253 { FUNC_TYPE_CIPHER, "bf", enc_main },
254 { FUNC_TYPE_CIPHER, "bf-cbc", enc_main },
255 { FUNC_TYPE_CIPHER, "bf-ecb", enc_main },
256 { FUNC_TYPE_CIPHER, "bf-cfb", enc_main },
257 { FUNC_TYPE_CIPHER, "bf-ofb", enc_main },
258#endif
259#ifndef OPENSSL_NO_CAMELLIA
260 { FUNC_TYPE_CIPHER, "camellia-128-cbc", enc_main },
261 { FUNC_TYPE_CIPHER, "camellia-128-ecb", enc_main },
262 { FUNC_TYPE_CIPHER, "camellia-192-cbc", enc_main },
263 { FUNC_TYPE_CIPHER, "camellia-192-ecb", enc_main },
264 { FUNC_TYPE_CIPHER, "camellia-256-cbc", enc_main },
265 { FUNC_TYPE_CIPHER, "camellia-256-ecb", enc_main },
266#endif
267#ifndef OPENSSL_NO_CAST
268 { FUNC_TYPE_CIPHER, "cast", enc_main },
269 { FUNC_TYPE_CIPHER, "cast5-cbc", enc_main },
270 { FUNC_TYPE_CIPHER, "cast5-ecb", enc_main },
271 { FUNC_TYPE_CIPHER, "cast5-cfb", enc_main },
272 { FUNC_TYPE_CIPHER, "cast5-ofb", enc_main },
273 { FUNC_TYPE_CIPHER, "cast-cbc", enc_main },
274#endif
275#ifndef OPENSSL_NO_CHACHA
276 { FUNC_TYPE_CIPHER, "chacha", enc_main },
277#endif
278#ifndef OPENSSL_NO_DES
279 { FUNC_TYPE_CIPHER, "des", enc_main },
280 { FUNC_TYPE_CIPHER, "des3", enc_main },
281 { FUNC_TYPE_CIPHER, "desx", enc_main },
282 { FUNC_TYPE_CIPHER, "des-ecb", enc_main },
283 { FUNC_TYPE_CIPHER, "des-ede", enc_main },
284 { FUNC_TYPE_CIPHER, "des-ede3", enc_main },
285 { FUNC_TYPE_CIPHER, "des-cbc", enc_main },
286 { FUNC_TYPE_CIPHER, "des-ede-cbc", enc_main },
287 { FUNC_TYPE_CIPHER, "des-ede3-cbc", enc_main },
288 { FUNC_TYPE_CIPHER, "des-cfb", enc_main },
289 { FUNC_TYPE_CIPHER, "des-ede-cfb", enc_main },
290 { FUNC_TYPE_CIPHER, "des-ede3-cfb", enc_main },
291 { FUNC_TYPE_CIPHER, "des-ofb", enc_main },
292 { FUNC_TYPE_CIPHER, "des-ede-ofb", enc_main },
293 { FUNC_TYPE_CIPHER, "des-ede3-ofb", enc_main },
294#endif
295#ifndef OPENSSL_NO_IDEA
296 { FUNC_TYPE_CIPHER, "idea", enc_main },
297 { FUNC_TYPE_CIPHER, "idea-cbc", enc_main },
298 { FUNC_TYPE_CIPHER, "idea-ecb", enc_main },
299 { FUNC_TYPE_CIPHER, "idea-cfb", enc_main },
300 { FUNC_TYPE_CIPHER, "idea-ofb", enc_main },
301#endif
302#ifndef OPENSSL_NO_RC2
303 { FUNC_TYPE_CIPHER, "rc2", enc_main },
304 { FUNC_TYPE_CIPHER, "rc2-cbc", enc_main },
305 { FUNC_TYPE_CIPHER, "rc2-ecb", enc_main },
306 { FUNC_TYPE_CIPHER, "rc2-cfb", enc_main },
307 { FUNC_TYPE_CIPHER, "rc2-ofb", enc_main },
308 { FUNC_TYPE_CIPHER, "rc2-64-cbc", enc_main },
309 { FUNC_TYPE_CIPHER, "rc2-40-cbc", enc_main },
310#endif
311#ifndef OPENSSL_NO_RC4
312 { FUNC_TYPE_CIPHER, "rc4", enc_main },
313 { FUNC_TYPE_CIPHER, "rc4-40", enc_main },
314#endif
315#ifndef OPENSSL_NO_SM4
316 { FUNC_TYPE_CIPHER, "sm4", enc_main },
317 { FUNC_TYPE_CIPHER, "sm4-ecb", enc_main },
318 { FUNC_TYPE_CIPHER, "sm4-cbc", enc_main },
319 { FUNC_TYPE_CIPHER, "sm4-ofb", enc_main },
320 { FUNC_TYPE_CIPHER, "sm4-cfb", enc_main },
321#endif
322 { 0, NULL, NULL }
323};
324
325static void openssl_startup(void);
326static void openssl_shutdown(void);
327
328/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the
329 * base prototypes (we cast each variable inside the function to the required
330 * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
331 * functions. */
332
333static LHASH_OF(FUNCTION) *prog_init(void);
334static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]);
335static void print_help(void);
336static void list_pkey(BIO * out);
337static void list_cipher(BIO * out);
338static void list_md(BIO * out);
339char *default_config_file = NULL;
340
341CONF *config = NULL;
342BIO *bio_err = NULL;
343
344static void
345openssl_startup(void)
346{
347 signal(SIGPIPE, SIG_IGN);
348
349 OpenSSL_add_all_algorithms();
350 SSL_library_init();
351 SSL_load_error_strings();
352
353 setup_ui();
354}
355
356static void
357openssl_shutdown(void)
358{
359 CONF_modules_unload(1);
360 destroy_ui();
361 OBJ_cleanup();
362 EVP_cleanup();
363 CRYPTO_cleanup_all_ex_data();
364 ERR_remove_thread_state(NULL);
365 ERR_free_strings();
366}
367
368int
369main(int argc, char **argv)
370{
371 char *to_free = NULL;
372 int i, ret = 0;
373 char *p;
374 LHASH_OF(FUNCTION) * prog = NULL;
375 long errline;
376
377 if (pledge("stdio cpath wpath rpath inet dns proc flock tty", NULL) == -1) {
378 fprintf(stderr, "openssl: pledge: %s\n", strerror(errno));
379 exit(1);
380 }
381
382 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
383 if (bio_err == NULL) {
384 fprintf(stderr, "openssl: failed to initialise bio_err\n");
385 exit(1);
386 }
387
388 if (BIO_sock_init() != 1) {
389 BIO_printf(bio_err, "BIO_sock_init failed\n");
390 exit(1);
391 }
392
393 openssl_startup();
394
395 /* Lets load up our environment a little */
396 p = getenv("OPENSSL_CONF");
397 if (p == NULL) {
398 p = to_free = make_config_name();
399 if (p == NULL) {
400 BIO_printf(bio_err, "error making config file name\n");
401 goto end;
402 }
403 }
404
405 default_config_file = p;
406
407 config = NCONF_new(NULL);
408 i = NCONF_load(config, p, &errline);
409 if (i == 0) {
410 if (ERR_GET_REASON(ERR_peek_last_error()) ==
411 CONF_R_NO_SUCH_FILE) {
412 BIO_printf(bio_err,
413 "WARNING: can't open config file: %s\n", p);
414 ERR_clear_error();
415 NCONF_free(config);
416 config = NULL;
417 } else {
418 ERR_print_errors(bio_err);
419 NCONF_free(config);
420 exit(1);
421 }
422 }
423
424 if (!load_config(bio_err, NULL)) {
425 BIO_printf(bio_err, "failed to load configuration\n");
426 goto end;
427 }
428
429 prog = prog_init();
430
431 /*
432 * ok, now check that there are not arguments, if there are, run with
433 * them, shifting the executable name off the front
434 */
435 argc--;
436 argv++;
437
438 if (argc < 1) {
439 print_help();
440 goto end;
441 }
442
443 ret = do_cmd(prog, argc, argv);
444 if (ret < 0)
445 ret = 0;
446
447 end:
448 free(to_free);
449
450 if (config != NULL) {
451 NCONF_free(config);
452 config = NULL;
453 }
454 if (prog != NULL)
455 lh_FUNCTION_free(prog);
456
457 openssl_shutdown();
458
459 if (bio_err != NULL) {
460 BIO_free(bio_err);
461 bio_err = NULL;
462 }
463 return (ret);
464}
465
466#define LIST_STANDARD_COMMANDS "list-standard-commands"
467#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
468#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms"
469#define LIST_CIPHER_COMMANDS "list-cipher-commands"
470#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms"
471#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
472
473
474static int
475do_cmd(LHASH_OF(FUNCTION) * prog, int argc, char *argv[])
476{
477 FUNCTION f, *fp;
478 int ret = 1;
479
480 if (argc <= 0 || argv[0] == NULL)
481 return 0;
482
483 f.name = argv[0];
484 fp = lh_FUNCTION_retrieve(prog, &f);
485 if (fp == NULL) {
486 if (EVP_get_digestbyname(argv[0])) {
487 f.type = FUNC_TYPE_MD;
488 f.func = dgst_main;
489 fp = &f;
490 } else if (EVP_get_cipherbyname(argv[0])) {
491 f.type = FUNC_TYPE_CIPHER;
492 f.func = enc_main;
493 fp = &f;
494 }
495 }
496
497 if (fp != NULL)
498 return fp->func(argc, argv);
499
500 if (strcmp(argv[0], "help") == 0) {
501 print_help();
502 return 0;
503 }
504
505 if ((strncmp(argv[0], "no-", 3)) == 0) {
506 BIO *bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
507 f.name = argv[0] + 3;
508 ret = (lh_FUNCTION_retrieve(prog, &f) != NULL);
509 if (!ret)
510 BIO_printf(bio_stdout, "%s\n", argv[0]);
511 else
512 BIO_printf(bio_stdout, "%s\n", argv[0] + 3);
513 BIO_free_all(bio_stdout);
514 return ret;
515 }
516
517 if ((strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) ||
518 (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
519 (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) ||
520 (strcmp(argv[0], LIST_CIPHER_COMMANDS) == 0) ||
521 (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) ||
522 (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)) {
523 int list_type;
524 BIO *bio_stdout;
525
526 if (strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0)
527 list_type = FUNC_TYPE_GENERAL;
528 else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0)
529 list_type = FUNC_TYPE_MD;
530 else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0)
531 list_type = FUNC_TYPE_MD_ALG;
532 else if (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)
533 list_type = FUNC_TYPE_PKEY;
534 else if (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0)
535 list_type = FUNC_TYPE_CIPHER_ALG;
536 else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
537 list_type = FUNC_TYPE_CIPHER;
538 bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
539
540 if (list_type == FUNC_TYPE_PKEY)
541 list_pkey(bio_stdout);
542 if (list_type == FUNC_TYPE_MD_ALG)
543 list_md(bio_stdout);
544 if (list_type == FUNC_TYPE_CIPHER_ALG)
545 list_cipher(bio_stdout);
546 else {
547 for (fp = functions; fp->name != NULL; fp++)
548 if (fp->type == list_type)
549 BIO_printf(bio_stdout, "%s\n",
550 fp->name);
551 }
552 BIO_free_all(bio_stdout);
553 return 0;
554 }
555
556 BIO_printf(bio_err,
557 "openssl:Error: '%s' is an invalid command.\n",
558 argv[0]);
559 print_help();
560
561 return 1;
562}
563
564static void
565print_help(void)
566{
567 FUNCTION *fp;
568 int i = 0;
569 int tp = 0;
570 int nl;
571
572 BIO_printf(bio_err, "\nStandard commands");
573 for (fp = functions; fp->name != NULL; fp++) {
574 nl = 0;
575#ifdef OPENSSL_NO_CAMELLIA
576 if (((i++) % 5) == 0)
577#else
578 if (((i++) % 4) == 0)
579#endif
580 {
581 BIO_printf(bio_err, "\n");
582 nl = 1;
583 }
584 if (fp->type != tp) {
585 tp = fp->type;
586 if (!nl)
587 BIO_printf(bio_err, "\n");
588 if (tp == FUNC_TYPE_MD) {
589 i = 1;
590 BIO_printf(bio_err,
591 "\nMessage Digest commands (see the `dgst' command for more details)\n");
592 } else if (tp == FUNC_TYPE_CIPHER) {
593 i = 1;
594 BIO_printf(bio_err, "\nCipher commands (see the `enc' command for more details)\n");
595 }
596 }
597#ifdef OPENSSL_NO_CAMELLIA
598 BIO_printf(bio_err, "%-15s", fp->name);
599#else
600 BIO_printf(bio_err, "%-18s", fp->name);
601#endif
602 }
603
604 BIO_printf(bio_err, "\n\n");
605}
606
607static int
608SortFnByName(const void *_f1, const void *_f2)
609{
610 const FUNCTION *f1 = _f1;
611 const FUNCTION *f2 = _f2;
612
613 if (f1->type != f2->type)
614 return f1->type - f2->type;
615 return strcmp(f1->name, f2->name);
616}
617
618static void
619list_pkey(BIO * out)
620{
621 int i;
622
623 for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
624 const EVP_PKEY_ASN1_METHOD *ameth;
625 int pkey_id, pkey_base_id, pkey_flags;
626 const char *pinfo, *pem_str;
627 ameth = EVP_PKEY_asn1_get0(i);
628 EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
629 &pinfo, &pem_str, ameth);
630 if (pkey_flags & ASN1_PKEY_ALIAS) {
631 BIO_printf(out, "Name: %s\n",
632 OBJ_nid2ln(pkey_id));
633 BIO_printf(out, "\tType: Alias to %s\n",
634 OBJ_nid2ln(pkey_base_id));
635 } else {
636 BIO_printf(out, "Name: %s\n", pinfo);
637 BIO_printf(out, "\tType: %s Algorithm\n",
638 pkey_flags & ASN1_PKEY_DYNAMIC ?
639 "External" : "Builtin");
640 BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
641 if (pem_str == NULL)
642 pem_str = "(none)";
643 BIO_printf(out, "\tPEM string: %s\n", pem_str);
644 }
645
646 }
647}
648
649static void
650list_cipher_fn(const EVP_CIPHER * c, const char *from, const char *to,
651 void *arg)
652{
653 if (c)
654 BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
655 else {
656 if (!from)
657 from = "<undefined>";
658 if (!to)
659 to = "<undefined>";
660 BIO_printf(arg, "%s => %s\n", from, to);
661 }
662}
663
664static void
665list_cipher(BIO * out)
666{
667 EVP_CIPHER_do_all_sorted(list_cipher_fn, out);
668}
669
670static void
671list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg)
672{
673 if (m)
674 BIO_printf(arg, "%s\n", EVP_MD_name(m));
675 else {
676 if (!from)
677 from = "<undefined>";
678 if (!to)
679 to = "<undefined>";
680 BIO_printf(arg, "%s => %s\n", from, to);
681 }
682}
683
684static void
685list_md(BIO * out)
686{
687 EVP_MD_do_all_sorted(list_md_fn, out);
688}
689
690static int
691function_cmp(const FUNCTION * a, const FUNCTION * b)
692{
693 return strncmp(a->name, b->name, 8);
694}
695
696static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION)
697
698static unsigned long
699function_hash(const FUNCTION * a)
700{
701 return lh_strhash(a->name);
702}
703
704static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION)
705
706static LHASH_OF(FUNCTION) *
707prog_init(void)
708{
709 LHASH_OF(FUNCTION) * ret;
710 FUNCTION *f;
711 size_t i;
712
713 /* Purely so it looks nice when the user hits ? */
714 for (i = 0, f = functions; f->name != NULL; ++f, ++i)
715 ;
716 qsort(functions, i, sizeof *functions, SortFnByName);
717
718 if ((ret = lh_FUNCTION_new()) == NULL)
719 return (NULL);
720
721 for (f = functions; f->name != NULL; f++)
722 (void) lh_FUNCTION_insert(ret, f);
723 return (ret);
724}
diff --git a/src/usr.bin/openssl/passwd.c b/src/usr.bin/openssl/passwd.c
deleted file mode 100644
index a8dfa27db1..0000000000
--- a/src/usr.bin/openssl/passwd.c
+++ /dev/null
@@ -1,524 +0,0 @@
1/* $OpenBSD: passwd.c,v 1.14 2023/03/06 14:32:06 tb Exp $ */
2
3#if defined OPENSSL_NO_MD5
4#define NO_MD5CRYPT_1
5#endif
6
7#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
8
9#include <assert.h>
10#include <string.h>
11
12#include "apps.h"
13
14#include <openssl/bio.h>
15#include <openssl/err.h>
16#include <openssl/evp.h>
17
18#ifndef OPENSSL_NO_DES
19#include <openssl/des.h>
20#endif
21
22#ifndef NO_MD5CRYPT_1
23#include <openssl/md5.h>
24#endif
25
26static unsigned const char cov_2char[64] = {
27 /* from crypto/des/fcrypt.c */
28 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
29 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
30 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
31 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
32 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
33 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
34 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
35 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
36};
37
38static int
39do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
40 char *passwd, BIO * out, int quiet, int table, int reverse,
41 size_t pw_maxlen, int usecrypt, int use1, int useapr1);
42
43static struct {
44 char *infile;
45 int in_stdin;
46 int noverify;
47 int quiet;
48 int reverse;
49 char *salt;
50 int table;
51 int use1;
52 int useapr1;
53 int usecrypt;
54} cfg;
55
56static const struct option passwd_options[] = {
57#ifndef NO_MD5CRYPT_1
58 {
59 .name = "1",
60 .desc = "Use MD5 based BSD password algorithm 1",
61 .type = OPTION_FLAG,
62 .opt.flag = &cfg.use1,
63 },
64 {
65 .name = "apr1",
66 .desc = "Use apr1 algorithm (Apache variant of BSD algorithm)",
67 .type = OPTION_FLAG,
68 .opt.flag = &cfg.useapr1,
69 },
70#endif
71#ifndef OPENSSL_NO_DES
72 {
73 .name = "crypt",
74 .desc = "Use crypt algorithm (default)",
75 .type = OPTION_FLAG,
76 .opt.flag = &cfg.usecrypt,
77 },
78#endif
79 {
80 .name = "in",
81 .argname = "file",
82 .desc = "Read passwords from specified file",
83 .type = OPTION_ARG,
84 .opt.arg = &cfg.infile,
85 },
86 {
87 .name = "noverify",
88 .desc = "Do not verify password",
89 .type = OPTION_FLAG,
90 .opt.flag = &cfg.noverify,
91 },
92 {
93 .name = "quiet",
94 .desc = "Do not output warnings",
95 .type = OPTION_FLAG,
96 .opt.flag = &cfg.quiet,
97 },
98 {
99 .name = "reverse",
100 .desc = "Reverse table columns (requires -table)",
101 .type = OPTION_FLAG,
102 .opt.flag = &cfg.reverse,
103 },
104 {
105 .name = "salt",
106 .argname = "string",
107 .desc = "Use specified salt",
108 .type = OPTION_ARG,
109 .opt.arg = &cfg.salt,
110 },
111 {
112 .name = "stdin",
113 .desc = "Read passwords from stdin",
114 .type = OPTION_FLAG,
115 .opt.flag = &cfg.in_stdin,
116 },
117 {
118 .name = "table",
119 .desc = "Output cleartext and hashed passwords (tab separated)",
120 .type = OPTION_FLAG,
121 .opt.flag = &cfg.table,
122 },
123 { NULL },
124};
125
126static void
127passwd_usage(void)
128{
129 fprintf(stderr, "usage: passwd [-1 | -apr1 | -crypt] [-in file] "
130 "[-noverify] [-quiet]\n"
131 " [-reverse] [-salt string] [-stdin] [-table] [password]\n\n");
132 options_usage(passwd_options);
133}
134
135int
136passwd_main(int argc, char **argv)
137{
138 char *passwd = NULL, **passwds = NULL;
139 char *salt_malloc = NULL, *passwd_malloc = NULL;
140 size_t passwd_malloc_size = 0;
141 BIO *in = NULL, *out = NULL;
142 int badopt = 0;
143 int passed_salt = 0;
144 size_t pw_maxlen = 0;
145 int argsused;
146 int ret = 1;
147
148 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
149 perror("pledge");
150 exit(1);
151 }
152
153 memset(&cfg, 0, sizeof(cfg));
154
155 if (options_parse(argc, argv, passwd_options, NULL, &argsused) != 0) {
156 passwd_usage();
157 goto err;
158 }
159
160 if (argsused < argc)
161 passwds = &argv[argsused];
162 if (cfg.salt != NULL)
163 passed_salt = 1;
164
165 if (!cfg.usecrypt && !cfg.use1 &&
166 !cfg.useapr1)
167 cfg.usecrypt = 1; /* use default */
168 if (cfg.usecrypt + cfg.use1 +
169 cfg.useapr1 > 1)
170 badopt = 1; /* conflicting options */
171
172 /* Reject unsupported algorithms */
173#ifdef OPENSSL_NO_DES
174 if (cfg.usecrypt)
175 badopt = 1;
176#endif
177#ifdef NO_MD5CRYPT_1
178 if (cfg.use1 || cfg.useapr1)
179 badopt = 1;
180#endif
181
182 if (badopt) {
183 passwd_usage();
184 goto err;
185 }
186
187 if ((out = BIO_new(BIO_s_file())) == NULL)
188 goto err;
189 BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
190
191 if (cfg.infile != NULL || cfg.in_stdin) {
192 if ((in = BIO_new(BIO_s_file())) == NULL)
193 goto err;
194 if (cfg.infile != NULL) {
195 assert(cfg.in_stdin == 0);
196 if (BIO_read_filename(in, cfg.infile) <= 0)
197 goto err;
198 } else {
199 assert(cfg.in_stdin);
200 BIO_set_fp(in, stdin, BIO_NOCLOSE);
201 }
202 }
203 if (cfg.usecrypt)
204 pw_maxlen = 8;
205 else if (cfg.use1 || cfg.useapr1)
206 pw_maxlen = 256;/* arbitrary limit, should be enough for most
207 * passwords */
208
209 if (passwds == NULL) {
210 /* no passwords on the command line */
211
212 passwd_malloc_size = pw_maxlen + 2;
213 /* longer than necessary so that we can warn about truncation */
214 passwd = passwd_malloc = malloc(passwd_malloc_size);
215 if (passwd_malloc == NULL)
216 goto err;
217 }
218 if (in == NULL && passwds == NULL) {
219 /* build a null-terminated list */
220 static char *passwds_static[2] = {NULL, NULL};
221
222 passwds = passwds_static;
223 if (in == NULL)
224 if (EVP_read_pw_string(passwd_malloc,
225 passwd_malloc_size, "Password: ",
226 !(passed_salt || cfg.noverify)) != 0)
227 goto err;
228 passwds[0] = passwd_malloc;
229 }
230 if (in == NULL) {
231 assert(passwds != NULL);
232 assert(*passwds != NULL);
233
234 do { /* loop over list of passwords */
235 passwd = *passwds++;
236 if (!do_passwd(passed_salt, &cfg.salt,
237 &salt_malloc, passwd, out, cfg.quiet,
238 cfg.table, cfg.reverse,
239 pw_maxlen, cfg.usecrypt,
240 cfg.use1, cfg.useapr1))
241 goto err;
242 } while (*passwds != NULL);
243 } else {
244 int done;
245
246 assert(passwd != NULL);
247 do {
248 int r = BIO_gets(in, passwd, pw_maxlen + 1);
249 if (r > 0) {
250 char *c = (strchr(passwd, '\n'));
251 if (c != NULL)
252 *c = 0; /* truncate at newline */
253 else {
254 /* ignore rest of line */
255 char trash[BUFSIZ];
256 do
257 r = BIO_gets(in, trash, sizeof trash);
258 while ((r > 0) && (!strchr(trash, '\n')));
259 }
260
261 if (!do_passwd(passed_salt, &cfg.salt,
262 &salt_malloc, passwd, out,
263 cfg.quiet, cfg.table,
264 cfg.reverse, pw_maxlen,
265 cfg.usecrypt, cfg.use1,
266 cfg.useapr1))
267 goto err;
268 }
269 done = (r <= 0);
270 } while (!done);
271 }
272 ret = 0;
273
274 err:
275 ERR_print_errors(bio_err);
276
277 free(salt_malloc);
278 free(passwd_malloc);
279
280 BIO_free(in);
281 BIO_free_all(out);
282
283 return (ret);
284}
285
286
287#ifndef NO_MD5CRYPT_1
288/* MD5-based password algorithm (should probably be available as a library
289 * function; then the static buffer would not be acceptable).
290 * For magic string "1", this should be compatible to the MD5-based BSD
291 * password algorithm.
292 * For 'magic' string "apr1", this is compatible to the MD5-based Apache
293 * password algorithm.
294 * (Apparently, the Apache password algorithm is identical except that the
295 * 'magic' string was changed -- the laziest application of the NIH principle
296 * I've ever encountered.)
297 */
298static char *
299md5crypt(const char *passwd, const char *magic, const char *salt)
300{
301 static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5h
302 * ash..........\0" */
303 unsigned char buf[MD5_DIGEST_LENGTH];
304 char *salt_out;
305 int n;
306 unsigned int i;
307 EVP_MD_CTX *md = NULL, *md2 = NULL;
308 size_t passwd_len, salt_len;
309
310 passwd_len = strlen(passwd);
311 out_buf[0] = '$';
312 out_buf[1] = 0;
313 assert(strlen(magic) <= 4); /* "1" or "apr1" */
314 strlcat(out_buf, magic, sizeof(out_buf));
315 strlcat(out_buf, "$", sizeof(out_buf));
316 strlcat(out_buf, salt, sizeof(out_buf));
317 assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
318 salt_out = out_buf + 2 + strlen(magic);
319 salt_len = strlen(salt_out);
320 assert(salt_len <= 8);
321
322 if ((md = EVP_MD_CTX_new()) == NULL)
323 goto err;
324 if (!EVP_DigestInit_ex(md, EVP_md5(), NULL))
325 goto err;
326 if (!EVP_DigestUpdate(md, passwd, passwd_len))
327 goto err;
328 if (!EVP_DigestUpdate(md, "$", 1))
329 goto err;
330 if (!EVP_DigestUpdate(md, magic, strlen(magic)))
331 goto err;
332 if (!EVP_DigestUpdate(md, "$", 1))
333 goto err;
334 if (!EVP_DigestUpdate(md, salt_out, salt_len))
335 goto err;
336
337 if ((md2 = EVP_MD_CTX_new()) == NULL)
338 goto err;
339 if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
340 goto err;
341 if (!EVP_DigestUpdate(md2, passwd, passwd_len))
342 goto err;
343 if (!EVP_DigestUpdate(md2, salt_out, salt_len))
344 goto err;
345 if (!EVP_DigestUpdate(md2, passwd, passwd_len))
346 goto err;
347 if (!EVP_DigestFinal_ex(md2, buf, NULL))
348 goto err;
349
350 for (i = passwd_len; i > sizeof buf; i -= sizeof buf) {
351 if (!EVP_DigestUpdate(md, buf, sizeof buf))
352 goto err;
353 }
354 if (!EVP_DigestUpdate(md, buf, i))
355 goto err;
356
357 n = passwd_len;
358 while (n) {
359 if (!EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1))
360 goto err;
361 n >>= 1;
362 }
363 if (!EVP_DigestFinal_ex(md, buf, NULL))
364 goto err;
365
366 for (i = 0; i < 1000; i++) {
367 if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
368 goto err;
369 if (!EVP_DigestUpdate(md2,
370 (i & 1) ? (unsigned const char *) passwd : buf,
371 (i & 1) ? passwd_len : sizeof buf))
372 goto err;
373 if (i % 3) {
374 if (!EVP_DigestUpdate(md2, salt_out, salt_len))
375 goto err;
376 }
377 if (i % 7) {
378 if (!EVP_DigestUpdate(md2, passwd, passwd_len))
379 goto err;
380 }
381 if (!EVP_DigestUpdate(md2,
382 (i & 1) ? buf : (unsigned const char *) passwd,
383 (i & 1) ? sizeof buf : passwd_len))
384 goto err;
385 if (!EVP_DigestFinal_ex(md2, buf, NULL))
386 goto err;
387 }
388 EVP_MD_CTX_free(md2);
389 md2 = NULL;
390
391 {
392 /* transform buf into output string */
393
394 unsigned char buf_perm[sizeof buf];
395 int dest, source;
396 char *output;
397
398 /* silly output permutation */
399 for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17)
400 buf_perm[dest] = buf[source];
401 buf_perm[14] = buf[5];
402 buf_perm[15] = buf[11];
403 assert(16 == sizeof buf_perm);
404
405 output = salt_out + salt_len;
406 assert(output == out_buf + strlen(out_buf));
407
408 *output++ = '$';
409
410 for (i = 0; i < 15; i += 3) {
411 *output++ = cov_2char[buf_perm[i + 2] & 0x3f];
412 *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) |
413 (buf_perm[i + 2] >> 6)];
414 *output++ = cov_2char[((buf_perm[i] & 3) << 4) |
415 (buf_perm[i + 1] >> 4)];
416 *output++ = cov_2char[buf_perm[i] >> 2];
417 }
418 assert(i == 15);
419 *output++ = cov_2char[buf_perm[i] & 0x3f];
420 *output++ = cov_2char[buf_perm[i] >> 6];
421 *output = 0;
422 assert(strlen(out_buf) < sizeof(out_buf));
423 }
424 EVP_MD_CTX_free(md);
425
426 return out_buf;
427 err:
428 EVP_MD_CTX_free(md);
429 EVP_MD_CTX_free(md2);
430
431 return NULL;
432}
433#endif
434
435
436static int
437do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
438 char *passwd, BIO * out, int quiet, int table, int reverse,
439 size_t pw_maxlen, int usecrypt, int use1, int useapr1)
440{
441 char *hash = NULL;
442
443 assert(salt_p != NULL);
444 assert(salt_malloc_p != NULL);
445
446 /* first make sure we have a salt */
447 if (!passed_salt) {
448#ifndef OPENSSL_NO_DES
449 if (usecrypt) {
450 if (*salt_malloc_p == NULL) {
451 *salt_p = *salt_malloc_p = malloc(3);
452 if (*salt_malloc_p == NULL)
453 goto err;
454 }
455 arc4random_buf(*salt_p, 2);
456 (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
457 (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
458 (*salt_p)[2] = 0;
459 }
460#endif /* !OPENSSL_NO_DES */
461
462#ifndef NO_MD5CRYPT_1
463 if (use1 || useapr1) {
464 int i;
465
466 if (*salt_malloc_p == NULL) {
467 *salt_p = *salt_malloc_p = malloc(9);
468 if (*salt_malloc_p == NULL)
469 goto err;
470 }
471 arc4random_buf(*salt_p, 8);
472
473 for (i = 0; i < 8; i++)
474 (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
475 (*salt_p)[8] = 0;
476 }
477#endif /* !NO_MD5CRYPT_1 */
478 }
479 assert(*salt_p != NULL);
480
481 /* truncate password if necessary */
482 if ((strlen(passwd) > pw_maxlen)) {
483 if (!quiet)
484 BIO_printf(bio_err,
485 "Warning: truncating password to %zu characters\n",
486 pw_maxlen);
487 passwd[pw_maxlen] = 0;
488 }
489 assert(strlen(passwd) <= pw_maxlen);
490
491 /* now compute password hash */
492#ifndef OPENSSL_NO_DES
493 if (usecrypt)
494 hash = DES_crypt(passwd, *salt_p);
495#endif
496#ifndef NO_MD5CRYPT_1
497 if (use1 || useapr1)
498 if ((hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p)) == NULL)
499 goto err;
500#endif
501 assert(hash != NULL);
502
503 if (table && !reverse)
504 BIO_printf(out, "%s\t%s\n", passwd, hash);
505 else if (table && reverse)
506 BIO_printf(out, "%s\t%s\n", hash, passwd);
507 else
508 BIO_printf(out, "%s\n", hash);
509 return 1;
510
511 err:
512 free(*salt_malloc_p);
513 *salt_malloc_p = NULL;
514 return 0;
515}
516#else
517
518int
519passwd_main(int argc, char **argv)
520{
521 fputs("Program not available.\n", stderr)
522 return (1);
523}
524#endif
diff --git a/src/usr.bin/openssl/pkcs12.c b/src/usr.bin/openssl/pkcs12.c
deleted file mode 100644
index 1407a96e03..0000000000
--- a/src/usr.bin/openssl/pkcs12.c
+++ /dev/null
@@ -1,1124 +0,0 @@
1/* $OpenBSD: pkcs12.c,v 1.29 2024/12/26 14:10:48 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/opensslconf.h>
60
61#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66
67#include "apps.h"
68
69#include <openssl/crypto.h>
70#include <openssl/err.h>
71#include <openssl/pem.h>
72#include <openssl/pkcs12.h>
73#include <openssl/x509.h>
74
75#define NOKEYS 0x1
76#define NOCERTS 0x2
77#define INFO 0x4
78#define CLCERTS 0x8
79#define CACERTS 0x10
80
81static int get_cert_chain(X509 *cert, X509_STORE *store,
82 STACK_OF(X509) **chain);
83static int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen,
84 int options, char *pempass);
85static int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
86 char *pass, int passlen, int options, char *pempass);
87static int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass,
88 int passlen, int options, char *pempass);
89static int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
90 const char *name);
91static void hex_prin(BIO *out, unsigned char *buf, int len);
92static int alg_print(BIO *x, const X509_ALGOR *alg);
93static int set_pbe(BIO *err, int *ppbe, const char *str);
94
95static struct {
96 char *CAfile;
97 STACK_OF(OPENSSL_STRING) *canames;
98 char *CApath;
99 int cert_pbe;
100 char *certfile;
101 int chain;
102 const EVP_CIPHER *enc;
103 int export_cert;
104 int key_pbe;
105 char *keyname;
106 int keytype;
107 char *infile;
108 int iter;
109 char *macalg;
110 int maciter;
111 int macver;
112 char *name;
113 int noprompt;
114 int options;
115 char *outfile;
116 char *passarg;
117 char *passargin;
118 char *passargout;
119 int twopass;
120} cfg;
121
122static int
123pkcs12_opt_canames(char *arg)
124{
125 if (cfg.canames == NULL &&
126 (cfg.canames = sk_OPENSSL_STRING_new_null()) == NULL)
127 return (1);
128
129 if (!sk_OPENSSL_STRING_push(cfg.canames, arg))
130 return (1);
131
132 return (0);
133}
134
135static int
136pkcs12_opt_cert_pbe(char *arg)
137{
138 return (!set_pbe(bio_err, &cfg.cert_pbe, arg));
139}
140
141static int
142pkcs12_opt_key_pbe(char *arg)
143{
144 return (!set_pbe(bio_err, &cfg.key_pbe, arg));
145}
146
147static int
148pkcs12_opt_passarg(char *arg)
149{
150 cfg.passarg = arg;
151 cfg.noprompt = 1;
152 return (0);
153}
154
155static const EVP_CIPHER *get_cipher_by_name(char *name)
156{
157 if (name == NULL || strcmp(name, "") == 0)
158 return (NULL);
159#ifndef OPENSSL_NO_AES
160 else if (strcmp(name, "aes128") == 0)
161 return EVP_aes_128_cbc();
162 else if (strcmp(name, "aes192") == 0)
163 return EVP_aes_192_cbc();
164 else if (strcmp(name, "aes256") == 0)
165 return EVP_aes_256_cbc();
166#endif
167#ifndef OPENSSL_NO_CAMELLIA
168 else if (strcmp(name, "camellia128") == 0)
169 return EVP_camellia_128_cbc();
170 else if (strcmp(name, "camellia192") == 0)
171 return EVP_camellia_192_cbc();
172 else if (strcmp(name, "camellia256") == 0)
173 return EVP_camellia_256_cbc();
174#endif
175#ifndef OPENSSL_NO_DES
176 else if (strcmp(name, "des") == 0)
177 return EVP_des_cbc();
178 else if (strcmp(name, "des3") == 0)
179 return EVP_des_ede3_cbc();
180#endif
181#ifndef OPENSSL_NO_IDEA
182 else if (strcmp(name, "idea") == 0)
183 return EVP_idea_cbc();
184#endif
185 else
186 return (NULL);
187}
188
189static int
190pkcs12_opt_enc(int argc, char **argv, int *argsused)
191{
192 char *name = argv[0];
193
194 if (*name++ != '-')
195 return (1);
196
197 if (strcmp(name, "nodes") == 0)
198 cfg.enc = NULL;
199 else if ((cfg.enc = get_cipher_by_name(name)) == NULL)
200 return (1);
201
202 *argsused = 1;
203 return (0);
204}
205
206static const struct option pkcs12_options[] = {
207#ifndef OPENSSL_NO_AES
208 {
209 .name = "aes128",
210 .desc = "Encrypt PEM output with CBC AES",
211 .type = OPTION_ARGV_FUNC,
212 .opt.argvfunc = pkcs12_opt_enc,
213 },
214 {
215 .name = "aes192",
216 .desc = "Encrypt PEM output with CBC AES",
217 .type = OPTION_ARGV_FUNC,
218 .opt.argvfunc = pkcs12_opt_enc,
219 },
220 {
221 .name = "aes256",
222 .desc = "Encrypt PEM output with CBC AES",
223 .type = OPTION_ARGV_FUNC,
224 .opt.argvfunc = pkcs12_opt_enc,
225 },
226#endif
227#ifndef OPENSSL_NO_CAMELLIA
228 {
229 .name = "camellia128",
230 .desc = "Encrypt PEM output with CBC Camellia",
231 .type = OPTION_ARGV_FUNC,
232 .opt.argvfunc = pkcs12_opt_enc,
233 },
234 {
235 .name = "camellia192",
236 .desc = "Encrypt PEM output with CBC Camellia",
237 .type = OPTION_ARGV_FUNC,
238 .opt.argvfunc = pkcs12_opt_enc,
239 },
240 {
241 .name = "camellia256",
242 .desc = "Encrypt PEM output with CBC Camellia",
243 .type = OPTION_ARGV_FUNC,
244 .opt.argvfunc = pkcs12_opt_enc,
245 },
246#endif
247 {
248 .name = "des",
249 .desc = "Encrypt private keys with DES",
250 .type = OPTION_ARGV_FUNC,
251 .opt.argvfunc = pkcs12_opt_enc,
252 },
253 {
254 .name = "des3",
255 .desc = "Encrypt private keys with triple DES (default)",
256 .type = OPTION_ARGV_FUNC,
257 .opt.argvfunc = pkcs12_opt_enc,
258 },
259#ifndef OPENSSL_NO_IDEA
260 {
261 .name = "idea",
262 .desc = "Encrypt private keys with IDEA",
263 .type = OPTION_ARGV_FUNC,
264 .opt.argvfunc = pkcs12_opt_enc,
265 },
266#endif
267 {
268 .name = "cacerts",
269 .desc = "Only output CA certificates",
270 .type = OPTION_VALUE_OR,
271 .opt.value = &cfg.options,
272 .value = CACERTS,
273 },
274 {
275 .name = "CAfile",
276 .argname = "file",
277 .desc = "PEM format file of CA certificates",
278 .type = OPTION_ARG,
279 .opt.arg = &cfg.CAfile,
280 },
281 {
282 .name = "caname",
283 .argname = "name",
284 .desc = "Use name as CA friendly name (can be used more than once)",
285 .type = OPTION_ARG_FUNC,
286 .opt.argfunc = pkcs12_opt_canames,
287 },
288 {
289 .name = "CApath",
290 .argname = "directory",
291 .desc = "PEM format directory of CA certificates",
292 .type = OPTION_ARG,
293 .opt.arg = &cfg.CApath,
294 },
295 {
296 .name = "certfile",
297 .argname = "file",
298 .desc = "Add all certs in file",
299 .type = OPTION_ARG,
300 .opt.arg = &cfg.certfile,
301 },
302 {
303 .name = "certpbe",
304 .argname = "alg",
305 .desc = "Specify certificate PBE algorithm (default RC2-40)",
306 .type = OPTION_ARG_FUNC,
307 .opt.argfunc = pkcs12_opt_cert_pbe,
308 },
309 {
310 .name = "chain",
311 .desc = "Add certificate chain",
312 .type = OPTION_FLAG,
313 .opt.flag = &cfg.chain,
314 },
315 {
316 .name = "clcerts",
317 .desc = "Only output client certificates",
318 .type = OPTION_VALUE_OR,
319 .opt.value = &cfg.options,
320 .value = CLCERTS,
321 },
322 {
323 .name = "descert",
324 .desc = "Encrypt PKCS#12 certificates with triple DES (default RC2-40)",
325 .type = OPTION_VALUE,
326 .opt.value = &cfg.cert_pbe,
327 .value = NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
328 },
329 {
330 .name = "export",
331 .desc = "Output PKCS#12 file",
332 .type = OPTION_FLAG,
333 .opt.flag = &cfg.export_cert,
334 },
335 {
336 .name = "in",
337 .argname = "file",
338 .desc = "Input filename",
339 .type = OPTION_ARG,
340 .opt.arg = &cfg.infile,
341 },
342 {
343 .name = "info",
344 .desc = "Give info about PKCS#12 structure",
345 .type = OPTION_VALUE_OR,
346 .opt.value = &cfg.options,
347 .value = INFO,
348 },
349 {
350 .name = "inkey",
351 .argname = "file",
352 .desc = "Private key if not infile",
353 .type = OPTION_ARG,
354 .opt.arg = &cfg.keyname,
355 },
356 {
357 .name = "keyex",
358 .desc = "Set MS key exchange type",
359 .type = OPTION_VALUE,
360 .opt.value = &cfg.keytype,
361 .value = KEY_EX,
362 },
363 {
364 .name = "keypbe",
365 .argname = "alg",
366 .desc = "Specify private key PBE algorithm (default 3DES)",
367 .type = OPTION_ARG_FUNC,
368 .opt.argfunc = pkcs12_opt_key_pbe,
369 },
370 {
371 .name = "keysig",
372 .desc = "Set MS key signature type",
373 .type = OPTION_VALUE,
374 .opt.value = &cfg.keytype,
375 .value = KEY_SIG,
376 },
377 {
378 .name = "macalg",
379 .argname = "alg",
380 .desc = "Digest algorithm used in MAC (default SHA1)",
381 .type = OPTION_ARG,
382 .opt.arg = &cfg.macalg,
383 },
384 {
385 .name = "maciter",
386 .desc = "Use MAC iteration",
387 .type = OPTION_VALUE,
388 .opt.value = &cfg.maciter,
389 .value = PKCS12_DEFAULT_ITER,
390 },
391 {
392 .name = "name",
393 .argname = "name",
394 .desc = "Use name as friendly name",
395 .type = OPTION_ARG,
396 .opt.arg = &cfg.name,
397 },
398 {
399 .name = "nocerts",
400 .desc = "Don't output certificates",
401 .type = OPTION_VALUE_OR,
402 .opt.value = &cfg.options,
403 .value = NOCERTS,
404 },
405 {
406 .name = "nodes",
407 .desc = "Don't encrypt private keys",
408 .type = OPTION_ARGV_FUNC,
409 .opt.argvfunc = pkcs12_opt_enc,
410 },
411 {
412 .name = "noiter",
413 .desc = "Don't use encryption iteration",
414 .type = OPTION_VALUE,
415 .opt.value = &cfg.iter,
416 .value = 1,
417 },
418 {
419 .name = "nokeys",
420 .desc = "Don't output private keys",
421 .type = OPTION_VALUE_OR,
422 .opt.value = &cfg.options,
423 .value = NOKEYS,
424 },
425 {
426 .name = "nomac",
427 .desc = "Don't generate MAC",
428 .type = OPTION_VALUE,
429 .opt.value = &cfg.maciter,
430 .value = -1,
431 },
432 {
433 .name = "nomaciter",
434 .desc = "Don't use MAC iteration",
435 .type = OPTION_VALUE,
436 .opt.value = &cfg.maciter,
437 .value = 1,
438 },
439 {
440 .name = "nomacver",
441 .desc = "Don't verify MAC",
442 .type = OPTION_VALUE,
443 .opt.value = &cfg.macver,
444 .value = 0,
445 },
446 {
447 .name = "noout",
448 .desc = "Don't output anything, just verify",
449 .type = OPTION_VALUE_OR,
450 .opt.value = &cfg.options,
451 .value = (NOKEYS | NOCERTS),
452 },
453 {
454 .name = "out",
455 .argname = "file",
456 .desc = "Output filename",
457 .type = OPTION_ARG,
458 .opt.arg = &cfg.outfile,
459 },
460 {
461 .name = "passin",
462 .argname = "arg",
463 .desc = "Input file passphrase source",
464 .type = OPTION_ARG,
465 .opt.arg = &cfg.passargin,
466 },
467 {
468 .name = "passout",
469 .argname = "arg",
470 .desc = "Output file passphrase source",
471 .type = OPTION_ARG,
472 .opt.arg = &cfg.passargout,
473 },
474 {
475 .name = "password",
476 .argname = "arg",
477 .desc = "Set import/export password source",
478 .type = OPTION_ARG_FUNC,
479 .opt.argfunc = pkcs12_opt_passarg,
480 },
481 {
482 .name = "twopass",
483 .desc = "Separate MAC, encryption passwords",
484 .type = OPTION_FLAG,
485 .opt.flag = &cfg.twopass,
486 },
487 { NULL },
488};
489
490static void
491pkcs12_usage(void)
492{
493 fprintf(stderr, "usage: pkcs12 [-aes128 | -aes192 | -aes256 |");
494 fprintf(stderr, " -camellia128 |\n");
495 fprintf(stderr, " -camellia192 | -camellia256 | -des | -des3 |");
496 fprintf(stderr, " -idea]\n");
497 fprintf(stderr, " [-cacerts] [-CAfile file] [-caname name]\n");
498 fprintf(stderr, " [-CApath directory] [-certfile file]");
499 fprintf(stderr, " [-certpbe alg]\n");
500 fprintf(stderr, " [-chain] [-clcerts] [-CSP name] [-descert]");
501 fprintf(stderr, " [-export]\n");
502 fprintf(stderr, " [-in file] [-info] [-inkey file] [-keyex]");
503 fprintf(stderr, " [-keypbe alg]\n");
504 fprintf(stderr, " [-keysig] [-LMK] [-macalg alg] [-maciter]");
505 fprintf(stderr, " [-name name]\n");
506 fprintf(stderr, " [-nocerts] [-nodes] [-noiter] [-nokeys]");
507 fprintf(stderr, " [-nomac]\n");
508 fprintf(stderr, " [-nomaciter] [-nomacver] [-noout] [-out file]\n");
509 fprintf(stderr, " [-passin arg] [-passout arg] [-password arg]");
510 fprintf(stderr, " [-twopass]\n\n");
511 options_usage(pkcs12_options);
512 fprintf(stderr, "\n");
513}
514
515int
516pkcs12_main(int argc, char **argv)
517{
518 BIO *in = NULL, *out = NULL;
519 PKCS12 *p12 = NULL;
520 char pass[50], macpass[50];
521 int ret = 1;
522 char *cpass = NULL, *mpass = NULL;
523 char *passin = NULL, *passout = NULL;
524
525 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
526 perror("pledge");
527 exit(1);
528 }
529
530 memset(&cfg, 0, sizeof(cfg));
531 cfg.cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
532 cfg.enc = EVP_des_ede3_cbc();
533 cfg.iter = PKCS12_DEFAULT_ITER;
534 cfg.key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
535 cfg.maciter = PKCS12_DEFAULT_ITER;
536 cfg.macver = 1;
537
538 if (options_parse(argc, argv, pkcs12_options, NULL, NULL) != 0) {
539 pkcs12_usage();
540 goto end;
541 }
542
543 if (cfg.passarg != NULL) {
544 if (cfg.export_cert)
545 cfg.passargout = cfg.passarg;
546 else
547 cfg.passargin = cfg.passarg;
548 }
549 if (!app_passwd(bio_err, cfg.passargin,
550 cfg.passargout, &passin, &passout)) {
551 BIO_printf(bio_err, "Error getting passwords\n");
552 goto end;
553 }
554 if (cpass == NULL) {
555 if (cfg.export_cert)
556 cpass = passout;
557 else
558 cpass = passin;
559 }
560 if (cpass != NULL) {
561 mpass = cpass;
562 cfg.noprompt = 1;
563 } else {
564 cpass = pass;
565 mpass = macpass;
566 }
567
568 if (cfg.infile == NULL)
569 in = BIO_new_fp(stdin, BIO_NOCLOSE);
570 else
571 in = BIO_new_file(cfg.infile, "rb");
572 if (in == NULL) {
573 BIO_printf(bio_err, "Error opening input file %s\n",
574 cfg.infile ? cfg.infile : "<stdin>");
575 perror(cfg.infile);
576 goto end;
577 }
578
579 if (cfg.outfile == NULL) {
580 out = BIO_new_fp(stdout, BIO_NOCLOSE);
581 } else
582 out = BIO_new_file(cfg.outfile, "wb");
583 if (out == NULL) {
584 BIO_printf(bio_err, "Error opening output file %s\n",
585 cfg.outfile ? cfg.outfile : "<stdout>");
586 perror(cfg.outfile);
587 goto end;
588 }
589 if (cfg.twopass) {
590 if (EVP_read_pw_string(macpass, sizeof macpass,
591 "Enter MAC Password:", cfg.export_cert)) {
592 BIO_printf(bio_err, "Can't read Password\n");
593 goto end;
594 }
595 }
596 if (cfg.export_cert) {
597 EVP_PKEY *key = NULL;
598 X509 *ucert = NULL, *x = NULL;
599 STACK_OF(X509) *certs = NULL;
600 const EVP_MD *macmd = NULL;
601 unsigned char *catmp = NULL;
602 int i;
603
604 if ((cfg.options & (NOCERTS | NOKEYS)) ==
605 (NOCERTS | NOKEYS)) {
606 BIO_printf(bio_err, "Nothing to do!\n");
607 goto export_end;
608 }
609 if (cfg.options & NOCERTS)
610 cfg.chain = 0;
611
612 if (!(cfg.options & NOKEYS)) {
613 key = load_key(bio_err, cfg.keyname ?
614 cfg.keyname : cfg.infile,
615 FORMAT_PEM, 1, passin, "private key");
616 if (!key)
617 goto export_end;
618 }
619
620 /* Load in all certs in input file */
621 if (!(cfg.options & NOCERTS)) {
622 certs = load_certs(bio_err, cfg.infile,
623 FORMAT_PEM, NULL, "certificates");
624 if (certs == NULL)
625 goto export_end;
626
627 if (key != NULL) {
628 /* Look for matching private key */
629 for (i = 0; i < sk_X509_num(certs); i++) {
630 x = sk_X509_value(certs, i);
631 if (X509_check_private_key(x, key)) {
632 ucert = x;
633 /* Zero keyid and alias */
634 X509_keyid_set1(ucert, NULL, 0);
635 X509_alias_set1(ucert, NULL, 0);
636 /* Remove from list */
637 (void) sk_X509_delete(certs, i);
638 break;
639 }
640 }
641 if (ucert == NULL) {
642 BIO_printf(bio_err,
643 "No certificate matches private key\n");
644 goto export_end;
645 }
646 }
647 }
648
649 /* Add any more certificates asked for */
650 if (cfg.certfile != NULL) {
651 STACK_OF(X509) *morecerts = NULL;
652 if ((morecerts = load_certs(bio_err,
653 cfg.certfile, FORMAT_PEM, NULL,
654 "certificates from certfile")) == NULL)
655 goto export_end;
656 while (sk_X509_num(morecerts) > 0) {
657 X509 *cert = sk_X509_shift(morecerts);
658
659 if (!sk_X509_push(certs, cert)) {
660 X509_free(cert);
661 sk_X509_pop_free(morecerts, X509_free);
662 goto export_end;
663 }
664 }
665
666 sk_X509_free(morecerts);
667 }
668
669
670 /* If chaining get chain from user cert */
671 if (cfg.chain) {
672 int vret;
673 STACK_OF(X509) *chain2;
674 X509_STORE *store = X509_STORE_new();
675 if (store == NULL) {
676 BIO_printf(bio_err,
677 "Memory allocation error\n");
678 goto export_end;
679 }
680 if (!X509_STORE_load_locations(store,
681 cfg.CAfile, cfg.CApath))
682 X509_STORE_set_default_paths(store);
683
684 vret = get_cert_chain(ucert, store, &chain2);
685 X509_STORE_free(store);
686
687 if (vret == X509_V_OK) {
688 /* Exclude verified certificate */
689 X509_free(sk_X509_shift(chain2));
690
691 while (sk_X509_num(chain2) > 0) {
692 X509 *cert = sk_X509_shift(chain2);
693
694 if (!sk_X509_push(certs, cert)) {
695 X509_free(cert);
696 sk_X509_pop_free(chain2,
697 X509_free);
698 goto export_end;
699 }
700 }
701 sk_X509_free(chain2);
702 } else {
703 if (vret != X509_V_ERR_UNSPECIFIED)
704 BIO_printf(bio_err,
705 "Error %s getting chain.\n",
706 X509_verify_cert_error_string(
707 vret));
708 else
709 ERR_print_errors(bio_err);
710 sk_X509_pop_free(chain2, X509_free);
711 goto export_end;
712 }
713 }
714 /* Add any CA names */
715
716 for (i = 0; i < sk_OPENSSL_STRING_num(cfg.canames);
717 i++) {
718 catmp = (unsigned char *) sk_OPENSSL_STRING_value(
719 cfg.canames, i);
720 X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
721 }
722
723 if (!cfg.noprompt &&
724 EVP_read_pw_string(pass, sizeof pass,
725 "Enter Export Password:", 1)) {
726 BIO_printf(bio_err, "Can't read Password\n");
727 goto export_end;
728 }
729 if (!cfg.twopass)
730 strlcpy(macpass, pass, sizeof macpass);
731
732
733 p12 = PKCS12_create(cpass, cfg.name, key, ucert,
734 certs, cfg.key_pbe, cfg.cert_pbe,
735 cfg.iter, -1, cfg.keytype);
736
737 if (p12 == NULL) {
738 ERR_print_errors(bio_err);
739 goto export_end;
740 }
741 if (cfg.macalg != NULL) {
742 macmd = EVP_get_digestbyname(cfg.macalg);
743 if (macmd == NULL) {
744 BIO_printf(bio_err,
745 "Unknown digest algorithm %s\n",
746 cfg.macalg);
747 }
748 }
749 if (cfg.maciter != -1)
750 PKCS12_set_mac(p12, mpass, -1, NULL, 0,
751 cfg.maciter, macmd);
752
753 i2d_PKCS12_bio(out, p12);
754
755 ret = 0;
756
757 export_end:
758 EVP_PKEY_free(key);
759 sk_X509_pop_free(certs, X509_free);
760 X509_free(ucert);
761
762 goto end;
763
764 }
765 if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) {
766 ERR_print_errors(bio_err);
767 goto end;
768 }
769 if (!cfg.noprompt && EVP_read_pw_string(pass, sizeof pass,
770 "Enter Import Password:", 0)) {
771 BIO_printf(bio_err, "Can't read Password\n");
772 goto end;
773 }
774
775 if (!cfg.twopass)
776 strlcpy(macpass, pass, sizeof macpass);
777
778 if ((cfg.options & INFO) != 0 && PKCS12_mac_present(p12)) {
779 const ASN1_INTEGER *iter;
780
781 PKCS12_get0_mac(NULL, NULL, NULL, &iter, p12);
782 BIO_printf(bio_err, "MAC Iteration %ld\n",
783 iter != NULL ? ASN1_INTEGER_get(iter) : 1);
784 }
785 if (cfg.macver) {
786 /* If we enter empty password try no password first */
787 if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
788 /* If mac and crypto pass the same set it to NULL too */
789 if (!cfg.twopass)
790 cpass = NULL;
791 } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
792 BIO_printf(bio_err,
793 "Mac verify error: invalid password?\n");
794 ERR_print_errors(bio_err);
795 goto end;
796 }
797 BIO_printf(bio_err, "MAC verified OK\n");
798 }
799 if (!dump_certs_keys_p12(out, p12, cpass, -1, cfg.options,
800 passout)) {
801 BIO_printf(bio_err, "Error outputting keys and certificates\n");
802 ERR_print_errors(bio_err);
803 goto end;
804 }
805 ret = 0;
806 end:
807 PKCS12_free(p12);
808 BIO_free(in);
809 BIO_free_all(out);
810 sk_OPENSSL_STRING_free(cfg.canames);
811 free(passin);
812 free(passout);
813
814 return (ret);
815}
816
817static int
818dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options,
819 char *pempass)
820{
821 STACK_OF(PKCS7) *asafes = NULL;
822 STACK_OF(PKCS12_SAFEBAG) *bags;
823 int i, bagnid;
824 int ret = 0;
825 PKCS7 *p7;
826
827 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
828 return 0;
829 for (i = 0; i < sk_PKCS7_num(asafes); i++) {
830 p7 = sk_PKCS7_value(asafes, i);
831 bagnid = OBJ_obj2nid(p7->type);
832 if (bagnid == NID_pkcs7_data) {
833 bags = PKCS12_unpack_p7data(p7);
834 if (options & INFO)
835 BIO_printf(bio_err, "PKCS7 Data\n");
836 } else if (bagnid == NID_pkcs7_encrypted) {
837 if (options & INFO) {
838 BIO_printf(bio_err, "PKCS7 Encrypted data: ");
839 alg_print(bio_err,
840 p7->d.encrypted->enc_data->algorithm);
841 }
842 bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
843 } else
844 continue;
845 if (bags == NULL)
846 goto err;
847 if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
848 options, pempass)) {
849 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
850 goto err;
851 }
852 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
853 bags = NULL;
854 }
855 ret = 1;
856
857 err:
858 sk_PKCS7_pop_free(asafes, PKCS7_free);
859 return ret;
860}
861
862static int
863dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
864 char *pass, int passlen, int options, char *pempass)
865{
866 int i;
867
868 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
869 if (!dump_certs_pkeys_bag(out,
870 sk_PKCS12_SAFEBAG_value(bags, i),
871 pass, passlen,
872 options, pempass))
873 return 0;
874 }
875 return 1;
876}
877
878static int
879dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, int passlen,
880 int options, char *pempass)
881{
882 EVP_PKEY *pkey;
883 const STACK_OF(X509_ATTRIBUTE) *attrs;
884 X509 *x509;
885
886 attrs = PKCS12_SAFEBAG_get0_attrs(bag);
887
888 switch (PKCS12_SAFEBAG_get_nid(bag)) {
889 case NID_keyBag:
890 {
891 const PKCS8_PRIV_KEY_INFO *p8;
892
893 if (options & INFO)
894 BIO_printf(bio_err, "Key bag\n");
895 if (options & NOKEYS)
896 return 1;
897 print_attribs(out, attrs, "Bag Attributes");
898 if ((p8 = PKCS12_SAFEBAG_get0_p8inf(bag)) == NULL)
899 return 0;
900 if ((pkey = EVP_PKCS82PKEY(p8)) == NULL)
901 return 0;
902 print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
903 PEM_write_bio_PrivateKey(out, pkey, cfg.enc, NULL, 0,
904 NULL, pempass);
905 EVP_PKEY_free(pkey);
906 break;
907 }
908
909 case NID_pkcs8ShroudedKeyBag:
910 {
911 PKCS8_PRIV_KEY_INFO *p8;
912
913 if (options & INFO) {
914 const X509_SIG *tp8;
915 const X509_ALGOR *tp8alg;
916
917 BIO_printf(bio_err, "Shrouded Keybag: ");
918 if ((tp8 = PKCS12_SAFEBAG_get0_pkcs8(bag)) == NULL)
919 return 0;
920 X509_SIG_get0(tp8, &tp8alg, NULL);
921 alg_print(bio_err, tp8alg);
922 }
923 if (options & NOKEYS)
924 return 1;
925 print_attribs(out, attrs, "Bag Attributes");
926 if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
927 return 0;
928 if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) {
929 PKCS8_PRIV_KEY_INFO_free(p8);
930 return 0;
931 }
932 print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
933 PKCS8_PRIV_KEY_INFO_free(p8);
934 PEM_write_bio_PrivateKey(out, pkey, cfg.enc, NULL, 0,
935 NULL, pempass);
936 EVP_PKEY_free(pkey);
937 break;
938 }
939
940 case NID_certBag:
941 if (options & INFO)
942 BIO_printf(bio_err, "Certificate bag\n");
943 if (options & NOCERTS)
944 return 1;
945 if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID) != NULL) {
946 if (options & CACERTS)
947 return 1;
948 } else if (options & CLCERTS)
949 return 1;
950 print_attribs(out, attrs, "Bag Attributes");
951 if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
952 return 1;
953 if ((x509 = PKCS12_certbag2x509(bag)) == NULL)
954 return 0;
955 dump_cert_text(out, x509);
956 PEM_write_bio_X509(out, x509);
957 X509_free(x509);
958 break;
959
960 case NID_safeContentsBag:
961 if (options & INFO)
962 BIO_printf(bio_err, "Safe Contents bag\n");
963 print_attribs(out, attrs, "Bag Attributes");
964 return dump_certs_pkeys_bags(out, PKCS12_SAFEBAG_get0_safes(bag),
965 pass, passlen, options, pempass);
966
967 default:
968 BIO_printf(bio_err, "Warning unsupported bag type: ");
969 i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_type(bag));
970 BIO_printf(bio_err, "\n");
971 return 1;
972 break;
973 }
974 return 1;
975}
976
977/* Given a single certificate return a verified chain or NULL if error */
978static int
979get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **out_chain)
980{
981 X509_STORE_CTX *store_ctx = NULL;
982 STACK_OF(X509) *chain = NULL;
983 int ret = X509_V_ERR_UNSPECIFIED;
984
985 if ((store_ctx = X509_STORE_CTX_new()) == NULL)
986 goto err;
987 if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL))
988 goto err;
989
990 if (X509_verify_cert(store_ctx) > 0) {
991 if ((chain = X509_STORE_CTX_get1_chain(store_ctx)) == NULL)
992 goto err;
993 }
994 ret = X509_STORE_CTX_get_error(store_ctx);
995
996 err:
997 X509_STORE_CTX_free(store_ctx);
998 *out_chain = chain;
999
1000 return ret;
1001}
1002
1003static int
1004alg_print(BIO *x, const X509_ALGOR *alg)
1005{
1006 PBEPARAM *pbe = NULL;
1007 const ASN1_OBJECT *aobj;
1008 int param_type;
1009 const void *param;
1010
1011 X509_ALGOR_get0(&aobj, &param_type, &param, alg);
1012 if (param_type == V_ASN1_SEQUENCE)
1013 pbe = ASN1_item_unpack(param, &PBEPARAM_it);
1014 if (pbe == NULL)
1015 return 1;
1016 BIO_printf(bio_err, "%s, Iteration %ld\n",
1017 OBJ_nid2ln(OBJ_obj2nid(aobj)),
1018 ASN1_INTEGER_get(pbe->iter));
1019 ASN1_item_free((ASN1_VALUE *)pbe, &PBEPARAM_it);
1020 return 1;
1021}
1022
1023/* Generalised attribute print: handle PKCS#8 and bag attributes */
1024static void
1025print_attribute(BIO *out, const ASN1_TYPE *av)
1026{
1027 char *value;
1028
1029 switch (av->type) {
1030 case V_ASN1_BMPSTRING:
1031 value = OPENSSL_uni2asc(
1032 av->value.bmpstring->data,
1033 av->value.bmpstring->length);
1034 BIO_printf(out, "%s\n", value);
1035 free(value);
1036 break;
1037
1038 case V_ASN1_OCTET_STRING:
1039 hex_prin(out, av->value.octet_string->data,
1040 av->value.octet_string->length);
1041 BIO_printf(out, "\n");
1042 break;
1043
1044 case V_ASN1_BIT_STRING:
1045 hex_prin(out, av->value.bit_string->data,
1046 av->value.bit_string->length);
1047 BIO_printf(out, "\n");
1048 break;
1049
1050 default:
1051 BIO_printf(out, "<Unsupported tag %d>\n",
1052 av->type);
1053 break;
1054 }
1055}
1056
1057static int
1058print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
1059 const char *name)
1060{
1061 X509_ATTRIBUTE *attr;
1062 ASN1_TYPE *av;
1063 int i, j, attr_nid;
1064
1065 if (attrlst == NULL) {
1066 BIO_printf(out, "%s: <No Attributes>\n", name);
1067 return 1;
1068 }
1069 if (!sk_X509_ATTRIBUTE_num(attrlst)) {
1070 BIO_printf(out, "%s: <Empty Attributes>\n", name);
1071 return 1;
1072 }
1073 BIO_printf(out, "%s\n", name);
1074 for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
1075 ASN1_OBJECT *obj;
1076
1077 attr = sk_X509_ATTRIBUTE_value(attrlst, i);
1078 obj = X509_ATTRIBUTE_get0_object(attr);
1079 attr_nid = OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr));
1080 BIO_printf(out, " ");
1081 if (attr_nid == NID_undef) {
1082 i2a_ASN1_OBJECT(out, obj);
1083 BIO_printf(out, ": ");
1084 } else
1085 BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
1086
1087 if (X509_ATTRIBUTE_count(attr)) {
1088 for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) {
1089 av = X509_ATTRIBUTE_get0_type(attr, j);
1090 print_attribute(out, av);
1091 }
1092 } else
1093 BIO_printf(out, "<No Values>\n");
1094 }
1095 return 1;
1096}
1097
1098static void
1099hex_prin(BIO *out, unsigned char *buf, int len)
1100{
1101 int i;
1102
1103 for (i = 0; i < len; i++)
1104 BIO_printf(out, "%02X ", buf[i]);
1105}
1106
1107static int
1108set_pbe(BIO *err, int *ppbe, const char *str)
1109{
1110 if (str == NULL)
1111 return 0;
1112 if (strcmp(str, "NONE") == 0) {
1113 *ppbe = -1;
1114 return 1;
1115 }
1116 *ppbe = OBJ_txt2nid(str);
1117 if (*ppbe == NID_undef) {
1118 BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
1119 return 0;
1120 }
1121 return 1;
1122}
1123
1124#endif
diff --git a/src/usr.bin/openssl/pkcs7.c b/src/usr.bin/openssl/pkcs7.c
deleted file mode 100644
index da30e23e65..0000000000
--- a/src/usr.bin/openssl/pkcs7.c
+++ /dev/null
@@ -1,291 +0,0 @@
1/* $OpenBSD: pkcs7.c,v 1.15 2023/07/23 11:39:29 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#include <time.h>
63
64#include "apps.h"
65
66#include <openssl/err.h>
67#include <openssl/evp.h>
68#include <openssl/objects.h>
69#include <openssl/pem.h>
70#include <openssl/pkcs7.h>
71#include <openssl/x509.h>
72
73static struct {
74 char *infile;
75 int informat;
76 int noout;
77 char *outfile;
78 int outformat;
79 int p7_print;
80 int print_certs;
81 int text;
82} cfg;
83
84static const struct option pkcs7_options[] = {
85 {
86 .name = "in",
87 .argname = "file",
88 .desc = "Input file (default stdin)",
89 .type = OPTION_ARG,
90 .opt.arg = &cfg.infile,
91 },
92 {
93 .name = "inform",
94 .argname = "format",
95 .desc = "Input format (DER or PEM (default))",
96 .type = OPTION_ARG_FORMAT,
97 .opt.value = &cfg.informat,
98 },
99 {
100 .name = "noout",
101 .desc = "Do not output encoded version of PKCS#7 structure",
102 .type = OPTION_FLAG,
103 .opt.flag = &cfg.noout,
104 },
105 {
106 .name = "out",
107 .argname = "file",
108 .desc = "Output file (default stdout)",
109 .type = OPTION_ARG,
110 .opt.arg = &cfg.outfile,
111 },
112 {
113 .name = "outform",
114 .argname = "format",
115 .desc = "Output format (DER or PEM (default))",
116 .type = OPTION_ARG_FORMAT,
117 .opt.value = &cfg.outformat,
118 },
119 {
120 .name = "print",
121 .desc = "Output ASN.1 representation of PKCS#7 structure",
122 .type = OPTION_FLAG,
123 .opt.flag = &cfg.p7_print,
124 },
125 {
126 .name = "print_certs",
127 .desc = "Print out any certificates or CRLs contained in file",
128 .type = OPTION_FLAG,
129 .opt.flag = &cfg.print_certs,
130 },
131 {
132 .name = "text",
133 .desc = "Print out full certificate details",
134 .type = OPTION_FLAG,
135 .opt.flag = &cfg.text,
136 },
137 { NULL },
138};
139
140static void
141pkcs7_usage(void)
142{
143 fprintf(stderr, "usage: pkcs7 [-in file] "
144 "[-inform DER | PEM] [-noout]\n"
145 " [-out file] [-outform DER | PEM] [-print_certs] [-text]\n\n");
146 options_usage(pkcs7_options);
147}
148
149int
150pkcs7_main(int argc, char **argv)
151{
152 PKCS7 *p7 = NULL;
153 BIO *in = NULL, *out = NULL;
154 int ret = 1;
155 int i;
156
157 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
158 perror("pledge");
159 exit(1);
160 }
161
162 memset(&cfg, 0, sizeof(cfg));
163
164 cfg.informat = FORMAT_PEM;
165 cfg.outformat = FORMAT_PEM;
166
167 if (options_parse(argc, argv, pkcs7_options, NULL, NULL) != 0) {
168 pkcs7_usage();
169 goto end;
170 }
171
172 in = BIO_new(BIO_s_file());
173 out = BIO_new(BIO_s_file());
174 if ((in == NULL) || (out == NULL)) {
175 ERR_print_errors(bio_err);
176 goto end;
177 }
178 if (cfg.infile == NULL)
179 BIO_set_fp(in, stdin, BIO_NOCLOSE);
180 else {
181 if (BIO_read_filename(in, cfg.infile) <= 0) {
182 perror(cfg.infile);
183 goto end;
184 }
185 }
186
187 if (cfg.informat == FORMAT_ASN1)
188 p7 = d2i_PKCS7_bio(in, NULL);
189 else if (cfg.informat == FORMAT_PEM)
190 p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
191 else {
192 BIO_printf(bio_err, "bad input format specified for pkcs7 object\n");
193 goto end;
194 }
195 if (p7 == NULL) {
196 BIO_printf(bio_err, "unable to load PKCS7 object\n");
197 ERR_print_errors(bio_err);
198 goto end;
199 }
200 if (cfg.outfile == NULL) {
201 BIO_set_fp(out, stdout, BIO_NOCLOSE);
202 } else {
203 if (BIO_write_filename(out, cfg.outfile) <= 0) {
204 perror(cfg.outfile);
205 goto end;
206 }
207 }
208
209 if (cfg.p7_print)
210 PKCS7_print_ctx(out, p7, 0, NULL);
211
212 if (cfg.print_certs) {
213 STACK_OF(X509) * certs = NULL;
214 STACK_OF(X509_CRL) * crls = NULL;
215
216 i = OBJ_obj2nid(p7->type);
217 switch (i) {
218 case NID_pkcs7_signed:
219 if (p7->d.sign != NULL) {
220 certs = p7->d.sign->cert;
221 crls = p7->d.sign->crl;
222 }
223 break;
224 case NID_pkcs7_signedAndEnveloped:
225 if (p7->d.signed_and_enveloped != NULL) {
226 certs = p7->d.signed_and_enveloped->cert;
227 crls = p7->d.signed_and_enveloped->crl;
228 }
229 break;
230 default:
231 break;
232 }
233
234 if (certs != NULL) {
235 X509 *x;
236
237 for (i = 0; i < sk_X509_num(certs); i++) {
238 x = sk_X509_value(certs, i);
239 if (cfg.text)
240 X509_print(out, x);
241 else
242 dump_cert_text(out, x);
243
244 if (!cfg.noout)
245 PEM_write_bio_X509(out, x);
246 BIO_puts(out, "\n");
247 }
248 }
249 if (crls != NULL) {
250 X509_CRL *crl;
251
252 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
253 crl = sk_X509_CRL_value(crls, i);
254
255 X509_CRL_print(out, crl);
256
257 if (!cfg.noout)
258 PEM_write_bio_X509_CRL(out, crl);
259 BIO_puts(out, "\n");
260 }
261 }
262 ret = 0;
263 goto end;
264 }
265 if (!cfg.noout) {
266 if (cfg.outformat == FORMAT_ASN1)
267 i = i2d_PKCS7_bio(out, p7);
268 else if (cfg.outformat == FORMAT_PEM)
269 i = PEM_write_bio_PKCS7(out, p7);
270 else {
271 BIO_printf(bio_err, "bad output format specified for outfile\n");
272 goto end;
273 }
274
275 if (!i) {
276 BIO_printf(bio_err, "unable to write pkcs7 object\n");
277 ERR_print_errors(bio_err);
278 goto end;
279 }
280 }
281 ret = 0;
282 end:
283 if (p7 != NULL)
284 PKCS7_free(p7);
285 if (in != NULL)
286 BIO_free(in);
287 if (out != NULL)
288 BIO_free_all(out);
289
290 return (ret);
291}
diff --git a/src/usr.bin/openssl/pkcs8.c b/src/usr.bin/openssl/pkcs8.c
deleted file mode 100644
index 10fad7aed1..0000000000
--- a/src/usr.bin/openssl/pkcs8.c
+++ /dev/null
@@ -1,365 +0,0 @@
1/* $OpenBSD: pkcs8.c,v 1.18 2025/01/02 12:31:44 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999-2004.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include "apps.h"
63
64#include <openssl/err.h>
65#include <openssl/evp.h>
66#include <openssl/pem.h>
67#include <openssl/pkcs12.h>
68
69static struct {
70 const EVP_CIPHER *cipher;
71 char *infile;
72 int informat;
73 int iter;
74 int nocrypt;
75 char *outfile;
76 int outformat;
77 char *passargin;
78 char *passargout;
79 int pbe_nid;
80 int topk8;
81} cfg;
82
83static int
84pkcs8_opt_v1(char *arg)
85{
86 if ((cfg.pbe_nid = OBJ_txt2nid(arg)) == NID_undef) {
87 fprintf(stderr, "Unknown PBE algorithm '%s'\n", arg);
88 return (1);
89 }
90
91 return (0);
92}
93
94static int
95pkcs8_opt_v2(char *arg)
96{
97 if ((cfg.cipher = EVP_get_cipherbyname(arg)) == NULL) {
98 fprintf(stderr, "Unknown cipher '%s'\n", arg);
99 return (1);
100 }
101
102 return (0);
103}
104
105static const struct option pkcs8_options[] = {
106 {
107 .name = "in",
108 .argname = "file",
109 .desc = "Input file (default stdin)",
110 .type = OPTION_ARG,
111 .opt.arg = &cfg.infile,
112 },
113 {
114 .name = "inform",
115 .argname = "der | pem",
116 .desc = "Input format (default PEM)",
117 .type = OPTION_ARG_FORMAT,
118 .opt.value = &cfg.informat,
119 },
120 {
121 .name = "nocrypt",
122 .desc = "Use or expect unencrypted private key",
123 .type = OPTION_FLAG,
124 .opt.flag = &cfg.nocrypt,
125 },
126 {
127 .name = "noiter",
128 .desc = "Use 1 as iteration count",
129 .type = OPTION_VALUE,
130 .value = 1,
131 .opt.value = &cfg.iter,
132 },
133 {
134 .name = "out",
135 .argname = "file",
136 .desc = "Output file (default stdout)",
137 .type = OPTION_ARG,
138 .opt.arg = &cfg.outfile,
139 },
140 {
141 .name = "outform",
142 .argname = "der | pem",
143 .desc = "Output format (default PEM)",
144 .type = OPTION_ARG_FORMAT,
145 .opt.value = &cfg.outformat,
146 },
147 {
148 .name = "passin",
149 .argname = "source",
150 .desc = "Input file passphrase source",
151 .type = OPTION_ARG,
152 .opt.arg = &cfg.passargin,
153 },
154 {
155 .name = "passout",
156 .argname = "source",
157 .desc = "Output file passphrase source",
158 .type = OPTION_ARG,
159 .opt.arg = &cfg.passargout,
160 },
161 {
162 .name = "topk8",
163 .desc = "Read traditional format key and write PKCS#8 format"
164 " key",
165 .type = OPTION_FLAG,
166 .opt.flag = &cfg.topk8,
167 },
168 {
169 .name = "v1",
170 .argname = "algorithm",
171 .desc = "Use PKCS#5 v1.5 or PKCS#12 with given algorithm",
172 .type = OPTION_ARG_FUNC,
173 .opt.argfunc = pkcs8_opt_v1,
174 },
175 {
176 .name = "v2",
177 .argname = "cipher",
178 .desc = "Use PKCS#5 v2.0 with given cipher",
179 .type = OPTION_ARG_FUNC,
180 .opt.argfunc = pkcs8_opt_v2,
181 },
182 { NULL },
183};
184
185static void
186pkcs8_usage(void)
187{
188 fprintf(stderr, "usage: pkcs8 [-in file] [inform der | pem] "
189 "[-nocrypt] [-noiter]\n"
190 " [-out file] [-outform der | pem] [-passin arg]\n"
191 " [-passout arg] [-topk8] [-v1 alg] [-v2 alg]\n\n");
192 options_usage(pkcs8_options);
193}
194
195int
196pkcs8_main(int argc, char **argv)
197{
198 BIO *in = NULL, *out = NULL;
199 X509_SIG *p8 = NULL;
200 PKCS8_PRIV_KEY_INFO *p8inf = NULL;
201 EVP_PKEY *pkey = NULL;
202 char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
203 int ret = 1;
204
205 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
206 perror("pledge");
207 exit(1);
208 }
209
210 memset(&cfg, 0, sizeof(cfg));
211
212 cfg.iter = PKCS12_DEFAULT_ITER;
213 cfg.informat = FORMAT_PEM;
214 cfg.outformat = FORMAT_PEM;
215 cfg.pbe_nid = -1;
216
217 if (options_parse(argc, argv, pkcs8_options, NULL, NULL) != 0) {
218 pkcs8_usage();
219 return (1);
220 }
221
222 if (!app_passwd(bio_err, cfg.passargin,
223 cfg.passargout, &passin, &passout)) {
224 BIO_printf(bio_err, "Error getting passwords\n");
225 goto end;
226 }
227 if ((cfg.pbe_nid == -1) && !cfg.cipher)
228 cfg.pbe_nid = NID_pbeWithMD5AndDES_CBC;
229
230 if (cfg.infile) {
231 if (!(in = BIO_new_file(cfg.infile, "rb"))) {
232 BIO_printf(bio_err,
233 "Can't open input file '%s'\n",
234 cfg.infile);
235 goto end;
236 }
237 } else
238 in = BIO_new_fp(stdin, BIO_NOCLOSE);
239
240 if (cfg.outfile) {
241 if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
242 BIO_printf(bio_err, "Can't open output file '%s'\n",
243 cfg.outfile);
244 goto end;
245 }
246 } else {
247 out = BIO_new_fp(stdout, BIO_NOCLOSE);
248 }
249 if (cfg.topk8) {
250 pkey = load_key(bio_err, cfg.infile,
251 cfg.informat, 1, passin, "key");
252 if (!pkey)
253 goto end;
254 if (!(p8inf = EVP_PKEY2PKCS8(pkey))) {
255 BIO_printf(bio_err, "Error converting key\n");
256 ERR_print_errors(bio_err);
257 goto end;
258 }
259 if (cfg.nocrypt) {
260 if (cfg.outformat == FORMAT_PEM)
261 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
262 else if (cfg.outformat == FORMAT_ASN1)
263 i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
264 else {
265 BIO_printf(bio_err,
266 "Bad format specified for key\n");
267 goto end;
268 }
269 } else {
270 if (passout)
271 p8pass = passout;
272 else {
273 p8pass = pass;
274 if (EVP_read_pw_string(pass, sizeof pass,
275 "Enter Encryption Password:", 1))
276 goto end;
277 }
278 if (!(p8 = PKCS8_encrypt(cfg.pbe_nid,
279 cfg.cipher, p8pass, strlen(p8pass),
280 NULL, 0, cfg.iter, p8inf))) {
281 BIO_printf(bio_err, "Error encrypting key\n");
282 ERR_print_errors(bio_err);
283 goto end;
284 }
285 if (cfg.outformat == FORMAT_PEM)
286 PEM_write_bio_PKCS8(out, p8);
287 else if (cfg.outformat == FORMAT_ASN1)
288 i2d_PKCS8_bio(out, p8);
289 else {
290 BIO_printf(bio_err,
291 "Bad format specified for key\n");
292 goto end;
293 }
294 }
295
296 ret = 0;
297 goto end;
298 }
299 if (cfg.nocrypt) {
300 if (cfg.informat == FORMAT_PEM)
301 p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL,
302 NULL, NULL);
303 else if (cfg.informat == FORMAT_ASN1)
304 p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
305 else {
306 BIO_printf(bio_err, "Bad format specified for key\n");
307 goto end;
308 }
309 } else {
310 if (cfg.informat == FORMAT_PEM)
311 p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
312 else if (cfg.informat == FORMAT_ASN1)
313 p8 = d2i_PKCS8_bio(in, NULL);
314 else {
315 BIO_printf(bio_err, "Bad format specified for key\n");
316 goto end;
317 }
318
319 if (!p8) {
320 BIO_printf(bio_err, "Error reading key\n");
321 ERR_print_errors(bio_err);
322 goto end;
323 }
324 if (passin)
325 p8pass = passin;
326 else {
327 p8pass = pass;
328 EVP_read_pw_string(pass, sizeof pass,
329 "Enter Password:", 0);
330 }
331 p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
332 }
333
334 if (!p8inf) {
335 BIO_printf(bio_err, "Error decrypting key\n");
336 ERR_print_errors(bio_err);
337 goto end;
338 }
339 if (!(pkey = EVP_PKCS82PKEY(p8inf))) {
340 BIO_printf(bio_err, "Error converting key\n");
341 ERR_print_errors(bio_err);
342 goto end;
343 }
344 if (cfg.outformat == FORMAT_PEM)
345 PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL,
346 passout);
347 else if (cfg.outformat == FORMAT_ASN1)
348 i2d_PrivateKey_bio(out, pkey);
349 else {
350 BIO_printf(bio_err, "Bad format specified for key\n");
351 goto end;
352 }
353 ret = 0;
354
355 end:
356 X509_SIG_free(p8);
357 PKCS8_PRIV_KEY_INFO_free(p8inf);
358 EVP_PKEY_free(pkey);
359 BIO_free_all(out);
360 BIO_free(in);
361 free(passin);
362 free(passout);
363
364 return ret;
365}
diff --git a/src/usr.bin/openssl/pkey.c b/src/usr.bin/openssl/pkey.c
deleted file mode 100644
index d3c9f27d25..0000000000
--- a/src/usr.bin/openssl/pkey.c
+++ /dev/null
@@ -1,287 +0,0 @@
1/* $OpenBSD: pkey.c,v 1.21 2024/08/29 17:01:02 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include "apps.h"
63
64#include <openssl/err.h>
65#include <openssl/evp.h>
66#include <openssl/pem.h>
67
68static struct {
69 const EVP_CIPHER *cipher;
70 char *infile;
71 int informat;
72 int noout;
73 char *outfile;
74 int outformat;
75 char *passargin;
76 char *passargout;
77 int pubin;
78 int pubout;
79 int pubtext;
80 int text;
81} cfg;
82
83static int
84pkey_opt_cipher(int argc, char **argv, int *argsused)
85{
86 char *name = argv[0];
87
88 if (*name++ != '-')
89 return (1);
90
91 if ((cfg.cipher = EVP_get_cipherbyname(name)) == NULL) {
92 BIO_printf(bio_err, "Unknown cipher %s\n", name);
93 return (1);
94 }
95
96 *argsused = 1;
97 return (0);
98}
99
100static const struct option pkey_options[] = {
101 {
102 .name = "in",
103 .argname = "file",
104 .desc = "Input file (default stdin)",
105 .type = OPTION_ARG,
106 .opt.arg = &cfg.infile,
107 },
108 {
109 .name = "inform",
110 .argname = "format",
111 .desc = "Input format (DER or PEM (default))",
112 .type = OPTION_ARG_FORMAT,
113 .opt.value = &cfg.informat,
114 },
115 {
116 .name = "noout",
117 .desc = "Do not print encoded version of the key",
118 .type = OPTION_FLAG,
119 .opt.flag = &cfg.noout,
120 },
121 {
122 .name = "out",
123 .argname = "file",
124 .desc = "Output file (default stdout)",
125 .type = OPTION_ARG,
126 .opt.arg = &cfg.outfile,
127 },
128 {
129 .name = "outform",
130 .argname = "format",
131 .desc = "Output format (DER or PEM (default))",
132 .type = OPTION_ARG_FORMAT,
133 .opt.value = &cfg.outformat,
134 },
135 {
136 .name = "passin",
137 .argname = "src",
138 .desc = "Input file passphrase source",
139 .type = OPTION_ARG,
140 .opt.arg = &cfg.passargin,
141 },
142 {
143 .name = "passout",
144 .argname = "src",
145 .desc = "Output file passphrase source",
146 .type = OPTION_ARG,
147 .opt.arg = &cfg.passargout,
148 },
149 {
150 .name = "pubin",
151 .desc = "Expect a public key (default private key)",
152 .type = OPTION_VALUE,
153 .value = 1,
154 .opt.value = &cfg.pubin,
155 },
156 {
157 .name = "pubout",
158 .desc = "Output a public key (default private key)",
159 .type = OPTION_VALUE,
160 .value = 1,
161 .opt.value = &cfg.pubout,
162 },
163 {
164 .name = "text",
165 .desc = "Print the public/private key in plain text",
166 .type = OPTION_FLAG,
167 .opt.flag = &cfg.text,
168 },
169 {
170 .name = "text_pub",
171 .desc = "Print out only public key in plain text",
172 .type = OPTION_FLAG,
173 .opt.flag = &cfg.pubtext,
174 },
175 {
176 .name = NULL,
177 .type = OPTION_ARGV_FUNC,
178 .opt.argvfunc = pkey_opt_cipher,
179 },
180 { NULL }
181};
182
183static void
184pkey_usage(void)
185{
186 int n = 0;
187
188 fprintf(stderr,
189 "usage: pkey [-ciphername] [-in file] [-inform fmt] "
190 "[-noout] [-out file]\n"
191 " [-outform fmt] [-passin src] [-passout src] "
192 "[-pubin] [-pubout]\n"
193 " [-text] [-text_pub]\n\n");
194 options_usage(pkey_options);
195 fprintf(stderr, "\n");
196
197 fprintf(stderr, "Valid ciphername values:\n\n");
198 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
199 fprintf(stderr, "\n");
200}
201
202int
203pkey_main(int argc, char **argv)
204{
205 BIO *in = NULL, *out = NULL;
206 EVP_PKEY *pkey = NULL;
207 char *passin = NULL, *passout = NULL;
208 int ret = 1;
209
210 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
211 perror("pledge");
212 exit(1);
213 }
214
215 memset(&cfg, 0, sizeof(cfg));
216 cfg.informat = FORMAT_PEM;
217 cfg.outformat = FORMAT_PEM;
218
219 if (options_parse(argc, argv, pkey_options, NULL, NULL) != 0) {
220 pkey_usage();
221 goto end;
222 }
223
224 if (cfg.pubtext)
225 cfg.text = 1;
226 if (cfg.pubin)
227 cfg.pubout = cfg.pubtext = 1;
228
229 if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
230 &passin, &passout)) {
231 BIO_printf(bio_err, "Error getting passwords\n");
232 goto end;
233 }
234 if (cfg.outfile) {
235 if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
236 BIO_printf(bio_err,
237 "Can't open output file %s\n", cfg.outfile);
238 goto end;
239 }
240 } else {
241 out = BIO_new_fp(stdout, BIO_NOCLOSE);
242 }
243
244 if (cfg.pubin)
245 pkey = load_pubkey(bio_err, cfg.infile,
246 cfg.informat, 1, passin, "Public Key");
247 else
248 pkey = load_key(bio_err, cfg.infile,
249 cfg.informat, 1, passin, "key");
250 if (!pkey)
251 goto end;
252
253 if (!cfg.noout) {
254 if (cfg.outformat == FORMAT_PEM) {
255 if (cfg.pubout)
256 PEM_write_bio_PUBKEY(out, pkey);
257 else
258 PEM_write_bio_PrivateKey(out, pkey,
259 cfg.cipher, NULL, 0, NULL, passout);
260 } else if (cfg.outformat == FORMAT_ASN1) {
261 if (cfg.pubout)
262 i2d_PUBKEY_bio(out, pkey);
263 else
264 i2d_PrivateKey_bio(out, pkey);
265 } else {
266 BIO_printf(bio_err, "Bad format specified for key\n");
267 goto end;
268 }
269
270 }
271 if (cfg.text) {
272 if (cfg.pubtext)
273 EVP_PKEY_print_public(out, pkey, 0, NULL);
274 else
275 EVP_PKEY_print_private(out, pkey, 0, NULL);
276 }
277 ret = 0;
278
279 end:
280 EVP_PKEY_free(pkey);
281 BIO_free_all(out);
282 BIO_free(in);
283 free(passin);
284 free(passout);
285
286 return ret;
287}
diff --git a/src/usr.bin/openssl/pkeyparam.c b/src/usr.bin/openssl/pkeyparam.c
deleted file mode 100644
index ce0206a700..0000000000
--- a/src/usr.bin/openssl/pkeyparam.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/* $OpenBSD: pkeyparam.c,v 1.19 2024/08/29 17:01:02 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include "apps.h"
63
64#include <openssl/err.h>
65#include <openssl/evp.h>
66#include <openssl/pem.h>
67
68static struct {
69 char *infile;
70 int noout;
71 char *outfile;
72 int text;
73} cfg;
74
75static const struct option pkeyparam_options[] = {
76 {
77 .name = "in",
78 .argname = "file",
79 .desc = "Input file (default stdin)",
80 .type = OPTION_ARG,
81 .opt.arg = &cfg.infile,
82 },
83 {
84 .name = "noout",
85 .desc = "Do not print encoded version of the parameters",
86 .type = OPTION_FLAG,
87 .opt.flag = &cfg.noout,
88 },
89 {
90 .name = "out",
91 .argname = "file",
92 .desc = "Output file (default stdout)",
93 .type = OPTION_ARG,
94 .opt.arg = &cfg.outfile,
95 },
96 {
97 .name = "text",
98 .desc = "Print out the parameters in plain text",
99 .type = OPTION_FLAG,
100 .opt.flag = &cfg.text,
101 },
102 { NULL },
103};
104
105static void
106pkeyparam_usage(void)
107{
108 fprintf(stderr,
109 "usage: pkeyparam [-in file] [-noout] [-out file] [-text]\n");
110 options_usage(pkeyparam_options);
111}
112
113int
114pkeyparam_main(int argc, char **argv)
115{
116 BIO *in = NULL, *out = NULL;
117 EVP_PKEY *pkey = NULL;
118 int ret = 1;
119
120 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
121 perror("pledge");
122 exit(1);
123 }
124
125 memset(&cfg, 0, sizeof(cfg));
126
127 if (options_parse(argc, argv, pkeyparam_options, NULL, NULL) != 0) {
128 pkeyparam_usage();
129 return (1);
130 }
131
132 if (cfg.infile) {
133 if (!(in = BIO_new_file(cfg.infile, "r"))) {
134 BIO_printf(bio_err, "Can't open input file %s\n",
135 cfg.infile);
136 goto end;
137 }
138 } else
139 in = BIO_new_fp(stdin, BIO_NOCLOSE);
140
141 if (cfg.outfile) {
142 if (!(out = BIO_new_file(cfg.outfile, "w"))) {
143 BIO_printf(bio_err, "Can't open output file %s\n",
144 cfg.outfile);
145 goto end;
146 }
147 } else {
148 out = BIO_new_fp(stdout, BIO_NOCLOSE);
149 }
150
151 pkey = PEM_read_bio_Parameters(in, NULL);
152 if (!pkey) {
153 BIO_printf(bio_err, "Error reading parameters\n");
154 ERR_print_errors(bio_err);
155 goto end;
156 }
157
158 if (!cfg.noout)
159 PEM_write_bio_Parameters(out, pkey);
160
161 if (cfg.text)
162 EVP_PKEY_print_params(out, pkey, 0, NULL);
163
164 ret = 0;
165
166 end:
167 EVP_PKEY_free(pkey);
168 BIO_free_all(out);
169 BIO_free(in);
170
171 return ret;
172}
diff --git a/src/usr.bin/openssl/pkeyutl.c b/src/usr.bin/openssl/pkeyutl.c
deleted file mode 100644
index eebd14855b..0000000000
--- a/src/usr.bin/openssl/pkeyutl.c
+++ /dev/null
@@ -1,571 +0,0 @@
1/* $OpenBSD: pkeyutl.c,v 1.20 2023/07/23 11:39:29 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <string.h>
60
61#include "apps.h"
62
63#include <openssl/err.h>
64#include <openssl/evp.h>
65#include <openssl/pem.h>
66
67#define KEY_PRIVKEY 1
68#define KEY_PUBKEY 2
69#define KEY_CERT 3
70
71static struct {
72 int asn1parse;
73 EVP_PKEY_CTX *ctx;
74 int hexdump;
75 char *infile;
76 int key_type;
77 int keyform;
78 int keysize;
79 char *outfile;
80 char *passargin;
81 int peerform;
82 int pkey_op;
83 int rev;
84 char *sigfile;
85} cfg;
86
87static void pkeyutl_usage(void);
88
89static int init_ctx(char *keyfile);
90
91static int setup_peer(char *file);
92
93static int pkeyutl_pkeyopt(char *pkeyopt);
94
95static int do_keyop(EVP_PKEY_CTX * ctx, int pkey_op,
96 unsigned char *out, size_t * poutlen,
97 unsigned char *in, size_t inlen);
98
99static const struct option pkeyutl_options[] = {
100 {
101 .name = "asn1parse",
102 .desc = "ASN.1 parse the output data",
103 .type = OPTION_FLAG,
104 .opt.flag = &cfg.asn1parse,
105 },
106 {
107 .name = "certin",
108 .desc = "Input is a certificate containing a public key",
109 .type = OPTION_VALUE,
110 .value = KEY_CERT,
111 .opt.value = &cfg.key_type,
112 },
113 {
114 .name = "decrypt",
115 .desc = "Decrypt the input data using a private key",
116 .type = OPTION_VALUE,
117 .value = EVP_PKEY_OP_DECRYPT,
118 .opt.value = &cfg.pkey_op,
119 },
120 {
121 .name = "derive",
122 .desc = "Derive a shared secret using the peer key",
123 .type = OPTION_VALUE,
124 .value = EVP_PKEY_OP_DERIVE,
125 .opt.value = &cfg.pkey_op,
126 },
127 {
128 .name = "encrypt",
129 .desc = "Encrypt the input data using a public key",
130 .type = OPTION_VALUE,
131 .value = EVP_PKEY_OP_ENCRYPT,
132 .opt.value = &cfg.pkey_op,
133 },
134 {
135 .name = "hexdump",
136 .desc = "Hex dump the output data",
137 .type = OPTION_FLAG,
138 .opt.flag = &cfg.hexdump,
139 },
140 {
141 .name = "in",
142 .argname = "file",
143 .desc = "Input file (default stdin)",
144 .type = OPTION_ARG,
145 .opt.arg = &cfg.infile,
146 },
147 {
148 .name = "inkey",
149 .argname = "file",
150 .desc = "Input key file",
151 .type = OPTION_ARG_FUNC,
152 .opt.argfunc = init_ctx,
153 },
154 {
155 .name = "keyform",
156 .argname = "fmt",
157 .desc = "Input key format (DER or PEM (default))",
158 .type = OPTION_ARG_FORMAT,
159 .opt.value = &cfg.keyform,
160 },
161 {
162 .name = "out",
163 .argname = "file",
164 .desc = "Output file (default stdout)",
165 .type = OPTION_ARG,
166 .opt.arg = &cfg.outfile,
167 },
168 {
169 .name = "passin",
170 .argname = "arg",
171 .desc = "Key password source",
172 .type = OPTION_ARG,
173 .opt.arg = &cfg.passargin,
174 },
175 {
176 .name = "peerform",
177 .argname = "fmt",
178 .desc = "Input key format (DER or PEM (default))",
179 .type = OPTION_ARG_FORMAT,
180 .opt.value = &cfg.peerform,
181 },
182 {
183 .name = "peerkey",
184 .argname = "file",
185 .desc = "Peer key file",
186 .type = OPTION_ARG_FUNC,
187 .opt.argfunc = setup_peer,
188 },
189 {
190 .name = "pkeyopt",
191 .argname = "opt:value",
192 .desc = "Public key options",
193 .type = OPTION_ARG_FUNC,
194 .opt.argfunc = pkeyutl_pkeyopt,
195 },
196 {
197 .name = "pubin",
198 .desc = "Input is a public key",
199 .type = OPTION_VALUE,
200 .value = KEY_PUBKEY,
201 .opt.value = &cfg.key_type,
202 },
203 {
204 .name = "rev",
205 .desc = "Reverse the input data",
206 .type = OPTION_FLAG,
207 .opt.flag = &cfg.rev,
208 },
209 {
210 .name = "sigfile",
211 .argname = "file",
212 .desc = "Signature file (verify operation only)",
213 .type = OPTION_ARG,
214 .opt.arg = &cfg.sigfile,
215 },
216 {
217 .name = "sign",
218 .desc = "Sign the input data using private key",
219 .type = OPTION_VALUE,
220 .value = EVP_PKEY_OP_SIGN,
221 .opt.value = &cfg.pkey_op,
222 },
223 {
224 .name = "verify",
225 .desc = "Verify the input data using public key",
226 .type = OPTION_VALUE,
227 .value = EVP_PKEY_OP_VERIFY,
228 .opt.value = &cfg.pkey_op,
229 },
230 {
231 .name = "verifyrecover",
232 .desc = "Verify with public key, recover original data",
233 .type = OPTION_VALUE,
234 .value = EVP_PKEY_OP_VERIFYRECOVER,
235 .opt.value = &cfg.pkey_op,
236 },
237
238 {NULL},
239};
240
241static void
242pkeyutl_usage(void)
243{
244 fprintf(stderr,
245 "usage: pkeyutl [-asn1parse] [-certin] [-decrypt] [-derive] "
246 "[-encrypt]\n"
247 " [-hexdump] [-in file] [-inkey file] [-keyform fmt]\n"
248 " [-out file] [-passin arg] [-peerform fmt]\n"
249 " [-peerkey file] [-pkeyopt opt:value] [-pubin] [-rev]\n"
250 " [-sigfile file] [-sign] [-verify] [-verifyrecover]\n\n");
251 options_usage(pkeyutl_options);
252 fprintf(stderr, "\n");
253}
254
255int
256pkeyutl_main(int argc, char **argv)
257{
258 BIO *in = NULL, *out = NULL;
259
260 unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
261 size_t buf_outlen = 0;
262 int buf_inlen = 0, siglen = -1;
263
264 int ret = 1, rv = -1;
265
266 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
267 perror("pledge");
268 exit(1);
269 }
270
271 memset(&cfg, 0, sizeof(cfg));
272 cfg.pkey_op = EVP_PKEY_OP_SIGN;
273 cfg.key_type = KEY_PRIVKEY;
274 cfg.keyform = FORMAT_PEM;
275 cfg.peerform = FORMAT_PEM;
276 cfg.keysize = -1;
277
278 if (options_parse(argc, argv, pkeyutl_options, NULL, NULL) != 0) {
279 pkeyutl_usage();
280 goto end;
281 }
282
283 if (!cfg.ctx) {
284 pkeyutl_usage();
285 goto end;
286 }
287 if (cfg.sigfile &&
288 (cfg.pkey_op != EVP_PKEY_OP_VERIFY)) {
289 BIO_puts(bio_err, "Signature file specified for non verify\n");
290 goto end;
291 }
292 if (!cfg.sigfile &&
293 (cfg.pkey_op == EVP_PKEY_OP_VERIFY)) {
294 BIO_puts(bio_err, "No signature file specified for verify\n");
295 goto end;
296 }
297
298 if (cfg.pkey_op != EVP_PKEY_OP_DERIVE) {
299 if (cfg.infile) {
300 if (!(in = BIO_new_file(cfg.infile, "rb"))) {
301 BIO_puts(bio_err,
302 "Error Opening Input File\n");
303 ERR_print_errors(bio_err);
304 goto end;
305 }
306 } else
307 in = BIO_new_fp(stdin, BIO_NOCLOSE);
308 }
309 if (cfg.outfile) {
310 if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
311 BIO_printf(bio_err, "Error Creating Output File\n");
312 ERR_print_errors(bio_err);
313 goto end;
314 }
315 } else {
316 out = BIO_new_fp(stdout, BIO_NOCLOSE);
317 }
318
319 if (cfg.sigfile) {
320 BIO *sigbio = BIO_new_file(cfg.sigfile, "rb");
321 if (!sigbio) {
322 BIO_printf(bio_err, "Can't open signature file %s\n",
323 cfg.sigfile);
324 goto end;
325 }
326 siglen = bio_to_mem(&sig, cfg.keysize * 10, sigbio);
327 BIO_free(sigbio);
328 if (siglen <= 0) {
329 BIO_printf(bio_err, "Error reading signature data\n");
330 goto end;
331 }
332 }
333 if (in) {
334 /* Read the input data */
335 buf_inlen = bio_to_mem(&buf_in, cfg.keysize * 10, in);
336 if (buf_inlen <= 0) {
337 BIO_printf(bio_err, "Error reading input Data\n");
338 exit(1);
339 }
340 if (cfg.rev) {
341 size_t i;
342 unsigned char ctmp;
343 size_t l = (size_t) buf_inlen;
344 for (i = 0; i < l / 2; i++) {
345 ctmp = buf_in[i];
346 buf_in[i] = buf_in[l - 1 - i];
347 buf_in[l - 1 - i] = ctmp;
348 }
349 }
350 }
351 if (cfg.pkey_op == EVP_PKEY_OP_VERIFY) {
352 rv = EVP_PKEY_verify(cfg.ctx, sig, (size_t) siglen,
353 buf_in, (size_t) buf_inlen);
354 if (rv == 1) {
355 BIO_puts(out, "Signature Verified Successfully\n");
356 ret = 0;
357 } else
358 BIO_puts(out, "Signature Verification Failure\n");
359 if (rv >= 0)
360 goto end;
361 } else {
362 rv = do_keyop(cfg.ctx, cfg.pkey_op, NULL,
363 (size_t *)&buf_outlen, buf_in, (size_t) buf_inlen);
364 if (rv > 0) {
365 buf_out = malloc(buf_outlen);
366 if (!buf_out)
367 rv = -1;
368 else
369 rv = do_keyop(cfg.ctx,
370 cfg.pkey_op,
371 buf_out, (size_t *) & buf_outlen,
372 buf_in, (size_t) buf_inlen);
373 }
374 }
375
376 if (rv <= 0) {
377 BIO_printf(bio_err, "Public Key operation error\n");
378 ERR_print_errors(bio_err);
379 goto end;
380 }
381 ret = 0;
382 if (cfg.asn1parse) {
383 if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
384 ERR_print_errors(bio_err);
385 } else if (cfg.hexdump)
386 BIO_dump(out, (char *) buf_out, buf_outlen);
387 else
388 BIO_write(out, buf_out, buf_outlen);
389
390 end:
391 EVP_PKEY_CTX_free(cfg.ctx);
392 BIO_free(in);
393 BIO_free_all(out);
394 free(buf_in);
395 free(buf_out);
396 free(sig);
397
398 return ret;
399}
400
401static int
402init_ctx(char *keyfile)
403{
404 EVP_PKEY *pkey = NULL;
405 char *passin = NULL;
406 int rv = -1;
407 X509 *x;
408
409 if (((cfg.pkey_op == EVP_PKEY_OP_SIGN)
410 || (cfg.pkey_op == EVP_PKEY_OP_DECRYPT)
411 || (cfg.pkey_op == EVP_PKEY_OP_DERIVE))
412 && (cfg.key_type != KEY_PRIVKEY)) {
413 BIO_printf(bio_err,
414 "A private key is needed for this operation\n");
415 goto end;
416 }
417 if (!app_passwd(bio_err, cfg.passargin, NULL, &passin,
418 NULL)) {
419 BIO_printf(bio_err, "Error getting password\n");
420 goto end;
421 }
422 switch (cfg.key_type) {
423 case KEY_PRIVKEY:
424 pkey = load_key(bio_err, keyfile, cfg.keyform, 0,
425 passin, "Private Key");
426 break;
427
428 case KEY_PUBKEY:
429 pkey = load_pubkey(bio_err, keyfile, cfg.keyform, 0,
430 NULL, "Public Key");
431 break;
432
433 case KEY_CERT:
434 x = load_cert(bio_err, keyfile, cfg.keyform,
435 NULL, "Certificate");
436 if (x) {
437 pkey = X509_get_pubkey(x);
438 X509_free(x);
439 }
440 break;
441 }
442
443 cfg.keysize = EVP_PKEY_size(pkey);
444
445 if (!pkey)
446 goto end;
447
448 cfg.ctx = EVP_PKEY_CTX_new(pkey, NULL);
449
450 EVP_PKEY_free(pkey);
451
452 if (!cfg.ctx)
453 goto end;
454
455 switch (cfg.pkey_op) {
456 case EVP_PKEY_OP_SIGN:
457 rv = EVP_PKEY_sign_init(cfg.ctx);
458 break;
459
460 case EVP_PKEY_OP_VERIFY:
461 rv = EVP_PKEY_verify_init(cfg.ctx);
462 break;
463
464 case EVP_PKEY_OP_VERIFYRECOVER:
465 rv = EVP_PKEY_verify_recover_init(cfg.ctx);
466 break;
467
468 case EVP_PKEY_OP_ENCRYPT:
469 rv = EVP_PKEY_encrypt_init(cfg.ctx);
470 break;
471
472 case EVP_PKEY_OP_DECRYPT:
473 rv = EVP_PKEY_decrypt_init(cfg.ctx);
474 break;
475
476 case EVP_PKEY_OP_DERIVE:
477 rv = EVP_PKEY_derive_init(cfg.ctx);
478 break;
479 }
480
481 if (rv <= 0) {
482 EVP_PKEY_CTX_free(cfg.ctx);
483 cfg.ctx = NULL;
484 }
485
486 end:
487 free(passin);
488
489 if (!cfg.ctx) {
490 BIO_puts(bio_err, "Error initializing context\n");
491 ERR_print_errors(bio_err);
492 return (1);
493 }
494
495 return (0);
496}
497
498static int
499setup_peer(char *file)
500{
501 EVP_PKEY *peer = NULL;
502 int ret;
503
504 if (!cfg.ctx) {
505 BIO_puts(bio_err, "-peerkey command before -inkey\n");
506 return (1);
507 }
508 peer = load_pubkey(bio_err, file, cfg.peerform, 0, NULL,
509 "Peer Key");
510
511 if (!peer) {
512 BIO_printf(bio_err, "Error reading peer key %s\n", file);
513 ERR_print_errors(bio_err);
514 return (1);
515 }
516 ret = EVP_PKEY_derive_set_peer(cfg.ctx, peer);
517
518 EVP_PKEY_free(peer);
519 if (ret <= 0) {
520 ERR_print_errors(bio_err);
521 return (1);
522 }
523
524 return (0);
525}
526
527static int
528pkeyutl_pkeyopt(char *pkeyopt)
529{
530 if (!cfg.ctx) {
531 BIO_puts(bio_err, "-pkeyopt command before -inkey\n");
532 return (1);
533 } else if (pkey_ctrl_string(cfg.ctx, pkeyopt) <= 0) {
534 BIO_puts(bio_err, "parameter setting error\n");
535 ERR_print_errors(bio_err);
536 return (1);
537 }
538
539 return (0);
540}
541
542static int
543do_keyop(EVP_PKEY_CTX * ctx, int pkey_op,
544 unsigned char *out, size_t * poutlen,
545 unsigned char *in, size_t inlen)
546{
547 int rv = 0;
548 switch (pkey_op) {
549 case EVP_PKEY_OP_VERIFYRECOVER:
550 rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
551 break;
552
553 case EVP_PKEY_OP_SIGN:
554 rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
555 break;
556
557 case EVP_PKEY_OP_ENCRYPT:
558 rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
559 break;
560
561 case EVP_PKEY_OP_DECRYPT:
562 rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
563 break;
564
565 case EVP_PKEY_OP_DERIVE:
566 rv = EVP_PKEY_derive(ctx, out, poutlen);
567 break;
568
569 }
570 return rv;
571}
diff --git a/src/usr.bin/openssl/prime.c b/src/usr.bin/openssl/prime.c
deleted file mode 100644
index 36703c5748..0000000000
--- a/src/usr.bin/openssl/prime.c
+++ /dev/null
@@ -1,201 +0,0 @@
1/* $OpenBSD: prime.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
2/* ====================================================================
3 * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 */
50
51#include <string.h>
52#include <limits.h>
53
54#include "apps.h"
55
56#include <openssl/bn.h>
57#include <openssl/err.h>
58
59static struct {
60 int bits;
61 int checks;
62 int generate;
63 int hex;
64 int safe;
65} cfg;
66
67static const struct option prime_options[] = {
68 {
69 .name = "bits",
70 .argname = "n",
71 .desc = "Number of bits in the generated prime number",
72 .type = OPTION_ARG_INT,
73 .opt.value = &cfg.bits,
74 },
75 {
76 .name = "checks",
77 .argname = "n",
78 .desc = "Miller-Rabin probabilistic primality test iterations",
79 .type = OPTION_ARG_INT,
80 .opt.value = &cfg.checks,
81 },
82 {
83 .name = "generate",
84 .desc = "Generate a pseudo-random prime number",
85 .type = OPTION_FLAG,
86 .opt.flag = &cfg.generate,
87 },
88 {
89 .name = "hex",
90 .desc = "Hexadecimal prime numbers",
91 .type = OPTION_FLAG,
92 .opt.flag = &cfg.hex,
93 },
94 {
95 .name = "safe",
96 .desc = "Generate only \"safe\" prime numbers",
97 .type = OPTION_FLAG,
98 .opt.flag = &cfg.safe,
99 },
100 {NULL},
101};
102
103static void
104prime_usage(void)
105{
106 fprintf(stderr,
107 "usage: prime [-bits n] [-checks n] [-generate] [-hex] [-safe] "
108 "p\n");
109 options_usage(prime_options);
110}
111
112int
113prime_main(int argc, char **argv)
114{
115 BIGNUM *bn = NULL;
116 char *prime = NULL;
117 BIO *bio_out;
118 char *s;
119 int is_prime, ret = 1;
120
121 if (pledge("stdio rpath", NULL) == -1) {
122 perror("pledge");
123 exit(1);
124 }
125
126 memset(&cfg, 0, sizeof(cfg));
127
128 /* Default iterations for Miller-Rabin probabilistic primality test. */
129 cfg.checks = 20;
130
131 if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) {
132 prime_usage();
133 return (1);
134 }
135
136 if (prime == NULL && cfg.generate == 0) {
137 BIO_printf(bio_err, "No prime specified.\n");
138 prime_usage();
139 return (1);
140 }
141
142 if ((bio_out = BIO_new(BIO_s_file())) == NULL) {
143 ERR_print_errors(bio_err);
144 return (1);
145 }
146 BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
147
148 if (cfg.generate != 0) {
149 if (cfg.bits == 0) {
150 BIO_printf(bio_err, "Specify the number of bits.\n");
151 goto end;
152 }
153 bn = BN_new();
154 if (!bn) {
155 BIO_printf(bio_err, "Out of memory.\n");
156 goto end;
157 }
158 if (!BN_generate_prime_ex(bn, cfg.bits,
159 cfg.safe, NULL, NULL, NULL)) {
160 BIO_printf(bio_err, "Prime generation error.\n");
161 goto end;
162 }
163 s = cfg.hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
164 if (s == NULL) {
165 BIO_printf(bio_err, "Out of memory.\n");
166 goto end;
167 }
168 BIO_printf(bio_out, "%s\n", s);
169 free(s);
170 } else {
171 if (cfg.hex) {
172 if (!BN_hex2bn(&bn, prime)) {
173 BIO_printf(bio_err, "%s is an invalid hex "
174 "value.\n", prime);
175 goto end;
176 }
177 } else {
178 if (!BN_dec2bn(&bn, prime)) {
179 BIO_printf(bio_err, "%s is an invalid decimal "
180 "value.\n", prime);
181 goto end;
182 }
183 }
184
185 is_prime = BN_is_prime_ex(bn, cfg.checks, NULL, NULL);
186 if (is_prime < 0) {
187 BIO_printf(bio_err, "BN_is_prime_ex failed.\n");
188 goto end;
189 }
190 BIO_printf(bio_out, "%s is %sprime\n", prime,
191 is_prime == 1 ? "" : "not ");
192 }
193
194 ret = 0;
195
196 end:
197 BN_free(bn);
198 BIO_free_all(bio_out);
199
200 return (ret);
201}
diff --git a/src/usr.bin/openssl/rand.c b/src/usr.bin/openssl/rand.c
deleted file mode 100644
index 26003224c0..0000000000
--- a/src/usr.bin/openssl/rand.c
+++ /dev/null
@@ -1,182 +0,0 @@
1/* $OpenBSD: rand.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
2/* ====================================================================
3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <ctype.h>
57#include <stdio.h>
58#include <string.h>
59
60#include "apps.h"
61
62#include <openssl/bio.h>
63#include <openssl/err.h>
64
65static struct {
66 int base64;
67 int hex;
68 char *outfile;
69} cfg;
70
71static const struct option rand_options[] = {
72 {
73 .name = "base64",
74 .desc = "Perform base64 encoding on output",
75 .type = OPTION_FLAG,
76 .opt.flag = &cfg.base64,
77 },
78 {
79 .name = "hex",
80 .desc = "Hexadecimal output",
81 .type = OPTION_FLAG,
82 .opt.flag = &cfg.hex,
83 },
84 {
85 .name = "out",
86 .argname = "file",
87 .desc = "Write to the given file instead of standard output",
88 .type = OPTION_ARG,
89 .opt.arg = &cfg.outfile,
90 },
91 {NULL},
92};
93
94static void
95rand_usage(void)
96{
97 fprintf(stderr,
98 "usage: rand [-base64 | -hex] [-out file] num\n");
99 options_usage(rand_options);
100}
101
102int
103rand_main(int argc, char **argv)
104{
105 char *num_bytes = NULL;
106 int ret = 1;
107 int badopt = 0;
108 int num = -1;
109 int i, r;
110 BIO *out = NULL;
111
112 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
113 perror("pledge");
114 exit(1);
115 }
116
117 memset(&cfg, 0, sizeof(cfg));
118
119 if (options_parse(argc, argv, rand_options, &num_bytes, NULL) != 0) {
120 rand_usage();
121 return (1);
122 }
123
124 if (num_bytes != NULL) {
125 r = sscanf(num_bytes, "%d", &num);
126 if (r == 0 || num < 0)
127 badopt = 1;
128 } else
129 badopt = 1;
130
131 if (cfg.hex && cfg.base64)
132 badopt = 1;
133
134 if (badopt) {
135 rand_usage();
136 goto err;
137 }
138
139 out = BIO_new(BIO_s_file());
140 if (out == NULL)
141 goto err;
142 if (cfg.outfile != NULL)
143 r = BIO_write_filename(out, cfg.outfile);
144 else
145 r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
146 if (r <= 0)
147 goto err;
148 if (cfg.base64) {
149 BIO *b64 = BIO_new(BIO_f_base64());
150 if (b64 == NULL)
151 goto err;
152 out = BIO_push(b64, out);
153 }
154
155 while (num > 0) {
156 unsigned char buf[4096];
157 int chunk;
158
159 chunk = num;
160 if (chunk > (int) sizeof(buf))
161 chunk = sizeof(buf);
162 arc4random_buf(buf, chunk);
163 if (cfg.hex) {
164 for (i = 0; i < chunk; i++)
165 BIO_printf(out, "%02x", buf[i]);
166 } else
167 BIO_write(out, buf, chunk);
168 num -= chunk;
169 }
170
171 if (cfg.hex)
172 BIO_puts(out, "\n");
173 (void) BIO_flush(out);
174
175 ret = 0;
176
177 err:
178 ERR_print_errors(bio_err);
179 BIO_free_all(out);
180
181 return (ret);
182}
diff --git a/src/usr.bin/openssl/req.c b/src/usr.bin/openssl/req.c
deleted file mode 100644
index 1044f145ab..0000000000
--- a/src/usr.bin/openssl/req.c
+++ /dev/null
@@ -1,1879 +0,0 @@
1/* $OpenBSD: req.c,v 1.29 2024/04/17 01:24:43 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/* Until the key-gen callbacks are modified to use newer prototypes, we allow
60 * deprecated functions for openssl-internal code */
61#ifdef OPENSSL_NO_DEPRECATED
62#undef OPENSSL_NO_DEPRECATED
63#endif
64
65#include <ctype.h>
66#include <limits.h>
67#include <stdio.h>
68#include <stdlib.h>
69#include <string.h>
70#include <time.h>
71
72#include "apps.h"
73
74#include <openssl/asn1.h>
75#include <openssl/bio.h>
76#include <openssl/bn.h>
77#include <openssl/conf.h>
78#include <openssl/err.h>
79#include <openssl/evp.h>
80#include <openssl/objects.h>
81#include <openssl/pem.h>
82#include <openssl/x509.h>
83#include <openssl/x509v3.h>
84
85#include <openssl/dsa.h>
86
87#include <openssl/rsa.h>
88
89#define SECTION "req"
90
91#define BITS "default_bits"
92#define KEYFILE "default_keyfile"
93#define PROMPT "prompt"
94#define DISTINGUISHED_NAME "distinguished_name"
95#define ATTRIBUTES "attributes"
96#define V3_EXTENSIONS "x509_extensions"
97#define REQ_EXTENSIONS "req_extensions"
98#define STRING_MASK "string_mask"
99#define UTF8_IN "utf8"
100
101#define DEFAULT_KEY_LENGTH 2048
102#define MIN_KEY_LENGTH 384
103
104static int make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *dn, int multirdn,
105 int attribs, unsigned long chtype);
106static int build_subject(X509_REQ * req, char *subj, unsigned long chtype,
107 int multirdn);
108static int prompt_info(X509_REQ * req,
109 STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect,
110 STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs,
111 unsigned long chtype);
112static int auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * sk,
113 STACK_OF(CONF_VALUE) * attr, int attribs,
114 unsigned long chtype);
115static int add_attribute_object(X509_REQ * req, char *text, const char *def,
116 char *value, int nid, int n_min,
117 int n_max, unsigned long chtype);
118static int add_DN_object(X509_NAME * n, char *text, const char *def, char *value,
119 int nid, int n_min, int n_max, unsigned long chtype, int mval);
120static int genpkey_cb(EVP_PKEY_CTX * ctx);
121static int req_check_len(int len, int n_min, int n_max);
122static int check_end(const char *str, const char *end);
123static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
124 long *pkeylen, char **palgnam);
125static unsigned long ext_name_hash(const OPENSSL_STRING *a);
126static int ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b);
127static void exts_cleanup(OPENSSL_STRING *x);
128static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv);
129static CONF *req_conf = NULL;
130static CONF *addext_conf = NULL;
131
132static struct {
133 LHASH_OF(OPENSSL_STRING) *addexts;
134 BIO *addext_bio;
135 int batch;
136 unsigned long chtype;
137 int days;
138 const EVP_MD *digest;
139 char *extensions;
140 char *infile;
141 int informat;
142 char *keyalg;
143 char *keyfile;
144 int keyform;
145 char *keyout;
146 int modulus;
147 int multirdn;
148 int newhdr;
149 long newkey;
150 int newreq;
151 unsigned long nmflag;
152 int nodes;
153 int noout;
154 char *outfile;
155 int outformat;
156 char *passargin;
157 char *passargout;
158 STACK_OF(OPENSSL_STRING) *pkeyopts;
159 int pubkey;
160 char *req_exts;
161 unsigned long reqflag;
162 ASN1_INTEGER *serial;
163 STACK_OF(OPENSSL_STRING) *sigopts;
164 char *subj;
165 int subject;
166 char *template;
167 int text;
168 int verbose;
169 int verify;
170 int x509;
171} cfg;
172
173static int
174req_opt_addext(char *arg)
175{
176 int i;
177
178 if (cfg.addexts == NULL) {
179 cfg.addexts = (LHASH_OF(OPENSSL_STRING) *)lh_new(
180 (LHASH_HASH_FN_TYPE)ext_name_hash,
181 (LHASH_COMP_FN_TYPE)ext_name_cmp);
182 cfg.addext_bio = BIO_new(BIO_s_mem());
183 if (cfg.addexts == NULL ||
184 cfg.addext_bio == NULL)
185 return (1);
186 }
187 i = duplicated(cfg.addexts, arg);
188 if (i == 1)
189 return (1);
190 if (i < 0 || BIO_printf(cfg.addext_bio, "%s\n", arg) < 0)
191 return (1);
192
193 return (0);
194}
195
196static int
197req_opt_days(char *arg)
198{
199 const char *errstr;
200
201 cfg.days = strtonum(arg, 1, INT_MAX, &errstr);
202 if (errstr != NULL) {
203 BIO_printf(bio_err, "bad -days %s, using 0: %s\n",
204 arg, errstr);
205 cfg.days = 30;
206 }
207 return (0);
208}
209
210static int
211req_opt_digest(int argc, char **argv, int *argsused)
212{
213 char *name = argv[0];
214
215 if (*name++ != '-')
216 return (1);
217
218 if ((cfg.digest = EVP_get_digestbyname(name)) == NULL)
219 return (1);
220
221 *argsused = 1;
222 return (0);
223}
224
225static int
226req_opt_newkey(char *arg)
227{
228 cfg.keyalg = arg;
229 cfg.newreq = 1;
230 return (0);
231}
232
233static int
234req_opt_nameopt(char *arg)
235{
236 if (!set_name_ex(&cfg.nmflag, arg))
237 return (1);
238 return (0);
239}
240
241static int
242req_opt_pkeyopt(char *arg)
243{
244 if (cfg.pkeyopts == NULL)
245 cfg.pkeyopts = sk_OPENSSL_STRING_new_null();
246 if (cfg.pkeyopts == NULL)
247 return (1);
248 if (!sk_OPENSSL_STRING_push(cfg.pkeyopts, arg))
249 return (1);
250 return (0);
251}
252
253static int
254req_opt_reqopt(char *arg)
255{
256 if (!set_cert_ex(&cfg.reqflag, arg))
257 return (1);
258 return (0);
259}
260
261static int
262req_opt_set_serial(char *arg)
263{
264 cfg.serial = s2i_ASN1_INTEGER(NULL, arg);
265 if (cfg.serial == NULL)
266 return (1);
267 return (0);
268}
269
270static int
271req_opt_sigopt(char *arg)
272{
273 if (cfg.sigopts == NULL)
274 cfg.sigopts = sk_OPENSSL_STRING_new_null();
275 if (cfg.sigopts == NULL)
276 return (1);
277 if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
278 return (1);
279 return (0);
280}
281
282static int
283req_opt_utf8(void)
284{
285 cfg.chtype = MBSTRING_UTF8;
286 return (0);
287}
288
289static const struct option req_options[] = {
290 {
291 .name = "addext",
292 .argname = "key=value",
293 .desc = "Additional certificate extension (may be repeated)",
294 .type = OPTION_ARG_FUNC,
295 .opt.argfunc = req_opt_addext,
296 },
297 {
298 .name = "batch",
299 .desc = "Operate in batch mode",
300 .type = OPTION_FLAG,
301 .opt.flag = &cfg.batch,
302 },
303 {
304 .name = "config",
305 .argname = "file",
306 .desc = "Configuration file to use as request template",
307 .type = OPTION_ARG,
308 .opt.arg = &cfg.template,
309 },
310 {
311 .name = "days",
312 .argname = "number",
313 .desc = "Number of days generated certificate is valid for",
314 .type = OPTION_ARG_FUNC,
315 .opt.argfunc = req_opt_days,
316 },
317 {
318 .name = "extensions",
319 .argname = "section",
320 .desc = "Config section to use for certificate extensions",
321 .type = OPTION_ARG,
322 .opt.arg = &cfg.extensions,
323 },
324 {
325 .name = "in",
326 .argname = "file",
327 .desc = "Input file (default stdin)",
328 .type = OPTION_ARG,
329 .opt.arg = &cfg.infile,
330 },
331 {
332 .name = "inform",
333 .argname = "format",
334 .desc = "Input format (DER or PEM (default))",
335 .type = OPTION_ARG_FORMAT,
336 .opt.value = &cfg.informat,
337 },
338 {
339 .name = "key",
340 .argname = "file",
341 .desc = "Private key file",
342 .type = OPTION_ARG,
343 .opt.arg = &cfg.keyfile,
344 },
345 {
346 .name = "keyform",
347 .argname = "format",
348 .desc = "Private key format (DER or PEM (default))",
349 .type = OPTION_ARG_FORMAT,
350 .opt.value = &cfg.keyform,
351 },
352 {
353 .name = "keyout",
354 .argname = "file",
355 .desc = "Private key output file",
356 .type = OPTION_ARG,
357 .opt.arg = &cfg.keyout,
358 },
359 {
360 .name = "modulus",
361 .desc = "Print RSA modulus",
362 .type = OPTION_FLAG,
363 .opt.flag = &cfg.modulus,
364 },
365 {
366 .name = "multivalue-rdn",
367 .desc = "Enable support for multivalued RDNs",
368 .type = OPTION_FLAG,
369 .opt.flag = &cfg.multirdn,
370 },
371 {
372 .name = "nameopt",
373 .argname = "arg",
374 .desc = "Certificate name options",
375 .type = OPTION_ARG_FUNC,
376 .opt.argfunc = req_opt_nameopt,
377 },
378 {
379 .name = "new",
380 .desc = "New request",
381 .type = OPTION_FLAG,
382 .opt.flag = &cfg.newreq,
383 },
384 {
385 .name = "newhdr",
386 .desc = "Include 'NEW' in header lines",
387 .type = OPTION_FLAG,
388 .opt.flag = &cfg.newhdr,
389 },
390 {
391 .name = "newkey",
392 .argname = "param",
393 .desc = "Generate a new key using given parameters",
394 .type = OPTION_ARG_FUNC,
395 .opt.argfunc = req_opt_newkey,
396 },
397 {
398 .name = "nodes",
399 .desc = "Do not encrypt output private key",
400 .type = OPTION_FLAG,
401 .opt.flag = &cfg.nodes,
402 },
403 {
404 .name = "noout",
405 .desc = "Do not output request",
406 .type = OPTION_FLAG,
407 .opt.flag = &cfg.noout,
408 },
409 {
410 .name = "out",
411 .argname = "file",
412 .desc = "Output file (default stdout)",
413 .type = OPTION_ARG,
414 .opt.arg = &cfg.outfile,
415 },
416 {
417 .name = "outform",
418 .argname = "format",
419 .desc = "Output format (DER or PEM (default))",
420 .type = OPTION_ARG_FORMAT,
421 .opt.value = &cfg.outformat,
422 },
423 {
424 .name = "passin",
425 .argname = "source",
426 .desc = "Private key input password source",
427 .type = OPTION_ARG,
428 .opt.arg = &cfg.passargin,
429 },
430 {
431 .name = "passout",
432 .argname = "source",
433 .desc = "Private key output password source",
434 .type = OPTION_ARG,
435 .opt.arg = &cfg.passargout,
436 },
437 {
438 .name = "pkeyopt",
439 .argname = "opt:val",
440 .desc = "Set the public key algorithm option opt to val",
441 .type = OPTION_ARG_FUNC,
442 .opt.argfunc = req_opt_pkeyopt,
443 },
444 {
445 .name = "pubkey",
446 .desc = "Output the public key",
447 .type = OPTION_FLAG,
448 .opt.flag = &cfg.pubkey,
449 },
450 {
451 .name = "reqexts",
452 .argname = "section",
453 .desc = "Config section to use for request extensions",
454 .type = OPTION_ARG,
455 .opt.arg = &cfg.req_exts,
456 },
457 {
458 .name = "reqopt",
459 .argname = "option",
460 .desc = "Request text options",
461 .type = OPTION_ARG_FUNC,
462 .opt.argfunc = req_opt_reqopt,
463 },
464 {
465 .name = "set_serial",
466 .argname = "serial",
467 .desc = "Serial number to use for generated certificate",
468 .type = OPTION_ARG_FUNC,
469 .opt.argfunc = req_opt_set_serial,
470 },
471 {
472 .name = "sigopt",
473 .argname = "name:val",
474 .desc = "Signature options",
475 .type = OPTION_ARG_FUNC,
476 .opt.argfunc = req_opt_sigopt,
477 },
478 {
479 .name = "subj",
480 .argname = "name",
481 .desc = "Set or modify the request subject",
482 .type = OPTION_ARG,
483 .opt.arg = &cfg.subj,
484 },
485 {
486 .name = "subject",
487 .desc = "Output the subject of the request",
488 .type = OPTION_FLAG,
489 .opt.flag = &cfg.subject,
490 },
491 {
492 .name = "text",
493 .desc = "Print request in text form",
494 .type = OPTION_FLAG,
495 .opt.flag = &cfg.text,
496 },
497 {
498 .name = "utf8",
499 .desc = "Input characters are in UTF-8 (default ASCII)",
500 .type = OPTION_FUNC,
501 .opt.func = req_opt_utf8,
502 },
503 {
504 .name = "verbose",
505 .desc = "Verbose",
506 .type = OPTION_FLAG,
507 .opt.flag = &cfg.verbose,
508 },
509 {
510 .name = "verify",
511 .desc = "Verify signature on request",
512 .type = OPTION_FLAG,
513 .opt.flag = &cfg.verify,
514 },
515 {
516 .name = "x509",
517 .desc = "Output an X.509 structure instead of a certificate request",
518 .type = OPTION_FLAG,
519 .opt.flag = &cfg.x509,
520 },
521 {
522 .name = NULL,
523 .desc = "",
524 .type = OPTION_ARGV_FUNC,
525 .opt.argvfunc = req_opt_digest,
526 },
527 { NULL },
528};
529
530static void
531req_usage(void)
532{
533 fprintf(stderr,
534 "usage: req [-addext ext] [-batch] [-config file]\n"
535 " [-days n] [-extensions section] [-in file]\n"
536 " [-inform der | pem] [-key keyfile] [-keyform der | pem]\n"
537 " [-keyout file] [-md4 | -md5 | -sha1] [-modulus]\n"
538 " [-multivalue-rdn] [-nameopt option] [-new] [-newhdr]\n"
539 " [-newkey arg] [-nodes] [-noout]\n"
540 " [-out file] [-outform der | pem] [-passin arg]\n"
541 " [-passout arg] [-pkeyopt opt:value] [-pubkey]\n"
542 " [-reqexts section] [-reqopt option] [-set_serial n]\n"
543 " [-sigopt nm:v] [-subj arg] [-subject] [-text] [-utf8]\n"
544 " [-verbose] [-verify] [-x509]\n\n");
545
546 options_usage(req_options);
547 fprintf(stderr, "\n");
548}
549
550int
551req_main(int argc, char **argv)
552{
553 int ex = 1;
554 X509 *x509ss = NULL;
555 X509_REQ *req = NULL;
556 EVP_PKEY_CTX *genctx = NULL;
557 char *keyalgstr = NULL;
558 const EVP_CIPHER *cipher = NULL;
559 EVP_PKEY *pkey = NULL;
560 int i = 0, pkey_type = -1;
561 BIO *in = NULL, *out = NULL;
562 char *passin = NULL, *passout = NULL;
563 const EVP_MD *md_alg = NULL;
564 char *p;
565
566 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
567 perror("pledge");
568 exit(1);
569 }
570
571 memset(&cfg, 0, sizeof(cfg));
572
573 cfg.chtype = MBSTRING_ASC;
574 cfg.days = 30;
575 cfg.digest = EVP_sha256();
576 cfg.newkey = -1;
577 cfg.informat = FORMAT_PEM;
578 cfg.keyform = FORMAT_PEM;
579 cfg.outformat = FORMAT_PEM;
580
581 if (options_parse(argc, argv, req_options, NULL, NULL) != 0) {
582 req_usage();
583 return (1);
584 }
585
586 req_conf = NULL;
587 cipher = EVP_aes_256_cbc();
588
589 if (!app_passwd(bio_err, cfg.passargin, cfg.passargout, &passin, &passout)) {
590 BIO_printf(bio_err, "Error getting passwords\n");
591 goto end;
592 }
593 if (cfg.template != NULL) {
594 long errline = -1;
595
596 if (cfg.verbose)
597 BIO_printf(bio_err, "Using configuration from %s\n", cfg.template);
598 if ((req_conf = NCONF_new(NULL)) == NULL)
599 goto end;
600 if(!NCONF_load(req_conf, cfg.template, &errline)) {
601 BIO_printf(bio_err, "error on line %ld of %s\n", errline, cfg.template);
602 goto end;
603 }
604 } else {
605 req_conf = config;
606
607 if (req_conf == NULL) {
608 BIO_printf(bio_err, "Unable to load config info from %s\n", default_config_file);
609 if (cfg.newreq)
610 goto end;
611 } else if (cfg.verbose)
612 BIO_printf(bio_err, "Using configuration from %s\n",
613 default_config_file);
614 }
615
616 if (cfg.addext_bio != NULL) {
617 long errline = -1;
618 if (cfg.verbose)
619 BIO_printf(bio_err,
620 "Using additional configuration from command line\n");
621 if ((addext_conf = NCONF_new(NULL)) == NULL)
622 goto end;
623 if (!NCONF_load_bio(addext_conf, cfg.addext_bio, &errline)) {
624 BIO_printf(bio_err,
625 "req: Error on line %ld of config input\n",
626 errline);
627 goto end;
628 }
629 }
630
631 if (req_conf != NULL) {
632 if (!load_config(bio_err, req_conf))
633 goto end;
634 p = NCONF_get_string(req_conf, NULL, "oid_file");
635 if (p == NULL)
636 ERR_clear_error();
637 if (p != NULL) {
638 BIO *oid_bio;
639
640 oid_bio = BIO_new_file(p, "r");
641 if (oid_bio == NULL) {
642 /*
643 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
644 ERR_print_errors(bio_err);
645 */
646 } else {
647 OBJ_create_objects(oid_bio);
648 BIO_free(oid_bio);
649 }
650 }
651 }
652 if (!add_oid_section(bio_err, req_conf))
653 goto end;
654
655 if (md_alg == NULL) {
656 p = NCONF_get_string(req_conf, SECTION, "default_md");
657 if (p == NULL)
658 ERR_clear_error();
659 if (p != NULL) {
660 if ((md_alg = EVP_get_digestbyname(p)) != NULL)
661 cfg.digest = md_alg;
662 }
663 }
664 if (!cfg.extensions) {
665 cfg.extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
666 if (!cfg.extensions)
667 ERR_clear_error();
668 }
669 if (cfg.extensions) {
670 /* Check syntax of file */
671 X509V3_CTX ctx;
672 X509V3_set_ctx_test(&ctx);
673 X509V3_set_nconf(&ctx, req_conf);
674 if (!X509V3_EXT_add_nconf(req_conf, &ctx, cfg.extensions, NULL)) {
675 BIO_printf(bio_err,
676 "Error Loading extension section %s\n", cfg.extensions);
677 goto end;
678 }
679 }
680 if (addext_conf != NULL) {
681 /* Check syntax of command line extensions */
682 X509V3_CTX ctx;
683 X509V3_set_ctx_test(&ctx);
684 X509V3_set_nconf(&ctx, addext_conf);
685 if (!X509V3_EXT_add_nconf(addext_conf, &ctx, "default", NULL)) {
686 BIO_printf(bio_err,
687 "Error Loading command line extensions\n");
688 goto end;
689 }
690 }
691 if (!passin) {
692 passin = NCONF_get_string(req_conf, SECTION, "input_password");
693 if (!passin)
694 ERR_clear_error();
695 }
696 if (!passout) {
697 passout = NCONF_get_string(req_conf, SECTION, "output_password");
698 if (!passout)
699 ERR_clear_error();
700 }
701 p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
702 if (!p)
703 ERR_clear_error();
704
705 if (p && !ASN1_STRING_set_default_mask_asc(p)) {
706 BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
707 goto end;
708 }
709 if (cfg.chtype != MBSTRING_UTF8) {
710 p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
711 if (!p)
712 ERR_clear_error();
713 else if (!strcmp(p, "yes"))
714 cfg.chtype = MBSTRING_UTF8;
715 }
716 if (!cfg.req_exts) {
717 cfg.req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
718 if (!cfg.req_exts)
719 ERR_clear_error();
720 }
721 if (cfg.req_exts) {
722 /* Check syntax of file */
723 X509V3_CTX ctx;
724 X509V3_set_ctx_test(&ctx);
725 X509V3_set_nconf(&ctx, req_conf);
726 if (!X509V3_EXT_add_nconf(req_conf, &ctx, cfg.req_exts, NULL)) {
727 BIO_printf(bio_err,
728 "Error Loading request extension section %s\n",
729 cfg.req_exts);
730 goto end;
731 }
732 }
733 in = BIO_new(BIO_s_file());
734 out = BIO_new(BIO_s_file());
735 if ((in == NULL) || (out == NULL))
736 goto end;
737
738 if (cfg.keyfile != NULL) {
739 pkey = load_key(bio_err, cfg.keyfile, cfg.keyform, 0, passin,
740 "Private Key");
741 if (!pkey) {
742 /*
743 * load_key() has already printed an appropriate
744 * message
745 */
746 goto end;
747 }
748 }
749 if (cfg.newreq && (pkey == NULL)) {
750 if (!NCONF_get_number(req_conf, SECTION, BITS, &cfg.newkey)) {
751 cfg.newkey = DEFAULT_KEY_LENGTH;
752 }
753 if (cfg.keyalg) {
754 genctx = set_keygen_ctx(bio_err, cfg.keyalg, &pkey_type, &cfg.newkey,
755 &keyalgstr);
756 if (!genctx)
757 goto end;
758 }
759 if (cfg.newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
760 BIO_printf(bio_err, "private key length is too short,\n");
761 BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", MIN_KEY_LENGTH, cfg.newkey);
762 goto end;
763 }
764 if (!genctx) {
765 genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &cfg.newkey,
766 &keyalgstr);
767 if (!genctx)
768 goto end;
769 }
770 if (cfg.pkeyopts) {
771 char *genopt;
772 for (i = 0; i < sk_OPENSSL_STRING_num(cfg.pkeyopts); i++) {
773 genopt = sk_OPENSSL_STRING_value(cfg.pkeyopts, i);
774 if (pkey_ctrl_string(genctx, genopt) <= 0) {
775 BIO_printf(bio_err,
776 "parameter error \"%s\"\n",
777 genopt);
778 ERR_print_errors(bio_err);
779 goto end;
780 }
781 }
782 }
783 BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
784 cfg.newkey, keyalgstr);
785
786 EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
787 EVP_PKEY_CTX_set_app_data(genctx, bio_err);
788
789 if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
790 BIO_puts(bio_err, "Error Generating Key\n");
791 goto end;
792 }
793 EVP_PKEY_CTX_free(genctx);
794 genctx = NULL;
795
796 if (cfg.keyout == NULL) {
797 cfg.keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
798 if (cfg.keyout == NULL)
799 ERR_clear_error();
800 }
801 if (cfg.keyout == NULL) {
802 BIO_printf(bio_err, "writing new private key to stdout\n");
803 BIO_set_fp(out, stdout, BIO_NOCLOSE);
804 } else {
805 BIO_printf(bio_err, "writing new private key to '%s'\n", cfg.keyout);
806 if (BIO_write_filename(out, cfg.keyout) <= 0) {
807 perror(cfg.keyout);
808 goto end;
809 }
810 }
811
812 p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
813 if (p == NULL) {
814 ERR_clear_error();
815 p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
816 if (p == NULL)
817 ERR_clear_error();
818 }
819 if ((p != NULL) && (strcmp(p, "no") == 0))
820 cipher = NULL;
821 if (cfg.nodes)
822 cipher = NULL;
823
824 i = 0;
825 loop:
826 if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
827 NULL, 0, NULL, passout)) {
828 if ((ERR_GET_REASON(ERR_peek_error()) ==
829 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
830 ERR_clear_error();
831 i++;
832 goto loop;
833 }
834 goto end;
835 }
836 BIO_printf(bio_err, "-----\n");
837 }
838 if (!cfg.newreq) {
839 if (cfg.infile == NULL)
840 BIO_set_fp(in, stdin, BIO_NOCLOSE);
841 else {
842 if (BIO_read_filename(in, cfg.infile) <= 0) {
843 perror(cfg.infile);
844 goto end;
845 }
846 }
847
848 if (cfg.informat == FORMAT_ASN1)
849 req = d2i_X509_REQ_bio(in, NULL);
850 else if (cfg.informat == FORMAT_PEM)
851 req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
852 else {
853 BIO_printf(bio_err, "bad input format specified for X509 request\n");
854 goto end;
855 }
856 if (req == NULL) {
857 BIO_printf(bio_err, "unable to load X509 request\n");
858 goto end;
859 }
860 }
861 if (cfg.newreq || cfg.x509) {
862 if (pkey == NULL) {
863 BIO_printf(bio_err, "you need to specify a private key\n");
864 goto end;
865 }
866 if (req == NULL) {
867 req = X509_REQ_new();
868 if (req == NULL) {
869 goto end;
870 }
871 i = make_REQ(req, pkey, cfg.subj, cfg.multirdn, !cfg.x509, cfg.chtype);
872 cfg.subj = NULL; /* done processing '-subj' option */
873 if (!i) {
874 BIO_printf(bio_err, "problems making Certificate Request\n");
875 goto end;
876 }
877 }
878 if (cfg.x509) {
879 EVP_PKEY *tmppkey;
880
881 X509V3_CTX ext_ctx;
882 if ((x509ss = X509_new()) == NULL)
883 goto end;
884
885 /* Set version to V3 */
886 if ((cfg.extensions != NULL || addext_conf != NULL) &&
887 !X509_set_version(x509ss, 2))
888 goto end;
889 if (cfg.serial) {
890 if (!X509_set_serialNumber(x509ss, cfg.serial))
891 goto end;
892 } else {
893 if (!rand_serial(NULL,
894 X509_get_serialNumber(x509ss)))
895 goto end;
896 }
897
898 if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
899 goto end;
900 if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
901 goto end;
902 if (!X509_time_adj_ex(X509_get_notAfter(x509ss), cfg.days, 0, NULL))
903 goto end;
904 if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req)))
905 goto end;
906 if ((tmppkey = X509_REQ_get0_pubkey(req)) == NULL)
907 goto end;
908 if (!X509_set_pubkey(x509ss, tmppkey))
909 goto end;
910
911 /* Set up V3 context struct */
912
913 X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
914 X509V3_set_nconf(&ext_ctx, req_conf);
915
916 /* Add extensions */
917 if (cfg.extensions && !X509V3_EXT_add_nconf(req_conf,
918 &ext_ctx, cfg.extensions, x509ss)) {
919 BIO_printf(bio_err,
920 "Error Loading extension section %s\n",
921 cfg.extensions);
922 goto end;
923 }
924 if (addext_conf != NULL &&
925 !X509V3_EXT_add_nconf(addext_conf, &ext_ctx,
926 "default", x509ss)) {
927 BIO_printf(bio_err,
928 "Error Loading command line extensions\n");
929 goto end;
930 }
931 i = do_X509_sign(bio_err, x509ss, pkey, cfg.digest, cfg.sigopts);
932 if (!i) {
933 ERR_print_errors(bio_err);
934 goto end;
935 }
936 } else {
937 X509V3_CTX ext_ctx;
938
939 /* Set up V3 context struct */
940
941 X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
942 X509V3_set_nconf(&ext_ctx, req_conf);
943
944 /* Add extensions */
945 if (cfg.req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
946 &ext_ctx, cfg.req_exts, req)) {
947 BIO_printf(bio_err,
948 "Error Loading extension section %s\n",
949 cfg.req_exts);
950 goto end;
951 }
952 if (addext_conf != NULL &&
953 !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx,
954 "default", req)) {
955 BIO_printf(bio_err,
956 "Error Loading command line extensions\n");
957 goto end;
958 }
959 i = do_X509_REQ_sign(bio_err, req, pkey, cfg.digest, cfg.sigopts);
960 if (!i) {
961 ERR_print_errors(bio_err);
962 goto end;
963 }
964 }
965 }
966 if (cfg.subj && cfg.x509) {
967 BIO_printf(bio_err, "Cannot modify certificate subject\n");
968 goto end;
969 }
970 if (cfg.subj && !cfg.x509) {
971 if (cfg.verbose) {
972 BIO_printf(bio_err, "Modifying Request's Subject\n");
973 print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), cfg.nmflag);
974 }
975 if (build_subject(req, cfg.subj, cfg.chtype, cfg.multirdn) == 0) {
976 BIO_printf(bio_err, "ERROR: cannot modify subject\n");
977 ex = 1;
978 goto end;
979 }
980
981 if (cfg.verbose) {
982 print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), cfg.nmflag);
983 }
984 }
985 if (cfg.verify && !cfg.x509) {
986 EVP_PKEY *pubkey = pkey;
987
988 if (pubkey == NULL)
989 pubkey = X509_REQ_get0_pubkey(req);
990 if (pubkey == NULL)
991 goto end;
992 i = X509_REQ_verify(req, pubkey);
993 if (i < 0) {
994 goto end;
995 } else if (i == 0) {
996 BIO_printf(bio_err, "verify failure\n");
997 ERR_print_errors(bio_err);
998 } else /* if (i > 0) */
999 BIO_printf(bio_err, "verify OK\n");
1000 }
1001 if (cfg.noout && !cfg.text && !cfg.modulus && !cfg.subject && !cfg.pubkey) {
1002 ex = 0;
1003 goto end;
1004 }
1005 if (cfg.outfile == NULL) {
1006 BIO_set_fp(out, stdout, BIO_NOCLOSE);
1007 } else {
1008 if ((cfg.keyout != NULL) && (strcmp(cfg.outfile, cfg.keyout) == 0))
1009 i = (int) BIO_append_filename(out, cfg.outfile);
1010 else
1011 i = (int) BIO_write_filename(out, cfg.outfile);
1012 if (!i) {
1013 perror(cfg.outfile);
1014 goto end;
1015 }
1016 }
1017
1018 if (cfg.pubkey) {
1019 EVP_PKEY *tpubkey;
1020
1021 if ((tpubkey = X509_REQ_get0_pubkey(req)) == NULL) {
1022 BIO_printf(bio_err, "Error getting public key\n");
1023 ERR_print_errors(bio_err);
1024 goto end;
1025 }
1026 PEM_write_bio_PUBKEY(out, tpubkey);
1027 }
1028 if (cfg.text) {
1029 if (cfg.x509)
1030 X509_print_ex(out, x509ss, cfg.nmflag, cfg.reqflag);
1031 else
1032 X509_REQ_print_ex(out, req, cfg.nmflag, cfg.reqflag);
1033 }
1034 if (cfg.subject) {
1035 if (cfg.x509)
1036 print_name(out, "subject=", X509_get_subject_name(x509ss), cfg.nmflag);
1037 else
1038 print_name(out, "subject=", X509_REQ_get_subject_name(req), cfg.nmflag);
1039 }
1040 if (cfg.modulus) {
1041 EVP_PKEY *tpubkey;
1042
1043 if (cfg.x509)
1044 tpubkey = X509_get0_pubkey(x509ss);
1045 else
1046 tpubkey = X509_REQ_get0_pubkey(req);
1047 if (tpubkey == NULL) {
1048 fprintf(stdout, "Modulus=unavailable\n");
1049 goto end;
1050 }
1051 fprintf(stdout, "Modulus=");
1052 if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) {
1053 const BIGNUM *n = NULL;
1054
1055 RSA_get0_key(EVP_PKEY_get0_RSA(tpubkey), &n, NULL, NULL);
1056
1057 BN_print(out, n);
1058 } else
1059 fprintf(stdout, "Wrong Algorithm type");
1060 fprintf(stdout, "\n");
1061 }
1062 if (!cfg.noout && !cfg.x509) {
1063 if (cfg.outformat == FORMAT_ASN1)
1064 i = i2d_X509_REQ_bio(out, req);
1065 else if (cfg.outformat == FORMAT_PEM) {
1066 if (cfg.newhdr)
1067 i = PEM_write_bio_X509_REQ_NEW(out, req);
1068 else
1069 i = PEM_write_bio_X509_REQ(out, req);
1070 } else {
1071 BIO_printf(bio_err, "bad output format specified for outfile\n");
1072 goto end;
1073 }
1074 if (!i) {
1075 BIO_printf(bio_err, "unable to write X509 request\n");
1076 goto end;
1077 }
1078 }
1079 if (!cfg.noout && cfg.x509 && (x509ss != NULL)) {
1080 if (cfg.outformat == FORMAT_ASN1)
1081 i = i2d_X509_bio(out, x509ss);
1082 else if (cfg.outformat == FORMAT_PEM)
1083 i = PEM_write_bio_X509(out, x509ss);
1084 else {
1085 BIO_printf(bio_err, "bad output format specified for outfile\n");
1086 goto end;
1087 }
1088 if (!i) {
1089 BIO_printf(bio_err, "unable to write X509 certificate\n");
1090 goto end;
1091 }
1092 }
1093 ex = 0;
1094 end:
1095 if (ex) {
1096 ERR_print_errors(bio_err);
1097 }
1098 if ((req_conf != NULL) && (req_conf != config))
1099 NCONF_free(req_conf);
1100 NCONF_free(addext_conf);
1101 BIO_free(cfg.addext_bio);
1102 BIO_free(in);
1103 BIO_free_all(out);
1104 EVP_PKEY_free(pkey);
1105 if (genctx)
1106 EVP_PKEY_CTX_free(genctx);
1107 if (cfg.pkeyopts)
1108 sk_OPENSSL_STRING_free(cfg.pkeyopts);
1109 if (cfg.sigopts)
1110 sk_OPENSSL_STRING_free(cfg.sigopts);
1111 lh_OPENSSL_STRING_doall(cfg.addexts, (LHASH_DOALL_FN_TYPE)exts_cleanup);
1112 lh_OPENSSL_STRING_free(cfg.addexts);
1113 free(keyalgstr);
1114 X509_REQ_free(req);
1115 X509_free(x509ss);
1116 ASN1_INTEGER_free(cfg.serial);
1117 if (cfg.passargin && passin)
1118 free(passin);
1119 if (cfg.passargout && passout)
1120 free(passout);
1121 OBJ_cleanup();
1122
1123 return (ex);
1124}
1125
1126static int
1127make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *subj, int multirdn,
1128 int attribs, unsigned long chtype)
1129{
1130 int ret = 0, i;
1131 char no_prompt = 0;
1132 STACK_OF(CONF_VALUE) * dn_sk, *attr_sk = NULL;
1133 char *tmp, *dn_sect, *attr_sect;
1134
1135 tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
1136 if (tmp == NULL)
1137 ERR_clear_error();
1138 if ((tmp != NULL) && !strcmp(tmp, "no"))
1139 no_prompt = 1;
1140
1141 dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
1142 if (dn_sect == NULL) {
1143 BIO_printf(bio_err, "unable to find '%s' in config\n",
1144 DISTINGUISHED_NAME);
1145 goto err;
1146 }
1147 dn_sk = NCONF_get_section(req_conf, dn_sect);
1148 if (dn_sk == NULL) {
1149 BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
1150 goto err;
1151 }
1152 attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
1153 if (attr_sect == NULL) {
1154 ERR_clear_error();
1155 attr_sk = NULL;
1156 } else {
1157 attr_sk = NCONF_get_section(req_conf, attr_sect);
1158 if (attr_sk == NULL) {
1159 BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
1160 goto err;
1161 }
1162 }
1163
1164 /* setup version number */
1165 if (!X509_REQ_set_version(req, 0L))
1166 goto err; /* version 1 */
1167
1168 if (no_prompt)
1169 i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
1170 else {
1171 if (subj)
1172 i = build_subject(req, subj, chtype, multirdn);
1173 else
1174 i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
1175 }
1176 if (!i)
1177 goto err;
1178
1179 if (!X509_REQ_set_pubkey(req, pkey))
1180 goto err;
1181
1182 ret = 1;
1183 err:
1184 return (ret);
1185}
1186
1187/*
1188 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1189 * where characters may be escaped by \
1190 */
1191static int
1192build_subject(X509_REQ * req, char *subject, unsigned long chtype, int multirdn)
1193{
1194 X509_NAME *n;
1195
1196 if (!(n = parse_name(subject, chtype, multirdn)))
1197 return 0;
1198
1199 if (!X509_REQ_set_subject_name(req, n)) {
1200 X509_NAME_free(n);
1201 return 0;
1202 }
1203 X509_NAME_free(n);
1204 return 1;
1205}
1206
1207
1208static int
1209prompt_info(X509_REQ * req,
1210 STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect,
1211 STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs,
1212 unsigned long chtype)
1213{
1214 int i;
1215 char *p, *q;
1216 char buf[100];
1217 int nid, mval;
1218 long n_min, n_max;
1219 char *type, *value;
1220 const char *def;
1221 CONF_VALUE *v;
1222 X509_NAME *subj;
1223 subj = X509_REQ_get_subject_name(req);
1224
1225 if (!cfg.batch) {
1226 BIO_printf(bio_err, "You are about to be asked to enter information that will be incorporated\n");
1227 BIO_printf(bio_err, "into your certificate request.\n");
1228 BIO_printf(bio_err, "What you are about to enter is what is called a Distinguished Name or a DN.\n");
1229 BIO_printf(bio_err, "There are quite a few fields but you can leave some blank\n");
1230 BIO_printf(bio_err, "For some fields there will be a default value,\n");
1231 BIO_printf(bio_err, "If you enter '.', the field will be left blank.\n");
1232 BIO_printf(bio_err, "-----\n");
1233 }
1234 if (sk_CONF_VALUE_num(dn_sk)) {
1235 i = -1;
1236 start: for (;;) {
1237 int ret;
1238 i++;
1239 if (sk_CONF_VALUE_num(dn_sk) <= i)
1240 break;
1241
1242 v = sk_CONF_VALUE_value(dn_sk, i);
1243 p = q = NULL;
1244 type = v->name;
1245 if (!check_end(type, "_min") || !check_end(type, "_max") ||
1246 !check_end(type, "_default") ||
1247 !check_end(type, "_value"))
1248 continue;
1249 /*
1250 * Skip past any leading X. X: X, etc to allow for
1251 * multiple instances
1252 */
1253 for (p = v->name; *p; p++)
1254 if ((*p == ':') || (*p == ',') ||
1255 (*p == '.')) {
1256 p++;
1257 if (*p)
1258 type = p;
1259 break;
1260 }
1261 if (*type == '+') {
1262 mval = -1;
1263 type++;
1264 } else
1265 mval = 0;
1266 /* If OBJ not recognised ignore it */
1267 if ((nid = OBJ_txt2nid(type)) == NID_undef)
1268 goto start;
1269 ret = snprintf(buf, sizeof buf, "%s_default", v->name);
1270 if (ret < 0 || ret >= sizeof(buf)) {
1271 BIO_printf(bio_err, "Name '%s' too long for default\n",
1272 v->name);
1273 return 0;
1274 }
1275 if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1276 ERR_clear_error();
1277 def = "";
1278 }
1279 ret = snprintf(buf, sizeof buf, "%s_value", v->name);
1280 if (ret < 0 || ret >= sizeof(buf)) {
1281 BIO_printf(bio_err, "Name '%s' too long for value\n",
1282 v->name);
1283 return 0;
1284 }
1285 if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1286 ERR_clear_error();
1287 value = NULL;
1288 }
1289 ret = snprintf(buf, sizeof buf, "%s_min", v->name);
1290 if (ret < 0 || ret >= sizeof(buf)) {
1291 BIO_printf(bio_err, "Name '%s' too long for min\n",
1292 v->name);
1293 return 0;
1294 }
1295 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
1296 ERR_clear_error();
1297 n_min = -1;
1298 }
1299 ret = snprintf(buf, sizeof buf, "%s_max", v->name);
1300 if (ret < 0 || ret >= sizeof(buf)) {
1301 BIO_printf(bio_err, "Name '%s' too long for max\n",
1302 v->name);
1303 return 0;
1304 }
1305 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
1306 ERR_clear_error();
1307 n_max = -1;
1308 }
1309 if (!add_DN_object(subj, v->value, def, value, nid,
1310 n_min, n_max, chtype, mval))
1311 return 0;
1312 }
1313 if (X509_NAME_entry_count(subj) == 0) {
1314 BIO_printf(bio_err, "error, no objects specified in config file\n");
1315 return 0;
1316 }
1317 if (attribs) {
1318 if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) &&
1319 (!cfg.batch)) {
1320 BIO_printf(bio_err,
1321 "\nPlease enter the following 'extra' attributes\n");
1322 BIO_printf(bio_err,
1323 "to be sent with your certificate request\n");
1324 }
1325 i = -1;
1326start2: for (;;) {
1327 int ret;
1328 i++;
1329 if ((attr_sk == NULL) ||
1330 (sk_CONF_VALUE_num(attr_sk) <= i))
1331 break;
1332
1333 v = sk_CONF_VALUE_value(attr_sk, i);
1334 type = v->name;
1335 if ((nid = OBJ_txt2nid(type)) == NID_undef)
1336 goto start2;
1337 ret = snprintf(buf, sizeof buf, "%s_default", type);
1338 if (ret < 0 || ret >= sizeof(buf)) {
1339 BIO_printf(bio_err, "Name '%s' too long for default\n",
1340 v->name);
1341 return 0;
1342 }
1343 if ((def = NCONF_get_string(req_conf, attr_sect, buf))
1344 == NULL) {
1345 ERR_clear_error();
1346 def = "";
1347 }
1348 ret = snprintf(buf, sizeof buf, "%s_value", type);
1349 if (ret < 0 || ret >= sizeof(buf)) {
1350 BIO_printf(bio_err, "Name '%s' too long for value\n",
1351 v->name);
1352 return 0;
1353 }
1354 if ((value = NCONF_get_string(req_conf, attr_sect, buf))
1355 == NULL) {
1356 ERR_clear_error();
1357 value = NULL;
1358 }
1359 ret = snprintf(buf, sizeof buf, "%s_min", type);
1360 if (ret < 0 || ret >= sizeof(buf)) {
1361 BIO_printf(bio_err, "Name '%s' too long for min\n",
1362 v->name);
1363 return 0;
1364 }
1365 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
1366 ERR_clear_error();
1367 n_min = -1;
1368 }
1369 ret = snprintf(buf, sizeof buf, "%s_max", type);
1370 if (ret < 0 || ret >= sizeof(buf)) {
1371 BIO_printf(bio_err, "Name '%s' too long for max\n",
1372 v->name);
1373 return 0;
1374 }
1375 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
1376 ERR_clear_error();
1377 n_max = -1;
1378 }
1379 if (!add_attribute_object(req,
1380 v->value, def, value, nid, n_min, n_max, chtype))
1381 return 0;
1382 }
1383 }
1384 } else {
1385 BIO_printf(bio_err, "No template, please set one up.\n");
1386 return 0;
1387 }
1388
1389 return 1;
1390
1391}
1392
1393static int
1394auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * dn_sk,
1395 STACK_OF(CONF_VALUE) * attr_sk, int attribs, unsigned long chtype)
1396{
1397 int i;
1398 char *p, *q;
1399 char *type;
1400 CONF_VALUE *v;
1401 X509_NAME *subj;
1402
1403 subj = X509_REQ_get_subject_name(req);
1404
1405 for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1406 int mval;
1407 v = sk_CONF_VALUE_value(dn_sk, i);
1408 p = q = NULL;
1409 type = v->name;
1410 /*
1411 * Skip past any leading X. X: X, etc to allow for multiple
1412 * instances
1413 */
1414 for (p = v->name; *p; p++)
1415 if ((*p == ':') || (*p == ',') || (*p == '.')) {
1416 p++;
1417 if (*p)
1418 type = p;
1419 break;
1420 }
1421 if (*p == '+') {
1422 p++;
1423 mval = -1;
1424 } else
1425 mval = 0;
1426 if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
1427 (unsigned char *) v->value, -1, -1, mval))
1428 return 0;
1429
1430 }
1431
1432 if (!X509_NAME_entry_count(subj)) {
1433 BIO_printf(bio_err, "error, no objects specified in config file\n");
1434 return 0;
1435 }
1436 if (attribs) {
1437 for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1438 v = sk_CONF_VALUE_value(attr_sk, i);
1439 if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1440 (unsigned char *) v->value, -1))
1441 return 0;
1442 }
1443 }
1444 return 1;
1445}
1446
1447
1448static int
1449add_DN_object(X509_NAME * n, char *text, const char *def, char *value,
1450 int nid, int n_min, int n_max, unsigned long chtype, int mval)
1451{
1452 int i, ret = 0;
1453 char buf[1024];
1454 start:
1455 if (!cfg.batch)
1456 BIO_printf(bio_err, "%s [%s]:", text, def);
1457 (void) BIO_flush(bio_err);
1458 if (value != NULL) {
1459 strlcpy(buf, value, sizeof buf);
1460 strlcat(buf, "\n", sizeof buf);
1461 BIO_printf(bio_err, "%s\n", value);
1462 } else {
1463 buf[0] = '\0';
1464 if (!cfg.batch) {
1465 if (!fgets(buf, sizeof buf, stdin))
1466 return 0;
1467 } else {
1468 buf[0] = '\n';
1469 buf[1] = '\0';
1470 }
1471 }
1472
1473 if (buf[0] == '\0')
1474 return (0);
1475 else if (buf[0] == '\n') {
1476 if ((def == NULL) || (def[0] == '\0'))
1477 return (1);
1478 strlcpy(buf, def, sizeof buf);
1479 strlcat(buf, "\n", sizeof buf);
1480 } else if ((buf[0] == '.') && (buf[1] == '\n'))
1481 return (1);
1482
1483 i = strlen(buf);
1484 if (buf[i - 1] != '\n') {
1485 BIO_printf(bio_err, "weird input :-(\n");
1486 return (0);
1487 }
1488 buf[--i] = '\0';
1489 if (!req_check_len(i, n_min, n_max))
1490 goto start;
1491 if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1492 (unsigned char *) buf, -1, -1, mval))
1493 goto err;
1494 ret = 1;
1495 err:
1496 return (ret);
1497}
1498
1499static int
1500add_attribute_object(X509_REQ * req, char *text, const char *def,
1501 char *value, int nid, int n_min,
1502 int n_max, unsigned long chtype)
1503{
1504 int i;
1505 static char buf[1024];
1506
1507 start:
1508 if (!cfg.batch)
1509 BIO_printf(bio_err, "%s [%s]:", text, def);
1510 (void) BIO_flush(bio_err);
1511 if (value != NULL) {
1512 strlcpy(buf, value, sizeof buf);
1513 strlcat(buf, "\n", sizeof buf);
1514 BIO_printf(bio_err, "%s\n", value);
1515 } else {
1516 buf[0] = '\0';
1517 if (!cfg.batch) {
1518 if (!fgets(buf, sizeof buf, stdin))
1519 return 0;
1520 } else {
1521 buf[0] = '\n';
1522 buf[1] = '\0';
1523 }
1524 }
1525
1526 if (buf[0] == '\0')
1527 return (0);
1528 else if (buf[0] == '\n') {
1529 if ((def == NULL) || (def[0] == '\0'))
1530 return (1);
1531 strlcpy(buf, def, sizeof buf);
1532 strlcat(buf, "\n", sizeof buf);
1533 } else if ((buf[0] == '.') && (buf[1] == '\n'))
1534 return (1);
1535
1536 i = strlen(buf);
1537 if (buf[i - 1] != '\n') {
1538 BIO_printf(bio_err, "weird input :-(\n");
1539 return (0);
1540 }
1541 buf[--i] = '\0';
1542 if (!req_check_len(i, n_min, n_max))
1543 goto start;
1544
1545 if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1546 (unsigned char *) buf, -1)) {
1547 BIO_printf(bio_err, "Error adding attribute\n");
1548 ERR_print_errors(bio_err);
1549 goto err;
1550 }
1551 return (1);
1552 err:
1553 return (0);
1554}
1555
1556static int
1557req_check_len(int len, int n_min, int n_max)
1558{
1559 if ((n_min > 0) && (len < n_min)) {
1560 BIO_printf(bio_err, "string is too short, it needs to be at least %d bytes long\n", n_min);
1561 return (0);
1562 }
1563 if ((n_max >= 0) && (len > n_max)) {
1564 BIO_printf(bio_err, "string is too long, it needs to be less than %d bytes long\n", n_max);
1565 return (0);
1566 }
1567 return (1);
1568}
1569
1570/* Check if the end of a string matches 'end' */
1571static int
1572check_end(const char *str, const char *end)
1573{
1574 int elen, slen;
1575 const char *tmp;
1576 elen = strlen(end);
1577 slen = strlen(str);
1578 if (elen > slen)
1579 return 1;
1580 tmp = str + slen - elen;
1581 return strcmp(tmp, end);
1582}
1583
1584static EVP_PKEY_CTX *
1585set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
1586 long *pkeylen, char **palgnam)
1587{
1588 EVP_PKEY_CTX *gctx = NULL;
1589 EVP_PKEY *param = NULL;
1590 long keylen = -1;
1591 BIO *pbio = NULL;
1592 const char *paramfile = NULL;
1593 const char *errstr;
1594
1595 if (gstr == NULL) {
1596 *pkey_type = EVP_PKEY_RSA;
1597 keylen = *pkeylen;
1598 } else if (gstr[0] >= '0' && gstr[0] <= '9') {
1599 *pkey_type = EVP_PKEY_RSA;
1600 keylen = strtonum(gstr, 0, LONG_MAX, &errstr);
1601 if (errstr) {
1602 BIO_printf(err, "bad algorithm %s: %s\n", gstr, errstr);
1603 return NULL;
1604 }
1605 *pkeylen = keylen;
1606 } else if (!strncmp(gstr, "param:", 6))
1607 paramfile = gstr + 6;
1608 else {
1609 const char *p = strchr(gstr, ':');
1610 int len;
1611 const EVP_PKEY_ASN1_METHOD *ameth;
1612
1613 if (p)
1614 len = p - gstr;
1615 else
1616 len = strlen(gstr);
1617
1618 ameth = EVP_PKEY_asn1_find_str(NULL, gstr, len);
1619
1620 if (!ameth) {
1621 BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
1622 return NULL;
1623 }
1624 EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
1625 ameth);
1626 if (*pkey_type == EVP_PKEY_RSA) {
1627 if (p) {
1628 keylen = strtonum(p + 1, 0, LONG_MAX, &errstr);
1629 if (errstr) {
1630 BIO_printf(err, "bad algorithm %s: %s\n",
1631 p + 1, errstr);
1632 return NULL;
1633 }
1634 *pkeylen = keylen;
1635 } else
1636 keylen = *pkeylen;
1637 } else if (p)
1638 paramfile = p + 1;
1639 }
1640
1641 if (paramfile) {
1642 pbio = BIO_new_file(paramfile, "r");
1643 if (!pbio) {
1644 BIO_printf(err, "Can't open parameter file %s\n",
1645 paramfile);
1646 return NULL;
1647 }
1648 param = PEM_read_bio_Parameters(pbio, NULL);
1649
1650 if (!param) {
1651 X509 *x;
1652 (void) BIO_reset(pbio);
1653 x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
1654 if (x) {
1655 param = X509_get_pubkey(x);
1656 X509_free(x);
1657 }
1658 }
1659 BIO_free(pbio);
1660
1661 if (!param) {
1662 BIO_printf(err, "Error reading parameter file %s\n",
1663 paramfile);
1664 return NULL;
1665 }
1666 if (*pkey_type == -1)
1667 *pkey_type = EVP_PKEY_id(param);
1668 else if (*pkey_type != EVP_PKEY_base_id(param)) {
1669 BIO_printf(err, "Key Type does not match parameters\n");
1670 EVP_PKEY_free(param);
1671 return NULL;
1672 }
1673 }
1674 if (palgnam) {
1675 const EVP_PKEY_ASN1_METHOD *ameth;
1676 const char *anam;
1677 ameth = EVP_PKEY_asn1_find(NULL, *pkey_type);
1678 if (!ameth) {
1679 BIO_puts(err, "Internal error: can't find key algorithm\n");
1680 return NULL;
1681 }
1682 EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
1683 *palgnam = strdup(anam);
1684 }
1685 if (param) {
1686 gctx = EVP_PKEY_CTX_new(param, NULL);
1687 *pkeylen = EVP_PKEY_bits(param);
1688 EVP_PKEY_free(param);
1689 } else
1690 gctx = EVP_PKEY_CTX_new_id(*pkey_type, NULL);
1691
1692 if (!gctx) {
1693 BIO_puts(err, "Error allocating keygen context\n");
1694 ERR_print_errors(err);
1695 return NULL;
1696 }
1697 if (EVP_PKEY_keygen_init(gctx) <= 0) {
1698 BIO_puts(err, "Error initializing keygen context\n");
1699 ERR_print_errors(err);
1700 EVP_PKEY_CTX_free(gctx);
1701 return NULL;
1702 }
1703 if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
1704 if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
1705 BIO_puts(err, "Error setting RSA keysize\n");
1706 ERR_print_errors(err);
1707 EVP_PKEY_CTX_free(gctx);
1708 return NULL;
1709 }
1710 }
1711
1712 return gctx;
1713}
1714
1715static int
1716genpkey_cb(EVP_PKEY_CTX * ctx)
1717{
1718 char c = '*';
1719 BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
1720 int p;
1721 p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
1722 if (p == 0)
1723 c = '.';
1724 if (p == 1)
1725 c = '+';
1726 if (p == 2)
1727 c = '*';
1728 if (p == 3)
1729 c = '\n';
1730 BIO_write(b, &c, 1);
1731 (void) BIO_flush(b);
1732 return 1;
1733}
1734
1735static int
1736do_sign_init(BIO * err, EVP_MD_CTX * ctx, EVP_PKEY * pkey,
1737 const EVP_MD * md, STACK_OF(OPENSSL_STRING) * sigopts)
1738{
1739 EVP_PKEY_CTX *pkctx = NULL;
1740 int default_nid;
1741 int i;
1742
1743 if (EVP_PKEY_get_default_digest_nid(pkey, &default_nid) == 2 &&
1744 default_nid == NID_undef) {
1745 /* The digest is required to be EVP_md_null() (EdDSA). */
1746 md = EVP_md_null();
1747 }
1748
1749 if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
1750 return 0;
1751 for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
1752 char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
1753 if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
1754 BIO_printf(err, "parameter error \"%s\"\n", sigopt);
1755 ERR_print_errors(bio_err);
1756 return 0;
1757 }
1758 }
1759 return 1;
1760}
1761
1762int
1763do_X509_sign(BIO * err, X509 * x, EVP_PKEY * pkey, const EVP_MD * md,
1764 STACK_OF(OPENSSL_STRING) * sigopts)
1765{
1766 EVP_MD_CTX *mctx;
1767 int rv;
1768
1769 if ((mctx = EVP_MD_CTX_new()) == NULL)
1770 return 0;
1771
1772 rv = do_sign_init(err, mctx, pkey, md, sigopts);
1773 if (rv > 0)
1774 rv = X509_sign_ctx(x, mctx);
1775
1776 EVP_MD_CTX_free(mctx);
1777
1778 return rv > 0;
1779}
1780
1781
1782int
1783do_X509_REQ_sign(BIO * err, X509_REQ * x, EVP_PKEY * pkey, const EVP_MD * md,
1784 STACK_OF(OPENSSL_STRING) * sigopts)
1785{
1786 EVP_MD_CTX *mctx;
1787 int rv;
1788
1789 if ((mctx = EVP_MD_CTX_new()) == NULL)
1790 return 0;
1791
1792 rv = do_sign_init(err, mctx, pkey, md, sigopts);
1793 if (rv > 0)
1794 rv = X509_REQ_sign_ctx(x, mctx);
1795
1796 EVP_MD_CTX_free(mctx);
1797
1798 return rv > 0;
1799}
1800
1801
1802
1803int
1804do_X509_CRL_sign(BIO * err, X509_CRL * x, EVP_PKEY * pkey, const EVP_MD * md,
1805 STACK_OF(OPENSSL_STRING) * sigopts)
1806{
1807 int rv;
1808 EVP_MD_CTX *mctx;
1809
1810 if ((mctx = EVP_MD_CTX_new()) == NULL)
1811 return 0;
1812
1813 rv = do_sign_init(err, mctx, pkey, md, sigopts);
1814 if (rv > 0)
1815 rv = X509_CRL_sign_ctx(x, mctx);
1816
1817 EVP_MD_CTX_free(mctx);
1818
1819 return rv > 0;
1820}
1821
1822static unsigned long
1823ext_name_hash(const OPENSSL_STRING *a)
1824{
1825 return lh_strhash((const char *)a);
1826}
1827
1828static int
1829ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b)
1830{
1831 return strcmp((const char *)a, (const char *)b);
1832}
1833
1834static void
1835exts_cleanup(OPENSSL_STRING *x)
1836{
1837 free((char *)x);
1838}
1839
1840/*
1841 * Is the |kv| key already duplicated ? This is remarkably tricky to get right.
1842 * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error.
1843 */
1844static int
1845duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
1846{
1847 char *p;
1848 size_t off;
1849
1850 /* Check syntax. */
1851 /* Skip leading whitespace, make a copy. */
1852 while (*kv && isspace(*kv))
1853 if (*++kv == '\0')
1854 return 1;
1855 if ((p = strchr(kv, '=')) == NULL)
1856 return 1;
1857 off = p - kv;
1858 if ((kv = strdup(kv)) == NULL)
1859 return -1;
1860
1861 /* Skip trailing space before the equal sign. */
1862 for (p = kv + off; p > kv; --p)
1863 if (!isspace(p[-1]))
1864 break;
1865 if (p == kv) {
1866 free(kv);
1867 return 1;
1868 }
1869 *p = '\0';
1870
1871 /* See if "key" is there by attempting to add it. */
1872 if ((p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv))
1873 != NULL || lh_OPENSSL_STRING_error(addexts)) {
1874 free(p != NULL ? p : kv);
1875 return -1;
1876 }
1877
1878 return 0;
1879}
diff --git a/src/usr.bin/openssl/rsa.c b/src/usr.bin/openssl/rsa.c
deleted file mode 100644
index a98ae8be90..0000000000
--- a/src/usr.bin/openssl/rsa.c
+++ /dev/null
@@ -1,410 +0,0 @@
1/* $OpenBSD: rsa.c,v 1.20 2025/01/02 12:31:44 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h>
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <time.h>
65
66#include "apps.h"
67
68#include <openssl/bio.h>
69#include <openssl/bn.h>
70#include <openssl/err.h>
71#include <openssl/evp.h>
72#include <openssl/pem.h>
73#include <openssl/rsa.h>
74#include <openssl/x509.h>
75
76static struct {
77 int check;
78 const EVP_CIPHER *enc;
79 char *infile;
80 int informat;
81 int modulus;
82 int noout;
83 char *outfile;
84 int outformat;
85 char *passargin;
86 char *passargout;
87 int pubin;
88 int pubout;
89 int pvk_encr;
90 int text;
91} cfg;
92
93static int
94rsa_opt_cipher(int argc, char **argv, int *argsused)
95{
96 char *name = argv[0];
97
98 if (*name++ != '-')
99 return (1);
100
101 if ((cfg.enc = EVP_get_cipherbyname(name)) == NULL) {
102 fprintf(stderr, "Invalid cipher '%s'\n", name);
103 return (1);
104 }
105
106 *argsused = 1;
107 return (0);
108}
109
110static const struct option rsa_options[] = {
111 {
112 .name = "check",
113 .desc = "Check consistency of RSA private key",
114 .type = OPTION_FLAG,
115 .opt.flag = &cfg.check,
116 },
117 {
118 .name = "in",
119 .argname = "file",
120 .desc = "Input file (default stdin)",
121 .type = OPTION_ARG,
122 .opt.arg = &cfg.infile,
123 },
124 {
125 .name = "inform",
126 .argname = "format",
127 .desc = "Input format (DER, NET or PEM (default))",
128 .type = OPTION_ARG_FORMAT,
129 .opt.value = &cfg.informat,
130 },
131 {
132 .name = "modulus",
133 .desc = "Print the RSA key modulus",
134 .type = OPTION_FLAG,
135 .opt.flag = &cfg.modulus,
136 },
137 {
138 .name = "noout",
139 .desc = "Do not print encoded version of the key",
140 .type = OPTION_FLAG,
141 .opt.flag = &cfg.noout,
142 },
143 {
144 .name = "out",
145 .argname = "file",
146 .desc = "Output file (default stdout)",
147 .type = OPTION_ARG,
148 .opt.arg = &cfg.outfile,
149 },
150 {
151 .name = "outform",
152 .argname = "format",
153 .desc = "Output format (DER, NET or PEM (default PEM))",
154 .type = OPTION_ARG_FORMAT,
155 .opt.value = &cfg.outformat,
156 },
157 {
158 .name = "passin",
159 .argname = "src",
160 .desc = "Input file passphrase source",
161 .type = OPTION_ARG,
162 .opt.arg = &cfg.passargin,
163 },
164 {
165 .name = "passout",
166 .argname = "src",
167 .desc = "Output file passphrase source",
168 .type = OPTION_ARG,
169 .opt.arg = &cfg.passargout,
170 },
171 {
172 .name = "pubin",
173 .desc = "Expect a public key (default private key)",
174 .type = OPTION_VALUE,
175 .value = 1,
176 .opt.value = &cfg.pubin,
177 },
178 {
179 .name = "pubout",
180 .desc = "Output a public key (default private key)",
181 .type = OPTION_VALUE,
182 .value = 1,
183 .opt.value = &cfg.pubout,
184 },
185 {
186 .name = "pvk-none",
187 .type = OPTION_VALUE,
188 .value = 0,
189 .opt.value = &cfg.pvk_encr,
190 },
191 {
192 .name = "pvk-strong",
193 .type = OPTION_VALUE,
194 .value = 2,
195 .opt.value = &cfg.pvk_encr,
196 },
197 {
198 .name = "pvk-weak",
199 .type = OPTION_VALUE,
200 .value = 1,
201 .opt.value = &cfg.pvk_encr,
202 },
203 {
204 .name = "RSAPublicKey_in",
205 .type = OPTION_VALUE,
206 .value = 2,
207 .opt.value = &cfg.pubin,
208 },
209 {
210 .name = "RSAPublicKey_out",
211 .type = OPTION_VALUE,
212 .value = 2,
213 .opt.value = &cfg.pubout,
214 },
215 {
216 .name = "text",
217 .desc = "Print in plain text in addition to encoded",
218 .type = OPTION_FLAG,
219 .opt.flag = &cfg.text,
220 },
221 {
222 .name = NULL,
223 .type = OPTION_ARGV_FUNC,
224 .opt.argvfunc = rsa_opt_cipher,
225 },
226 { NULL }
227};
228
229static void
230rsa_usage(void)
231{
232 int n = 0;
233
234 fprintf(stderr,
235 "usage: rsa [-ciphername] [-check] [-in file] "
236 "[-inform fmt]\n"
237 " [-modulus] [-noout] [-out file] [-outform fmt] "
238 "[-passin src]\n"
239 " [-passout src] [-pubin] [-pubout] [-text]\n\n");
240 options_usage(rsa_options);
241 fprintf(stderr, "\n");
242
243 fprintf(stderr, "Valid ciphername values:\n\n");
244 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
245 fprintf(stderr, "\n");
246}
247
248int
249rsa_main(int argc, char **argv)
250{
251 int ret = 1;
252 RSA *rsa = NULL;
253 int i;
254 BIO *out = NULL;
255 char *passin = NULL, *passout = NULL;
256
257 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
258 perror("pledge");
259 exit(1);
260 }
261
262 memset(&cfg, 0, sizeof(cfg));
263 cfg.pvk_encr = 2;
264 cfg.informat = FORMAT_PEM;
265 cfg.outformat = FORMAT_PEM;
266
267 if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) {
268 rsa_usage();
269 goto end;
270 }
271
272 if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
273 &passin, &passout)) {
274 BIO_printf(bio_err, "Error getting passwords\n");
275 goto end;
276 }
277 if (cfg.check && cfg.pubin) {
278 BIO_printf(bio_err, "Only private keys can be checked\n");
279 goto end;
280 }
281 out = BIO_new(BIO_s_file());
282
283 {
284 EVP_PKEY *pkey;
285
286 if (cfg.pubin) {
287 int tmpformat = -1;
288 if (cfg.pubin == 2) {
289 if (cfg.informat == FORMAT_PEM)
290 tmpformat = FORMAT_PEMRSA;
291 else if (cfg.informat == FORMAT_ASN1)
292 tmpformat = FORMAT_ASN1RSA;
293 } else
294 tmpformat = cfg.informat;
295
296 pkey = load_pubkey(bio_err, cfg.infile,
297 tmpformat, 1, passin, "Public Key");
298 } else
299 pkey = load_key(bio_err, cfg.infile,
300 cfg.informat, 1, passin, "Private Key");
301
302 if (pkey != NULL)
303 rsa = EVP_PKEY_get1_RSA(pkey);
304 EVP_PKEY_free(pkey);
305 }
306
307 if (rsa == NULL) {
308 ERR_print_errors(bio_err);
309 goto end;
310 }
311 if (cfg.outfile == NULL) {
312 BIO_set_fp(out, stdout, BIO_NOCLOSE);
313 } else {
314 if (BIO_write_filename(out, cfg.outfile) <= 0) {
315 perror(cfg.outfile);
316 goto end;
317 }
318 }
319
320 if (cfg.text)
321 if (!RSA_print(out, rsa, 0)) {
322 perror(cfg.outfile);
323 ERR_print_errors(bio_err);
324 goto end;
325 }
326 if (cfg.modulus) {
327 BIO_printf(out, "Modulus=");
328 BN_print(out, RSA_get0_n(rsa));
329 BIO_printf(out, "\n");
330 }
331 if (cfg.check) {
332 int r = RSA_check_key(rsa);
333
334 if (r == 1)
335 BIO_printf(out, "RSA key ok\n");
336 else if (r == 0) {
337 unsigned long err;
338
339 while ((err = ERR_peek_error()) != 0 &&
340 ERR_GET_LIB(err) == ERR_LIB_RSA &&
341 ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
342 ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {
343 BIO_printf(out, "RSA key error: %s\n",
344 ERR_reason_error_string(err));
345 ERR_get_error(); /* remove e from error
346 * stack */
347 }
348 }
349 if (r == -1 || ERR_peek_error() != 0) { /* should happen only if
350 * r == -1 */
351 ERR_print_errors(bio_err);
352 goto end;
353 }
354 }
355 if (cfg.noout) {
356 ret = 0;
357 goto end;
358 }
359 BIO_printf(bio_err, "writing RSA key\n");
360 if (cfg.outformat == FORMAT_ASN1) {
361 if (cfg.pubout || cfg.pubin) {
362 if (cfg.pubout == 2)
363 i = i2d_RSAPublicKey_bio(out, rsa);
364 else
365 i = i2d_RSA_PUBKEY_bio(out, rsa);
366 } else
367 i = i2d_RSAPrivateKey_bio(out, rsa);
368 } else if (cfg.outformat == FORMAT_PEM) {
369 if (cfg.pubout || cfg.pubin) {
370 if (cfg.pubout == 2)
371 i = PEM_write_bio_RSAPublicKey(out, rsa);
372 else
373 i = PEM_write_bio_RSA_PUBKEY(out, rsa);
374 } else
375 i = PEM_write_bio_RSAPrivateKey(out, rsa,
376 cfg.enc, NULL, 0, NULL, passout);
377#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
378 } else if (cfg.outformat == FORMAT_MSBLOB ||
379 cfg.outformat == FORMAT_PVK) {
380 EVP_PKEY *pk;
381 pk = EVP_PKEY_new();
382 EVP_PKEY_set1_RSA(pk, rsa);
383 if (cfg.outformat == FORMAT_PVK)
384 i = i2b_PVK_bio(out, pk, cfg.pvk_encr, 0,
385 passout);
386 else if (cfg.pubin || cfg.pubout)
387 i = i2b_PublicKey_bio(out, pk);
388 else
389 i = i2b_PrivateKey_bio(out, pk);
390 EVP_PKEY_free(pk);
391#endif
392 } else {
393 BIO_printf(bio_err,
394 "bad output format specified for outfile\n");
395 goto end;
396 }
397 if (i <= 0) {
398 BIO_printf(bio_err, "unable to write key\n");
399 ERR_print_errors(bio_err);
400 } else
401 ret = 0;
402
403 end:
404 BIO_free_all(out);
405 RSA_free(rsa);
406 free(passin);
407 free(passout);
408
409 return (ret);
410}
diff --git a/src/usr.bin/openssl/rsautl.c b/src/usr.bin/openssl/rsautl.c
deleted file mode 100644
index 6d8069cd77..0000000000
--- a/src/usr.bin/openssl/rsautl.c
+++ /dev/null
@@ -1,402 +0,0 @@
1/* $OpenBSD: rsautl.c,v 1.24 2023/07/23 11:39:29 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/opensslconf.h>
60
61#include <string.h>
62
63#include "apps.h"
64
65#include <openssl/err.h>
66#include <openssl/pem.h>
67#include <openssl/rsa.h>
68
69#define RSA_SIGN 1
70#define RSA_VERIFY 2
71#define RSA_ENCRYPT 3
72#define RSA_DECRYPT 4
73
74#define KEY_PRIVKEY 1
75#define KEY_PUBKEY 2
76#define KEY_CERT 3
77
78static struct {
79 int asn1parse;
80 int hexdump;
81 char *infile;
82 char *keyfile;
83 int keyform;
84 int key_type;
85 char *outfile;
86 int pad;
87 char *passargin;
88 int rev;
89 int rsa_mode;
90} cfg;
91
92static const struct option rsautl_options[] = {
93 {
94 .name = "asn1parse",
95 .desc = "ASN.1 parse the output data",
96 .type = OPTION_FLAG,
97 .opt.flag = &cfg.asn1parse,
98 },
99 {
100 .name = "certin",
101 .desc = "Input is a certificate containing an RSA public key",
102 .type = OPTION_VALUE,
103 .value = KEY_CERT,
104 .opt.value = &cfg.key_type,
105 },
106 {
107 .name = "decrypt",
108 .desc = "Decrypt the input data using RSA private key",
109 .type = OPTION_VALUE,
110 .value = RSA_DECRYPT,
111 .opt.value = &cfg.rsa_mode,
112 },
113 {
114 .name = "encrypt",
115 .desc = "Encrypt the input data using RSA public key",
116 .type = OPTION_VALUE,
117 .value = RSA_ENCRYPT,
118 .opt.value = &cfg.rsa_mode,
119 },
120 {
121 .name = "hexdump",
122 .desc = "Hex dump the output data",
123 .type = OPTION_FLAG,
124 .opt.flag = &cfg.hexdump,
125 },
126 {
127 .name = "in",
128 .argname = "file",
129 .desc = "Input file (default stdin)",
130 .type = OPTION_ARG,
131 .opt.arg = &cfg.infile,
132 },
133 {
134 .name = "inkey",
135 .argname = "file",
136 .desc = "Input key file",
137 .type = OPTION_ARG,
138 .opt.arg = &cfg.keyfile,
139 },
140 {
141 .name = "keyform",
142 .argname = "fmt",
143 .desc = "Input key format (DER, TXT or PEM (default))",
144 .type = OPTION_ARG_FORMAT,
145 .opt.value = &cfg.keyform,
146 },
147 {
148 .name = "oaep",
149 .desc = "Use PKCS#1 OAEP padding",
150 .type = OPTION_VALUE,
151 .value = RSA_PKCS1_OAEP_PADDING,
152 .opt.value = &cfg.pad,
153 },
154 {
155 .name = "out",
156 .argname = "file",
157 .desc = "Output file (default stdout)",
158 .type = OPTION_ARG,
159 .opt.arg = &cfg.outfile,
160 },
161 {
162 .name = "passin",
163 .argname = "arg",
164 .desc = "Key password source",
165 .type = OPTION_ARG,
166 .opt.arg = &cfg.passargin,
167 },
168 {
169 .name = "pkcs",
170 .desc = "Use PKCS#1 v1.5 padding (default)",
171 .type = OPTION_VALUE,
172 .value = RSA_PKCS1_PADDING,
173 .opt.value = &cfg.pad,
174 },
175 {
176 .name = "pubin",
177 .desc = "Input is an RSA public key",
178 .type = OPTION_VALUE,
179 .value = KEY_PUBKEY,
180 .opt.value = &cfg.key_type,
181 },
182 {
183 .name = "raw",
184 .desc = "Use no padding",
185 .type = OPTION_VALUE,
186 .value = RSA_NO_PADDING,
187 .opt.value = &cfg.pad,
188 },
189 {
190 .name = "rev",
191 .desc = "Reverse the input data",
192 .type = OPTION_FLAG,
193 .opt.flag = &cfg.rev,
194 },
195 {
196 .name = "sign",
197 .desc = "Sign the input data using RSA private key",
198 .type = OPTION_VALUE,
199 .value = RSA_SIGN,
200 .opt.value = &cfg.rsa_mode,
201 },
202 {
203 .name = "verify",
204 .desc = "Verify the input data using RSA public key",
205 .type = OPTION_VALUE,
206 .value = RSA_VERIFY,
207 .opt.value = &cfg.rsa_mode,
208 },
209 {
210 .name = "x931",
211 .desc = "Use ANSI X9.31 padding",
212 .type = OPTION_VALUE,
213 .value = RSA_X931_PADDING,
214 .opt.value = &cfg.pad,
215 },
216
217 {NULL},
218};
219
220static void
221rsautl_usage(void)
222{
223 fprintf(stderr,
224 "usage: rsautl [-asn1parse] [-certin] [-decrypt] [-encrypt] "
225 "[-hexdump]\n"
226 " [-in file] [-inkey file] [-keyform der | pem]\n"
227 " [-oaep | -pkcs | -raw | -x931] [-out file] [-passin arg]\n"
228 " [-pubin] [-rev] [-sign] [-verify]\n\n");
229
230 options_usage(rsautl_options);
231}
232
233int
234rsautl_main(int argc, char **argv)
235{
236 BIO *in = NULL, *out = NULL;
237 X509 *x;
238 EVP_PKEY *pkey = NULL;
239 RSA *rsa = NULL;
240 unsigned char *rsa_in = NULL, *rsa_out = NULL;
241 char *passin = NULL;
242 int rsa_inlen, rsa_outlen = 0;
243 int need_priv = 0;
244 int keysize;
245 int ret = 1;
246
247 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
248 perror("pledge");
249 exit(1);
250 }
251
252 memset(&cfg, 0, sizeof(cfg));
253 cfg.keyform = FORMAT_PEM;
254 cfg.key_type = KEY_PRIVKEY;
255 cfg.pad = RSA_PKCS1_PADDING;
256 cfg.rsa_mode = RSA_VERIFY;
257
258 if (options_parse(argc, argv, rsautl_options, NULL, NULL) != 0) {
259 rsautl_usage();
260 return (1);
261 }
262
263 if (cfg.rsa_mode == RSA_SIGN ||
264 cfg.rsa_mode == RSA_DECRYPT)
265 need_priv = 1;
266
267 if (need_priv && cfg.key_type != KEY_PRIVKEY) {
268 BIO_printf(bio_err, "A private key is needed for this operation\n");
269 goto end;
270 }
271 if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
272 BIO_printf(bio_err, "Error getting password\n");
273 goto end;
274 }
275
276 switch (cfg.key_type) {
277 case KEY_PRIVKEY:
278 pkey = load_key(bio_err, cfg.keyfile,
279 cfg.keyform, 0, passin, "Private Key");
280 break;
281
282 case KEY_PUBKEY:
283 pkey = load_pubkey(bio_err, cfg.keyfile,
284 cfg.keyform, 0, NULL, "Public Key");
285 break;
286
287 case KEY_CERT:
288 x = load_cert(bio_err, cfg.keyfile,
289 cfg.keyform, NULL, "Certificate");
290 if (x) {
291 pkey = X509_get_pubkey(x);
292 X509_free(x);
293 }
294 break;
295 }
296
297 if (!pkey)
298 goto end;
299
300 rsa = EVP_PKEY_get1_RSA(pkey);
301 EVP_PKEY_free(pkey);
302
303 if (!rsa) {
304 BIO_printf(bio_err, "Error getting RSA key\n");
305 ERR_print_errors(bio_err);
306 goto end;
307 }
308 if (cfg.infile) {
309 if (!(in = BIO_new_file(cfg.infile, "rb"))) {
310 BIO_printf(bio_err, "Error Reading Input File\n");
311 ERR_print_errors(bio_err);
312 goto end;
313 }
314 } else
315 in = BIO_new_fp(stdin, BIO_NOCLOSE);
316
317 if (cfg.outfile) {
318 if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
319 BIO_printf(bio_err, "Error Reading Output File\n");
320 ERR_print_errors(bio_err);
321 goto end;
322 }
323 } else {
324 out = BIO_new_fp(stdout, BIO_NOCLOSE);
325 }
326
327 keysize = RSA_size(rsa);
328
329 rsa_in = reallocarray(NULL, keysize, 2);
330 if (rsa_in == NULL) {
331 BIO_printf(bio_err, "Error allocating memory for input data\n");
332 exit(1);
333 }
334 rsa_out = malloc(keysize);
335 if (rsa_out == NULL) {
336 BIO_printf(bio_err, "Error allocating memory for output data\n");
337 exit(1);
338 }
339
340 /* Read the input data */
341 rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
342 if (rsa_inlen <= 0) {
343 BIO_printf(bio_err, "Error reading input Data\n");
344 exit(1);
345 }
346 if (cfg.rev) {
347 int i;
348 unsigned char ctmp;
349 for (i = 0; i < rsa_inlen / 2; i++) {
350 ctmp = rsa_in[i];
351 rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
352 rsa_in[rsa_inlen - 1 - i] = ctmp;
353 }
354 }
355
356 switch (cfg.rsa_mode) {
357 case RSA_VERIFY:
358 rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out,
359 rsa, cfg.pad);
360 break;
361
362 case RSA_SIGN:
363 rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out,
364 rsa, cfg.pad);
365 break;
366
367 case RSA_ENCRYPT:
368 rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out,
369 rsa, cfg.pad);
370 break;
371
372 case RSA_DECRYPT:
373 rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out,
374 rsa, cfg.pad);
375 break;
376 }
377
378 if (rsa_outlen <= 0) {
379 BIO_printf(bio_err, "RSA operation error\n");
380 ERR_print_errors(bio_err);
381 goto end;
382 }
383 ret = 0;
384 if (cfg.asn1parse) {
385 if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
386 ERR_print_errors(bio_err);
387 }
388 } else if (cfg.hexdump)
389 BIO_dump(out, (char *) rsa_out, rsa_outlen);
390 else
391 BIO_write(out, rsa_out, rsa_outlen);
392
393 end:
394 RSA_free(rsa);
395 BIO_free(in);
396 BIO_free_all(out);
397 free(rsa_in);
398 free(rsa_out);
399 free(passin);
400
401 return ret;
402}
diff --git a/src/usr.bin/openssl/s_cb.c b/src/usr.bin/openssl/s_cb.c
deleted file mode 100644
index fcb2cd3076..0000000000
--- a/src/usr.bin/openssl/s_cb.c
+++ /dev/null
@@ -1,930 +0,0 @@
1/* $OpenBSD: s_cb.c,v 1.22 2025/01/02 13:10:03 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <sys/socket.h>
113
114#include <netinet/in.h>
115
116#include <netdb.h>
117#include <stdio.h>
118#include <stdlib.h>
119#include <string.h>
120
121#include "apps.h"
122
123#include <openssl/err.h>
124#include <openssl/ssl.h>
125#include <openssl/x509.h>
126
127#define COOKIE_SECRET_LENGTH 16
128
129int verify_depth = 0;
130int verify_return_error = 0;
131unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
132int cookie_initialized = 0;
133
134int
135verify_callback(int ok, X509_STORE_CTX * ctx)
136{
137 X509 *err_cert;
138 int err, depth;
139
140 err_cert = X509_STORE_CTX_get_current_cert(ctx);
141 err = X509_STORE_CTX_get_error(ctx);
142 depth = X509_STORE_CTX_get_error_depth(ctx);
143
144 BIO_printf(bio_err, "depth=%d ", depth);
145 if (err_cert) {
146 X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
147 0, XN_FLAG_ONELINE);
148 BIO_puts(bio_err, "\n");
149 } else
150 BIO_puts(bio_err, "<no cert>\n");
151 if (!ok) {
152 BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
153 X509_verify_cert_error_string(err));
154 if (verify_depth >= depth) {
155 if (!verify_return_error)
156 ok = 1;
157 } else {
158 ok = 0;
159 }
160 }
161 switch (err) {
162 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
163 BIO_puts(bio_err, "issuer= ");
164 if (err_cert == NULL)
165 BIO_puts(bio_err, "<error getting cert>");
166 else
167 X509_NAME_print_ex(bio_err,
168 X509_get_issuer_name(err_cert), 0, XN_FLAG_ONELINE);
169 BIO_puts(bio_err, "\n");
170 break;
171 case X509_V_ERR_CERT_NOT_YET_VALID:
172 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
173 BIO_printf(bio_err, "notBefore=");
174 if (err_cert == NULL)
175 BIO_printf(bio_err, " <error getting cert>");
176 else
177 ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert));
178 BIO_printf(bio_err, "\n");
179 break;
180 case X509_V_ERR_CERT_HAS_EXPIRED:
181 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
182 BIO_printf(bio_err, "notAfter=");
183 if (err_cert == NULL)
184 BIO_printf(bio_err, " <error getting cert>");
185 else
186 ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert));
187 BIO_printf(bio_err, "\n");
188 break;
189 case X509_V_ERR_NO_EXPLICIT_POLICY:
190 break;
191 }
192
193 BIO_printf(bio_err, "verify return:%d\n", ok);
194 return (ok);
195}
196
197int
198set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
199{
200 if (cert_file == NULL)
201 return 1;
202
203 if (key_file == NULL)
204 key_file = cert_file;
205
206 if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) {
207 BIO_printf(bio_err,
208 "unable to get certificate from '%s'\n", cert_file);
209 ERR_print_errors(bio_err);
210 return 0;
211 }
212 if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
213 BIO_printf(bio_err, "unable to get private key from '%s'\n",
214 key_file);
215 ERR_print_errors(bio_err);
216 return 0;
217 }
218
219 /* Now we know that a key and cert have been set against the context. */
220 if (!SSL_CTX_check_private_key(ctx)) {
221 BIO_printf(bio_err,
222 "Private key does not match the certificate public key\n");
223 return 0;
224 }
225
226 return 1;
227}
228
229int
230set_cert_key_stuff(SSL_CTX * ctx, X509 * cert, EVP_PKEY * key)
231{
232 if (cert == NULL)
233 return 1;
234 if (SSL_CTX_use_certificate(ctx, cert) <= 0) {
235 BIO_printf(bio_err, "error setting certificate\n");
236 ERR_print_errors(bio_err);
237 return 0;
238 }
239 if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) {
240 BIO_printf(bio_err, "error setting private key\n");
241 ERR_print_errors(bio_err);
242 return 0;
243 }
244 /*
245 * Now we know that a key and cert have been set against the SSL
246 * context
247 */
248 if (!SSL_CTX_check_private_key(ctx)) {
249 BIO_printf(bio_err,
250 "Private key does not match the certificate public key\n");
251 return 0;
252 }
253 return 1;
254}
255
256int
257ssl_print_tmp_key(BIO *out, SSL *s)
258{
259 const char *cname;
260 EVP_PKEY *pkey;
261 EC_KEY *ec;
262 const EC_GROUP *group;
263 int nid;
264
265 if (!SSL_get_server_tmp_key(s, &pkey))
266 return 0;
267
268 BIO_puts(out, "Server Temp Key: ");
269 switch (EVP_PKEY_id(pkey)) {
270 case EVP_PKEY_DH:
271 BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(pkey));
272 break;
273
274 case EVP_PKEY_EC:
275 if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
276 goto err;
277 if ((group = EC_KEY_get0_group(ec)) == NULL)
278 goto err;
279
280 nid = EC_GROUP_get_curve_name(group);
281
282 if ((cname = EC_curve_nid2nist(nid)) == NULL)
283 cname = OBJ_nid2sn(nid);
284
285 BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(pkey));
286 break;
287
288 default:
289 BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(pkey)),
290 EVP_PKEY_bits(pkey));
291 }
292
293 err:
294 EVP_PKEY_free(pkey);
295 return 1;
296}
297
298long
299bio_dump_callback(BIO * bio, int cmd, const char *argp,
300 int argi, long argl, long ret)
301{
302 BIO *out;
303
304 out = (BIO *) BIO_get_callback_arg(bio);
305 if (out == NULL)
306 return (ret);
307
308 if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
309 BIO_printf(out,
310 "read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
311 (void *) bio, argp, (unsigned long) argi, ret, ret);
312 BIO_dump(out, argp, (int) ret);
313 return (ret);
314 } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
315 BIO_printf(out,
316 "write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
317 (void *) bio, argp, (unsigned long) argi, ret, ret);
318 BIO_dump(out, argp, (int) ret);
319 }
320 return (ret);
321}
322
323void
324apps_ssl_info_callback(const SSL * s, int where, int ret)
325{
326 const char *str;
327 int w;
328
329 w = where & ~SSL_ST_MASK;
330
331 if (w & SSL_ST_CONNECT)
332 str = "SSL_connect";
333 else if (w & SSL_ST_ACCEPT)
334 str = "SSL_accept";
335 else
336 str = "undefined";
337
338 if (where & SSL_CB_LOOP) {
339 BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s));
340 } else if (where & SSL_CB_ALERT) {
341 str = (where & SSL_CB_READ) ? "read" : "write";
342 BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", str,
343 SSL_alert_type_string_long(ret),
344 SSL_alert_desc_string_long(ret));
345 } else if (where & SSL_CB_EXIT) {
346 if (ret == 0)
347 BIO_printf(bio_err, "%s:failed in %s\n",
348 str, SSL_state_string_long(s));
349 else if (ret < 0) {
350 BIO_printf(bio_err, "%s:error in %s\n",
351 str, SSL_state_string_long(s));
352 }
353 }
354}
355
356
357void
358msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg)
359{
360 BIO *bio = arg;
361 const char *str_write_p, *str_version, *str_content_type = "",
362 *str_details1 = "", *str_details2 = "";
363
364 str_write_p = write_p ? ">>>" : "<<<";
365
366 /* XXX convert to using ssl_get_version */
367 switch (version) {
368 case SSL2_VERSION:
369 str_version = "SSL 2.0";
370 break;
371 case SSL3_VERSION:
372 str_version = "SSL 3.0 ";
373 break;
374 case TLS1_VERSION:
375 str_version = "TLS 1.0 ";
376 break;
377 case TLS1_1_VERSION:
378 str_version = "TLS 1.1 ";
379 break;
380 case TLS1_2_VERSION:
381 str_version = "TLS 1.2 ";
382 break;
383 case TLS1_3_VERSION:
384 str_version = "TLS 1.3 ";
385 break;
386 case DTLS1_VERSION:
387 str_version = "DTLS 1.0 ";
388 break;
389 case DTLS1_2_VERSION:
390 str_version = "DTLS 1.2 ";
391 break;
392 default:
393 str_version = "???";
394 }
395
396 if (version == SSL2_VERSION) {
397 str_details1 = "???";
398
399 if (len > 0) {
400 /* XXX magic numbers */
401 switch (((const unsigned char *) buf)[0]) {
402 case 0:
403 str_details1 = ", ERROR:";
404 str_details2 = " ???";
405 if (len >= 3) {
406 unsigned err = (((const unsigned char *) buf)[1] << 8) + ((const unsigned char *) buf)[2];
407
408 switch (err) {
409 case 0x0001:
410 str_details2 = " NO-CIPHER-ERROR";
411 break;
412 case 0x0002:
413 str_details2 = " NO-CERTIFICATE-ERROR";
414 break;
415 case 0x0004:
416 str_details2 = " BAD-CERTIFICATE-ERROR";
417 break;
418 case 0x0006:
419 str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
420 break;
421 }
422 }
423 break;
424 case 1:
425 str_details1 = ", CLIENT-HELLO";
426 break;
427 case 2:
428 str_details1 = ", CLIENT-MASTER-KEY";
429 break;
430 case 3:
431 str_details1 = ", CLIENT-FINISHED";
432 break;
433 case 4:
434 str_details1 = ", SERVER-HELLO";
435 break;
436 case 5:
437 str_details1 = ", SERVER-VERIFY";
438 break;
439 case 6:
440 str_details1 = ", SERVER-FINISHED";
441 break;
442 case 7:
443 str_details1 = ", REQUEST-CERTIFICATE";
444 break;
445 case 8:
446 str_details1 = ", CLIENT-CERTIFICATE";
447 break;
448 }
449 }
450 }
451 if (version == SSL3_VERSION || version == TLS1_VERSION ||
452 version == TLS1_1_VERSION || version == TLS1_2_VERSION ||
453 version == TLS1_3_VERSION || version == DTLS1_VERSION ||
454 version == DTLS1_2_VERSION) {
455 /* XXX magic numbers are in ssl3.h */
456 switch (content_type) {
457 case 20:
458 str_content_type = "ChangeCipherSpec";
459 break;
460 case 21:
461 str_content_type = "Alert";
462 break;
463 case 22:
464 str_content_type = "Handshake";
465 break;
466 }
467
468 if (content_type == 21) { /* Alert */
469 str_details1 = ", ???";
470
471 if (len == 2) {
472 switch (((const unsigned char *) buf)[0]) {
473 case 1:
474 str_details1 = ", warning";
475 break;
476 case 2:
477 str_details1 = ", fatal";
478 break;
479 }
480
481 str_details2 = " ???";
482 switch (((const unsigned char *) buf)[1]) {
483 case 0:
484 str_details2 = " close_notify";
485 break;
486 case 10:
487 str_details2 = " unexpected_message";
488 break;
489 case 20:
490 str_details2 = " bad_record_mac";
491 break;
492 case 21:
493 str_details2 = " decryption_failed";
494 break;
495 case 22:
496 str_details2 = " record_overflow";
497 break;
498 case 30:
499 str_details2 = " decompression_failure";
500 break;
501 case 40:
502 str_details2 = " handshake_failure";
503 break;
504 case 42:
505 str_details2 = " bad_certificate";
506 break;
507 case 43:
508 str_details2 = " unsupported_certificate";
509 break;
510 case 44:
511 str_details2 = " certificate_revoked";
512 break;
513 case 45:
514 str_details2 = " certificate_expired";
515 break;
516 case 46:
517 str_details2 = " certificate_unknown";
518 break;
519 case 47:
520 str_details2 = " illegal_parameter";
521 break;
522 case 48:
523 str_details2 = " unknown_ca";
524 break;
525 case 49:
526 str_details2 = " access_denied";
527 break;
528 case 50:
529 str_details2 = " decode_error";
530 break;
531 case 51:
532 str_details2 = " decrypt_error";
533 break;
534 case 60:
535 str_details2 = " export_restriction";
536 break;
537 case 70:
538 str_details2 = " protocol_version";
539 break;
540 case 71:
541 str_details2 = " insufficient_security";
542 break;
543 case 80:
544 str_details2 = " internal_error";
545 break;
546 case 90:
547 str_details2 = " user_canceled";
548 break;
549 case 100:
550 str_details2 = " no_renegotiation";
551 break;
552 case 110:
553 str_details2 = " unsupported_extension";
554 break;
555 case 111:
556 str_details2 = " certificate_unobtainable";
557 break;
558 case 112:
559 str_details2 = " unrecognized_name";
560 break;
561 case 113:
562 str_details2 = " bad_certificate_status_response";
563 break;
564 case 114:
565 str_details2 = " bad_certificate_hash_value";
566 break;
567 case 115:
568 str_details2 = " unknown_psk_identity";
569 break;
570 }
571 }
572 }
573 if (content_type == 22) { /* Handshake */
574 str_details1 = "???";
575
576 if (len > 0) {
577 switch (((const unsigned char *) buf)[0]) {
578 case 0:
579 str_details1 = ", HelloRequest";
580 break;
581 case 1:
582 str_details1 = ", ClientHello";
583 break;
584 case 2:
585 str_details1 = ", ServerHello";
586 break;
587 case 3:
588 str_details1 = ", HelloVerifyRequest";
589 break;
590 case 4:
591 str_details1 = ", NewSessionTicket";
592 break;
593 case 5:
594 str_details1 = ", EndOfEarlyData";
595 break;
596 case 8:
597 str_details1 = ", EncryptedExtensions";
598 break;
599 case 11:
600 str_details1 = ", Certificate";
601 break;
602 case 12:
603 str_details1 = ", ServerKeyExchange";
604 break;
605 case 13:
606 str_details1 = ", CertificateRequest";
607 break;
608 case 14:
609 str_details1 = ", ServerHelloDone";
610 break;
611 case 15:
612 str_details1 = ", CertificateVerify";
613 break;
614 case 16:
615 str_details1 = ", ClientKeyExchange";
616 break;
617 case 20:
618 str_details1 = ", Finished";
619 break;
620 case 24:
621 str_details1 = ", KeyUpdate";
622 break;
623 }
624 }
625 }
626 }
627 BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p,
628 str_version, str_content_type, (unsigned long) len,
629 str_details1, str_details2);
630
631 if (len > 0) {
632 size_t num, i;
633
634 BIO_printf(bio, " ");
635 num = len;
636
637 for (i = 0; i < num; i++) {
638 if (i % 16 == 0 && i > 0)
639 BIO_printf(bio, "\n ");
640 BIO_printf(bio, " %02x",
641 ((const unsigned char *) buf)[i]);
642 }
643 if (i < len)
644 BIO_printf(bio, " ...");
645 BIO_printf(bio, "\n");
646 }
647 (void) BIO_flush(bio);
648}
649
650void
651tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len,
652 void *arg)
653{
654 BIO *bio = arg;
655 char *extname;
656
657 switch (type) {
658 case TLSEXT_TYPE_server_name:
659 extname = "server name";
660 break;
661
662 case TLSEXT_TYPE_max_fragment_length:
663 extname = "max fragment length";
664 break;
665
666 case TLSEXT_TYPE_client_certificate_url:
667 extname = "client certificate URL";
668 break;
669
670 case TLSEXT_TYPE_trusted_ca_keys:
671 extname = "trusted CA keys";
672 break;
673
674 case TLSEXT_TYPE_truncated_hmac:
675 extname = "truncated HMAC";
676 break;
677
678 case TLSEXT_TYPE_status_request:
679 extname = "status request";
680 break;
681
682 case TLSEXT_TYPE_user_mapping:
683 extname = "user mapping";
684 break;
685
686 case TLSEXT_TYPE_client_authz:
687 extname = "client authz";
688 break;
689
690 case TLSEXT_TYPE_server_authz:
691 extname = "server authz";
692 break;
693
694 case TLSEXT_TYPE_cert_type:
695 extname = "cert type";
696 break;
697
698 case TLSEXT_TYPE_supported_groups:
699 extname = "supported groups";
700 break;
701
702 case TLSEXT_TYPE_ec_point_formats:
703 extname = "EC point formats";
704 break;
705
706 case TLSEXT_TYPE_srp:
707 extname = "SRP";
708 break;
709
710 case TLSEXT_TYPE_signature_algorithms:
711 extname = "signature algorithms";
712 break;
713
714 case TLSEXT_TYPE_use_srtp:
715 extname = "use SRTP";
716 break;
717
718 case TLSEXT_TYPE_heartbeat:
719 extname = "heartbeat";
720 break;
721
722 case TLSEXT_TYPE_application_layer_protocol_negotiation:
723 extname = "application layer protocol negotiation";
724 break;
725
726 case TLSEXT_TYPE_padding:
727 extname = "TLS padding";
728 break;
729
730 case TLSEXT_TYPE_session_ticket:
731 extname = "session ticket";
732 break;
733
734#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL)
735 case TLSEXT_TYPE_pre_shared_key:
736 extname = "pre shared key";
737 break;
738
739 case TLSEXT_TYPE_early_data:
740 extname = "early data";
741 break;
742
743 case TLSEXT_TYPE_supported_versions:
744 extname = "supported versions";
745 break;
746
747 case TLSEXT_TYPE_cookie:
748 extname = "cookie";
749 break;
750
751 case TLSEXT_TYPE_psk_key_exchange_modes:
752 extname = "PSK key exchange modes";
753 break;
754
755 case TLSEXT_TYPE_certificate_authorities:
756 extname = "certificate authorities";
757 break;
758
759 case TLSEXT_TYPE_oid_filters:
760 extname = "OID filters";
761 break;
762
763 case TLSEXT_TYPE_post_handshake_auth:
764 extname = "post handshake auth";
765 break;
766
767 case TLSEXT_TYPE_signature_algorithms_cert:
768 extname = "signature algorithms cert";
769 break;
770
771 case TLSEXT_TYPE_key_share:
772 extname = "key share";
773 break;
774#endif
775
776 case TLSEXT_TYPE_renegotiate:
777 extname = "renegotiation info";
778 break;
779
780 default:
781 extname = "unknown";
782 break;
783
784 }
785
786 BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
787 client_server ? "server" : "client", extname, type, len);
788 BIO_dump(bio, (char *) data, len);
789 (void) BIO_flush(bio);
790}
791
792int
793generate_cookie_callback(SSL * ssl, unsigned char *cookie,
794 unsigned int *cookie_len)
795{
796 unsigned char *buffer, result[EVP_MAX_MD_SIZE];
797 unsigned int length, resultlength;
798 union {
799 struct sockaddr sa;
800 struct sockaddr_in s4;
801 struct sockaddr_in6 s6;
802 } peer;
803
804 /* Initialize a random secret */
805 if (!cookie_initialized) {
806 arc4random_buf(cookie_secret, COOKIE_SECRET_LENGTH);
807 cookie_initialized = 1;
808 }
809 /* Read peer information */
810 (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
811
812 /* Create buffer with peer's address and port */
813 length = 0;
814 switch (peer.sa.sa_family) {
815 case AF_INET:
816 length += sizeof(struct in_addr);
817 length += sizeof(peer.s4.sin_port);
818 break;
819 case AF_INET6:
820 length += sizeof(struct in6_addr);
821 length += sizeof(peer.s6.sin6_port);
822 break;
823 default:
824 OPENSSL_assert(0);
825 break;
826 }
827 buffer = malloc(length);
828
829 if (buffer == NULL) {
830 BIO_printf(bio_err, "out of memory\n");
831 return 0;
832 }
833 switch (peer.sa.sa_family) {
834 case AF_INET:
835 memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
836 memcpy(buffer + sizeof(peer.s4.sin_port),
837 &peer.s4.sin_addr, sizeof(struct in_addr));
838 break;
839 case AF_INET6:
840 memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
841 memcpy(buffer + sizeof(peer.s6.sin6_port),
842 &peer.s6.sin6_addr, sizeof(struct in6_addr));
843 break;
844 default:
845 OPENSSL_assert(0);
846 break;
847 }
848
849 /* Calculate HMAC of buffer using the secret */
850 HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
851 buffer, length, result, &resultlength);
852 free(buffer);
853
854 memcpy(cookie, result, resultlength);
855 *cookie_len = resultlength;
856
857 return 1;
858}
859
860int
861verify_cookie_callback(SSL * ssl, const unsigned char *cookie,
862 unsigned int cookie_len)
863{
864 unsigned char *buffer, result[EVP_MAX_MD_SIZE];
865 unsigned int length, resultlength;
866 union {
867 struct sockaddr sa;
868 struct sockaddr_in s4;
869 struct sockaddr_in6 s6;
870 } peer;
871
872 /* If secret isn't initialized yet, the cookie can't be valid */
873 if (!cookie_initialized)
874 return 0;
875
876 /* Read peer information */
877 (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
878
879 /* Create buffer with peer's address and port */
880 length = 0;
881 switch (peer.sa.sa_family) {
882 case AF_INET:
883 length += sizeof(struct in_addr);
884 length += sizeof(peer.s4.sin_port);
885 break;
886 case AF_INET6:
887 length += sizeof(struct in6_addr);
888 length += sizeof(peer.s6.sin6_port);
889 break;
890 default:
891 OPENSSL_assert(0);
892 break;
893 }
894 buffer = malloc(length);
895
896 if (buffer == NULL) {
897 BIO_printf(bio_err, "out of memory\n");
898 return 0;
899 }
900 switch (peer.sa.sa_family) {
901 case AF_INET:
902 memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
903 memcpy(buffer + sizeof(peer.s4.sin_port),
904 &peer.s4.sin_addr, sizeof(struct in_addr));
905 break;
906 case AF_INET6:
907 memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
908 memcpy(buffer + sizeof(peer.s6.sin6_port),
909 &peer.s6.sin6_addr, sizeof(struct in6_addr));
910 break;
911 default:
912 OPENSSL_assert(0);
913 break;
914 }
915
916 /* Calculate HMAC of buffer using the secret */
917 if (HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
918 buffer, length, result, &resultlength) == NULL) {
919 free(buffer);
920 return 0;
921 }
922
923 free(buffer);
924
925 if (cookie_len == resultlength &&
926 memcmp(result, cookie, resultlength) == 0)
927 return 1;
928
929 return 0;
930}
diff --git a/src/usr.bin/openssl/s_client.c b/src/usr.bin/openssl/s_client.c
deleted file mode 100644
index 84718c19fd..0000000000
--- a/src/usr.bin/openssl/s_client.c
+++ /dev/null
@@ -1,1823 +0,0 @@
1/* $OpenBSD: s_client.c,v 1.67 2025/01/02 16:07:41 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111/* ====================================================================
112 * Copyright 2005 Nokia. All rights reserved.
113 *
114 * The portions of the attached software ("Contribution") is developed by
115 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116 * license.
117 *
118 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120 * support (see RFC 4279) to OpenSSL.
121 *
122 * No patent licenses or other rights except those expressly stated in
123 * the OpenSSL open source license shall be deemed granted or received
124 * expressly, by implication, estoppel, or otherwise.
125 *
126 * No assurances are provided by Nokia that the Contribution does not
127 * infringe the patent or other intellectual property rights of any third
128 * party or that the license provides you with all the necessary rights
129 * to make use of the Contribution.
130 *
131 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135 * OTHERWISE.
136 */
137
138#include <sys/types.h>
139#include <sys/socket.h>
140
141#include <netinet/in.h>
142
143#include <assert.h>
144#include <ctype.h>
145#include <limits.h>
146#include <netdb.h>
147#include <stdio.h>
148#include <stdlib.h>
149#include <string.h>
150#include <unistd.h>
151#include <poll.h>
152
153#include "apps.h"
154
155#include <openssl/bn.h>
156#include <openssl/err.h>
157#include <openssl/ocsp.h>
158#include <openssl/pem.h>
159#include <openssl/ssl.h>
160#include <openssl/x509.h>
161
162#define SSL_HOST_NAME "localhost"
163
164#define BUFSIZZ 1024*8
165
166static void sc_usage(void);
167static void print_stuff(BIO *berr, SSL *con, int full);
168static int ocsp_resp_cb(SSL *s, void *arg);
169static int ssl_servername_cb(SSL *s, int *ad, void *arg);
170
171enum {
172 PROTO_OFF = 0,
173 PROTO_SMTP,
174 PROTO_LMTP,
175 PROTO_POP3,
176 PROTO_IMAP,
177 PROTO_FTP,
178 PROTO_XMPP,
179};
180
181/* This is a context that we pass to callbacks */
182typedef struct tlsextctx_st {
183 BIO *biodebug;
184 int ack;
185} tlsextctx;
186
187static struct {
188 int af;
189 char *alpn_in;
190 int bugs;
191 char *CAfile;
192 char *CApath;
193 char *cert_file;
194 int cert_format;
195 char *cipher;
196 unsigned int clr;
197 char *connect;
198 int crlf;
199 int debug;
200 int enable_timeouts;
201 const char *errstr;
202 char *groups_in;
203 char *host;
204 int ign_eof;
205 char *key_file;
206 int key_format;
207 char *keymatexportlabel;
208 int keymatexportlen;
209 uint16_t max_version;
210 uint16_t min_version;
211 const SSL_METHOD *meth;
212 int msg;
213 int nbio;
214 int nbio_test;
215 int no_servername;
216 char *npn_in;
217 unsigned int off;
218 char *passarg;
219 int peekaboo;
220 char *port;
221 int prexit;
222 char *proxy;
223 int quiet;
224 int reconnect;
225 char *servername;
226 char *sess_in;
227 char *sess_out;
228 int showcerts;
229 int socket_type;
230 long socket_mtu;
231#ifndef OPENSSL_NO_SRTP
232 char *srtp_profiles;
233#endif
234 int starttls_proto;
235 int state;
236 int status_req;
237 int tlsextdebug;
238 int verify;
239 X509_VERIFY_PARAM *vpm;
240 char *xmpphost;
241} cfg;
242
243static int
244s_client_opt_keymatexportlen(char *arg)
245{
246 cfg.keymatexportlen = strtonum(arg, 1, INT_MAX,
247 &cfg.errstr);
248 if (cfg.errstr != NULL) {
249 BIO_printf(bio_err, "invalid argument %s: %s\n",
250 arg, cfg.errstr);
251 return (1);
252 }
253 return (0);
254}
255
256#ifndef OPENSSL_NO_DTLS
257static int
258s_client_opt_mtu(char *arg)
259{
260 cfg.socket_mtu = strtonum(arg, 0, LONG_MAX,
261 &cfg.errstr);
262 if (cfg.errstr != NULL) {
263 BIO_printf(bio_err, "invalid argument %s: %s\n",
264 arg, cfg.errstr);
265 return (1);
266 }
267 return (0);
268}
269#endif
270
271static int
272s_client_opt_port(char *arg)
273{
274 if (*arg == '\0')
275 return (1);
276
277 cfg.port = arg;
278 return (0);
279}
280
281#ifndef OPENSSL_NO_DTLS
282static int
283s_client_opt_protocol_version_dtls(void)
284{
285 cfg.meth = DTLS_client_method();
286 cfg.socket_type = SOCK_DGRAM;
287 return (0);
288}
289#endif
290
291#ifndef OPENSSL_NO_DTLS1_2
292static int
293s_client_opt_protocol_version_dtls1_2(void)
294{
295 cfg.meth = DTLS_client_method();
296 cfg.min_version = DTLS1_2_VERSION;
297 cfg.max_version = DTLS1_2_VERSION;
298 cfg.socket_type = SOCK_DGRAM;
299 return (0);
300}
301#endif
302
303static int
304s_client_opt_protocol_version_tls1_2(void)
305{
306 cfg.min_version = TLS1_2_VERSION;
307 cfg.max_version = TLS1_2_VERSION;
308 return (0);
309}
310
311static int
312s_client_opt_protocol_version_tls1_3(void)
313{
314 cfg.min_version = TLS1_3_VERSION;
315 cfg.max_version = TLS1_3_VERSION;
316 return (0);
317}
318
319static int
320s_client_opt_quiet(void)
321{
322 cfg.quiet = 1;
323 cfg.ign_eof = 1;
324 return (0);
325}
326
327static int
328s_client_opt_starttls(char *arg)
329{
330 if (strcmp(arg, "smtp") == 0)
331 cfg.starttls_proto = PROTO_SMTP;
332 else if (strcmp(arg, "lmtp") == 0)
333 cfg.starttls_proto = PROTO_LMTP;
334 else if (strcmp(arg, "pop3") == 0)
335 cfg.starttls_proto = PROTO_POP3;
336 else if (strcmp(arg, "imap") == 0)
337 cfg.starttls_proto = PROTO_IMAP;
338 else if (strcmp(arg, "ftp") == 0)
339 cfg.starttls_proto = PROTO_FTP;
340 else if (strcmp(arg, "xmpp") == 0)
341 cfg.starttls_proto = PROTO_XMPP;
342 else
343 return (1);
344 return (0);
345}
346
347static int
348s_client_opt_verify(char *arg)
349{
350 cfg.verify = SSL_VERIFY_PEER;
351
352 verify_depth = strtonum(arg, 0, INT_MAX, &cfg.errstr);
353 if (cfg.errstr != NULL) {
354 BIO_printf(bio_err, "invalid argument %s: %s\n",
355 arg, cfg.errstr);
356 return (1);
357 }
358 BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
359 return (0);
360}
361
362static int
363s_client_opt_verify_param(int argc, char **argv, int *argsused)
364{
365 char **pargs = argv;
366 int pargc = argc;
367 int badarg = 0;
368
369 if (!args_verify(&pargs, &pargc, &badarg, bio_err,
370 &cfg.vpm)) {
371 BIO_printf(bio_err, "unknown option %s\n", *argv);
372 return (1);
373 }
374 if (badarg)
375 return (1);
376
377 *argsused = argc - pargc;
378 return (0);
379}
380
381static const struct option s_client_options[] = {
382 {
383 .name = "4",
384 .desc = "Use IPv4 only",
385 .type = OPTION_VALUE,
386 .opt.value = &cfg.af,
387 .value = AF_INET,
388 },
389 {
390 .name = "6",
391 .desc = "Use IPv6 only",
392 .type = OPTION_VALUE,
393 .opt.value = &cfg.af,
394 .value = AF_INET6,
395 },
396 {
397 .name = "alpn",
398 .argname = "protocols",
399 .desc = "Set the advertised protocols for ALPN"
400 " (comma-separated list)",
401 .type = OPTION_ARG,
402 .opt.arg = &cfg.alpn_in,
403 },
404 {
405 .name = "bugs",
406 .desc = "Enable various workarounds for buggy implementations",
407 .type = OPTION_FLAG,
408 .opt.flag = &cfg.bugs,
409 },
410 {
411 .name = "CAfile",
412 .argname = "file",
413 .desc = "PEM format file of CA certificates",
414 .type = OPTION_ARG,
415 .opt.arg = &cfg.CAfile,
416 },
417 {
418 .name = "CApath",
419 .argname = "directory",
420 .desc = "PEM format directory of CA certificates",
421 .type = OPTION_ARG,
422 .opt.arg = &cfg.CApath,
423 },
424 {
425 .name = "cert",
426 .argname = "file",
427 .desc = "Certificate file to use, PEM format assumed",
428 .type = OPTION_ARG,
429 .opt.arg = &cfg.cert_file,
430 },
431 {
432 .name = "certform",
433 .argname = "fmt",
434 .desc = "Certificate format (PEM or DER) PEM default",
435 .type = OPTION_ARG_FORMAT,
436 .opt.value = &cfg.cert_format,
437 },
438 {
439 .name = "cipher",
440 .argname = "cipherlist",
441 .desc = "Preferred cipher to use (see 'openssl ciphers')",
442 .type = OPTION_ARG,
443 .opt.arg = &cfg.cipher,
444 },
445 {
446 .name = "connect",
447 .argname = "host:port",
448 .desc = "Who to connect to (default is localhost:4433)",
449 .type = OPTION_ARG,
450 .opt.arg = &cfg.connect,
451 },
452 {
453 .name = "crlf",
454 .desc = "Convert LF from terminal into CRLF",
455 .type = OPTION_FLAG,
456 .opt.flag = &cfg.crlf,
457 },
458 {
459 .name = "debug",
460 .desc = "Print extensive debugging information",
461 .type = OPTION_FLAG,
462 .opt.flag = &cfg.debug,
463 },
464#ifndef OPENSSL_NO_DTLS
465 {
466 .name = "dtls",
467 .desc = "Use any version of DTLS",
468 .type = OPTION_FUNC,
469 .opt.func = s_client_opt_protocol_version_dtls,
470 },
471#endif
472#ifndef OPENSSL_NO_DTLS1_2
473 {
474 .name = "dtls1_2",
475 .desc = "Just use DTLSv1.2",
476 .type = OPTION_FUNC,
477 .opt.func = s_client_opt_protocol_version_dtls1_2,
478 },
479#endif
480 {
481 .name = "groups",
482 .argname = "list",
483 .desc = "Specify EC groups (colon-separated list)",
484 .type = OPTION_ARG,
485 .opt.arg = &cfg.groups_in,
486 },
487 {
488 .name = "host",
489 .argname = "host",
490 .desc = "Use -connect instead",
491 .type = OPTION_ARG,
492 .opt.arg = &cfg.host,
493 },
494 {
495 .name = "ign_eof",
496 .desc = "Ignore input EOF (default when -quiet)",
497 .type = OPTION_VALUE,
498 .opt.value = &cfg.ign_eof,
499 .value = 1,
500 },
501 {
502 .name = "key",
503 .argname = "file",
504 .desc = "Private key file to use, if not, -cert file is used",
505 .type = OPTION_ARG,
506 .opt.arg = &cfg.key_file,
507 },
508 {
509 .name = "keyform",
510 .argname = "fmt",
511 .desc = "Key format (PEM or DER) PEM default",
512 .type = OPTION_ARG_FORMAT,
513 .opt.value = &cfg.key_format,
514 },
515 {
516 .name = "keymatexport",
517 .argname = "label",
518 .desc = "Export keying material using label",
519 .type = OPTION_ARG,
520 .opt.arg = &cfg.keymatexportlabel,
521 },
522 {
523 .name = "keymatexportlen",
524 .argname = "len",
525 .desc = "Export len bytes of keying material (default 20)",
526 .type = OPTION_ARG_FUNC,
527 .opt.argfunc = s_client_opt_keymatexportlen,
528 },
529 {
530 .name = "legacy_renegotiation",
531 .type = OPTION_DISCARD,
532 },
533 {
534 .name = "legacy_server_connect",
535 .desc = "Allow initial connection to servers that don't support RI",
536 .type = OPTION_VALUE_OR,
537 .opt.value = &cfg.off,
538 .value = SSL_OP_LEGACY_SERVER_CONNECT,
539 },
540 {
541 .name = "msg",
542 .desc = "Show all protocol messages with hex dump",
543 .type = OPTION_FLAG,
544 .opt.flag = &cfg.msg,
545 },
546#ifndef OPENSSL_NO_DTLS
547 {
548 .name = "mtu",
549 .argname = "mtu",
550 .desc = "Set the link layer MTU on DTLS connections",
551 .type = OPTION_ARG_FUNC,
552 .opt.argfunc = s_client_opt_mtu,
553 },
554#endif
555 {
556 .name = "nbio",
557 .desc = "Turn on non-blocking I/O",
558 .type = OPTION_FLAG,
559 .opt.flag = &cfg.nbio,
560 },
561 {
562 .name = "nbio_test",
563 .desc = "Test non-blocking I/O",
564 .type = OPTION_FLAG,
565 .opt.flag = &cfg.nbio_test,
566 },
567 {
568 .name = "nextprotoneg",
569 .argname = "protocols",
570 .type = OPTION_ARG,
571 .opt.arg = &cfg.npn_in, /* Ignored. */
572 },
573 {
574 .name = "no_comp",
575 .type = OPTION_VALUE_OR,
576 .opt.value = &cfg.off,
577 .value = SSL_OP_NO_COMPRESSION,
578 },
579 {
580 .name = "no_ign_eof",
581 .desc = "Don't ignore input EOF",
582 .type = OPTION_VALUE,
583 .opt.value = &cfg.ign_eof,
584 .value = 0,
585 },
586 {
587 .name = "no_legacy_server_connect",
588 .desc = "Disallow initial connection to servers that don't support RI",
589 .type = OPTION_VALUE_OR,
590 .opt.value = &cfg.clr,
591 .value = SSL_OP_LEGACY_SERVER_CONNECT,
592 },
593 {
594 .name = "no_servername",
595 .desc = "Do not send a Server Name Indication (SNI) extension",
596 .type = OPTION_FLAG,
597 .opt.value = &cfg.no_servername,
598 },
599 {
600 .name = "no_ssl2",
601 .type = OPTION_VALUE_OR,
602 .opt.value = &cfg.off,
603 .value = SSL_OP_NO_SSLv2,
604 },
605 {
606 .name = "no_ssl3",
607 .type = OPTION_VALUE_OR,
608 .opt.value = &cfg.off,
609 .value = SSL_OP_NO_SSLv3,
610 },
611 {
612 .name = "no_ticket",
613 .desc = "Disable use of RFC4507 session ticket support",
614 .type = OPTION_VALUE_OR,
615 .opt.value = &cfg.off,
616 .value = SSL_OP_NO_TICKET,
617 },
618 {
619 .name = "no_tls1",
620 .type = OPTION_DISCARD,
621 },
622 {
623 .name = "no_tls1_1",
624 .type = OPTION_DISCARD,
625 },
626 {
627 .name = "no_tls1_2",
628 .desc = "Disable the use of TLSv1.2",
629 .type = OPTION_VALUE_OR,
630 .opt.value = &cfg.off,
631 .value = SSL_OP_NO_TLSv1_2,
632 },
633 {
634 .name = "no_tls1_3",
635 .desc = "Disable the use of TLSv1.3",
636 .type = OPTION_VALUE_OR,
637 .opt.value = &cfg.off,
638 .value = SSL_OP_NO_TLSv1_3,
639 },
640 {
641 .name = "noservername",
642 .type = OPTION_FLAG,
643 .opt.value = &cfg.no_servername,
644 },
645 {
646 .name = "pass",
647 .argname = "arg",
648 .desc = "Private key file pass phrase source",
649 .type = OPTION_ARG,
650 .opt.arg = &cfg.passarg,
651 },
652 {
653 .name = "pause",
654 .type = OPTION_DISCARD,
655 },
656 {
657 .name = "peekaboo",
658 .type = OPTION_FLAG,
659 .opt.flag = &cfg.peekaboo,
660 },
661 {
662 .name = "port",
663 .argname = "port",
664 .desc = "Use -connect instead",
665 .type = OPTION_ARG_FUNC,
666 .opt.argfunc = s_client_opt_port,
667 },
668 {
669 .name = "prexit",
670 .desc = "Print session information when the program exits",
671 .type = OPTION_FLAG,
672 .opt.flag = &cfg.prexit,
673 },
674 {
675 .name = "proxy",
676 .argname = "host:port",
677 .desc = "Connect to http proxy",
678 .type = OPTION_ARG,
679 .opt.arg = &cfg.proxy,
680 },
681 {
682 .name = "quiet",
683 .desc = "Inhibit printing of session and certificate info",
684 .type = OPTION_FUNC,
685 .opt.func = s_client_opt_quiet,
686 },
687 {
688 .name = "reconnect",
689 .desc = "Drop and re-make the connection with the same Session-ID",
690 .type = OPTION_VALUE,
691 .opt.value = &cfg.reconnect,
692 .value = 5,
693 },
694 {
695 .name = "servername",
696 .argname = "name",
697 .desc = "Set TLS extension servername in ClientHello (SNI)",
698 .type = OPTION_ARG,
699 .opt.arg = &cfg.servername,
700 },
701 {
702 .name = "serverpref",
703 .desc = "Use server's cipher preferences",
704 .type = OPTION_VALUE_OR,
705 .opt.value = &cfg.off,
706 .value = SSL_OP_CIPHER_SERVER_PREFERENCE,
707 },
708 {
709 .name = "sess_in",
710 .argname = "file",
711 .desc = "File to read TLS session from",
712 .type = OPTION_ARG,
713 .opt.arg = &cfg.sess_in,
714 },
715 {
716 .name = "sess_out",
717 .argname = "file",
718 .desc = "File to write TLS session to",
719 .type = OPTION_ARG,
720 .opt.arg = &cfg.sess_out,
721 },
722 {
723 .name = "showcerts",
724 .desc = "Show all server certificates in the chain",
725 .type = OPTION_FLAG,
726 .opt.flag = &cfg.showcerts,
727 },
728 {
729 .name = "starttls",
730 .argname = "protocol",
731 .desc = "Use the STARTTLS command before starting TLS,\n"
732 "smtp, lmtp, pop3, imap, ftp and xmpp are supported.",
733 .type = OPTION_ARG_FUNC,
734 .opt.argfunc = s_client_opt_starttls,
735 },
736 {
737 .name = "state",
738 .desc = "Print the TLS session states",
739 .type = OPTION_FLAG,
740 .opt.flag = &cfg.state,
741 },
742 {
743 .name = "status",
744 .desc = "Send a certificate status request to the server (OCSP)",
745 .type = OPTION_FLAG,
746 .opt.flag = &cfg.status_req,
747 },
748#ifndef OPENSSL_NO_DTLS
749 {
750 .name = "timeout",
751 .desc = "Enable send/receive timeout on DTLS connections",
752 .type = OPTION_FLAG,
753 .opt.flag = &cfg.enable_timeouts,
754 },
755#endif
756 {
757 .name = "tls1_2",
758 .desc = "Just use TLSv1.2",
759 .type = OPTION_FUNC,
760 .opt.func = s_client_opt_protocol_version_tls1_2,
761 },
762 {
763 .name = "tls1_3",
764 .desc = "Just use TLSv1.3",
765 .type = OPTION_FUNC,
766 .opt.func = s_client_opt_protocol_version_tls1_3,
767 },
768 {
769 .name = "tlsextdebug",
770 .desc = "Hex dump of all TLS extensions received",
771 .type = OPTION_FLAG,
772 .opt.flag = &cfg.tlsextdebug,
773 },
774#ifndef OPENSSL_NO_SRTP
775 {
776 .name = "use_srtp",
777 .argname = "profiles",
778 .desc = "Offer SRTP key management with a colon-separated profiles",
779 .type = OPTION_ARG,
780 .opt.arg = &cfg.srtp_profiles,
781 },
782#endif
783 {
784 .name = "verify",
785 .argname = "depth",
786 .desc = "Turn on peer certificate verification, with a max of depth",
787 .type = OPTION_ARG_FUNC,
788 .opt.argfunc = s_client_opt_verify,
789 },
790 {
791 .name = "verify_return_error",
792 .desc = "Return verification error",
793 .type = OPTION_FLAG,
794 .opt.flag = &verify_return_error,
795 },
796 {
797 .name = "xmpphost",
798 .argname = "host",
799 .desc = "Connect to this virtual host on the xmpp server",
800 .type = OPTION_ARG,
801 .opt.arg = &cfg.xmpphost,
802 },
803 {
804 .name = NULL,
805 .desc = "",
806 .type = OPTION_ARGV_FUNC,
807 .opt.argvfunc = s_client_opt_verify_param,
808 },
809 { NULL },
810};
811
812static void
813sc_usage(void)
814{
815 fprintf(stderr, "usage: s_client "
816 "[-4 | -6] [-alpn protocols] [-bugs] [-CAfile file]\n"
817 " [-CApath directory] [-cert file] [-certform der | pem] [-check_ss_sig]\n"
818 " [-cipher cipherlist] [-connect host[:port]] [-crl_check]\n"
819 " [-crl_check_all] [-crlf] [-debug] [-dtls] [-dtls1_2] [-extended_crl]\n"
820 " [-groups list] [-host host] [-ign_eof] [-ignore_critical]\n"
821 " [-issuer_checks] [-key keyfile] [-keyform der | pem]\n"
822 " [-keymatexport label] [-keymatexportlen len] [-legacy_server_connect]\n"
823 " [-msg] [-mtu mtu] [-nbio] [-nbio_test] [-no_comp] [-no_ign_eof]\n"
824 " [-no_legacy_server_connect] [-no_ticket] \n"
825 " [-no_tls1_2] [-no_tls1_3] [-pass arg] [-policy_check]\n"
826 " [-port port] [-prexit] [-proxy host:port] [-quiet] [-reconnect]\n"
827 " [-servername name] [-serverpref] [-sess_in file] [-sess_out file]\n"
828 " [-showcerts] [-starttls protocol] [-state] [-status] [-timeout]\n"
829 " [-tls1_2] [-tls1_3] [-tlsextdebug]\n"
830 " [-use_srtp profiles] [-verify depth] [-verify_return_error]\n"
831 " [-x509_strict] [-xmpphost host]\n");
832 fprintf(stderr, "\n");
833 options_usage(s_client_options);
834 fprintf(stderr, "\n");
835}
836
837int
838s_client_main(int argc, char **argv)
839{
840 SSL *con = NULL;
841 int s, k, p = 0, pending = 0;
842 char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL, *pbuf = NULL;
843 int cbuf_len, cbuf_off;
844 int sbuf_len, sbuf_off;
845 int full_log = 1;
846 const char *servername;
847 char *pass = NULL;
848 X509 *cert = NULL;
849 EVP_PKEY *key = NULL;
850 int badop = 0;
851 int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
852 SSL_CTX *ctx = NULL;
853 int ret = 1, in_init = 1, i;
854 BIO *bio_c_out = NULL;
855 BIO *sbio;
856 int mbuf_len = 0;
857 struct timeval timeout;
858 tlsextctx tlsextcbp = {NULL, 0};
859 struct sockaddr_storage peer;
860 int peerlen = sizeof(peer);
861
862 if (pledge("stdio cpath wpath rpath inet dns tty", NULL) == -1) {
863 perror("pledge");
864 exit(1);
865 }
866
867 memset(&cfg, 0, sizeof(cfg));
868 cfg.af = AF_UNSPEC;
869 cfg.cert_format = FORMAT_PEM;
870 cfg.host = SSL_HOST_NAME;
871 cfg.key_format = FORMAT_PEM;
872 cfg.keymatexportlen = 20;
873 cfg.meth = TLS_client_method();
874 cfg.port = PORT_STR;
875 cfg.socket_type = SOCK_STREAM;
876 cfg.starttls_proto = PROTO_OFF;
877 cfg.verify = SSL_VERIFY_NONE;
878
879 if (((cbuf = malloc(BUFSIZZ)) == NULL) ||
880 ((sbuf = malloc(BUFSIZZ)) == NULL) ||
881 ((pbuf = malloc(BUFSIZZ)) == NULL) ||
882 ((mbuf = malloc(BUFSIZZ + 1)) == NULL)) { /* NUL byte */
883 BIO_printf(bio_err, "out of memory\n");
884 goto end;
885 }
886 verify_depth = 0;
887
888 if (options_parse(argc, argv, s_client_options, NULL, NULL) != 0) {
889 badop = 1;
890 goto bad;
891 }
892 if (cfg.proxy != NULL) {
893 if (!extract_host_port(cfg.proxy,
894 &cfg.host, NULL, &cfg.port))
895 goto bad;
896 if (cfg.connect == NULL)
897 cfg.connect = SSL_HOST_NAME;
898 } else if (cfg.connect != NULL) {
899 if (!extract_host_port(cfg.connect,
900 &cfg.host, NULL, &cfg.port))
901 goto bad;
902 }
903 if (badop) {
904 bad:
905 if (cfg.errstr == NULL)
906 sc_usage();
907 goto end;
908 }
909
910 if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) {
911 BIO_printf(bio_err, "Error getting password\n");
912 goto end;
913 }
914 if (cfg.key_file == NULL)
915 cfg.key_file = cfg.cert_file;
916
917
918 if (cfg.key_file) {
919
920 key = load_key(bio_err, cfg.key_file,
921 cfg.key_format, 0, pass,
922 "client certificate private key file");
923 if (!key) {
924 ERR_print_errors(bio_err);
925 goto end;
926 }
927 }
928 if (cfg.cert_file) {
929 cert = load_cert(bio_err, cfg.cert_file,
930 cfg.cert_format,
931 NULL, "client certificate file");
932
933 if (!cert) {
934 ERR_print_errors(bio_err);
935 goto end;
936 }
937 }
938 if (cfg.quiet && !cfg.debug &&
939 !cfg.msg) {
940 if ((bio_c_out = BIO_new(BIO_s_null())) == NULL)
941 goto end;
942 } else {
943 if ((bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
944 goto end;
945 }
946
947 ctx = SSL_CTX_new(cfg.meth);
948 if (ctx == NULL) {
949 ERR_print_errors(bio_err);
950 goto end;
951 }
952
953 SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
954
955 if (cfg.vpm)
956 SSL_CTX_set1_param(ctx, cfg.vpm);
957
958 if (!SSL_CTX_set_min_proto_version(ctx, cfg.min_version))
959 goto end;
960 if (!SSL_CTX_set_max_proto_version(ctx, cfg.max_version))
961 goto end;
962
963#ifndef OPENSSL_NO_SRTP
964 if (cfg.srtp_profiles != NULL)
965 SSL_CTX_set_tlsext_use_srtp(ctx, cfg.srtp_profiles);
966#endif
967 if (cfg.bugs)
968 SSL_CTX_set_options(ctx, SSL_OP_ALL | cfg.off);
969 else
970 SSL_CTX_set_options(ctx, cfg.off);
971
972 if (cfg.clr)
973 SSL_CTX_clear_options(ctx, cfg.clr);
974
975 if (cfg.alpn_in) {
976 unsigned short alpn_len;
977 unsigned char *alpn;
978
979 alpn = next_protos_parse(&alpn_len, cfg.alpn_in);
980 if (alpn == NULL) {
981 BIO_printf(bio_err, "Error parsing -alpn argument\n");
982 goto end;
983 }
984 SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
985 free(alpn);
986 }
987 if (cfg.groups_in != NULL) {
988 if (SSL_CTX_set1_groups_list(ctx, cfg.groups_in) != 1) {
989 BIO_printf(bio_err, "Failed to set groups '%s'\n",
990 cfg.groups_in);
991 goto end;
992 }
993 }
994
995 if (cfg.state)
996 SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
997 if (cfg.cipher != NULL)
998 if (!SSL_CTX_set_cipher_list(ctx, cfg.cipher)) {
999 BIO_printf(bio_err, "error setting cipher list\n");
1000 ERR_print_errors(bio_err);
1001 goto end;
1002 }
1003
1004 SSL_CTX_set_verify(ctx, cfg.verify, verify_callback);
1005 if (!set_cert_key_stuff(ctx, cert, key))
1006 goto end;
1007
1008 if ((cfg.CAfile || cfg.CApath)
1009 && !SSL_CTX_load_verify_locations(ctx, cfg.CAfile,
1010 cfg.CApath))
1011 ERR_print_errors(bio_err);
1012
1013 if (!SSL_CTX_set_default_verify_paths(ctx))
1014 ERR_print_errors(bio_err);
1015
1016 con = SSL_new(ctx);
1017 if (cfg.sess_in) {
1018 SSL_SESSION *sess;
1019 BIO *stmp = BIO_new_file(cfg.sess_in, "r");
1020 if (!stmp) {
1021 BIO_printf(bio_err, "Can't open session file %s\n",
1022 cfg.sess_in);
1023 ERR_print_errors(bio_err);
1024 goto end;
1025 }
1026 sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
1027 BIO_free(stmp);
1028 if (!sess) {
1029 BIO_printf(bio_err, "Can't open session file %s\n",
1030 cfg.sess_in);
1031 ERR_print_errors(bio_err);
1032 goto end;
1033 }
1034 SSL_set_session(con, sess);
1035 SSL_SESSION_free(sess);
1036 }
1037
1038 /* Attempt to opportunistically use the host name for SNI. */
1039 servername = cfg.servername;
1040 if (servername == NULL)
1041 servername = cfg.host;
1042
1043 if (!cfg.no_servername && servername != NULL &&
1044 !SSL_set_tlsext_host_name(con, servername)) {
1045 long ssl_err = ERR_peek_error();
1046
1047 if (cfg.servername != NULL ||
1048 ERR_GET_LIB(ssl_err) != ERR_LIB_SSL ||
1049 ERR_GET_REASON(ssl_err) != SSL_R_SSL3_EXT_INVALID_SERVERNAME) {
1050 BIO_printf(bio_err,
1051 "Unable to set TLS servername extension.\n");
1052 ERR_print_errors(bio_err);
1053 goto end;
1054 }
1055 servername = NULL;
1056 ERR_clear_error();
1057 }
1058 if (!cfg.no_servername && servername != NULL) {
1059 tlsextcbp.biodebug = bio_err;
1060 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
1061 SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
1062 }
1063
1064 re_start:
1065
1066 if (init_client(&s, cfg.host, cfg.port,
1067 cfg.socket_type, cfg.af) == 0) {
1068 BIO_printf(bio_err, "connect:errno=%d\n", errno);
1069 goto end;
1070 }
1071 BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
1072
1073 if (cfg.nbio) {
1074 if (!cfg.quiet)
1075 BIO_printf(bio_c_out, "turning on non blocking io\n");
1076 if (!BIO_socket_nbio(s, 1)) {
1077 ERR_print_errors(bio_err);
1078 goto end;
1079 }
1080 }
1081
1082 if (SSL_is_dtls(con)) {
1083 sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1084 if (getsockname(s, (struct sockaddr *)&peer,
1085 (void *)&peerlen) == -1) {
1086 BIO_printf(bio_err, "getsockname:errno=%d\n",
1087 errno);
1088 shutdown(s, SHUT_RD);
1089 close(s);
1090 goto end;
1091 }
1092 (void) BIO_ctrl_set_connected(sbio, 1, &peer);
1093
1094 if (cfg.enable_timeouts) {
1095 timeout.tv_sec = 0;
1096 timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1097 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0,
1098 &timeout);
1099
1100 timeout.tv_sec = 0;
1101 timeout.tv_usec = DGRAM_SND_TIMEOUT;
1102 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0,
1103 &timeout);
1104 }
1105 if (cfg.socket_mtu > 28) {
1106 SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1107 SSL_set_mtu(con, cfg.socket_mtu - 28);
1108 } else
1109 /* want to do MTU discovery */
1110 BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1111 } else
1112 sbio = BIO_new_socket(s, BIO_NOCLOSE);
1113
1114 if (cfg.nbio_test) {
1115 BIO *test;
1116
1117 test = BIO_new(BIO_f_nbio_test());
1118 sbio = BIO_push(test, sbio);
1119 }
1120 if (cfg.debug) {
1121 BIO_set_callback(sbio, bio_dump_callback);
1122 BIO_set_callback_arg(sbio, (char *) bio_c_out);
1123 }
1124 if (cfg.msg) {
1125 SSL_set_msg_callback(con, msg_cb);
1126 SSL_set_msg_callback_arg(con, bio_c_out);
1127 }
1128 if (cfg.tlsextdebug) {
1129 SSL_set_tlsext_debug_callback(con, tlsext_cb);
1130 SSL_set_tlsext_debug_arg(con, bio_c_out);
1131 }
1132 if (cfg.status_req) {
1133 SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
1134 SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
1135 SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
1136 }
1137
1138 SSL_set_bio(con, sbio, sbio);
1139 SSL_set_connect_state(con);
1140
1141 /* ok, lets connect */
1142 read_tty = 1;
1143 write_tty = 0;
1144 tty_on = 0;
1145 read_ssl = 1;
1146 write_ssl = 1;
1147
1148 cbuf_len = 0;
1149 cbuf_off = 0;
1150 sbuf_len = 0;
1151 sbuf_off = 0;
1152
1153 /* This is an ugly hack that does a lot of assumptions */
1154 /*
1155 * We do have to handle multi-line responses which may come in a
1156 * single packet or not. We therefore have to use BIO_gets() which
1157 * does need a buffering BIO. So during the initial chitchat we do
1158 * push a buffering BIO into the chain that is removed again later on
1159 * to not disturb the rest of the s_client operation.
1160 */
1161 if (cfg.starttls_proto == PROTO_SMTP ||
1162 cfg.starttls_proto == PROTO_LMTP) {
1163 int foundit = 0;
1164 BIO *fbio = BIO_new(BIO_f_buffer());
1165 BIO_push(fbio, sbio);
1166 /* wait for multi-line response to end from SMTP */
1167 do {
1168 mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1169 }
1170 while (mbuf_len > 3 && mbuf[3] == '-');
1171 /* STARTTLS command requires EHLO... */
1172 BIO_printf(fbio, "%cHLO openssl.client.net\r\n",
1173 cfg.starttls_proto == PROTO_SMTP ? 'E' : 'L');
1174 (void) BIO_flush(fbio);
1175 /* wait for multi-line response to end EHLO SMTP response */
1176 do {
1177 mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1178 if (strstr(mbuf, "STARTTLS"))
1179 foundit = 1;
1180 }
1181 while (mbuf_len > 3 && mbuf[3] == '-');
1182 (void) BIO_flush(fbio);
1183 BIO_pop(fbio);
1184 BIO_free(fbio);
1185 if (!foundit)
1186 BIO_printf(bio_err,
1187 "didn't find starttls in server response,"
1188 " try anyway...\n");
1189 BIO_printf(sbio, "STARTTLS\r\n");
1190 BIO_read(sbio, sbuf, BUFSIZZ);
1191 } else if (cfg.starttls_proto == PROTO_POP3) {
1192 mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
1193 if (mbuf_len == -1) {
1194 BIO_printf(bio_err, "BIO_read failed\n");
1195 goto end;
1196 }
1197 BIO_printf(sbio, "STLS\r\n");
1198 BIO_read(sbio, sbuf, BUFSIZZ);
1199 } else if (cfg.starttls_proto == PROTO_IMAP) {
1200 int foundit = 0;
1201 BIO *fbio = BIO_new(BIO_f_buffer());
1202 BIO_push(fbio, sbio);
1203 BIO_gets(fbio, mbuf, BUFSIZZ);
1204 /* STARTTLS command requires CAPABILITY... */
1205 BIO_printf(fbio, ". CAPABILITY\r\n");
1206 (void) BIO_flush(fbio);
1207 /* wait for multi-line CAPABILITY response */
1208 do {
1209 mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1210 if (strstr(mbuf, "STARTTLS"))
1211 foundit = 1;
1212 }
1213 while (mbuf_len > 3 && mbuf[0] != '.');
1214 (void) BIO_flush(fbio);
1215 BIO_pop(fbio);
1216 BIO_free(fbio);
1217 if (!foundit)
1218 BIO_printf(bio_err,
1219 "didn't find STARTTLS in server response,"
1220 " try anyway...\n");
1221 BIO_printf(sbio, ". STARTTLS\r\n");
1222 BIO_read(sbio, sbuf, BUFSIZZ);
1223 } else if (cfg.starttls_proto == PROTO_FTP) {
1224 BIO *fbio = BIO_new(BIO_f_buffer());
1225 BIO_push(fbio, sbio);
1226 /* wait for multi-line response to end from FTP */
1227 do {
1228 mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1229 }
1230 while (mbuf_len > 3 && mbuf[3] == '-');
1231 (void) BIO_flush(fbio);
1232 BIO_pop(fbio);
1233 BIO_free(fbio);
1234 BIO_printf(sbio, "AUTH TLS\r\n");
1235 BIO_read(sbio, sbuf, BUFSIZZ);
1236 } else if (cfg.starttls_proto == PROTO_XMPP) {
1237 int seen = 0;
1238 BIO_printf(sbio, "<stream:stream "
1239 "xmlns:stream='http://etherx.jabber.org/streams' "
1240 "xmlns='jabber:client' to='%s' version='1.0'>",
1241 cfg.xmpphost ?
1242 cfg.xmpphost : cfg.host);
1243 seen = BIO_read(sbio, mbuf, BUFSIZZ);
1244
1245 if (seen <= 0)
1246 goto shut;
1247
1248 mbuf[seen] = 0;
1249 while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") &&
1250 !strstr(mbuf, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"")) {
1251 seen = BIO_read(sbio, mbuf, BUFSIZZ);
1252
1253 if (seen <= 0)
1254 goto shut;
1255
1256 mbuf[seen] = 0;
1257 }
1258 BIO_printf(sbio,
1259 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
1260 seen = BIO_read(sbio, sbuf, BUFSIZZ);
1261 sbuf[seen] = 0;
1262 if (!strstr(sbuf, "<proceed"))
1263 goto shut;
1264 mbuf[0] = 0;
1265 } else if (cfg.proxy != NULL) {
1266 BIO_printf(sbio, "CONNECT %s HTTP/1.0\r\n\r\n",
1267 cfg.connect);
1268 mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
1269 if (mbuf_len == -1) {
1270 BIO_printf(bio_err, "BIO_read failed\n");
1271 goto end;
1272 }
1273 }
1274 for (;;) {
1275 struct pollfd pfd[3]; /* stdin, stdout, socket */
1276 int ptimeout = -1;
1277
1278 if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout))
1279 ptimeout = timeout.tv_sec * 1000 +
1280 timeout.tv_usec / 1000;
1281
1282 if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
1283 in_init = 1;
1284 tty_on = 0;
1285 } else {
1286 tty_on = 1;
1287 if (in_init) {
1288 in_init = 0;
1289 if (cfg.sess_out) {
1290 BIO *stmp = BIO_new_file(
1291 cfg.sess_out, "w");
1292 if (stmp) {
1293 PEM_write_bio_SSL_SESSION(stmp,
1294 SSL_get_session(con));
1295 BIO_free(stmp);
1296 } else
1297 BIO_printf(bio_err,
1298 "Error writing session file %s\n",
1299 cfg.sess_out);
1300 }
1301 print_stuff(bio_c_out, con, full_log);
1302 if (full_log > 0)
1303 full_log--;
1304
1305 if (cfg.starttls_proto) {
1306 BIO_write(bio_err, mbuf, mbuf_len);
1307 /* We don't need to know any more */
1308 cfg.starttls_proto = PROTO_OFF;
1309 }
1310 if (cfg.reconnect) {
1311 cfg.reconnect--;
1312 BIO_printf(bio_c_out,
1313 "drop connection and then reconnect\n");
1314 SSL_shutdown(con);
1315 SSL_set_connect_state(con);
1316 shutdown(SSL_get_fd(con), SHUT_RD);
1317 close(SSL_get_fd(con));
1318 goto re_start;
1319 }
1320 }
1321 }
1322
1323 ssl_pending = read_ssl && SSL_pending(con);
1324
1325 pfd[0].fd = -1;
1326 pfd[1].fd = -1;
1327 if (!ssl_pending) {
1328 if (tty_on) {
1329 if (read_tty) {
1330 pfd[0].fd = fileno(stdin);
1331 pfd[0].events = POLLIN;
1332 }
1333 if (write_tty) {
1334 pfd[1].fd = fileno(stdout);
1335 pfd[1].events = POLLOUT;
1336 }
1337 }
1338
1339 pfd[2].fd = SSL_get_fd(con);
1340 pfd[2].events = 0;
1341 if (read_ssl)
1342 pfd[2].events |= POLLIN;
1343 if (write_ssl)
1344 pfd[2].events |= POLLOUT;
1345
1346/* printf("mode tty(%d %d%d) ssl(%d%d)\n",
1347 tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
1348
1349 i = poll(pfd, 3, ptimeout);
1350 if (i == -1) {
1351 BIO_printf(bio_err, "bad select %d\n",
1352 errno);
1353 goto shut;
1354 /* goto end; */
1355 }
1356 }
1357 if (SSL_is_dtls(con) &&
1358 DTLSv1_handle_timeout(con) > 0)
1359 BIO_printf(bio_err, "TIMEOUT occured\n");
1360 if (!ssl_pending &&
1361 (pfd[2].revents & (POLLOUT|POLLERR|POLLNVAL))) {
1362 if (pfd[2].revents & (POLLERR|POLLNVAL)) {
1363 BIO_printf(bio_err, "poll error");
1364 goto shut;
1365 }
1366 k = SSL_write(con, &(cbuf[cbuf_off]),
1367 (unsigned int) cbuf_len);
1368 switch (SSL_get_error(con, k)) {
1369 case SSL_ERROR_NONE:
1370 cbuf_off += k;
1371 cbuf_len -= k;
1372 if (k <= 0)
1373 goto end;
1374 /* we have done a write(con,NULL,0); */
1375 if (cbuf_len <= 0) {
1376 read_tty = 1;
1377 write_ssl = 0;
1378 } else { /* if (cbuf_len > 0) */
1379 read_tty = 0;
1380 write_ssl = 1;
1381 }
1382 break;
1383 case SSL_ERROR_WANT_WRITE:
1384 BIO_printf(bio_c_out, "write W BLOCK\n");
1385 write_ssl = 1;
1386 read_tty = 0;
1387 break;
1388 case SSL_ERROR_WANT_READ:
1389 BIO_printf(bio_c_out, "write R BLOCK\n");
1390 write_tty = 0;
1391 read_ssl = 1;
1392 write_ssl = 0;
1393 break;
1394 case SSL_ERROR_WANT_X509_LOOKUP:
1395 BIO_printf(bio_c_out, "write X BLOCK\n");
1396 break;
1397 case SSL_ERROR_ZERO_RETURN:
1398 if (cbuf_len != 0) {
1399 BIO_printf(bio_c_out, "shutdown\n");
1400 ret = 0;
1401 goto shut;
1402 } else {
1403 read_tty = 1;
1404 write_ssl = 0;
1405 break;
1406 }
1407
1408 case SSL_ERROR_SYSCALL:
1409 if ((k != 0) || (cbuf_len != 0)) {
1410 BIO_printf(bio_err, "write:errno=%d\n",
1411 errno);
1412 goto shut;
1413 } else {
1414 read_tty = 1;
1415 write_ssl = 0;
1416 }
1417 break;
1418 case SSL_ERROR_SSL:
1419 ERR_print_errors(bio_err);
1420 goto shut;
1421 }
1422 } else if (!ssl_pending &&
1423 (pfd[1].revents & (POLLOUT|POLLERR|POLLNVAL))) {
1424 if (pfd[1].revents & (POLLERR|POLLNVAL)) {
1425 BIO_printf(bio_err, "poll error");
1426 goto shut;
1427 }
1428 i = write(fileno(stdout), &(sbuf[sbuf_off]), sbuf_len);
1429
1430 if (i <= 0) {
1431 BIO_printf(bio_c_out, "DONE\n");
1432 ret = 0;
1433 goto shut;
1434 /* goto end; */
1435 }
1436 sbuf_len -= i;
1437 sbuf_off += i;
1438 if (sbuf_len <= 0) {
1439 read_ssl = 1;
1440 write_tty = 0;
1441 }
1442 } else if (ssl_pending || (pfd[2].revents & (POLLIN|POLLHUP))) {
1443#ifdef RENEG
1444 {
1445 static int iiii;
1446 if (++iiii == 52) {
1447 SSL_renegotiate(con);
1448 iiii = 0;
1449 }
1450 }
1451#endif
1452 if (cfg.peekaboo) {
1453 k = p = SSL_peek(con, pbuf, 1024 /* BUFSIZZ */ );
1454 pending = SSL_pending(con);
1455 if (SSL_get_error(con, p) == SSL_ERROR_NONE) {
1456 if (p <= 0)
1457 goto end;
1458
1459 k = SSL_read(con, sbuf, p);
1460 }
1461 } else {
1462 k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ );
1463 }
1464
1465 switch (SSL_get_error(con, k)) {
1466 case SSL_ERROR_NONE:
1467 if (k <= 0)
1468 goto end;
1469 sbuf_off = 0;
1470 sbuf_len = k;
1471 if (cfg.peekaboo) {
1472 if (p != pending) {
1473 ret = -1;
1474 BIO_printf(bio_err,
1475 "peeked %d but pending %d!\n",
1476 p, pending);
1477 goto shut;
1478 }
1479 if (k < p) {
1480 ret = -1;
1481 BIO_printf(bio_err,
1482 "read less than peek!\n");
1483 goto shut;
1484 }
1485 if (p > 0 &&
1486 (memcmp(sbuf, pbuf, p) != 0)) {
1487 ret = -1;
1488 BIO_printf(bio_err,
1489 "peek of %d different from read of %d!\n",
1490 p, k);
1491 goto shut;
1492 }
1493 }
1494 read_ssl = 0;
1495 write_tty = 1;
1496 break;
1497 case SSL_ERROR_WANT_WRITE:
1498 BIO_printf(bio_c_out, "read W BLOCK\n");
1499 write_ssl = 1;
1500 read_tty = 0;
1501 break;
1502 case SSL_ERROR_WANT_READ:
1503 BIO_printf(bio_c_out, "read R BLOCK\n");
1504 write_tty = 0;
1505 read_ssl = 1;
1506 if ((read_tty == 0) && (write_ssl == 0))
1507 write_ssl = 1;
1508 break;
1509 case SSL_ERROR_WANT_X509_LOOKUP:
1510 BIO_printf(bio_c_out, "read X BLOCK\n");
1511 break;
1512 case SSL_ERROR_SYSCALL:
1513 ret = errno;
1514 BIO_printf(bio_err, "read:errno=%d\n", ret);
1515 goto shut;
1516 case SSL_ERROR_ZERO_RETURN:
1517 BIO_printf(bio_c_out, "closed\n");
1518 ret = 0;
1519 goto shut;
1520 case SSL_ERROR_SSL:
1521 ERR_print_errors(bio_err);
1522 goto shut;
1523 /* break; */
1524 }
1525 } else if (pfd[0].revents) {
1526 if (pfd[0].revents & (POLLERR|POLLNVAL)) {
1527 BIO_printf(bio_err, "poll error");
1528 goto shut;
1529 }
1530 if (cfg.crlf) {
1531 int j, lf_num;
1532
1533 i = read(fileno(stdin), cbuf, BUFSIZZ / 2);
1534 lf_num = 0;
1535 /* both loops are skipped when i <= 0 */
1536 for (j = 0; j < i; j++)
1537 if (cbuf[j] == '\n')
1538 lf_num++;
1539 for (j = i - 1; j >= 0; j--) {
1540 cbuf[j + lf_num] = cbuf[j];
1541 if (cbuf[j] == '\n') {
1542 lf_num--;
1543 i++;
1544 cbuf[j + lf_num] = '\r';
1545 }
1546 }
1547 assert(lf_num == 0);
1548 } else
1549 i = read(fileno(stdin), cbuf, BUFSIZZ);
1550
1551 if ((!cfg.ign_eof) &&
1552 ((i <= 0) || (cbuf[0] == 'Q'))) {
1553 BIO_printf(bio_err, "DONE\n");
1554 ret = 0;
1555 goto shut;
1556 }
1557 if ((!cfg.ign_eof) && (cbuf[0] == 'R')) {
1558 BIO_printf(bio_err, "RENEGOTIATING\n");
1559 SSL_renegotiate(con);
1560 cbuf_len = 0;
1561 } else {
1562 cbuf_len = i;
1563 cbuf_off = 0;
1564 }
1565
1566 write_ssl = 1;
1567 read_tty = 0;
1568 }
1569 }
1570
1571 ret = 0;
1572 shut:
1573 if (in_init)
1574 print_stuff(bio_c_out, con, full_log);
1575 SSL_shutdown(con);
1576 shutdown(SSL_get_fd(con), SHUT_RD);
1577 close(SSL_get_fd(con));
1578 end:
1579 if (con != NULL) {
1580 if (cfg.prexit != 0)
1581 print_stuff(bio_c_out, con, 1);
1582 SSL_free(con);
1583 }
1584 SSL_CTX_free(ctx);
1585 X509_free(cert);
1586 EVP_PKEY_free(key);
1587 free(pass);
1588 X509_VERIFY_PARAM_free(cfg.vpm);
1589 freezero(cbuf, BUFSIZZ);
1590 freezero(sbuf, BUFSIZZ);
1591 freezero(pbuf, BUFSIZZ);
1592 freezero(mbuf, BUFSIZZ);
1593 BIO_free(bio_c_out);
1594
1595 return (ret);
1596}
1597
1598static void
1599print_stuff(BIO *bio, SSL *s, int full)
1600{
1601 X509 *peer = NULL;
1602 char *p;
1603 static const char *space = " ";
1604 char buf[BUFSIZ];
1605 STACK_OF(X509) *sk;
1606 STACK_OF(X509_NAME) *sk2;
1607 const SSL_CIPHER *c;
1608 X509_NAME *xn;
1609 int j, i;
1610 unsigned char *exportedkeymat;
1611
1612 if (full) {
1613 int got_a_chain = 0;
1614
1615 sk = SSL_get_peer_cert_chain(s);
1616 if (sk != NULL) {
1617 got_a_chain = 1; /* we don't have it for SSL2
1618 * (yet) */
1619
1620 BIO_printf(bio, "---\nCertificate chain\n");
1621 for (i = 0; i < sk_X509_num(sk); i++) {
1622 X509_NAME_oneline(X509_get_subject_name(
1623 sk_X509_value(sk, i)), buf, sizeof buf);
1624 BIO_printf(bio, "%2d s:%s\n", i, buf);
1625 X509_NAME_oneline(X509_get_issuer_name(
1626 sk_X509_value(sk, i)), buf, sizeof buf);
1627 BIO_printf(bio, " i:%s\n", buf);
1628 if (cfg.showcerts)
1629 PEM_write_bio_X509(bio,
1630 sk_X509_value(sk, i));
1631 }
1632 }
1633 BIO_printf(bio, "---\n");
1634 peer = SSL_get_peer_certificate(s);
1635 if (peer != NULL) {
1636 BIO_printf(bio, "Server certificate\n");
1637 if (!(cfg.showcerts && got_a_chain)) {
1638 /* Redundant if we showed the whole chain */
1639 PEM_write_bio_X509(bio, peer);
1640 }
1641 X509_NAME_oneline(X509_get_subject_name(peer),
1642 buf, sizeof buf);
1643 BIO_printf(bio, "subject=%s\n", buf);
1644 X509_NAME_oneline(X509_get_issuer_name(peer),
1645 buf, sizeof buf);
1646 BIO_printf(bio, "issuer=%s\n", buf);
1647 } else
1648 BIO_printf(bio, "no peer certificate available\n");
1649
1650 sk2 = SSL_get_client_CA_list(s);
1651 if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
1652 BIO_printf(bio,
1653 "---\nAcceptable client certificate CA names\n");
1654 for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
1655 xn = sk_X509_NAME_value(sk2, i);
1656 X509_NAME_oneline(xn, buf, sizeof(buf));
1657 BIO_write(bio, buf, strlen(buf));
1658 BIO_write(bio, "\n", 1);
1659 }
1660 } else {
1661 BIO_printf(bio,
1662 "---\nNo client certificate CA names sent\n");
1663 }
1664 p = SSL_get_shared_ciphers(s, buf, sizeof buf);
1665 if (p != NULL) {
1666 /*
1667 * This works only for SSL 2. In later protocol
1668 * versions, the client does not know what other
1669 * ciphers (in addition to the one to be used in the
1670 * current connection) the server supports.
1671 */
1672
1673 BIO_printf(bio,
1674 "---\nCiphers common between both SSL endpoints:\n");
1675 j = i = 0;
1676 while (*p) {
1677 if (*p == ':') {
1678 BIO_write(bio, space, 15 - j % 25);
1679 i++;
1680 j = 0;
1681 BIO_write(bio,
1682 ((i % 3) ? " " : "\n"), 1);
1683 } else {
1684 BIO_write(bio, p, 1);
1685 j++;
1686 }
1687 p++;
1688 }
1689 BIO_write(bio, "\n", 1);
1690 }
1691
1692 ssl_print_tmp_key(bio, s);
1693
1694 BIO_printf(bio,
1695 "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
1696 BIO_number_read(SSL_get_rbio(s)),
1697 BIO_number_written(SSL_get_wbio(s)));
1698 }
1699 BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, "));
1700 c = SSL_get_current_cipher(s);
1701 BIO_printf(bio, "%s, Cipher is %s\n",
1702 SSL_CIPHER_get_version(c),
1703 SSL_CIPHER_get_name(c));
1704 if (peer != NULL) {
1705 EVP_PKEY *pktmp;
1706
1707 pktmp = X509_get0_pubkey(peer);
1708 BIO_printf(bio, "Server public key is %d bit\n",
1709 EVP_PKEY_bits(pktmp));
1710 }
1711 BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
1712 SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
1713
1714 /* Compression is not supported and will always be none. */
1715 BIO_printf(bio, "Compression: NONE\n");
1716 BIO_printf(bio, "Expansion: NONE\n");
1717
1718#ifdef SSL_DEBUG
1719 {
1720 /* Print out local port of connection: useful for debugging */
1721 int sock;
1722 struct sockaddr_in ladd;
1723 socklen_t ladd_size = sizeof(ladd);
1724 sock = SSL_get_fd(s);
1725 getsockname(sock, (struct sockaddr *) & ladd, &ladd_size);
1726 BIO_printf(bio, "LOCAL PORT is %u\n",
1727 ntohs(ladd.sin_port));
1728 }
1729#endif
1730
1731 {
1732 const unsigned char *proto;
1733 unsigned int proto_len;
1734 SSL_get0_alpn_selected(s, &proto, &proto_len);
1735 if (proto_len > 0) {
1736 BIO_printf(bio, "ALPN protocol: ");
1737 BIO_write(bio, proto, proto_len);
1738 BIO_write(bio, "\n", 1);
1739 } else
1740 BIO_printf(bio, "No ALPN negotiated\n");
1741 }
1742
1743#ifndef OPENSSL_NO_SRTP
1744 {
1745 SRTP_PROTECTION_PROFILE *srtp_profile;
1746
1747 srtp_profile = SSL_get_selected_srtp_profile(s);
1748 if (srtp_profile)
1749 BIO_printf(bio,
1750 "SRTP Extension negotiated, profile=%s\n",
1751 srtp_profile->name);
1752 }
1753#endif
1754
1755 SSL_SESSION_print(bio, SSL_get_session(s));
1756 if (cfg.keymatexportlabel != NULL) {
1757 BIO_printf(bio, "Keying material exporter:\n");
1758 BIO_printf(bio, " Label: '%s'\n",
1759 cfg.keymatexportlabel);
1760 BIO_printf(bio, " Length: %i bytes\n",
1761 cfg.keymatexportlen);
1762 exportedkeymat = malloc(cfg.keymatexportlen);
1763 if (exportedkeymat != NULL) {
1764 if (!SSL_export_keying_material(s, exportedkeymat,
1765 cfg.keymatexportlen,
1766 cfg.keymatexportlabel,
1767 strlen(cfg.keymatexportlabel),
1768 NULL, 0, 0)) {
1769 BIO_printf(bio, " Error\n");
1770 } else {
1771 BIO_printf(bio, " Keying material: ");
1772 for (i = 0; i < cfg.keymatexportlen; i++)
1773 BIO_printf(bio, "%02X",
1774 exportedkeymat[i]);
1775 BIO_printf(bio, "\n");
1776 }
1777 free(exportedkeymat);
1778 }
1779 }
1780 BIO_printf(bio, "---\n");
1781 X509_free(peer);
1782 /* flush, or debugging output gets mixed with http response */
1783 (void) BIO_flush(bio);
1784}
1785
1786static int
1787ocsp_resp_cb(SSL *s, void *arg)
1788{
1789 const unsigned char *p;
1790 int len;
1791 OCSP_RESPONSE *rsp;
1792 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
1793 BIO_puts(arg, "OCSP response: ");
1794 if (!p) {
1795 BIO_puts(arg, "no response sent\n");
1796 return 1;
1797 }
1798 rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
1799 if (!rsp) {
1800 BIO_puts(arg, "response parse error\n");
1801 BIO_dump_indent(arg, (char *) p, len, 4);
1802 return 0;
1803 }
1804 BIO_puts(arg, "\n======================================\n");
1805 OCSP_RESPONSE_print(arg, rsp, 0);
1806 BIO_puts(arg, "======================================\n");
1807 OCSP_RESPONSE_free(rsp);
1808 return 1;
1809}
1810
1811static int
1812ssl_servername_cb(SSL *s, int *ad, void *arg)
1813{
1814 tlsextctx *p = (tlsextctx *) arg;
1815 const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
1816 if (SSL_get_servername_type(s) != -1)
1817 p->ack = !SSL_session_reused(s) && hn != NULL;
1818 else
1819 BIO_printf(bio_err, "Can't use SSL_get_servername\n");
1820
1821 return SSL_TLSEXT_ERR_OK;
1822}
1823
diff --git a/src/usr.bin/openssl/s_server.c b/src/usr.bin/openssl/s_server.c
deleted file mode 100644
index f56042a4b4..0000000000
--- a/src/usr.bin/openssl/s_server.c
+++ /dev/null
@@ -1,2415 +0,0 @@
1/* $OpenBSD: s_server.c,v 1.61 2025/01/02 13:10:03 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111/* ====================================================================
112 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113 * ECC cipher suite support in OpenSSL originally developed by
114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115 */
116/* ====================================================================
117 * Copyright 2005 Nokia. All rights reserved.
118 *
119 * The portions of the attached software ("Contribution") is developed by
120 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
121 * license.
122 *
123 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
124 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
125 * support (see RFC 4279) to OpenSSL.
126 *
127 * No patent licenses or other rights except those expressly stated in
128 * the OpenSSL open source license shall be deemed granted or received
129 * expressly, by implication, estoppel, or otherwise.
130 *
131 * No assurances are provided by Nokia that the Contribution does not
132 * infringe the patent or other intellectual property rights of any third
133 * party or that the license provides you with all the necessary rights
134 * to make use of the Contribution.
135 *
136 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
137 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
138 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
139 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
140 * OTHERWISE.
141 */
142
143/* Until the key-gen callbacks are modified to use newer prototypes, we allow
144 * deprecated functions for openssl-internal code */
145#ifdef OPENSSL_NO_DEPRECATED
146#undef OPENSSL_NO_DEPRECATED
147#endif
148
149#include <sys/types.h>
150#include <sys/socket.h>
151
152#include <assert.h>
153#include <ctype.h>
154#include <stdio.h>
155#include <stdlib.h>
156#include <limits.h>
157#include <string.h>
158#include <unistd.h>
159#include <poll.h>
160
161#include "apps.h"
162
163#include <openssl/bn.h>
164#include <openssl/err.h>
165#include <openssl/lhash.h>
166#include <openssl/ocsp.h>
167#include <openssl/pem.h>
168#include <openssl/ssl.h>
169#include <openssl/x509.h>
170
171#ifndef OPENSSL_NO_DH
172#include <openssl/dh.h>
173#endif
174
175#include <openssl/rsa.h>
176
177static void s_server_init(void);
178static void sv_usage(void);
179static void print_stats(BIO *bp, SSL_CTX *ctx);
180static int sv_body(int s, unsigned char *context);
181static void close_accept_socket(void);
182static int init_ssl_connection(SSL *s);
183#ifndef OPENSSL_NO_DH
184static DH *load_dh_param(const char *dhfile);
185#endif
186static int www_body(int s, unsigned char *context);
187static int generate_session_id(const SSL *ssl, unsigned char *id,
188 unsigned int *id_len);
189static int ssl_servername_cb(SSL *s, int *ad, void *arg);
190static int cert_status_cb(SSL * s, void *arg);
191static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
192 const unsigned char *in, unsigned int inlen, void *arg);
193/* static int load_CA(SSL_CTX *ctx, char *file);*/
194
195#define BUFSIZZ 16*1024
196static int bufsize = BUFSIZZ;
197static int accept_socket = -1;
198
199#define TEST_CERT "server.pem"
200#define TEST_CERT2 "server2.pem"
201
202static int s_server_session_id_context = 1; /* anything will do */
203static SSL_CTX *ctx = NULL;
204static SSL_CTX *ctx2 = NULL;
205static BIO *bio_s_out = NULL;
206
207static int local_argc = 0;
208static char **local_argv;
209
210/* This is a context that we pass to callbacks */
211typedef struct tlsextctx_st {
212 char *servername;
213 BIO *biodebug;
214 int extension_error;
215} tlsextctx;
216
217/* Structure passed to cert status callback */
218typedef struct tlsextstatusctx_st {
219 /* Default responder to use */
220 char *host, *path, *port;
221 int use_ssl;
222 int timeout;
223 BIO *err;
224 int verbose;
225} tlsextstatusctx;
226
227/* This the context that we pass to alpn_cb */
228typedef struct tlsextalpnctx_st {
229 unsigned char *data;
230 unsigned short len;
231} tlsextalpnctx;
232
233static struct {
234 char *alpn_in;
235 char *npn_in; /* Ignored. */
236 int bugs;
237 char *CAfile;
238 char *CApath;
239#ifndef OPENSSL_NO_DTLS
240 int cert_chain;
241#endif
242 char *cert_file;
243 char *cert_file2;
244 int cert_format;
245 char *cipher;
246 unsigned char *context;
247 int crlf;
248 char *dcert_file;
249 int dcert_format;
250 int debug;
251 char *dhfile;
252 char *dkey_file;
253 int dkey_format;
254 char *dpassarg;
255 int enable_timeouts;
256 const char *errstr;
257 char *groups_in;
258 char *key_file;
259 char *key_file2;
260 int key_format;
261 char *keymatexportlabel;
262 int keymatexportlen;
263 uint16_t max_version;
264 uint16_t min_version;
265 const SSL_METHOD *meth;
266 int msg;
267 int naccept;
268 char *named_curve;
269 int nbio;
270 int nbio_test;
271 int no_cache;
272 int nocert;
273 int no_dhe;
274 int no_ecdhe;
275 int no_tmp_rsa; /* No-op. */
276 int off;
277 char *passarg;
278 short port;
279 int quiet;
280 int server_verify;
281 char *session_id_prefix;
282 long socket_mtu;
283 int socket_type;
284#ifndef OPENSSL_NO_SRTP
285 char *srtp_profiles;
286#endif
287 int state;
288 tlsextstatusctx tlscstatp;
289 tlsextctx tlsextcbp;
290 int tlsextdebug;
291 int tlsextstatus;
292 X509_VERIFY_PARAM *vpm;
293 int www;
294} cfg;
295
296static int
297s_server_opt_context(char *arg)
298{
299 cfg.context = (unsigned char *) arg;
300 return (0);
301}
302
303static int
304s_server_opt_keymatexportlen(char *arg)
305{
306 cfg.keymatexportlen = strtonum(arg, 1, INT_MAX,
307 &cfg.errstr);
308 if (cfg.errstr != NULL) {
309 BIO_printf(bio_err, "invalid argument %s: %s\n",
310 arg, cfg.errstr);
311 return (1);
312 }
313 return (0);
314}
315
316#ifndef OPENSSL_NO_DTLS
317static int
318s_server_opt_mtu(char *arg)
319{
320 cfg.socket_mtu = strtonum(arg, 0, LONG_MAX,
321 &cfg.errstr);
322 if (cfg.errstr != NULL) {
323 BIO_printf(bio_err, "invalid argument %s: %s\n",
324 arg, cfg.errstr);
325 return (1);
326 }
327 return (0);
328}
329#endif
330
331#ifndef OPENSSL_NO_DTLS
332static int
333s_server_opt_protocol_version_dtls(void)
334{
335 cfg.meth = DTLS_server_method();
336 cfg.socket_type = SOCK_DGRAM;
337 return (0);
338}
339#endif
340
341#ifndef OPENSSL_NO_DTLS1_2
342static int
343s_server_opt_protocol_version_dtls1_2(void)
344{
345 cfg.meth = DTLS_server_method();
346 cfg.min_version = DTLS1_2_VERSION;
347 cfg.max_version = DTLS1_2_VERSION;
348 cfg.socket_type = SOCK_DGRAM;
349 return (0);
350}
351#endif
352
353static int
354s_server_opt_protocol_version_tls1_2(void)
355{
356 cfg.min_version = TLS1_2_VERSION;
357 cfg.max_version = TLS1_2_VERSION;
358 return (0);
359}
360
361static int
362s_server_opt_protocol_version_tls1_3(void)
363{
364 cfg.min_version = TLS1_3_VERSION;
365 cfg.max_version = TLS1_3_VERSION;
366 return (0);
367}
368
369static int
370s_server_opt_nbio_test(void)
371{
372 cfg.nbio = 1;
373 cfg.nbio_test = 1;
374 return (0);
375}
376
377static int
378s_server_opt_port(char *arg)
379{
380 if (!extract_port(arg, &cfg.port))
381 return (1);
382 return (0);
383}
384
385static int
386s_server_opt_status_timeout(char *arg)
387{
388 cfg.tlsextstatus = 1;
389 cfg.tlscstatp.timeout = strtonum(arg, 0, INT_MAX,
390 &cfg.errstr);
391 if (cfg.errstr != NULL) {
392 BIO_printf(bio_err, "invalid argument %s: %s\n",
393 arg, cfg.errstr);
394 return (1);
395 }
396 return (0);
397}
398
399static int
400s_server_opt_status_url(char *arg)
401{
402 cfg.tlsextstatus = 1;
403 if (!OCSP_parse_url(arg, &cfg.tlscstatp.host,
404 &cfg.tlscstatp.port, &cfg.tlscstatp.path,
405 &cfg.tlscstatp.use_ssl)) {
406 BIO_printf(bio_err, "Error parsing URL\n");
407 return (1);
408 }
409 return (0);
410}
411
412static int
413s_server_opt_status_verbose(void)
414{
415 cfg.tlsextstatus = 1;
416 cfg.tlscstatp.verbose = 1;
417 return (0);
418}
419
420static int
421s_server_opt_verify(char *arg)
422{
423 cfg.server_verify = SSL_VERIFY_PEER |
424 SSL_VERIFY_CLIENT_ONCE;
425 verify_depth = strtonum(arg, 0, INT_MAX, &cfg.errstr);
426 if (cfg.errstr != NULL) {
427 BIO_printf(bio_err, "invalid argument %s: %s\n",
428 arg, cfg.errstr);
429 return (1);
430 }
431 BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
432 return (0);
433}
434
435static int
436s_server_opt_verify_fail(char *arg)
437{
438 cfg.server_verify = SSL_VERIFY_PEER |
439 SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE;
440 verify_depth = strtonum(arg, 0, INT_MAX, &cfg.errstr);
441 if (cfg.errstr != NULL) {
442 BIO_printf(bio_err, "invalid argument %s: %s\n",
443 arg, cfg.errstr);
444 return (1);
445 }
446 BIO_printf(bio_err, "verify depth is %d, must return a certificate\n",
447 verify_depth);
448 return (0);
449}
450
451static int
452s_server_opt_verify_param(int argc, char **argv, int *argsused)
453{
454 char **pargs = argv;
455 int pargc = argc;
456 int badarg = 0;
457
458 if (!args_verify(&pargs, &pargc, &badarg, bio_err,
459 &cfg.vpm)) {
460 BIO_printf(bio_err, "unknown option %s\n", *argv);
461 return (1);
462 }
463 if (badarg)
464 return (1);
465
466 *argsused = argc - pargc;
467 return (0);
468}
469
470static const struct option s_server_options[] = {
471 {
472 .name = "4",
473 .type = OPTION_DISCARD,
474 },
475 {
476 .name = "6",
477 .type = OPTION_DISCARD,
478 },
479 {
480 .name = "accept",
481 .argname = "port",
482 .desc = "Port to accept on (default is 4433)",
483 .type = OPTION_ARG_FUNC,
484 .opt.argfunc = s_server_opt_port,
485 },
486 {
487 .name = "alpn",
488 .argname = "protocols",
489 .desc = "Set the advertised protocols for the ALPN extension"
490 " (comma-separated list)",
491 .type = OPTION_ARG,
492 .opt.arg = &cfg.alpn_in,
493 },
494 {
495 .name = "bugs",
496 .desc = "Turn on SSL bug compatibility",
497 .type = OPTION_FLAG,
498 .opt.flag = &cfg.bugs,
499 },
500 {
501 .name = "CAfile",
502 .argname = "file",
503 .desc = "PEM format file of CA certificates",
504 .type = OPTION_ARG,
505 .opt.arg = &cfg.CAfile,
506 },
507 {
508 .name = "CApath",
509 .argname = "directory",
510 .desc = "PEM format directory of CA certificates",
511 .type = OPTION_ARG,
512 .opt.arg = &cfg.CApath,
513 },
514 {
515 .name = "cert",
516 .argname = "file",
517 .desc = "Certificate file to use\n"
518 "(default is " TEST_CERT ")",
519 .type = OPTION_ARG,
520 .opt.arg = &cfg.cert_file,
521 },
522 {
523 .name = "cert2",
524 .argname = "file",
525 .desc = "Certificate file to use for servername\n"
526 "(default is " TEST_CERT2 ")",
527 .type = OPTION_ARG,
528 .opt.arg = &cfg.cert_file2,
529 },
530 {
531 .name = "certform",
532 .argname = "fmt",
533 .desc = "Certificate format (PEM or DER) PEM default",
534 .type = OPTION_ARG_FORMAT,
535 .opt.value = &cfg.cert_format,
536 },
537#ifndef OPENSSL_NO_DTLS
538 {
539 .name = "chain",
540 .type = OPTION_FLAG,
541 .opt.flag = &cfg.cert_chain,
542 },
543#endif
544 {
545 .name = "cipher",
546 .argname = "list",
547 .desc = "List of ciphers to enable (see `openssl ciphers`)",
548 .type = OPTION_ARG,
549 .opt.arg = &cfg.cipher,
550 },
551 {
552 .name = "context",
553 .argname = "id",
554 .desc = "Set session ID context",
555 .type = OPTION_ARG_FUNC,
556 .opt.argfunc = s_server_opt_context,
557 },
558 {
559 .name = "crlf",
560 .desc = "Convert LF from terminal into CRLF",
561 .type = OPTION_FLAG,
562 .opt.flag = &cfg.crlf,
563 },
564 {
565 .name = "dcert",
566 .argname = "file",
567 .desc = "Second certificate file to use (usually for DSA)",
568 .type = OPTION_ARG,
569 .opt.arg = &cfg.dcert_file,
570 },
571 {
572 .name = "dcertform",
573 .argname = "fmt",
574 .desc = "Second certificate format (PEM or DER) PEM default",
575 .type = OPTION_ARG_FORMAT,
576 .opt.value = &cfg.dcert_format,
577 },
578 {
579 .name = "debug",
580 .desc = "Print more output",
581 .type = OPTION_FLAG,
582 .opt.flag = &cfg.debug,
583 },
584 {
585 .name = "dhparam",
586 .argname = "file",
587 .desc = "DH parameter file to use, in cert file if not specified",
588 .type = OPTION_ARG,
589 .opt.arg = &cfg.dhfile,
590 },
591 {
592 .name = "dkey",
593 .argname = "file",
594 .desc = "Second private key file to use (usually for DSA)",
595 .type = OPTION_ARG,
596 .opt.arg = &cfg.dkey_file,
597 },
598 {
599 .name = "dkeyform",
600 .argname = "fmt",
601 .desc = "Second key format (PEM or DER) PEM default",
602 .type = OPTION_ARG_FORMAT,
603 .opt.value = &cfg.dkey_format,
604 },
605 {
606 .name = "dpass",
607 .argname = "arg",
608 .desc = "Second private key file pass phrase source",
609 .type = OPTION_ARG,
610 .opt.arg = &cfg.dpassarg,
611 },
612#ifndef OPENSSL_NO_DTLS
613 {
614 .name = "dtls",
615 .desc = "Use any version of DTLS",
616 .type = OPTION_FUNC,
617 .opt.func = s_server_opt_protocol_version_dtls,
618 },
619#endif
620#ifndef OPENSSL_NO_DTLS1_2
621 {
622 .name = "dtls1_2",
623 .desc = "Just use DTLSv1.2",
624 .type = OPTION_FUNC,
625 .opt.func = s_server_opt_protocol_version_dtls1_2,
626 },
627#endif
628 {
629 .name = "groups",
630 .argname = "list",
631 .desc = "Specify EC groups (colon-separated list)",
632 .type = OPTION_ARG,
633 .opt.arg = &cfg.groups_in,
634 },
635 {
636 .name = "HTTP",
637 .desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>",
638 .type = OPTION_VALUE,
639 .opt.value = &cfg.www,
640 .value = 3,
641 },
642 {
643 .name = "id_prefix",
644 .argname = "arg",
645 .desc = "Generate SSL/TLS session IDs prefixed by 'arg'",
646 .type = OPTION_ARG,
647 .opt.arg = &cfg.session_id_prefix,
648 },
649 {
650 .name = "key",
651 .argname = "file",
652 .desc = "Private Key file to use, in cert file if\n"
653 "not specified (default is " TEST_CERT ")",
654 .type = OPTION_ARG,
655 .opt.arg = &cfg.key_file,
656 },
657 {
658 .name = "key2",
659 .argname = "file",
660 .desc = "Private Key file to use for servername, in cert file if\n"
661 "not specified (default is " TEST_CERT2 ")",
662 .type = OPTION_ARG,
663 .opt.arg = &cfg.key_file2,
664 },
665 {
666 .name = "keyform",
667 .argname = "fmt",
668 .desc = "Key format (PEM or DER) PEM default",
669 .type = OPTION_ARG_FORMAT,
670 .opt.value = &cfg.key_format,
671 },
672 {
673 .name = "keymatexport",
674 .argname = "label",
675 .desc = "Export keying material using label",
676 .type = OPTION_ARG,
677 .opt.arg = &cfg.keymatexportlabel,
678 },
679 {
680 .name = "keymatexportlen",
681 .argname = "len",
682 .desc = "Export len bytes of keying material (default 20)",
683 .type = OPTION_ARG_FUNC,
684 .opt.argfunc = s_server_opt_keymatexportlen,
685 },
686 {
687 .name = "legacy_renegotiation",
688 .type = OPTION_DISCARD,
689 },
690 {
691 .name = "msg",
692 .desc = "Show protocol messages",
693 .type = OPTION_FLAG,
694 .opt.flag = &cfg.msg,
695 },
696#ifndef OPENSSL_NO_DTLS
697 {
698 .name = "mtu",
699 .argname = "mtu",
700 .desc = "Set link layer MTU",
701 .type = OPTION_ARG_FUNC,
702 .opt.argfunc = s_server_opt_mtu,
703 },
704#endif
705 {
706 .name = "naccept",
707 .argname = "num",
708 .desc = "Terminate after num connections",
709 .type = OPTION_ARG_INT,
710 .opt.value = &cfg.naccept
711 },
712 {
713 .name = "named_curve",
714 .argname = "arg",
715 .type = OPTION_ARG,
716 .opt.arg = &cfg.named_curve,
717 },
718 {
719 .name = "nbio",
720 .desc = "Run with non-blocking I/O",
721 .type = OPTION_FLAG,
722 .opt.flag = &cfg.nbio,
723 },
724 {
725 .name = "nbio_test",
726 .desc = "Test with the non-blocking test bio",
727 .type = OPTION_FUNC,
728 .opt.func = s_server_opt_nbio_test,
729 },
730 {
731 .name = "nextprotoneg",
732 .argname = "arg",
733 .type = OPTION_ARG,
734 .opt.arg = &cfg.npn_in, /* Ignored. */
735 },
736 {
737 .name = "no_cache",
738 .desc = "Disable session cache",
739 .type = OPTION_FLAG,
740 .opt.flag = &cfg.no_cache,
741 },
742 {
743 .name = "no_comp",
744 .desc = "Disable SSL/TLS compression",
745 .type = OPTION_VALUE_OR,
746 .opt.value = &cfg.off,
747 .value = SSL_OP_NO_COMPRESSION,
748 },
749 {
750 .name = "no_dhe",
751 .desc = "Disable ephemeral DH",
752 .type = OPTION_FLAG,
753 .opt.flag = &cfg.no_dhe,
754 },
755 {
756 .name = "no_ecdhe",
757 .desc = "Disable ephemeral ECDH",
758 .type = OPTION_FLAG,
759 .opt.flag = &cfg.no_ecdhe,
760 },
761 {
762 .name = "no_ticket",
763 .desc = "Disable use of RFC4507bis session tickets",
764 .type = OPTION_VALUE_OR,
765 .opt.value = &cfg.off,
766 .value = SSL_OP_NO_TICKET,
767 },
768 {
769 .name = "no_ssl2",
770 .type = OPTION_DISCARD,
771 },
772 {
773 .name = "no_ssl3",
774 .type = OPTION_DISCARD,
775 },
776 {
777 .name = "no_tls1",
778 .type = OPTION_DISCARD,
779 },
780 {
781 .name = "no_tls1_1",
782 .type = OPTION_DISCARD,
783 },
784 {
785 .name = "no_tls1_2",
786 .desc = "Just disable TLSv1.2",
787 .type = OPTION_VALUE_OR,
788 .opt.value = &cfg.off,
789 .value = SSL_OP_NO_TLSv1_2,
790 },
791 {
792 .name = "no_tls1_3",
793 .desc = "Just disable TLSv1.3",
794 .type = OPTION_VALUE_OR,
795 .opt.value = &cfg.off,
796 .value = SSL_OP_NO_TLSv1_3,
797 },
798 {
799 .name = "no_tmp_rsa",
800 .type = OPTION_DISCARD,
801 },
802 {
803 .name = "nocert",
804 .desc = "Don't use any certificates (Anon-DH)",
805 .type = OPTION_FLAG,
806 .opt.flag = &cfg.nocert,
807 },
808 {
809 .name = "pass",
810 .argname = "arg",
811 .desc = "Private key file pass phrase source",
812 .type = OPTION_ARG,
813 .opt.arg = &cfg.passarg,
814 },
815 {
816 .name = "port",
817 .argname = "port",
818 .type = OPTION_ARG_FUNC,
819 .opt.argfunc = s_server_opt_port,
820 },
821 {
822 .name = "quiet",
823 .desc = "Inhibit printing of session and certificate information",
824 .type = OPTION_FLAG,
825 .opt.flag = &cfg.quiet,
826 },
827 {
828 .name = "servername",
829 .argname = "name",
830 .desc = "Servername for HostName TLS extension",
831 .type = OPTION_ARG,
832 .opt.arg = &cfg.tlsextcbp.servername,
833 },
834 {
835 .name = "servername_fatal",
836 .desc = "On mismatch send fatal alert (default warning alert)",
837 .type = OPTION_VALUE,
838 .opt.value = &cfg.tlsextcbp.extension_error,
839 .value = SSL_TLSEXT_ERR_ALERT_FATAL,
840 },
841 {
842 .name = "serverpref",
843 .desc = "Use server's cipher preferences",
844 .type = OPTION_VALUE_OR,
845 .opt.value = &cfg.off,
846 .value = SSL_OP_CIPHER_SERVER_PREFERENCE,
847 },
848 {
849 .name = "state",
850 .desc = "Print the SSL states",
851 .type = OPTION_FLAG,
852 .opt.flag = &cfg.state,
853 },
854 {
855 .name = "status",
856 .desc = "Respond to certificate status requests",
857 .type = OPTION_FLAG,
858 .opt.flag = &cfg.tlsextstatus,
859 },
860 {
861 .name = "status_timeout",
862 .argname = "nsec",
863 .desc = "Status request responder timeout",
864 .type = OPTION_ARG_FUNC,
865 .opt.argfunc = s_server_opt_status_timeout,
866 },
867 {
868 .name = "status_url",
869 .argname = "url",
870 .desc = "Status request fallback URL",
871 .type = OPTION_ARG_FUNC,
872 .opt.argfunc = s_server_opt_status_url,
873 },
874 {
875 .name = "status_verbose",
876 .desc = "Enable status request verbose printout",
877 .type = OPTION_FUNC,
878 .opt.func = s_server_opt_status_verbose,
879 },
880#ifndef OPENSSL_NO_DTLS
881 {
882 .name = "timeout",
883 .desc = "Enable timeouts",
884 .type = OPTION_FLAG,
885 .opt.flag = &cfg.enable_timeouts,
886 },
887#endif
888 {
889 .name = "tls1_2",
890 .desc = "Just talk TLSv1.2",
891 .type = OPTION_FUNC,
892 .opt.func = s_server_opt_protocol_version_tls1_2,
893 },
894 {
895 .name = "tls1_3",
896 .desc = "Just talk TLSv1.3",
897 .type = OPTION_FUNC,
898 .opt.func = s_server_opt_protocol_version_tls1_3,
899 },
900 {
901 .name = "tlsextdebug",
902 .desc = "Hex dump of all TLS extensions received",
903 .type = OPTION_FLAG,
904 .opt.flag = &cfg.tlsextdebug,
905 },
906#ifndef OPENSSL_NO_SRTP
907 {
908 .name = "use_srtp",
909 .argname = "profiles",
910 .desc = "Offer SRTP key management with a colon-separated profile list",
911 .type = OPTION_ARG,
912 .opt.arg = &cfg.srtp_profiles,
913 },
914#endif
915 {
916 .name = "Verify",
917 .argname = "depth",
918 .desc = "Turn on peer certificate verification, must have a cert",
919 .type = OPTION_ARG_FUNC,
920 .opt.argfunc = s_server_opt_verify_fail,
921 },
922 {
923 .name = "verify",
924 .argname = "depth",
925 .desc = "Turn on peer certificate verification",
926 .type = OPTION_ARG_FUNC,
927 .opt.argfunc = s_server_opt_verify,
928 },
929 {
930 .name = "verify_return_error",
931 .desc = "Return verification error",
932 .type = OPTION_FLAG,
933 .opt.flag = &verify_return_error,
934 },
935 {
936 .name = "WWW",
937 .desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>",
938 .type = OPTION_VALUE,
939 .opt.value = &cfg.www,
940 .value = 2,
941 },
942 {
943 .name = "www",
944 .desc = "Respond to a 'GET /' with a status page",
945 .type = OPTION_VALUE,
946 .opt.value = &cfg.www,
947 .value = 1,
948 },
949 {
950 .name = NULL,
951 .desc = "",
952 .type = OPTION_ARGV_FUNC,
953 .opt.argvfunc = s_server_opt_verify_param,
954 },
955 { NULL },
956};
957
958static void
959s_server_init(void)
960{
961 accept_socket = -1;
962 cfg.cipher = NULL;
963 cfg.server_verify = SSL_VERIFY_NONE;
964 cfg.dcert_file = NULL;
965 cfg.dkey_file = NULL;
966 cfg.cert_file = TEST_CERT;
967 cfg.key_file = NULL;
968 cfg.cert_file2 = TEST_CERT2;
969 cfg.key_file2 = NULL;
970 ctx2 = NULL;
971 cfg.nbio = 0;
972 cfg.nbio_test = 0;
973 ctx = NULL;
974 cfg.www = 0;
975
976 bio_s_out = NULL;
977 cfg.debug = 0;
978 cfg.msg = 0;
979 cfg.quiet = 0;
980}
981
982static void
983sv_usage(void)
984{
985 fprintf(stderr, "usage: s_server "
986 "[-accept port] [-alpn protocols] [-bugs] [-CAfile file]\n"
987 " [-CApath directory] [-cert file] [-cert2 file]\n"
988 " [-certform der | pem] [-cipher cipherlist]\n"
989 " [-context id] [-crl_check] [-crl_check_all] [-crlf]\n"
990 " [-dcert file] [-dcertform der | pem] [-debug]\n"
991 " [-dhparam file] [-dkey file] [-dkeyform der | pem]\n"
992 " [-dpass arg] [-dtls] [-dtls1_2] [-groups list] [-HTTP]\n"
993 " [-id_prefix arg] [-key keyfile] [-key2 keyfile]\n"
994 " [-keyform der | pem] [-keymatexport label]\n"
995 " [-keymatexportlen len] [-msg] [-mtu mtu] [-naccept num]\n"
996 " [-named_curve arg] [-nbio] [-nbio_test] [-no_cache]\n"
997 " [-no_dhe] [-no_ecdhe] [-no_ticket] \n"
998 " [-no_tls1_2] [-no_tls1_3] [-no_tmp_rsa]\n"
999 " [-nocert] [-pass arg] [-quiet] [-servername name]\n"
1000 " [-servername_fatal] [-serverpref] [-state] [-status]\n"
1001 " [-status_timeout nsec] [-status_url url]\n"
1002 " [-status_verbose] [-timeout] \n"
1003 " [-tls1_2] [-tls1_3] [-tlsextdebug] [-use_srtp profiles]\n"
1004 " [-Verify depth] [-verify depth] [-verify_return_error]\n"
1005 " [-WWW] [-www]\n");
1006 fprintf(stderr, "\n");
1007 options_usage(s_server_options);
1008 fprintf(stderr, "\n");
1009}
1010
1011int
1012s_server_main(int argc, char *argv[])
1013{
1014 int ret = 1;
1015 char *pass = NULL;
1016 char *dpass = NULL;
1017 X509 *s_cert = NULL, *s_dcert = NULL;
1018 EVP_PKEY *s_key = NULL, *s_dkey = NULL;
1019 EVP_PKEY *s_key2 = NULL;
1020 X509 *s_cert2 = NULL;
1021 tlsextalpnctx alpn_ctx = { NULL, 0 };
1022
1023 if (pledge("stdio rpath inet dns tty", NULL) == -1) {
1024 perror("pledge");
1025 exit(1);
1026 }
1027
1028 memset(&cfg, 0, sizeof(cfg));
1029 cfg.keymatexportlen = 20;
1030 cfg.meth = TLS_server_method();
1031 cfg.naccept = -1;
1032 cfg.port = PORT;
1033 cfg.cert_file = TEST_CERT;
1034 cfg.cert_file2 = TEST_CERT2;
1035 cfg.cert_format = FORMAT_PEM;
1036 cfg.dcert_format = FORMAT_PEM;
1037 cfg.dkey_format = FORMAT_PEM;
1038 cfg.key_format = FORMAT_PEM;
1039 cfg.server_verify = SSL_VERIFY_NONE;
1040 cfg.socket_type = SOCK_STREAM;
1041 cfg.tlscstatp.timeout = -1;
1042 cfg.tlsextcbp.extension_error =
1043 SSL_TLSEXT_ERR_ALERT_WARNING;
1044
1045 local_argc = argc;
1046 local_argv = argv;
1047
1048 s_server_init();
1049
1050 verify_depth = 0;
1051
1052 if (options_parse(argc, argv, s_server_options, NULL, NULL) != 0) {
1053 if (cfg.errstr == NULL)
1054 sv_usage();
1055 goto end;
1056 }
1057
1058 if (!app_passwd(bio_err, cfg.passarg,
1059 cfg.dpassarg, &pass, &dpass)) {
1060 BIO_printf(bio_err, "Error getting password\n");
1061 goto end;
1062 }
1063 if (cfg.key_file == NULL)
1064 cfg.key_file = cfg.cert_file;
1065 if (cfg.key_file2 == NULL)
1066 cfg.key_file2 = cfg.cert_file2;
1067
1068 if (cfg.nocert == 0) {
1069 s_key = load_key(bio_err, cfg.key_file,
1070 cfg.key_format, 0, pass,
1071 "server certificate private key file");
1072 if (!s_key) {
1073 ERR_print_errors(bio_err);
1074 goto end;
1075 }
1076 s_cert = load_cert(bio_err, cfg.cert_file,
1077 cfg.cert_format,
1078 NULL, "server certificate file");
1079
1080 if (!s_cert) {
1081 ERR_print_errors(bio_err);
1082 goto end;
1083 }
1084 if (cfg.tlsextcbp.servername) {
1085 s_key2 = load_key(bio_err, cfg.key_file2,
1086 cfg.key_format, 0, pass,
1087 "second server certificate private key file");
1088 if (!s_key2) {
1089 ERR_print_errors(bio_err);
1090 goto end;
1091 }
1092 s_cert2 = load_cert(bio_err, cfg.cert_file2,
1093 cfg.cert_format,
1094 NULL, "second server certificate file");
1095
1096 if (!s_cert2) {
1097 ERR_print_errors(bio_err);
1098 goto end;
1099 }
1100 }
1101 }
1102 alpn_ctx.data = NULL;
1103 if (cfg.alpn_in) {
1104 unsigned short len;
1105 alpn_ctx.data = next_protos_parse(&len,
1106 cfg.alpn_in);
1107 if (alpn_ctx.data == NULL)
1108 goto end;
1109 alpn_ctx.len = len;
1110 }
1111
1112 if (cfg.dcert_file) {
1113
1114 if (cfg.dkey_file == NULL)
1115 cfg.dkey_file = cfg.dcert_file;
1116
1117 s_dkey = load_key(bio_err, cfg.dkey_file,
1118 cfg.dkey_format,
1119 0, dpass, "second certificate private key file");
1120 if (!s_dkey) {
1121 ERR_print_errors(bio_err);
1122 goto end;
1123 }
1124 s_dcert = load_cert(bio_err, cfg.dcert_file,
1125 cfg.dcert_format,
1126 NULL, "second server certificate file");
1127
1128 if (!s_dcert) {
1129 ERR_print_errors(bio_err);
1130 goto end;
1131 }
1132 }
1133 if (bio_s_out == NULL) {
1134 if (cfg.quiet && !cfg.debug &&
1135 !cfg.msg) {
1136 bio_s_out = BIO_new(BIO_s_null());
1137 } else {
1138 if (bio_s_out == NULL)
1139 bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
1140 }
1141 }
1142 if (cfg.nocert) {
1143 cfg.cert_file = NULL;
1144 cfg.key_file = NULL;
1145 cfg.dcert_file = NULL;
1146 cfg.dkey_file = NULL;
1147 cfg.cert_file2 = NULL;
1148 cfg.key_file2 = NULL;
1149 }
1150 ctx = SSL_CTX_new(cfg.meth);
1151 if (ctx == NULL) {
1152 ERR_print_errors(bio_err);
1153 goto end;
1154 }
1155
1156 SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
1157
1158 if (!SSL_CTX_set_min_proto_version(ctx, cfg.min_version))
1159 goto end;
1160 if (!SSL_CTX_set_max_proto_version(ctx, cfg.max_version))
1161 goto end;
1162
1163 if (cfg.session_id_prefix) {
1164 if (strlen(cfg.session_id_prefix) >= 32)
1165 BIO_printf(bio_err,
1166 "warning: id_prefix is too long, only one new session will be possible\n");
1167 else if (strlen(cfg.session_id_prefix) >= 16)
1168 BIO_printf(bio_err,
1169 "warning: id_prefix is too long if you use SSLv2\n");
1170 if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) {
1171 BIO_printf(bio_err, "error setting 'id_prefix'\n");
1172 ERR_print_errors(bio_err);
1173 goto end;
1174 }
1175 BIO_printf(bio_err, "id_prefix '%s' set.\n",
1176 cfg.session_id_prefix);
1177 }
1178 SSL_CTX_set_quiet_shutdown(ctx, 1);
1179 if (cfg.bugs)
1180 SSL_CTX_set_options(ctx, SSL_OP_ALL);
1181 SSL_CTX_set_options(ctx, cfg.off);
1182
1183 if (cfg.state)
1184 SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
1185 if (cfg.no_cache)
1186 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
1187 else
1188 SSL_CTX_sess_set_cache_size(ctx, 128);
1189
1190#ifndef OPENSSL_NO_SRTP
1191 if (cfg.srtp_profiles != NULL)
1192 SSL_CTX_set_tlsext_use_srtp(ctx, cfg.srtp_profiles);
1193#endif
1194
1195 if ((!SSL_CTX_load_verify_locations(ctx, cfg.CAfile,
1196 cfg.CApath)) ||
1197 (!SSL_CTX_set_default_verify_paths(ctx))) {
1198 /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
1199 ERR_print_errors(bio_err);
1200 /* goto end; */
1201 }
1202 if (cfg.vpm)
1203 SSL_CTX_set1_param(ctx, cfg.vpm);
1204
1205 if (s_cert2) {
1206 ctx2 = SSL_CTX_new(cfg.meth);
1207 if (ctx2 == NULL) {
1208 ERR_print_errors(bio_err);
1209 goto end;
1210 }
1211
1212 if (!SSL_CTX_set_min_proto_version(ctx2,
1213 cfg.min_version))
1214 goto end;
1215 if (!SSL_CTX_set_max_proto_version(ctx2,
1216 cfg.max_version))
1217 goto end;
1218 SSL_CTX_clear_mode(ctx2, SSL_MODE_AUTO_RETRY);
1219 }
1220 if (ctx2) {
1221 BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
1222
1223 if (cfg.session_id_prefix) {
1224 if (strlen(cfg.session_id_prefix) >= 32)
1225 BIO_printf(bio_err,
1226 "warning: id_prefix is too long, only one new session will be possible\n");
1227 else if (strlen(cfg.session_id_prefix) >= 16)
1228 BIO_printf(bio_err,
1229 "warning: id_prefix is too long if you use SSLv2\n");
1230 if (!SSL_CTX_set_generate_session_id(ctx2,
1231 generate_session_id)) {
1232 BIO_printf(bio_err,
1233 "error setting 'id_prefix'\n");
1234 ERR_print_errors(bio_err);
1235 goto end;
1236 }
1237 BIO_printf(bio_err, "id_prefix '%s' set.\n",
1238 cfg.session_id_prefix);
1239 }
1240 SSL_CTX_set_quiet_shutdown(ctx2, 1);
1241 if (cfg.bugs)
1242 SSL_CTX_set_options(ctx2, SSL_OP_ALL);
1243 SSL_CTX_set_options(ctx2, cfg.off);
1244
1245 if (cfg.state)
1246 SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback);
1247
1248 if (cfg.no_cache)
1249 SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF);
1250 else
1251 SSL_CTX_sess_set_cache_size(ctx2, 128);
1252
1253 if ((!SSL_CTX_load_verify_locations(ctx2,
1254 cfg.CAfile, cfg.CApath)) ||
1255 (!SSL_CTX_set_default_verify_paths(ctx2))) {
1256 ERR_print_errors(bio_err);
1257 }
1258 if (cfg.vpm)
1259 SSL_CTX_set1_param(ctx2, cfg.vpm);
1260 }
1261 if (alpn_ctx.data)
1262 SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
1263
1264 if (cfg.groups_in != NULL) {
1265 if (SSL_CTX_set1_groups_list(ctx, cfg.groups_in) != 1) {
1266 BIO_printf(bio_err, "Failed to set groups '%s'\n",
1267 cfg.groups_in);
1268 goto end;
1269 }
1270 }
1271
1272#ifndef OPENSSL_NO_DH
1273 if (!cfg.no_dhe) {
1274 DH *dh = NULL;
1275
1276 if (cfg.dhfile)
1277 dh = load_dh_param(cfg.dhfile);
1278 else if (cfg.cert_file)
1279 dh = load_dh_param(cfg.cert_file);
1280
1281 if (dh != NULL)
1282 BIO_printf(bio_s_out, "Setting temp DH parameters\n");
1283 else
1284 BIO_printf(bio_s_out, "Using auto DH parameters\n");
1285 (void) BIO_flush(bio_s_out);
1286
1287 if (dh == NULL)
1288 SSL_CTX_set_dh_auto(ctx, 1);
1289 else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
1290 BIO_printf(bio_err,
1291 "Error setting temp DH parameters\n");
1292 ERR_print_errors(bio_err);
1293 DH_free(dh);
1294 goto end;
1295 }
1296
1297 if (ctx2) {
1298 if (!cfg.dhfile) {
1299 DH *dh2 = NULL;
1300
1301 if (cfg.cert_file2 != NULL)
1302 dh2 = load_dh_param(
1303 cfg.cert_file2);
1304 if (dh2 != NULL) {
1305 BIO_printf(bio_s_out,
1306 "Setting temp DH parameters\n");
1307 (void) BIO_flush(bio_s_out);
1308
1309 DH_free(dh);
1310 dh = dh2;
1311 }
1312 }
1313 if (dh == NULL)
1314 SSL_CTX_set_dh_auto(ctx2, 1);
1315 else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
1316 BIO_printf(bio_err,
1317 "Error setting temp DH parameters\n");
1318 ERR_print_errors(bio_err);
1319 DH_free(dh);
1320 goto end;
1321 }
1322 }
1323 DH_free(dh);
1324 }
1325#endif
1326
1327 if (!cfg.no_ecdhe && cfg.named_curve != NULL) {
1328 EC_KEY *ecdh = NULL;
1329 int nid;
1330
1331 if ((nid = OBJ_sn2nid(cfg.named_curve)) == 0) {
1332 BIO_printf(bio_err, "unknown curve name (%s)\n",
1333 cfg.named_curve);
1334 goto end;
1335 }
1336 if ((ecdh = EC_KEY_new_by_curve_name(nid)) == NULL) {
1337 BIO_printf(bio_err, "unable to create curve (%s)\n",
1338 cfg.named_curve);
1339 goto end;
1340 }
1341 BIO_printf(bio_s_out, "Setting temp ECDH parameters\n");
1342 (void) BIO_flush(bio_s_out);
1343
1344 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1345 if (ctx2)
1346 SSL_CTX_set_tmp_ecdh(ctx2, ecdh);
1347 EC_KEY_free(ecdh);
1348 }
1349
1350 if (!set_cert_key_stuff(ctx, s_cert, s_key))
1351 goto end;
1352 if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2))
1353 goto end;
1354 if (s_dcert != NULL) {
1355 if (!set_cert_key_stuff(ctx, s_dcert, s_dkey))
1356 goto end;
1357 }
1358
1359 if (cfg.cipher != NULL) {
1360 if (!SSL_CTX_set_cipher_list(ctx, cfg.cipher)) {
1361 BIO_printf(bio_err, "error setting cipher list\n");
1362 ERR_print_errors(bio_err);
1363 goto end;
1364 }
1365 if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,
1366 cfg.cipher)) {
1367 BIO_printf(bio_err, "error setting cipher list\n");
1368 ERR_print_errors(bio_err);
1369 goto end;
1370 }
1371 }
1372 SSL_CTX_set_verify(ctx, cfg.server_verify, verify_callback);
1373 SSL_CTX_set_session_id_context(ctx,
1374 (void *) &s_server_session_id_context,
1375 sizeof s_server_session_id_context);
1376
1377 /* Set DTLS cookie generation and verification callbacks */
1378 SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
1379 SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
1380
1381 if (ctx2) {
1382 SSL_CTX_set_verify(ctx2, cfg.server_verify,
1383 verify_callback);
1384 SSL_CTX_set_session_id_context(ctx2,
1385 (void *) &s_server_session_id_context,
1386 sizeof s_server_session_id_context);
1387
1388 cfg.tlsextcbp.biodebug = bio_s_out;
1389 SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
1390 SSL_CTX_set_tlsext_servername_arg(ctx2,
1391 &cfg.tlsextcbp);
1392 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
1393 SSL_CTX_set_tlsext_servername_arg(ctx,
1394 &cfg.tlsextcbp);
1395 }
1396
1397 if (cfg.CAfile != NULL) {
1398 SSL_CTX_set_client_CA_list(ctx,
1399 SSL_load_client_CA_file(cfg.CAfile));
1400 if (ctx2)
1401 SSL_CTX_set_client_CA_list(ctx2,
1402 SSL_load_client_CA_file(cfg.CAfile));
1403 }
1404 BIO_printf(bio_s_out, "ACCEPT\n");
1405 (void) BIO_flush(bio_s_out);
1406 if (cfg.www)
1407 do_server(cfg.port, cfg.socket_type,
1408 &accept_socket, www_body, cfg.context,
1409 cfg.naccept);
1410 else
1411 do_server(cfg.port, cfg.socket_type,
1412 &accept_socket, sv_body, cfg.context,
1413 cfg.naccept);
1414 print_stats(bio_s_out, ctx);
1415 ret = 0;
1416 end:
1417 SSL_CTX_free(ctx);
1418 X509_free(s_cert);
1419 X509_free(s_dcert);
1420 EVP_PKEY_free(s_key);
1421 EVP_PKEY_free(s_dkey);
1422 free(pass);
1423 free(dpass);
1424 X509_VERIFY_PARAM_free(cfg.vpm);
1425 free(cfg.tlscstatp.host);
1426 free(cfg.tlscstatp.port);
1427 free(cfg.tlscstatp.path);
1428 SSL_CTX_free(ctx2);
1429 X509_free(s_cert2);
1430 EVP_PKEY_free(s_key2);
1431 free(alpn_ctx.data);
1432 if (bio_s_out != NULL) {
1433 BIO_free(bio_s_out);
1434 bio_s_out = NULL;
1435 }
1436
1437 return (ret);
1438}
1439
1440static void
1441print_stats(BIO *bio, SSL_CTX *ssl_ctx)
1442{
1443 BIO_printf(bio, "%4ld items in the session cache\n",
1444 SSL_CTX_sess_number(ssl_ctx));
1445 BIO_printf(bio, "%4ld client connects (SSL_connect())\n",
1446 SSL_CTX_sess_connect(ssl_ctx));
1447 BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n",
1448 SSL_CTX_sess_connect_renegotiate(ssl_ctx));
1449 BIO_printf(bio, "%4ld client connects that finished\n",
1450 SSL_CTX_sess_connect_good(ssl_ctx));
1451 BIO_printf(bio, "%4ld server accepts (SSL_accept())\n",
1452 SSL_CTX_sess_accept(ssl_ctx));
1453 BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n",
1454 SSL_CTX_sess_accept_renegotiate(ssl_ctx));
1455 BIO_printf(bio, "%4ld server accepts that finished\n",
1456 SSL_CTX_sess_accept_good(ssl_ctx));
1457 BIO_printf(bio, "%4ld session cache hits\n",
1458 SSL_CTX_sess_hits(ssl_ctx));
1459 BIO_printf(bio, "%4ld session cache misses\n",
1460 SSL_CTX_sess_misses(ssl_ctx));
1461 BIO_printf(bio, "%4ld session cache timeouts\n",
1462 SSL_CTX_sess_timeouts(ssl_ctx));
1463 BIO_printf(bio, "%4ld callback cache hits\n",
1464 SSL_CTX_sess_cb_hits(ssl_ctx));
1465 BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n",
1466 SSL_CTX_sess_cache_full(ssl_ctx),
1467 SSL_CTX_sess_get_cache_size(ssl_ctx));
1468}
1469
1470static int
1471sv_body(int s, unsigned char *context)
1472{
1473 char *buf = NULL;
1474 int ret = 1;
1475 int k, i;
1476 unsigned long l;
1477 SSL *con = NULL;
1478 BIO *sbio;
1479 struct timeval timeout;
1480
1481 if ((buf = malloc(bufsize)) == NULL) {
1482 BIO_printf(bio_err, "out of memory\n");
1483 goto err;
1484 }
1485 if (cfg.nbio) {
1486 if (!cfg.quiet)
1487 BIO_printf(bio_err, "turning on non blocking io\n");
1488 if (!BIO_socket_nbio(s, 1))
1489 ERR_print_errors(bio_err);
1490 }
1491
1492 if (con == NULL) {
1493 con = SSL_new(ctx);
1494 if (cfg.tlsextdebug) {
1495 SSL_set_tlsext_debug_callback(con, tlsext_cb);
1496 SSL_set_tlsext_debug_arg(con, bio_s_out);
1497 }
1498 if (cfg.tlsextstatus) {
1499 SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
1500 cfg.tlscstatp.err = bio_err;
1501 SSL_CTX_set_tlsext_status_arg(ctx,
1502 &cfg.tlscstatp);
1503 }
1504 if (context)
1505 SSL_set_session_id_context(con, context,
1506 strlen((char *) context));
1507 }
1508 SSL_clear(con);
1509
1510 if (SSL_is_dtls(con)) {
1511 sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1512
1513 if (cfg.enable_timeouts) {
1514 timeout.tv_sec = 0;
1515 timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1516 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0,
1517 &timeout);
1518
1519 timeout.tv_sec = 0;
1520 timeout.tv_usec = DGRAM_SND_TIMEOUT;
1521 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0,
1522 &timeout);
1523 }
1524 if (cfg.socket_mtu > 28) {
1525 SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1526 SSL_set_mtu(con, cfg.socket_mtu - 28);
1527 } else
1528 /* want to do MTU discovery */
1529 BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1530
1531 /* turn on cookie exchange */
1532 SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
1533 } else
1534 sbio = BIO_new_socket(s, BIO_NOCLOSE);
1535
1536 if (cfg.nbio_test) {
1537 BIO *test;
1538
1539 test = BIO_new(BIO_f_nbio_test());
1540 sbio = BIO_push(test, sbio);
1541 }
1542
1543 SSL_set_bio(con, sbio, sbio);
1544 SSL_set_accept_state(con);
1545 /* SSL_set_fd(con,s); */
1546
1547 if (cfg.debug) {
1548 BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
1549 BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out);
1550 }
1551 if (cfg.msg) {
1552 SSL_set_msg_callback(con, msg_cb);
1553 SSL_set_msg_callback_arg(con, bio_s_out);
1554 }
1555 if (cfg.tlsextdebug) {
1556 SSL_set_tlsext_debug_callback(con, tlsext_cb);
1557 SSL_set_tlsext_debug_arg(con, bio_s_out);
1558 }
1559
1560 for (;;) {
1561 int read_from_terminal;
1562 int read_from_sslcon;
1563 struct pollfd pfd[2];
1564 int ptimeout;
1565
1566 read_from_terminal = 0;
1567 read_from_sslcon = SSL_pending(con);
1568
1569 if (!read_from_sslcon) {
1570 pfd[0].fd = fileno(stdin);
1571 pfd[0].events = POLLIN;
1572 pfd[1].fd = s;
1573 pfd[1].events = POLLIN;
1574
1575 if (SSL_is_dtls(con) &&
1576 DTLSv1_get_timeout(con, &timeout))
1577 ptimeout = timeout.tv_sec * 1000 +
1578 timeout.tv_usec / 1000;
1579 else
1580 ptimeout = -1;
1581
1582 i = poll(pfd, 2, ptimeout);
1583
1584 if (SSL_is_dtls(con) &&
1585 DTLSv1_handle_timeout(con) > 0)
1586 BIO_printf(bio_err, "TIMEOUT occured\n");
1587 if (i <= 0)
1588 continue;
1589 if (pfd[0].revents) {
1590 if ((pfd[0].revents & (POLLERR|POLLNVAL)))
1591 continue;
1592 read_from_terminal = 1;
1593 }
1594 if (pfd[1].revents) {
1595 if ((pfd[1].revents & (POLLERR|POLLNVAL)))
1596 continue;
1597 read_from_sslcon = 1;
1598 }
1599 }
1600 if (read_from_terminal) {
1601 if (cfg.crlf) {
1602 int j, lf_num;
1603
1604 i = read(fileno(stdin), buf, bufsize / 2);
1605 lf_num = 0;
1606 /* both loops are skipped when i <= 0 */
1607 for (j = 0; j < i; j++)
1608 if (buf[j] == '\n')
1609 lf_num++;
1610 for (j = i - 1; j >= 0; j--) {
1611 buf[j + lf_num] = buf[j];
1612 if (buf[j] == '\n') {
1613 lf_num--;
1614 i++;
1615 buf[j + lf_num] = '\r';
1616 }
1617 }
1618 assert(lf_num == 0);
1619 } else
1620 i = read(fileno(stdin), buf, bufsize);
1621 if (!cfg.quiet) {
1622 if ((i <= 0) || (buf[0] == 'Q')) {
1623 BIO_printf(bio_s_out, "DONE\n");
1624 shutdown(s, SHUT_RD);
1625 close(s);
1626 close_accept_socket();
1627 ret = -11;
1628 goto err;
1629 }
1630 if ((i <= 0) || (buf[0] == 'q')) {
1631 BIO_printf(bio_s_out, "DONE\n");
1632 if (!SSL_is_dtls(con)) {
1633 shutdown(s, SHUT_RD);
1634 close(s);
1635 }
1636 /*
1637 * close_accept_socket(); ret= -11;
1638 */
1639 goto err;
1640 }
1641 if ((buf[0] == 'r') &&
1642 ((buf[1] == '\n') || (buf[1] == '\r'))) {
1643 SSL_renegotiate(con);
1644 i = SSL_do_handshake(con);
1645 printf("SSL_do_handshake -> %d\n", i);
1646 i = 0; /* 13; */
1647 continue;
1648 /*
1649 * RE-NEGOTIATE\n");
1650 */
1651 }
1652 if ((buf[0] == 'R') &&
1653 ((buf[1] == '\n') || (buf[1] == '\r'))) {
1654 SSL_set_verify(con,
1655 SSL_VERIFY_PEER |
1656 SSL_VERIFY_CLIENT_ONCE,
1657 NULL);
1658 SSL_renegotiate(con);
1659 i = SSL_do_handshake(con);
1660 printf("SSL_do_handshake -> %d\n", i);
1661 i = 0; /* 13; */
1662 continue;
1663 /*
1664 * RE-NEGOTIATE asking for client
1665 * cert\n");
1666 */
1667 }
1668 if (buf[0] == 'P') {
1669 static const char *str =
1670 "Lets print some clear text\n";
1671 BIO_write(SSL_get_wbio(con), str,
1672 strlen(str));
1673 }
1674 if (buf[0] == 'S') {
1675 print_stats(bio_s_out,
1676 SSL_get_SSL_CTX(con));
1677 }
1678 }
1679 l = k = 0;
1680 for (;;) {
1681 /* should do a select for the write */
1682#ifdef RENEG
1683 {
1684 static count = 0;
1685 if (++count == 100) {
1686 count = 0;
1687 SSL_renegotiate(con);
1688 }
1689 }
1690#endif
1691 k = SSL_write(con, &(buf[l]), (unsigned int) i);
1692 switch (SSL_get_error(con, k)) {
1693 case SSL_ERROR_NONE:
1694 break;
1695 case SSL_ERROR_WANT_WRITE:
1696 case SSL_ERROR_WANT_READ:
1697 case SSL_ERROR_WANT_X509_LOOKUP:
1698 BIO_printf(bio_s_out, "Write BLOCK\n");
1699 break;
1700 case SSL_ERROR_SYSCALL:
1701 case SSL_ERROR_SSL:
1702 BIO_printf(bio_s_out, "ERROR\n");
1703 ERR_print_errors(bio_err);
1704 ret = 1;
1705 goto err;
1706 /* break; */
1707 case SSL_ERROR_ZERO_RETURN:
1708 BIO_printf(bio_s_out, "DONE\n");
1709 ret = 1;
1710 goto err;
1711 }
1712 if (k <= 0)
1713 continue;
1714 l += k;
1715 i -= k;
1716 if (i <= 0)
1717 break;
1718 }
1719 }
1720 if (read_from_sslcon) {
1721 if (!SSL_is_init_finished(con)) {
1722 i = init_ssl_connection(con);
1723
1724 if (i < 0) {
1725 ret = 0;
1726 goto err;
1727 } else if (i == 0) {
1728 ret = 1;
1729 goto err;
1730 }
1731 } else {
1732 again:
1733 i = SSL_read(con, (char *) buf, bufsize);
1734 switch (SSL_get_error(con, i)) {
1735 case SSL_ERROR_NONE: {
1736 int len, n;
1737 for (len = 0; len < i;) {
1738 do {
1739 n = write(fileno(stdout), buf + len, i - len);
1740 } while (n == -1 && errno == EINTR);
1741
1742 if (n == -1) {
1743 BIO_printf(bio_s_out, "ERROR\n");
1744 goto err;
1745 }
1746 len += n;
1747 }
1748 }
1749 if (SSL_pending(con))
1750 goto again;
1751 break;
1752 case SSL_ERROR_WANT_WRITE:
1753 case SSL_ERROR_WANT_READ:
1754 BIO_printf(bio_s_out, "Read BLOCK\n");
1755 break;
1756 case SSL_ERROR_SYSCALL:
1757 case SSL_ERROR_SSL:
1758 BIO_printf(bio_s_out, "ERROR\n");
1759 ERR_print_errors(bio_err);
1760 ret = 1;
1761 goto err;
1762 case SSL_ERROR_ZERO_RETURN:
1763 BIO_printf(bio_s_out, "DONE\n");
1764 ret = 1;
1765 goto err;
1766 }
1767 }
1768 }
1769 }
1770 err:
1771 if (con != NULL) {
1772 BIO_printf(bio_s_out, "shutting down SSL\n");
1773 SSL_set_shutdown(con,
1774 SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
1775 SSL_free(con);
1776 }
1777 BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
1778 freezero(buf, bufsize);
1779 if (ret >= 0)
1780 BIO_printf(bio_s_out, "ACCEPT\n");
1781 return (ret);
1782}
1783
1784static void
1785close_accept_socket(void)
1786{
1787 BIO_printf(bio_err, "shutdown accept socket\n");
1788 if (accept_socket >= 0) {
1789 shutdown(accept_socket, SHUT_RDWR);
1790 close(accept_socket);
1791 }
1792}
1793
1794static int
1795init_ssl_connection(SSL *con)
1796{
1797 int i;
1798 const char *str;
1799 X509 *peer;
1800 long verify_error;
1801 char buf[BUFSIZ];
1802 unsigned char *exportedkeymat;
1803
1804 i = SSL_accept(con);
1805 if (i <= 0) {
1806 if (BIO_sock_should_retry(i)) {
1807 BIO_printf(bio_s_out, "DELAY\n");
1808 return (1);
1809 }
1810 BIO_printf(bio_err, "ERROR\n");
1811 verify_error = SSL_get_verify_result(con);
1812 if (verify_error != X509_V_OK) {
1813 BIO_printf(bio_err, "verify error:%s\n",
1814 X509_verify_cert_error_string(verify_error));
1815 } else
1816 ERR_print_errors(bio_err);
1817 return (0);
1818 }
1819 PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
1820
1821 peer = SSL_get_peer_certificate(con);
1822 if (peer != NULL) {
1823 BIO_printf(bio_s_out, "Client certificate\n");
1824 PEM_write_bio_X509(bio_s_out, peer);
1825 X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
1826 BIO_printf(bio_s_out, "subject=%s\n", buf);
1827 X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
1828 BIO_printf(bio_s_out, "issuer=%s\n", buf);
1829 X509_free(peer);
1830 }
1831 if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
1832 BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
1833 str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
1834 BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
1835
1836#ifndef OPENSSL_NO_SRTP
1837 {
1838 SRTP_PROTECTION_PROFILE *srtp_profile
1839 = SSL_get_selected_srtp_profile(con);
1840
1841 if (srtp_profile)
1842 BIO_printf(bio_s_out,
1843 "SRTP Extension negotiated, profile=%s\n",
1844 srtp_profile->name);
1845 }
1846#endif
1847 if (SSL_cache_hit(con))
1848 BIO_printf(bio_s_out, "Reused session-id\n");
1849 BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
1850 SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
1851 if (cfg.keymatexportlabel != NULL) {
1852 BIO_printf(bio_s_out, "Keying material exporter:\n");
1853 BIO_printf(bio_s_out, " Label: '%s'\n",
1854 cfg.keymatexportlabel);
1855 BIO_printf(bio_s_out, " Length: %i bytes\n",
1856 cfg.keymatexportlen);
1857 exportedkeymat = malloc(cfg.keymatexportlen);
1858 if (exportedkeymat != NULL) {
1859 if (!SSL_export_keying_material(con, exportedkeymat,
1860 cfg.keymatexportlen,
1861 cfg.keymatexportlabel,
1862 strlen(cfg.keymatexportlabel),
1863 NULL, 0, 0)) {
1864 BIO_printf(bio_s_out, " Error\n");
1865 } else {
1866 BIO_printf(bio_s_out, " Keying material: ");
1867 for (i = 0; i < cfg.keymatexportlen; i++)
1868 BIO_printf(bio_s_out, "%02X",
1869 exportedkeymat[i]);
1870 BIO_printf(bio_s_out, "\n");
1871 }
1872 free(exportedkeymat);
1873 }
1874 }
1875 return (1);
1876}
1877
1878#ifndef OPENSSL_NO_DH
1879static DH *
1880load_dh_param(const char *dhfile)
1881{
1882 DH *ret = NULL;
1883 BIO *bio;
1884
1885 if ((bio = BIO_new_file(dhfile, "r")) == NULL)
1886 goto err;
1887 ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1888 err:
1889 BIO_free(bio);
1890 return (ret);
1891}
1892#endif
1893
1894static int
1895www_body(int s, unsigned char *context)
1896{
1897 char *buf = NULL;
1898 int ret = 1;
1899 int i, j, k, dot;
1900 SSL *con;
1901 const SSL_CIPHER *c;
1902 BIO *io, *ssl_bio, *sbio;
1903
1904 buf = malloc(bufsize);
1905 if (buf == NULL)
1906 return (0);
1907 io = BIO_new(BIO_f_buffer());
1908 ssl_bio = BIO_new(BIO_f_ssl());
1909 if ((io == NULL) || (ssl_bio == NULL))
1910 goto err;
1911
1912 if (cfg.nbio) {
1913 if (!cfg.quiet)
1914 BIO_printf(bio_err, "turning on non blocking io\n");
1915 if (!BIO_socket_nbio(s, 1))
1916 ERR_print_errors(bio_err);
1917 }
1918
1919 /* lets make the output buffer a reasonable size */
1920 if (!BIO_set_write_buffer_size(io, bufsize))
1921 goto err;
1922
1923 if ((con = SSL_new(ctx)) == NULL)
1924 goto err;
1925 if (cfg.tlsextdebug) {
1926 SSL_set_tlsext_debug_callback(con, tlsext_cb);
1927 SSL_set_tlsext_debug_arg(con, bio_s_out);
1928 }
1929 if (context)
1930 SSL_set_session_id_context(con, context,
1931 strlen((char *) context));
1932
1933 sbio = BIO_new_socket(s, BIO_NOCLOSE);
1934 if (cfg.nbio_test) {
1935 BIO *test;
1936
1937 test = BIO_new(BIO_f_nbio_test());
1938 sbio = BIO_push(test, sbio);
1939 }
1940 SSL_set_bio(con, sbio, sbio);
1941 SSL_set_accept_state(con);
1942
1943 /* SSL_set_fd(con,s); */
1944 BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
1945 BIO_push(io, ssl_bio);
1946
1947 if (cfg.debug) {
1948 BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
1949 BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out);
1950 }
1951 if (cfg.msg) {
1952 SSL_set_msg_callback(con, msg_cb);
1953 SSL_set_msg_callback_arg(con, bio_s_out);
1954 }
1955 for (;;) {
1956 i = BIO_gets(io, buf, bufsize - 1);
1957 if (i < 0) { /* error */
1958 if (!BIO_should_retry(io)) {
1959 if (!cfg.quiet)
1960 ERR_print_errors(bio_err);
1961 goto err;
1962 } else {
1963 if (cfg.debug) {
1964 BIO_printf(bio_s_out, "read R BLOCK\n");
1965 sleep(1);
1966 }
1967 continue;
1968 }
1969 } else if (i == 0) { /* end of input */
1970 ret = 1;
1971 goto end;
1972 }
1973 /* else we have data */
1974 if (((cfg.www == 1) &&
1975 (strncmp("GET ", buf, 4) == 0)) ||
1976 ((cfg.www == 2) &&
1977 (strncmp("GET /stats ", buf, 11) == 0))) {
1978 char *p;
1979 X509 *peer;
1980 STACK_OF(SSL_CIPHER) *sk;
1981 static const char *space = " ";
1982
1983 BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
1984 BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
1985 BIO_puts(io, "<pre>\n");
1986/* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
1987 BIO_puts(io, "\n");
1988 for (i = 0; i < local_argc; i++) {
1989 BIO_puts(io, local_argv[i]);
1990 BIO_write(io, " ", 1);
1991 }
1992 BIO_puts(io, "\n");
1993
1994 BIO_printf(io,
1995 "Secure Renegotiation IS%s supported\n",
1996 SSL_get_secure_renegotiation_support(con) ?
1997 "" : " NOT");
1998
1999 /*
2000 * The following is evil and should not really be
2001 * done
2002 */
2003 BIO_printf(io,
2004 "Ciphers supported in s_server binary\n");
2005 sk = SSL_get_ciphers(con);
2006 j = sk_SSL_CIPHER_num(sk);
2007 for (i = 0; i < j; i++) {
2008 c = sk_SSL_CIPHER_value(sk, i);
2009 BIO_printf(io, "%-11s:%-25s",
2010 SSL_CIPHER_get_version(c),
2011 SSL_CIPHER_get_name(c));
2012 if ((((i + 1) % 2) == 0) && (i + 1 != j))
2013 BIO_puts(io, "\n");
2014 }
2015 BIO_puts(io, "\n");
2016 p = SSL_get_shared_ciphers(con, buf, bufsize);
2017 if (p != NULL) {
2018 BIO_printf(io,
2019 "---\nCiphers common between both SSL end points:\n");
2020 j = i = 0;
2021 while (*p) {
2022 if (*p == ':') {
2023 BIO_write(io, space, 26 - j);
2024 i++;
2025 j = 0;
2026 BIO_write(io,
2027 ((i % 3) ? " " : "\n"), 1);
2028 } else {
2029 BIO_write(io, p, 1);
2030 j++;
2031 }
2032 p++;
2033 }
2034 BIO_puts(io, "\n");
2035 }
2036 BIO_printf(io, (SSL_cache_hit(con)
2037 ? "---\nReused, "
2038 : "---\nNew, "));
2039 c = SSL_get_current_cipher(con);
2040 BIO_printf(io, "%s, Cipher is %s\n",
2041 SSL_CIPHER_get_version(c),
2042 SSL_CIPHER_get_name(c));
2043 SSL_SESSION_print(io, SSL_get_session(con));
2044 BIO_printf(io, "---\n");
2045 print_stats(io, SSL_get_SSL_CTX(con));
2046 BIO_printf(io, "---\n");
2047 peer = SSL_get_peer_certificate(con);
2048 if (peer != NULL) {
2049 BIO_printf(io, "Client certificate\n");
2050 X509_print(io, peer);
2051 PEM_write_bio_X509(io, peer);
2052 } else
2053 BIO_puts(io,
2054 "no client certificate available\n");
2055 BIO_puts(io, "</BODY></HTML>\r\n\r\n");
2056 break;
2057 } else if ((cfg.www == 2 ||
2058 cfg.www == 3) &&
2059 (strncmp("GET /", buf, 5) == 0)) {
2060 BIO *file;
2061 char *p, *e;
2062 static const char *text = "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
2063
2064 /* skip the '/' */
2065 p = &(buf[5]);
2066
2067 dot = 1;
2068 for (e = p; *e != '\0'; e++) {
2069 if (e[0] == ' ')
2070 break;
2071
2072 switch (dot) {
2073 case 1:
2074 dot = (e[0] == '.') ? 2 : 0;
2075 break;
2076 case 2:
2077 dot = (e[0] == '.') ? 3 : 0;
2078 break;
2079 case 3:
2080 dot = (e[0] == '/' || e[0] == '\\') ?
2081 -1 : 0;
2082 break;
2083 }
2084 if (dot == 0)
2085 dot = (e[0] == '/' || e[0] == '\\') ?
2086 1 : 0;
2087 }
2088 dot = (dot == 3) || (dot == -1); /* filename contains
2089 * ".." component */
2090
2091 if (*e == '\0') {
2092 BIO_puts(io, text);
2093 BIO_printf(io,
2094 "'%s' is an invalid file name\r\n", p);
2095 break;
2096 }
2097 *e = '\0';
2098
2099 if (dot) {
2100 BIO_puts(io, text);
2101 BIO_printf(io,
2102 "'%s' contains '..' reference\r\n", p);
2103 break;
2104 }
2105 if (*p == '/') {
2106 BIO_puts(io, text);
2107 BIO_printf(io,
2108 "'%s' is an invalid path\r\n", p);
2109 break;
2110 }
2111 /* if a directory, do the index thang */
2112 if (app_isdir(p) > 0) {
2113 BIO_puts(io, text);
2114 BIO_printf(io, "'%s' is a directory\r\n", p);
2115 break;
2116 }
2117 if ((file = BIO_new_file(p, "r")) == NULL) {
2118 BIO_puts(io, text);
2119 BIO_printf(io, "Error opening '%s'\r\n", p);
2120 ERR_print_errors(io);
2121 break;
2122 }
2123 if (!cfg.quiet)
2124 BIO_printf(bio_err, "FILE:%s\n", p);
2125
2126 if (cfg.www == 2) {
2127 i = strlen(p);
2128 if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
2129 ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
2130 ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
2131 BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
2132 else
2133 BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
2134 }
2135 /* send the file */
2136 for (;;) {
2137 i = BIO_read(file, buf, bufsize);
2138 if (i <= 0)
2139 break;
2140
2141#ifdef RENEG
2142 total_bytes += i;
2143 fprintf(stderr, "%d\n", i);
2144 if (total_bytes > 3 * 1024) {
2145 total_bytes = 0;
2146 fprintf(stderr, "RENEGOTIATE\n");
2147 SSL_renegotiate(con);
2148 }
2149#endif
2150
2151 for (j = 0; j < i;) {
2152#ifdef RENEG
2153 {
2154 static count = 0;
2155 if (++count == 13) {
2156 SSL_renegotiate(con);
2157 }
2158 }
2159#endif
2160 k = BIO_write(io, &(buf[j]), i - j);
2161 if (k <= 0) {
2162 if (!BIO_should_retry(io))
2163 goto write_error;
2164 else {
2165 BIO_printf(bio_s_out,
2166 "rwrite W BLOCK\n");
2167 }
2168 } else {
2169 j += k;
2170 }
2171 }
2172 }
2173 write_error:
2174 BIO_free(file);
2175 break;
2176 }
2177 }
2178
2179 for (;;) {
2180 i = (int) BIO_flush(io);
2181 if (i <= 0) {
2182 if (!BIO_should_retry(io))
2183 break;
2184 } else
2185 break;
2186 }
2187 end:
2188 /* make sure we re-use sessions */
2189 SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
2190
2191 err:
2192
2193 if (ret >= 0)
2194 BIO_printf(bio_s_out, "ACCEPT\n");
2195
2196 free(buf);
2197 BIO_free_all(io);
2198/* if (ssl_bio != NULL) BIO_free(ssl_bio);*/
2199 return (ret);
2200}
2201
2202#define MAX_SESSION_ID_ATTEMPTS 10
2203static int
2204generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len)
2205{
2206 unsigned int count = 0;
2207 do {
2208 arc4random_buf(id, *id_len);
2209 /*
2210 * Prefix the session_id with the required prefix. NB: If our
2211 * prefix is too long, clip it - but there will be worse
2212 * effects anyway, eg. the server could only possibly create
2213 * 1 session ID (ie. the prefix!) so all future session
2214 * negotiations will fail due to conflicts.
2215 */
2216 memcpy(id, cfg.session_id_prefix,
2217 (strlen(cfg.session_id_prefix) < *id_len) ?
2218 strlen(cfg.session_id_prefix) : *id_len);
2219 }
2220 while (SSL_has_matching_session_id(ssl, id, *id_len) &&
2221 (++count < MAX_SESSION_ID_ATTEMPTS));
2222 if (count >= MAX_SESSION_ID_ATTEMPTS)
2223 return 0;
2224 return 1;
2225}
2226
2227static int
2228ssl_servername_cb(SSL *s, int *ad, void *arg)
2229{
2230 tlsextctx *p = (tlsextctx *) arg;
2231 const char *servername = SSL_get_servername(s,
2232 TLSEXT_NAMETYPE_host_name);
2233
2234 if (servername && p->biodebug)
2235 BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
2236 servername);
2237
2238 if (!p->servername)
2239 return SSL_TLSEXT_ERR_NOACK;
2240
2241 if (servername) {
2242 if (strcmp(servername, p->servername))
2243 return p->extension_error;
2244 if (ctx2) {
2245 BIO_printf(p->biodebug, "Switching server context.\n");
2246 SSL_set_SSL_CTX(s, ctx2);
2247 }
2248 }
2249 return SSL_TLSEXT_ERR_OK;
2250}
2251
2252/* Certificate Status callback. This is called when a client includes a
2253 * certificate status request extension.
2254 *
2255 * This is a simplified version. It examines certificates each time and
2256 * makes one OCSP responder query for each request.
2257 *
2258 * A full version would store details such as the OCSP certificate IDs and
2259 * minimise the number of OCSP responses by caching them until they were
2260 * considered "expired".
2261 */
2262
2263static int
2264cert_status_cb(SSL *s, void *arg)
2265{
2266 tlsextstatusctx *srctx = arg;
2267 BIO *err = srctx->err;
2268 char *host = NULL, *port = NULL, *path = NULL;
2269 int use_ssl;
2270 unsigned char *rspder = NULL;
2271 int rspderlen;
2272 STACK_OF(OPENSSL_STRING) *aia = NULL;
2273 X509 *x = NULL;
2274 X509_STORE_CTX *inctx = NULL;
2275 X509_OBJECT *obj = NULL;
2276 OCSP_REQUEST *req = NULL;
2277 OCSP_RESPONSE *resp = NULL;
2278 OCSP_CERTID *id = NULL;
2279 STACK_OF(X509_EXTENSION) *exts;
2280 int ret = SSL_TLSEXT_ERR_NOACK;
2281 int i;
2282
2283 if (srctx->verbose)
2284 BIO_puts(err, "cert_status: callback called\n");
2285 /* Build up OCSP query from server certificate */
2286 x = SSL_get_certificate(s);
2287 aia = X509_get1_ocsp(x);
2288 if (aia) {
2289 if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
2290 &host, &port, &path, &use_ssl)) {
2291 BIO_puts(err, "cert_status: can't parse AIA URL\n");
2292 goto err;
2293 }
2294 if (srctx->verbose)
2295 BIO_printf(err, "cert_status: AIA URL: %s\n",
2296 sk_OPENSSL_STRING_value(aia, 0));
2297 } else {
2298 if (!srctx->host) {
2299 BIO_puts(srctx->err,
2300 "cert_status: no AIA and no default responder URL\n");
2301 goto done;
2302 }
2303 host = srctx->host;
2304 path = srctx->path;
2305 port = srctx->port;
2306 use_ssl = srctx->use_ssl;
2307 }
2308
2309 if ((inctx = X509_STORE_CTX_new()) == NULL)
2310 goto err;
2311
2312 if (!X509_STORE_CTX_init(inctx,
2313 SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
2314 NULL, NULL))
2315 goto err;
2316 if ((obj = X509_OBJECT_new()) == NULL)
2317 goto done;
2318 if (X509_STORE_get_by_subject(inctx, X509_LU_X509,
2319 X509_get_issuer_name(x), obj) <= 0) {
2320 BIO_puts(err,
2321 "cert_status: Can't retrieve issuer certificate.\n");
2322 X509_STORE_CTX_cleanup(inctx);
2323 goto done;
2324 }
2325 req = OCSP_REQUEST_new();
2326 if (!req)
2327 goto err;
2328 id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj));
2329 X509_OBJECT_free(obj);
2330 obj = NULL;
2331 X509_STORE_CTX_free(inctx);
2332 inctx = NULL;
2333 if (!id)
2334 goto err;
2335 if (!OCSP_request_add0_id(req, id))
2336 goto err;
2337 id = NULL;
2338 /* Add any extensions to the request */
2339 SSL_get_tlsext_status_exts(s, &exts);
2340 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
2341 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
2342 if (!OCSP_REQUEST_add_ext(req, ext, -1))
2343 goto err;
2344 }
2345 resp = process_responder(err, req, host, path, port, use_ssl, NULL,
2346 srctx->timeout);
2347 if (!resp) {
2348 BIO_puts(err, "cert_status: error querying responder\n");
2349 goto done;
2350 }
2351 rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
2352 if (rspderlen <= 0)
2353 goto err;
2354 SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
2355 if (srctx->verbose) {
2356 BIO_puts(err, "cert_status: ocsp response sent:\n");
2357 OCSP_RESPONSE_print(err, resp, 2);
2358 }
2359 ret = SSL_TLSEXT_ERR_OK;
2360 done:
2361 X509_STORE_CTX_free(inctx);
2362 X509_OBJECT_free(obj);
2363 if (ret != SSL_TLSEXT_ERR_OK)
2364 ERR_print_errors(err);
2365 if (aia) {
2366 free(host);
2367 free(path);
2368 free(port);
2369 X509_email_free(aia);
2370 }
2371 if (id)
2372 OCSP_CERTID_free(id);
2373 if (req)
2374 OCSP_REQUEST_free(req);
2375 if (resp)
2376 OCSP_RESPONSE_free(resp);
2377 return ret;
2378 err:
2379 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
2380 goto done;
2381}
2382
2383static int
2384alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
2385 const unsigned char *in, unsigned int inlen, void *arg)
2386{
2387 tlsextalpnctx *alpn_ctx = arg;
2388
2389 if (!cfg.quiet) {
2390 /* We can assume that in is syntactically valid. */
2391 unsigned i;
2392
2393 BIO_printf(bio_s_out,
2394 "ALPN protocols advertised by the client: ");
2395 for (i = 0; i < inlen; ) {
2396 if (i)
2397 BIO_write(bio_s_out, ", ", 2);
2398 BIO_write(bio_s_out, &in[i + 1], in[i]);
2399 i += in[i] + 1;
2400 }
2401 BIO_write(bio_s_out, "\n", 1);
2402 }
2403
2404 if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data,
2405 alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED)
2406 return (SSL_TLSEXT_ERR_NOACK);
2407
2408 if (!cfg.quiet) {
2409 BIO_printf(bio_s_out, "ALPN protocols selected: ");
2410 BIO_write(bio_s_out, *out, *outlen);
2411 BIO_write(bio_s_out, "\n", 1);
2412 }
2413
2414 return (SSL_TLSEXT_ERR_OK);
2415}
diff --git a/src/usr.bin/openssl/s_socket.c b/src/usr.bin/openssl/s_socket.c
deleted file mode 100644
index 86a23c56d1..0000000000
--- a/src/usr.bin/openssl/s_socket.c
+++ /dev/null
@@ -1,325 +0,0 @@
1/* $OpenBSD: s_socket.c,v 1.14 2025/01/02 13:10:03 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <sys/socket.h>
60
61#include <netinet/in.h>
62
63#include <errno.h>
64#include <netdb.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
68#include <unistd.h>
69
70#include "apps.h"
71
72#include <openssl/ssl.h>
73
74static int init_server(int *sock, int port, int type);
75static int init_server_long(int *sock, int port, char *ip, int type);
76static int do_accept(int acc_sock, int *sock);
77
78int
79init_client(int *sock, char *host, char *port, int type, int af)
80{
81 struct addrinfo hints, *ai_top, *ai;
82 int i, s = -1;
83
84 memset(&hints, '\0', sizeof(hints));
85 hints.ai_family = af;
86 hints.ai_socktype = type;
87
88 if ((i = getaddrinfo(host, port, &hints, &ai_top)) != 0) {
89 BIO_printf(bio_err, "getaddrinfo: %s\n", gai_strerror(i));
90 return (0);
91 }
92 if (ai_top == NULL || ai_top->ai_addr == NULL) {
93 BIO_printf(bio_err, "getaddrinfo returned no addresses\n");
94 if (ai_top != NULL) {
95 freeaddrinfo(ai_top);
96 }
97 return (0);
98 }
99 for (ai = ai_top; ai != NULL; ai = ai->ai_next) {
100 s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
101 if (s == -1) {
102 continue;
103 }
104 if (type == SOCK_STREAM) {
105 i = 0;
106 i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
107 (char *) &i, sizeof(i));
108 if (i == -1) {
109 perror("keepalive");
110 goto out;
111 }
112 }
113 if ((i = connect(s, ai->ai_addr, ai->ai_addrlen)) == 0) {
114 *sock = s;
115 freeaddrinfo(ai_top);
116 return (1);
117 }
118 close(s);
119 s = -1;
120 }
121
122 perror("connect");
123 out:
124 if (s != -1)
125 close(s);
126 freeaddrinfo(ai_top);
127 return (0);
128}
129
130int
131do_server(int port, int type, int *ret,
132 int (*cb)(int s, unsigned char *context),
133 unsigned char *context, int naccept)
134{
135 int sock;
136 int accept_socket = 0;
137 int i;
138
139 if (!init_server(&accept_socket, port, type))
140 return (0);
141
142 if (ret != NULL) {
143 *ret = accept_socket;
144 /* return(1); */
145 }
146 for (;;) {
147 if (type == SOCK_STREAM) {
148 if (do_accept(accept_socket, &sock) == 0) {
149 shutdown(accept_socket, SHUT_RD);
150 close(accept_socket);
151 return (0);
152 }
153 } else
154 sock = accept_socket;
155 i = cb(sock, context);
156 if (type == SOCK_STREAM) {
157 shutdown(sock, SHUT_RDWR);
158 close(sock);
159 }
160 if (naccept != -1)
161 naccept--;
162 if (i < 0 || naccept == 0) {
163 shutdown(accept_socket, SHUT_RDWR);
164 close(accept_socket);
165 return (i);
166 }
167 }
168}
169
170static int
171init_server_long(int *sock, int port, char *ip, int type)
172{
173 int ret = 0;
174 struct sockaddr_in server;
175 int s = -1;
176
177 memset((char *) &server, 0, sizeof(server));
178 server.sin_family = AF_INET;
179 server.sin_port = htons((unsigned short) port);
180 if (ip == NULL)
181 server.sin_addr.s_addr = INADDR_ANY;
182 else
183 memcpy(&server.sin_addr.s_addr, ip, 4);
184
185 if (type == SOCK_STREAM)
186 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
187 else /* type == SOCK_DGRAM */
188 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
189
190 if (s == -1)
191 goto err;
192#if defined SOL_SOCKET && defined SO_REUSEADDR
193 {
194 int j = 1;
195 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
196 (void *) &j, sizeof j) == -1) {
197 perror("setsockopt");
198 goto err;
199 }
200 }
201#endif
202 if (bind(s, (struct sockaddr *) & server, sizeof(server)) == -1) {
203 perror("bind");
204 goto err;
205 }
206 /* Make it 128 for linux */
207 if (type == SOCK_STREAM && listen(s, 128) == -1)
208 goto err;
209 *sock = s;
210 ret = 1;
211 err:
212 if ((ret == 0) && (s != -1)) {
213 shutdown(s, SHUT_RD);
214 close(s);
215 }
216 return (ret);
217}
218
219static int
220init_server(int *sock, int port, int type)
221{
222 return (init_server_long(sock, port, NULL, type));
223}
224
225static int
226do_accept(int acc_sock, int *sock)
227{
228 struct hostent *h1, *h2;
229 static struct sockaddr_in from;
230 socklen_t len;
231 char *host = NULL;
232 int ret;
233
234 redoit:
235
236 memset((char *) &from, 0, sizeof(from));
237 len = sizeof(from);
238 ret = accept(acc_sock, (struct sockaddr *) & from, &len);
239 if (ret == -1) {
240 if (errno == EINTR) {
241 /* check_timeout(); */
242 goto redoit;
243 }
244 fprintf(stderr, "errno=%d ", errno);
245 perror("accept");
246 return (0);
247 }
248
249 h1 = gethostbyaddr((char *) &from.sin_addr.s_addr,
250 sizeof(from.sin_addr.s_addr), AF_INET);
251 if (h1 == NULL) {
252 BIO_printf(bio_err, "bad gethostbyaddr\n");
253 } else {
254 if ((host = strdup(h1->h_name)) == NULL) {
255 perror("strdup");
256 close(ret);
257 return (0);
258 }
259
260 h2 = gethostbyname(host);
261 if (h2 == NULL) {
262 BIO_printf(bio_err, "gethostbyname failure\n");
263 close(ret);
264 free(host);
265 return (0);
266 }
267 if (h2->h_addrtype != AF_INET) {
268 BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n");
269 close(ret);
270 free(host);
271 return (0);
272 }
273 }
274
275 free(host);
276 *sock = ret;
277 return (1);
278}
279
280int
281extract_host_port(char *str, char **host_ptr, unsigned char *ip,
282 char **port_ptr)
283{
284 char *h, *p;
285
286 h = str;
287 p = strrchr(str, '/'); /* IPv6 host/port */
288 if (p == NULL) {
289 p = strrchr(str, ':');
290 }
291 if (p == NULL) {
292 BIO_printf(bio_err, "no port defined\n");
293 return (0);
294 }
295 *(p++) = '\0';
296
297 if (host_ptr != NULL)
298 *host_ptr = h;
299
300 if (port_ptr != NULL && p != NULL && *p != '\0')
301 *port_ptr = p;
302
303 return (1);
304}
305
306int
307extract_port(char *str, short *port_ptr)
308{
309 int i;
310 const char *errstr;
311 struct servent *s;
312
313 i = strtonum(str, 1, 65535, &errstr);
314 if (!errstr) {
315 *port_ptr = (unsigned short) i;
316 } else {
317 s = getservbyname(str, "tcp");
318 if (s == NULL) {
319 BIO_printf(bio_err, "getservbyname failure for %s\n", str);
320 return (0);
321 }
322 *port_ptr = ntohs((unsigned short) s->s_port);
323 }
324 return (1);
325}
diff --git a/src/usr.bin/openssl/s_time.c b/src/usr.bin/openssl/s_time.c
deleted file mode 100644
index c90be33f28..0000000000
--- a/src/usr.bin/openssl/s_time.c
+++ /dev/null
@@ -1,463 +0,0 @@
1/* $OpenBSD: s_time.c,v 1.39 2025/01/02 13:10:03 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/*-----------------------------------------
60 s_time - SSL client connection timer program
61 Written and donated by Larry Streepy <streepy@healthcare.com>
62 -----------------------------------------*/
63
64#include <sys/types.h>
65#include <sys/socket.h>
66
67#include <stdio.h>
68#include <stdlib.h>
69#include <limits.h>
70#include <string.h>
71#include <unistd.h>
72#include <poll.h>
73
74#include "apps.h"
75
76#include <openssl/err.h>
77#include <openssl/pem.h>
78#include <openssl/ssl.h>
79#include <openssl/x509.h>
80
81#define SSL_CONNECT_NAME "localhost:4433"
82
83#define BUFSIZZ 1024*10
84
85#define MYBUFSIZ 1024*8
86
87#define SECONDS 30
88extern int verify_depth;
89
90static void s_time_usage(void);
91static int run_test(SSL *);
92static int benchmark(int);
93static void print_tally_mark(SSL *);
94
95static SSL_CTX *tm_ctx = NULL;
96static const SSL_METHOD *s_time_meth = NULL;
97static long bytes_read = 0;
98
99static struct {
100 int bugs;
101 char *CAfile;
102 char *CApath;
103 char *certfile;
104 char *cipher;
105 char *host;
106 char *keyfile;
107 time_t maxtime;
108 int nbio;
109 int no_shutdown;
110 int perform;
111 int verify;
112 int verify_depth;
113 char *www_path;
114} cfg;
115
116static const struct option s_time_options[] = {
117 {
118 .name = "bugs",
119 .desc = "Enable workarounds for known SSL/TLS bugs",
120 .type = OPTION_FLAG,
121 .opt.flag = &cfg.bugs,
122 },
123 {
124 .name = "CAfile",
125 .argname = "file",
126 .desc = "File containing trusted certificates in PEM format",
127 .type = OPTION_ARG,
128 .opt.arg = &cfg.CAfile,
129 },
130 {
131 .name = "CApath",
132 .argname = "path",
133 .desc = "Directory containing trusted certificates",
134 .type = OPTION_ARG,
135 .opt.arg = &cfg.CApath,
136 },
137 {
138 .name = "cert",
139 .argname = "file",
140 .desc = "Client certificate to use, if one is requested",
141 .type = OPTION_ARG,
142 .opt.arg = &cfg.certfile,
143 },
144 {
145 .name = "cipher",
146 .argname = "list",
147 .desc = "List of cipher suites to send to the server",
148 .type = OPTION_ARG,
149 .opt.arg = &cfg.cipher,
150 },
151 {
152 .name = "connect",
153 .argname = "host:port",
154 .desc = "Host and port to connect to (default "
155 SSL_CONNECT_NAME ")",
156 .type = OPTION_ARG,
157 .opt.arg = &cfg.host,
158 },
159 {
160 .name = "key",
161 .argname = "file",
162 .desc = "Client private key to use, if one is required",
163 .type = OPTION_ARG,
164 .opt.arg = &cfg.keyfile,
165 },
166 {
167 .name = "nbio",
168 .desc = "Use non-blocking I/O",
169 .type = OPTION_FLAG,
170 .opt.flag = &cfg.nbio,
171 },
172 {
173 .name = "new",
174 .desc = "Use a new session ID for each connection",
175 .type = OPTION_VALUE,
176 .opt.value = &cfg.perform,
177 .value = 1,
178 },
179 {
180 .name = "no_shutdown",
181 .desc = "Shut down the connection without notifying the server",
182 .type = OPTION_FLAG,
183 .opt.flag = &cfg.no_shutdown,
184 },
185 {
186 .name = "reuse",
187 .desc = "Reuse the same session ID for each connection",
188 .type = OPTION_VALUE,
189 .opt.value = &cfg.perform,
190 .value = 2,
191 },
192 {
193 .name = "time",
194 .argname = "seconds",
195 .desc = "Duration to perform timing tests for (default 30)",
196 .type = OPTION_ARG_TIME,
197 .opt.tvalue = &cfg.maxtime,
198 },
199 {
200 .name = "verify",
201 .argname = "depth",
202 .desc = "Enable peer certificate verification with given depth",
203 .type = OPTION_ARG_INT,
204 .opt.value = &cfg.verify_depth,
205 },
206 {
207 .name = "www",
208 .argname = "page",
209 .desc = "Page to GET from the server (default none)",
210 .type = OPTION_ARG,
211 .opt.arg = &cfg.www_path,
212 },
213 { NULL },
214};
215
216static void
217s_time_usage(void)
218{
219 fprintf(stderr,
220 "usage: s_time "
221 "[-bugs] [-CAfile file] [-CApath directory] [-cert file]\n"
222 " [-cipher cipherlist] [-connect host:port] [-key keyfile]\n"
223 " [-nbio] [-new] [-no_shutdown] [-reuse] [-time seconds]\n"
224 " [-verify depth] [-www page]\n\n");
225 options_usage(s_time_options);
226}
227
228/***********************************************************************
229 * MAIN - main processing area for client
230 * real name depends on MONOLITH
231 */
232int
233s_time_main(int argc, char **argv)
234{
235 int ret = 1;
236
237 if (pledge("stdio rpath inet dns", NULL) == -1) {
238 perror("pledge");
239 exit(1);
240 }
241
242 s_time_meth = TLS_client_method();
243
244 verify_depth = 0;
245
246 memset(&cfg, 0, sizeof(cfg));
247
248 cfg.host = SSL_CONNECT_NAME;
249 cfg.maxtime = SECONDS;
250 cfg.perform = 3;
251 cfg.verify = SSL_VERIFY_NONE;
252 cfg.verify_depth = -1;
253
254 if (options_parse(argc, argv, s_time_options, NULL, NULL) != 0) {
255 s_time_usage();
256 goto end;
257 }
258
259 if (cfg.verify_depth >= 0) {
260 cfg.verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
261 verify_depth = cfg.verify_depth;
262 BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
263 }
264
265 if (cfg.www_path != NULL &&
266 strlen(cfg.www_path) > MYBUFSIZ - 100) {
267 BIO_printf(bio_err, "-www option too long\n");
268 goto end;
269 }
270
271 if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL)
272 return (1);
273
274 SSL_CTX_set_quiet_shutdown(tm_ctx, 1);
275
276 if (cfg.bugs)
277 SSL_CTX_set_options(tm_ctx, SSL_OP_ALL);
278
279 if (cfg.cipher != NULL) {
280 if (!SSL_CTX_set_cipher_list(tm_ctx, cfg.cipher)) {
281 BIO_printf(bio_err, "error setting cipher list\n");
282 ERR_print_errors(bio_err);
283 goto end;
284 }
285 }
286
287 SSL_CTX_set_verify(tm_ctx, cfg.verify, NULL);
288
289 if (!set_cert_stuff(tm_ctx, cfg.certfile,
290 cfg.keyfile))
291 goto end;
292
293 if ((!SSL_CTX_load_verify_locations(tm_ctx, cfg.CAfile,
294 cfg.CApath)) ||
295 (!SSL_CTX_set_default_verify_paths(tm_ctx))) {
296 /*
297 * BIO_printf(bio_err,"error setting default verify
298 * locations\n");
299 */
300 ERR_print_errors(bio_err);
301 /* goto end; */
302 }
303
304 /* Loop and time how long it takes to make connections */
305 if (cfg.perform & 1) {
306 printf("Collecting connection statistics for %lld seconds\n",
307 (long long)cfg.maxtime);
308 if (benchmark(0))
309 goto end;
310 }
311 /*
312 * Now loop and time connections using the same session id over and
313 * over
314 */
315 if (cfg.perform & 2) {
316 printf("\n\nNow timing with session id reuse.\n");
317 if (benchmark(1))
318 goto end;
319 }
320 ret = 0;
321 end:
322 if (tm_ctx != NULL) {
323 SSL_CTX_free(tm_ctx);
324 tm_ctx = NULL;
325 }
326
327 return (ret);
328}
329
330/***********************************************************************
331 * run_test - make a connection, get a file, and shut down the connection
332 *
333 * Args:
334 * scon = SSL connection
335 * Returns:
336 * 1 on success, 0 on error
337 */
338static int
339run_test(SSL *scon)
340{
341 char buf[1024 * 8];
342 struct pollfd pfd[1];
343 BIO *conn;
344 long verify_error;
345 int i, retval;
346
347 if ((conn = BIO_new(BIO_s_connect())) == NULL)
348 return 0;
349 BIO_set_conn_hostname(conn, cfg.host);
350 SSL_set_connect_state(scon);
351 SSL_set_bio(scon, conn, conn);
352 for (;;) {
353 i = SSL_connect(scon);
354 if (BIO_sock_should_retry(i)) {
355 BIO_printf(bio_err, "DELAY\n");
356 pfd[0].fd = SSL_get_fd(scon);
357 pfd[0].events = POLLIN;
358 poll(pfd, 1, -1);
359 continue;
360 }
361 break;
362 }
363 if (i <= 0) {
364 BIO_printf(bio_err, "ERROR\n");
365 verify_error = SSL_get_verify_result(scon);
366 if (verify_error != X509_V_OK)
367 BIO_printf(bio_err, "verify error:%s\n",
368 X509_verify_cert_error_string(verify_error));
369 else
370 ERR_print_errors(bio_err);
371 return 0;
372 }
373 if (cfg.www_path != NULL) {
374 retval = snprintf(buf, sizeof buf,
375 "GET %s HTTP/1.0\r\n\r\n", cfg.www_path);
376 if (retval < 0 || retval >= sizeof buf) {
377 fprintf(stderr, "URL too long\n");
378 return 0;
379 }
380 if (SSL_write(scon, buf, retval) != retval)
381 return 0;
382 while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
383 bytes_read += i;
384 }
385 if (cfg.no_shutdown)
386 SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN |
387 SSL_RECEIVED_SHUTDOWN);
388 else
389 SSL_shutdown(scon);
390 return 1;
391}
392
393static void
394print_tally_mark(SSL *scon)
395{
396 int ver;
397
398 if (SSL_session_reused(scon))
399 ver = 'r';
400 else {
401 ver = SSL_version(scon);
402 if (ver == TLS1_VERSION)
403 ver = 't';
404 else
405 ver = '*';
406 }
407 fputc(ver, stdout);
408 fflush(stdout);
409}
410
411static int
412benchmark(int reuse_session)
413{
414 double elapsed, totalTime;
415 int nConn = 0;
416 SSL *scon = NULL;
417 int ret = 1;
418
419 if (reuse_session) {
420 /* Get an SSL object so we can reuse the session id */
421 if ((scon = SSL_new(tm_ctx)) == NULL)
422 goto end;
423 if (!run_test(scon)) {
424 fprintf(stderr, "Unable to get connection\n");
425 goto end;
426 }
427 printf("starting\n");
428 }
429
430 nConn = 0;
431 bytes_read = 0;
432
433 app_timer_real(TM_RESET);
434 app_timer_user(TM_RESET);
435 for (;;) {
436 elapsed = app_timer_real(TM_GET);
437 if (elapsed > cfg.maxtime)
438 break;
439 if (scon == NULL) {
440 if ((scon = SSL_new(tm_ctx)) == NULL)
441 goto end;
442 }
443 if (!run_test(scon))
444 goto end;
445 nConn += 1;
446 print_tally_mark(scon);
447 if (!reuse_session) {
448 SSL_free(scon);
449 scon = NULL;
450 }
451 }
452 totalTime = app_timer_user(TM_GET);
453
454 printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
455 nConn, totalTime, ((double) nConn / totalTime), bytes_read);
456 printf("%d connections in %.0f real seconds, %ld bytes read per connection\n",
457 nConn, elapsed, nConn > 0 ? bytes_read / nConn : 0);
458
459 ret = 0;
460 end:
461 SSL_free(scon);
462 return ret;
463}
diff --git a/src/usr.bin/openssl/sess_id.c b/src/usr.bin/openssl/sess_id.c
deleted file mode 100644
index 26db2fa10f..0000000000
--- a/src/usr.bin/openssl/sess_id.c
+++ /dev/null
@@ -1,292 +0,0 @@
1/* $OpenBSD: sess_id.c,v 1.13 2025/01/02 12:31:44 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include "apps.h"
64
65#include <openssl/bio.h>
66#include <openssl/err.h>
67#include <openssl/pem.h>
68#include <openssl/ssl.h>
69#include <openssl/x509.h>
70
71static struct {
72 int cert;
73 char *context;
74 char *infile;
75 int informat;
76 int noout;
77 char *outfile;
78 int outformat;
79 int text;
80} cfg;
81
82static const struct option sess_id_options[] = {
83 {
84 .name = "cert",
85 .desc = "Output certificate if present in session",
86 .type = OPTION_FLAG,
87 .opt.flag = &cfg.cert,
88 },
89 {
90 .name = "context",
91 .argname = "id",
92 .desc = "Set the session ID context for output",
93 .type = OPTION_ARG,
94 .opt.arg = &cfg.context,
95 },
96 {
97 .name = "in",
98 .argname = "file",
99 .desc = "Input file (default stdin)",
100 .type = OPTION_ARG,
101 .opt.arg = &cfg.infile,
102 },
103 {
104 .name = "inform",
105 .argname = "format",
106 .desc = "Input format (DER or PEM (default))",
107 .type = OPTION_ARG_FORMAT,
108 .opt.value = &cfg.informat,
109 },
110 {
111 .name = "noout",
112 .desc = "Do not output the encoded session info",
113 .type = OPTION_FLAG,
114 .opt.flag = &cfg.noout,
115 },
116 {
117 .name = "out",
118 .argname = "file",
119 .desc = "Output file (default stdout)",
120 .type = OPTION_ARG,
121 .opt.arg = &cfg.outfile,
122 },
123 {
124 .name = "outform",
125 .argname = "format",
126 .desc = "Output format (DER or PEM (default))",
127 .type = OPTION_ARG_FORMAT,
128 .opt.value = &cfg.outformat,
129 },
130 {
131 .name = "text",
132 .desc = "Print various public or private key components in"
133 " plain text",
134 .type = OPTION_FLAG,
135 .opt.flag = &cfg.text,
136 },
137 { NULL }
138};
139
140static void
141sess_id_usage(void)
142{
143 fprintf(stderr,
144 "usage: sess_id [-cert] [-context id] [-in file] [-inform fmt] "
145 "[-noout]\n"
146 " [-out file] [-outform fmt] [-text]\n\n");
147 options_usage(sess_id_options);
148}
149
150static SSL_SESSION *load_sess_id(char *file, int format);
151
152int
153sess_id_main(int argc, char **argv)
154{
155 SSL_SESSION *x = NULL;
156 X509 *peer = NULL;
157 int ret = 1, i;
158 BIO *out = NULL;
159
160 if (pledge("stdio cpath wpath rpath", NULL) == -1) {
161 perror("pledge");
162 exit(1);
163 }
164
165 memset(&cfg, 0, sizeof(cfg));
166
167 cfg.informat = FORMAT_PEM;
168 cfg.outformat = FORMAT_PEM;
169
170 if (options_parse(argc, argv, sess_id_options, NULL, NULL) != 0) {
171 sess_id_usage();
172 return (1);
173 }
174
175 x = load_sess_id(cfg.infile, cfg.informat);
176 if (x == NULL) {
177 goto end;
178 }
179 peer = SSL_SESSION_get0_peer(x);
180
181 if (cfg.context) {
182 size_t ctx_len = strlen(cfg.context);
183 if (ctx_len > SSL_MAX_SID_CTX_LENGTH) {
184 BIO_printf(bio_err, "Context too long\n");
185 goto end;
186 }
187 SSL_SESSION_set1_id_context(x,
188 (unsigned char *)cfg.context, ctx_len);
189 }
190
191 if (!cfg.noout || cfg.text) {
192 out = BIO_new(BIO_s_file());
193 if (out == NULL) {
194 ERR_print_errors(bio_err);
195 goto end;
196 }
197 if (cfg.outfile == NULL) {
198 BIO_set_fp(out, stdout, BIO_NOCLOSE);
199 } else {
200 if (BIO_write_filename(out, cfg.outfile)
201 <= 0) {
202 perror(cfg.outfile);
203 goto end;
204 }
205 }
206 }
207 if (cfg.text) {
208 SSL_SESSION_print(out, x);
209
210 if (cfg.cert) {
211 if (peer == NULL)
212 BIO_puts(out, "No certificate present\n");
213 else
214 X509_print(out, peer);
215 }
216 }
217 if (!cfg.noout && !cfg.cert) {
218 if (cfg.outformat == FORMAT_ASN1)
219 i = i2d_SSL_SESSION_bio(out, x);
220 else if (cfg.outformat == FORMAT_PEM)
221 i = PEM_write_bio_SSL_SESSION(out, x);
222 else {
223 BIO_printf(bio_err,
224 "bad output format specified for outfile\n");
225 goto end;
226 }
227 if (!i) {
228 BIO_printf(bio_err, "unable to write SSL_SESSION\n");
229 goto end;
230 }
231 } else if (!cfg.noout && (peer != NULL)) {
232 /* just print the certificate */
233 if (cfg.outformat == FORMAT_ASN1)
234 i = (int) i2d_X509_bio(out, peer);
235 else if (cfg.outformat == FORMAT_PEM)
236 i = PEM_write_bio_X509(out, peer);
237 else {
238 BIO_printf(bio_err,
239 "bad output format specified for outfile\n");
240 goto end;
241 }
242 if (!i) {
243 BIO_printf(bio_err, "unable to write X509\n");
244 goto end;
245 }
246 }
247 ret = 0;
248
249 end:
250 BIO_free_all(out);
251 SSL_SESSION_free(x);
252
253 return (ret);
254}
255
256static SSL_SESSION *
257load_sess_id(char *infile, int format)
258{
259 SSL_SESSION *x = NULL;
260 BIO *in = NULL;
261
262 in = BIO_new(BIO_s_file());
263 if (in == NULL) {
264 ERR_print_errors(bio_err);
265 goto end;
266 }
267 if (infile == NULL)
268 BIO_set_fp(in, stdin, BIO_NOCLOSE);
269 else {
270 if (BIO_read_filename(in, infile) <= 0) {
271 perror(infile);
272 goto end;
273 }
274 }
275 if (format == FORMAT_ASN1)
276 x = d2i_SSL_SESSION_bio(in, NULL);
277 else if (format == FORMAT_PEM)
278 x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
279 else {
280 BIO_printf(bio_err,
281 "bad input format specified for input crl\n");
282 goto end;
283 }
284 if (x == NULL) {
285 BIO_printf(bio_err, "unable to load SSL_SESSION\n");
286 ERR_print_errors(bio_err);
287 goto end;
288 }
289 end:
290 BIO_free(in);
291 return (x);
292}
diff --git a/src/usr.bin/openssl/smime.c b/src/usr.bin/openssl/smime.c
deleted file mode 100644
index 46bfa08679..0000000000
--- a/src/usr.bin/openssl/smime.c
+++ /dev/null
@@ -1,1103 +0,0 @@
1/* $OpenBSD: smime.c,v 1.20 2023/04/14 15:27:13 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59/* S/MIME utility function */
60
61#include <stdio.h>
62#include <string.h>
63
64#include "apps.h"
65
66#include <openssl/crypto.h>
67#include <openssl/err.h>
68#include <openssl/pem.h>
69#include <openssl/x509_vfy.h>
70#include <openssl/x509v3.h>
71
72static int save_certs(char *signerfile, STACK_OF(X509) *signers);
73
74#define SMIME_OP 0x10
75#define SMIME_IP 0x20
76#define SMIME_SIGNERS 0x40
77#define SMIME_ENCRYPT (1 | SMIME_OP)
78#define SMIME_DECRYPT (2 | SMIME_IP)
79#define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS)
80#define SMIME_VERIFY (4 | SMIME_IP)
81#define SMIME_PK7OUT (5 | SMIME_IP | SMIME_OP)
82#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
83
84static struct {
85 char *CAfile;
86 char *CApath;
87 char *certfile;
88 const EVP_CIPHER *cipher;
89 char *contfile;
90 int flags;
91 char *from;
92 int indef;
93 char *infile;
94 int informat;
95 char *keyfile;
96 int keyform;
97 int operation;
98 char *outfile;
99 int outformat;
100 char *passargin;
101 char *recipfile;
102 const EVP_MD *sign_md;
103 char *signerfile;
104 STACK_OF(OPENSSL_STRING) *skkeys;
105 STACK_OF(OPENSSL_STRING) *sksigners;
106 char *subject;
107 char *to;
108 X509_VERIFY_PARAM *vpm;
109} cfg;
110
111static const EVP_CIPHER *
112get_cipher_by_name(char *name)
113{
114 if (name == NULL || strcmp(name, "") == 0)
115 return (NULL);
116#ifndef OPENSSL_NO_AES
117 else if (strcmp(name, "aes128") == 0)
118 return EVP_aes_128_cbc();
119 else if (strcmp(name, "aes192") == 0)
120 return EVP_aes_192_cbc();
121 else if (strcmp(name, "aes256") == 0)
122 return EVP_aes_256_cbc();
123#endif
124#ifndef OPENSSL_NO_CAMELLIA
125 else if (strcmp(name, "camellia128") == 0)
126 return EVP_camellia_128_cbc();
127 else if (strcmp(name, "camellia192") == 0)
128 return EVP_camellia_192_cbc();
129 else if (strcmp(name, "camellia256") == 0)
130 return EVP_camellia_256_cbc();
131#endif
132#ifndef OPENSSL_NO_DES
133 else if (strcmp(name, "des") == 0)
134 return EVP_des_cbc();
135 else if (strcmp(name, "des3") == 0)
136 return EVP_des_ede3_cbc();
137#endif
138#ifndef OPENSSL_NO_RC2
139 else if (!strcmp(name, "rc2-40"))
140 return EVP_rc2_40_cbc();
141 else if (!strcmp(name, "rc2-64"))
142 return EVP_rc2_64_cbc();
143 else if (!strcmp(name, "rc2-128"))
144 return EVP_rc2_cbc();
145#endif
146 else
147 return NULL;
148}
149
150static int
151smime_opt_cipher(int argc, char **argv, int *argsused)
152{
153 char *name = argv[0];
154
155 if (*name++ != '-')
156 return (1);
157
158 if ((cfg.cipher = get_cipher_by_name(name)) == NULL)
159 if ((cfg.cipher = EVP_get_cipherbyname(name)) == NULL)
160 return (1);
161
162 *argsused = 1;
163 return (0);
164}
165
166static int
167smime_opt_inkey(char *arg)
168{
169 if (cfg.keyfile == NULL) {
170 cfg.keyfile = arg;
171 return (0);
172 }
173
174 if (cfg.signerfile == NULL) {
175 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
176 return (1);
177 }
178
179 if (cfg.sksigners == NULL) {
180 if ((cfg.sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
181 return (1);
182 }
183 if (!sk_OPENSSL_STRING_push(cfg.sksigners,
184 cfg.signerfile))
185 return (1);
186
187 cfg.signerfile = NULL;
188
189 if (cfg.skkeys == NULL) {
190 if ((cfg.skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
191 return (1);
192 }
193 if (!sk_OPENSSL_STRING_push(cfg.skkeys, cfg.keyfile))
194 return (1);
195
196 cfg.keyfile = arg;
197 return (0);
198}
199
200static int
201smime_opt_md(char *arg)
202{
203 if ((cfg.sign_md = EVP_get_digestbyname(arg)) == NULL) {
204 BIO_printf(bio_err, "Unknown digest %s\n", arg);
205 return (1);
206 }
207 return (0);
208}
209
210static int
211smime_opt_signer(char *arg)
212{
213 if (cfg.signerfile == NULL) {
214 cfg.signerfile = arg;
215 return (0);
216 }
217
218 if (cfg.sksigners == NULL) {
219 if ((cfg.sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
220 return (1);
221 }
222 if (!sk_OPENSSL_STRING_push(cfg.sksigners,
223 cfg.signerfile))
224 return (1);
225
226 if (cfg.keyfile == NULL)
227 cfg.keyfile = cfg.signerfile;
228
229 if (cfg.skkeys == NULL) {
230 if ((cfg.skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
231 return (1);
232 }
233 if (!sk_OPENSSL_STRING_push(cfg.skkeys, cfg.keyfile))
234 return (1);
235
236 cfg.keyfile = NULL;
237
238 cfg.signerfile = arg;
239 return (0);
240}
241
242static int
243smime_opt_verify_param(int argc, char **argv, int *argsused)
244{
245 int oargc = argc;
246 int badarg = 0;
247
248 if (!args_verify(&argv, &argc, &badarg, bio_err, &cfg.vpm))
249 return (1);
250 if (badarg)
251 return (1);
252
253 *argsused = oargc - argc;
254
255 return (0);
256}
257
258static const struct option smime_options[] = {
259#ifndef OPENSSL_NO_AES
260 {
261 .name = "aes128",
262 .desc = "Encrypt PEM output with CBC AES",
263 .type = OPTION_ARGV_FUNC,
264 .opt.argvfunc = smime_opt_cipher,
265 },
266 {
267 .name = "aes192",
268 .desc = "Encrypt PEM output with CBC AES",
269 .type = OPTION_ARGV_FUNC,
270 .opt.argvfunc = smime_opt_cipher,
271 },
272 {
273 .name = "aes256",
274 .desc = "Encrypt PEM output with CBC AES",
275 .type = OPTION_ARGV_FUNC,
276 .opt.argvfunc = smime_opt_cipher,
277 },
278#endif
279#ifndef OPENSSL_NO_CAMELLIA
280 {
281 .name = "camellia128",
282 .desc = "Encrypt PEM output with CBC Camellia",
283 .type = OPTION_ARGV_FUNC,
284 .opt.argvfunc = smime_opt_cipher,
285 },
286 {
287 .name = "camellia192",
288 .desc = "Encrypt PEM output with CBC Camellia",
289 .type = OPTION_ARGV_FUNC,
290 .opt.argvfunc = smime_opt_cipher,
291 },
292 {
293 .name = "camellia256",
294 .desc = "Encrypt PEM output with CBC Camellia",
295 .type = OPTION_ARGV_FUNC,
296 .opt.argvfunc = smime_opt_cipher,
297 },
298#endif
299#ifndef OPENSSL_NO_DES
300 {
301 .name = "des",
302 .desc = "Encrypt with DES",
303 .type = OPTION_ARGV_FUNC,
304 .opt.argvfunc = smime_opt_cipher,
305 },
306 {
307 .name = "des3",
308 .desc = "Encrypt with triple DES",
309 .type = OPTION_ARGV_FUNC,
310 .opt.argvfunc = smime_opt_cipher,
311 },
312#endif
313#ifndef OPENSSL_NO_RC2
314 {
315 .name = "rc2-40",
316 .desc = "Encrypt with RC2-40 (default)",
317 .type = OPTION_ARGV_FUNC,
318 .opt.argvfunc = smime_opt_cipher,
319 },
320 {
321 .name = "rc2-64",
322 .desc = "Encrypt with RC2-64",
323 .type = OPTION_ARGV_FUNC,
324 .opt.argvfunc = smime_opt_cipher,
325 },
326 {
327 .name = "rc2-128",
328 .desc = "Encrypt with RC2-128",
329 .type = OPTION_ARGV_FUNC,
330 .opt.argvfunc = smime_opt_cipher,
331 },
332#endif
333 {
334 .name = "CAfile",
335 .argname = "file",
336 .desc = "Certificate Authority file",
337 .type = OPTION_ARG,
338 .opt.arg = &cfg.CAfile,
339 },
340 {
341 .name = "CApath",
342 .argname = "path",
343 .desc = "Certificate Authority path",
344 .type = OPTION_ARG,
345 .opt.arg = &cfg.CApath,
346 },
347 {
348 .name = "binary",
349 .desc = "Do not translate message to text",
350 .type = OPTION_VALUE_OR,
351 .opt.value = &cfg.flags,
352 .value = PKCS7_BINARY,
353 },
354 {
355 .name = "certfile",
356 .argname = "file",
357 .desc = "Other certificates file",
358 .type = OPTION_ARG,
359 .opt.arg = &cfg.certfile,
360 },
361 {
362 .name = "content",
363 .argname = "file",
364 .desc = "Supply or override content for detached signature",
365 .type = OPTION_ARG,
366 .opt.arg = &cfg.contfile,
367 },
368 {
369 .name = "crlfeol",
370 .desc = "Use CRLF as EOL termination instead of CR only",
371 .type = OPTION_VALUE_OR,
372 .opt.value = &cfg.flags,
373 .value = PKCS7_CRLFEOL,
374 },
375 {
376 .name = "decrypt",
377 .desc = "Decrypt encrypted message",
378 .type = OPTION_VALUE,
379 .opt.value = &cfg.operation,
380 .value = SMIME_DECRYPT,
381 },
382 {
383 .name = "encrypt",
384 .desc = "Encrypt message",
385 .type = OPTION_VALUE,
386 .opt.value = &cfg.operation,
387 .value = SMIME_ENCRYPT,
388 },
389 {
390 .name = "from",
391 .argname = "addr",
392 .desc = "From address",
393 .type = OPTION_ARG,
394 .opt.arg = &cfg.from,
395 },
396 {
397 .name = "in",
398 .argname = "file",
399 .desc = "Input file",
400 .type = OPTION_ARG,
401 .opt.arg = &cfg.infile,
402 },
403 {
404 .name = "indef",
405 .desc = "Same as -stream",
406 .type = OPTION_VALUE,
407 .opt.value = &cfg.indef,
408 .value = 1,
409 },
410 {
411 .name = "inform",
412 .argname = "fmt",
413 .desc = "Input format (DER, PEM or SMIME (default))",
414 .type = OPTION_ARG_FORMAT,
415 .opt.value = &cfg.informat,
416 },
417 {
418 .name = "inkey",
419 .argname = "file",
420 .desc = "Input key file",
421 .type = OPTION_ARG_FUNC,
422 .opt.argfunc = smime_opt_inkey,
423 },
424 {
425 .name = "keyform",
426 .argname = "fmt",
427 .desc = "Input key format (DER or PEM (default))",
428 .type = OPTION_ARG_FORMAT,
429 .opt.value = &cfg.keyform,
430 },
431 {
432 .name = "md",
433 .argname = "digest",
434 .desc = "Digest to use when signing or resigning",
435 .type = OPTION_ARG_FUNC,
436 .opt.argfunc = smime_opt_md,
437 },
438 {
439 .name = "noattr",
440 .desc = "Do not include any signed attributes",
441 .type = OPTION_VALUE_OR,
442 .opt.value = &cfg.flags,
443 .value = PKCS7_NOATTR,
444 },
445 {
446 .name = "nocerts",
447 .desc = "Do not include signer's certificate when signing",
448 .type = OPTION_VALUE_OR,
449 .opt.value = &cfg.flags,
450 .value = PKCS7_NOCERTS,
451 },
452 {
453 .name = "nochain",
454 .desc = "Do not chain verification of signer's certificates",
455 .type = OPTION_VALUE_OR,
456 .opt.value = &cfg.flags,
457 .value = PKCS7_NOCHAIN,
458 },
459 {
460 .name = "nodetach",
461 .desc = "Use opaque signing",
462 .type = OPTION_VALUE_AND,
463 .opt.value = &cfg.flags,
464 .value = ~PKCS7_DETACHED,
465 },
466 {
467 .name = "noindef",
468 .desc = "Disable streaming I/O",
469 .type = OPTION_VALUE,
470 .opt.value = &cfg.indef,
471 .value = 0,
472 },
473 {
474 .name = "nointern",
475 .desc = "Do not search certificates in message for signer",
476 .type = OPTION_VALUE_OR,
477 .opt.value = &cfg.flags,
478 .value = PKCS7_NOINTERN,
479 },
480 {
481 .name = "nooldmime",
482 .desc = "Output old S/MIME content type",
483 .type = OPTION_VALUE_OR,
484 .opt.value = &cfg.flags,
485 .value = PKCS7_NOOLDMIMETYPE,
486 },
487 {
488 .name = "nosigs",
489 .desc = "Do not verify message signature",
490 .type = OPTION_VALUE_OR,
491 .opt.value = &cfg.flags,
492 .value = PKCS7_NOSIGS,
493 },
494 {
495 .name = "nosmimecap",
496 .desc = "Omit the SMIMECapabilities attribute",
497 .type = OPTION_VALUE_OR,
498 .opt.value = &cfg.flags,
499 .value = PKCS7_NOSMIMECAP,
500 },
501 {
502 .name = "noverify",
503 .desc = "Do not verify signer's certificate",
504 .type = OPTION_VALUE_OR,
505 .opt.value = &cfg.flags,
506 .value = PKCS7_NOVERIFY,
507 },
508 {
509 .name = "out",
510 .argname = "file",
511 .desc = "Output file",
512 .type = OPTION_ARG,
513 .opt.arg = &cfg.outfile,
514 },
515 {
516 .name = "outform",
517 .argname = "fmt",
518 .desc = "Output format (DER, PEM or SMIME (default))",
519 .type = OPTION_ARG_FORMAT,
520 .opt.value = &cfg.outformat,
521 },
522 {
523 .name = "passin",
524 .argname = "src",
525 .desc = "Private key password source",
526 .type = OPTION_ARG,
527 .opt.arg = &cfg.passargin,
528 },
529 {
530 .name = "pk7out",
531 .desc = "Output PKCS#7 structure",
532 .type = OPTION_VALUE,
533 .opt.value = &cfg.operation,
534 .value = SMIME_PK7OUT,
535 },
536 {
537 .name = "recip",
538 .argname = "file",
539 .desc = "Recipient certificate file for decryption",
540 .type = OPTION_ARG,
541 .opt.arg = &cfg.recipfile,
542 },
543 {
544 .name = "resign",
545 .desc = "Resign a signed message",
546 .type = OPTION_VALUE,
547 .opt.value = &cfg.operation,
548 .value = SMIME_RESIGN,
549 },
550 {
551 .name = "sign",
552 .desc = "Sign message",
553 .type = OPTION_VALUE,
554 .opt.value = &cfg.operation,
555 .value = SMIME_SIGN,
556 },
557 {
558 .name = "signer",
559 .argname = "file",
560 .desc = "Signer certificate file",
561 .type = OPTION_ARG_FUNC,
562 .opt.argfunc = smime_opt_signer,
563 },
564 {
565 .name = "stream",
566 .desc = "Enable streaming I/O",
567 .type = OPTION_VALUE,
568 .opt.value = &cfg.indef,
569 .value = 1,
570 },
571 {
572 .name = "subject",
573 .argname = "s",
574 .desc = "Subject",
575 .type = OPTION_ARG,
576 .opt.arg = &cfg.subject,
577 },
578 {
579 .name = "text",
580 .desc = "Include or delete text MIME headers",
581 .type = OPTION_VALUE_OR,
582 .opt.value = &cfg.flags,
583 .value = PKCS7_TEXT,
584 },
585 {
586 .name = "to",
587 .argname = "addr",
588 .desc = "To address",
589 .type = OPTION_ARG,
590 .opt.arg = &cfg.to,
591 },
592 {
593 .name = "verify",
594 .desc = "Verify signed message",
595 .type = OPTION_VALUE,
596 .opt.value = &cfg.operation,
597 .value = SMIME_VERIFY,
598 },
599 {
600 .name = "check_ss_sig",
601 .type = OPTION_ARGV_FUNC,
602 .opt.argvfunc = smime_opt_verify_param,
603 },
604 {
605 .name = "crl_check",
606 .type = OPTION_ARGV_FUNC,
607 .opt.argvfunc = smime_opt_verify_param,
608 },
609 {
610 .name = "crl_check_all",
611 .type = OPTION_ARGV_FUNC,
612 .opt.argvfunc = smime_opt_verify_param,
613 },
614 {
615 .name = "extended_crl",
616 .type = OPTION_ARGV_FUNC,
617 .opt.argvfunc = smime_opt_verify_param,
618 },
619 {
620 .name = "ignore_critical",
621 .type = OPTION_ARGV_FUNC,
622 .opt.argvfunc = smime_opt_verify_param,
623 },
624 {
625 .name = "issuer_checks",
626 .type = OPTION_ARGV_FUNC,
627 .opt.argvfunc = smime_opt_verify_param,
628 },
629 {
630 .name = "policy_check",
631 .type = OPTION_ARGV_FUNC,
632 .opt.argvfunc = smime_opt_verify_param,
633 },
634 {
635 .name = "x509_strict",
636 .type = OPTION_ARGV_FUNC,
637 .opt.argvfunc = smime_opt_verify_param,
638 },
639 {
640 .name = NULL,
641 .type = OPTION_ARGV_FUNC,
642 .opt.argvfunc = smime_opt_cipher,
643 },
644 { NULL },
645};
646
647static const struct option verify_shared_options[] = {
648 {
649 .name = "check_ss_sig",
650 .desc = "Check the root CA self-signed certificate signature",
651 },
652 {
653 .name = "crl_check",
654 .desc = "Enable CRL checking for the leaf certificate",
655 },
656 {
657 .name = "crl_check_all",
658 .desc = "Enable CRL checking for the entire certificate chain",
659 },
660 {
661 .name = "extended_crl",
662 .desc = "Enable extended CRL support",
663 },
664 {
665 .name = "ignore_critical",
666 .desc = "Disable critical extension checking",
667 },
668 {
669 .name = "issuer_checks",
670 .desc = "Enable debugging of certificate issuer checks",
671 },
672 {
673 .name = "policy_check",
674 .desc = "Enable certificate policy checking",
675 },
676 {
677 .name = "x509_strict",
678 .desc = "Use strict X.509 rules (disables workarounds)",
679 },
680 { NULL },
681};
682
683static void
684smime_usage(void)
685{
686 fprintf(stderr, "usage: smime "
687 "[-aes128 | -aes192 | -aes256 | -des |\n"
688 " -des3 | -rc2-40 | -rc2-64 | -rc2-128] [-binary]\n"
689 " [-CAfile file] [-CApath directory] [-certfile file]\n"
690 " [-content file]\n"
691 " [-decrypt] [-encrypt]\n"
692 " [-from addr] [-in file] [-indef]\n"
693 " [-inform der | pem | smime] [-inkey file]\n"
694 " [-keyform der | pem] [-md digest] [-noattr] [-nocerts]\n"
695 " [-nochain] [-nodetach] [-noindef] [-nointern] [-nosigs]\n"
696 " [-nosmimecap] [-noverify] [-out file]\n"
697 " [-outform der | pem | smime] [-passin arg] [-pk7out]\n"
698 " [-recip file] [-resign] [-sign]\n"
699 " [-signer file] [-stream] [-subject s] [-text] [-to addr]\n"
700 " [-verify] [cert.pem ...]\n\n");
701
702 options_usage(smime_options);
703
704 fprintf(stderr, "\nVerification options:\n\n");
705 options_usage(verify_shared_options);
706}
707
708int
709smime_main(int argc, char **argv)
710{
711 int ret = 0;
712 char **args;
713 int argsused = 0;
714 const char *inmode = "r", *outmode = "w";
715 PKCS7 *p7 = NULL;
716 X509_STORE *store = NULL;
717 X509 *cert = NULL, *recip = NULL, *signer = NULL;
718 EVP_PKEY *key = NULL;
719 STACK_OF(X509) *encerts = NULL, *other = NULL;
720 BIO *in = NULL, *out = NULL, *indata = NULL;
721 int badarg = 0;
722 char *passin = NULL;
723
724 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
725 perror("pledge");
726 exit(1);
727 }
728
729 memset(&cfg, 0, sizeof(cfg));
730 cfg.flags = PKCS7_DETACHED;
731 cfg.informat = FORMAT_SMIME;
732 cfg.outformat = FORMAT_SMIME;
733 cfg.keyform = FORMAT_PEM;
734 if (options_parse(argc, argv, smime_options, NULL, &argsused) != 0) {
735 goto argerr;
736 }
737 args = argv + argsused;
738 ret = 1;
739
740 if (!(cfg.operation & SMIME_SIGNERS) &&
741 (cfg.skkeys != NULL || cfg.sksigners != NULL)) {
742 BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
743 goto argerr;
744 }
745 if (cfg.operation & SMIME_SIGNERS) {
746 /* Check to see if any final signer needs to be appended */
747 if (cfg.keyfile != NULL &&
748 cfg.signerfile == NULL) {
749 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
750 goto argerr;
751 }
752 if (cfg.signerfile != NULL) {
753 if (cfg.sksigners == NULL) {
754 if ((cfg.sksigners =
755 sk_OPENSSL_STRING_new_null()) == NULL)
756 goto end;
757 }
758 if (!sk_OPENSSL_STRING_push(cfg.sksigners,
759 cfg.signerfile))
760 goto end;
761 if (cfg.skkeys == NULL) {
762 if ((cfg.skkeys =
763 sk_OPENSSL_STRING_new_null()) == NULL)
764 goto end;
765 }
766 if (cfg.keyfile == NULL)
767 cfg.keyfile = cfg.signerfile;
768 if (!sk_OPENSSL_STRING_push(cfg.skkeys,
769 cfg.keyfile))
770 goto end;
771 }
772 if (cfg.sksigners == NULL) {
773 BIO_printf(bio_err,
774 "No signer certificate specified\n");
775 badarg = 1;
776 }
777 cfg.signerfile = NULL;
778 cfg.keyfile = NULL;
779 } else if (cfg.operation == SMIME_DECRYPT) {
780 if (cfg.recipfile == NULL &&
781 cfg.keyfile == NULL) {
782 BIO_printf(bio_err,
783 "No recipient certificate or key specified\n");
784 badarg = 1;
785 }
786 } else if (cfg.operation == SMIME_ENCRYPT) {
787 if (*args == NULL) {
788 BIO_printf(bio_err,
789 "No recipient(s) certificate(s) specified\n");
790 badarg = 1;
791 }
792 } else if (!cfg.operation) {
793 badarg = 1;
794 }
795
796 if (badarg) {
797 argerr:
798 smime_usage();
799 goto end;
800 }
801
802 if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
803 BIO_printf(bio_err, "Error getting password\n");
804 goto end;
805 }
806 ret = 2;
807
808 if (!(cfg.operation & SMIME_SIGNERS))
809 cfg.flags &= ~PKCS7_DETACHED;
810
811 if (cfg.operation & SMIME_OP) {
812 if (cfg.outformat == FORMAT_ASN1)
813 outmode = "wb";
814 } else {
815 if (cfg.flags & PKCS7_BINARY)
816 outmode = "wb";
817 }
818
819 if (cfg.operation & SMIME_IP) {
820 if (cfg.informat == FORMAT_ASN1)
821 inmode = "rb";
822 } else {
823 if (cfg.flags & PKCS7_BINARY)
824 inmode = "rb";
825 }
826
827 if (cfg.operation == SMIME_ENCRYPT) {
828 if (cfg.cipher == NULL) {
829#ifndef OPENSSL_NO_RC2
830 cfg.cipher = EVP_rc2_40_cbc();
831#else
832 BIO_printf(bio_err, "No cipher selected\n");
833 goto end;
834#endif
835 }
836 if ((encerts = sk_X509_new_null()) == NULL)
837 goto end;
838 while (*args != NULL) {
839 if ((cert = load_cert(bio_err, *args, FORMAT_PEM,
840 NULL, "recipient certificate file")) == NULL) {
841 goto end;
842 }
843 if (!sk_X509_push(encerts, cert))
844 goto end;
845 cert = NULL;
846 args++;
847 }
848 }
849 if (cfg.certfile != NULL) {
850 if ((other = load_certs(bio_err, cfg.certfile,
851 FORMAT_PEM, NULL, "certificate file")) == NULL) {
852 ERR_print_errors(bio_err);
853 goto end;
854 }
855 }
856 if (cfg.recipfile != NULL &&
857 (cfg.operation == SMIME_DECRYPT)) {
858 if ((recip = load_cert(bio_err, cfg.recipfile,
859 FORMAT_PEM, NULL, "recipient certificate file")) == NULL) {
860 ERR_print_errors(bio_err);
861 goto end;
862 }
863 }
864 if (cfg.operation == SMIME_DECRYPT) {
865 if (cfg.keyfile == NULL)
866 cfg.keyfile = cfg.recipfile;
867 } else if (cfg.operation == SMIME_SIGN) {
868 if (cfg.keyfile == NULL)
869 cfg.keyfile = cfg.signerfile;
870 } else {
871 cfg.keyfile = NULL;
872 }
873
874 if (cfg.keyfile != NULL) {
875 key = load_key(bio_err, cfg.keyfile,
876 cfg.keyform, 0, passin, "signing key file");
877 if (key == NULL)
878 goto end;
879 }
880 if (cfg.infile != NULL) {
881 if ((in = BIO_new_file(cfg.infile, inmode)) == NULL) {
882 BIO_printf(bio_err,
883 "Can't open input file %s\n", cfg.infile);
884 goto end;
885 }
886 } else {
887 if ((in = BIO_new_fp(stdin, BIO_NOCLOSE)) == NULL)
888 goto end;
889 }
890
891 if (cfg.operation & SMIME_IP) {
892 if (cfg.informat == FORMAT_SMIME)
893 p7 = SMIME_read_PKCS7(in, &indata);
894 else if (cfg.informat == FORMAT_PEM)
895 p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
896 else if (cfg.informat == FORMAT_ASN1)
897 p7 = d2i_PKCS7_bio(in, NULL);
898 else {
899 BIO_printf(bio_err,
900 "Bad input format for PKCS#7 file\n");
901 goto end;
902 }
903
904 if (p7 == NULL) {
905 BIO_printf(bio_err, "Error reading S/MIME message\n");
906 goto end;
907 }
908 if (cfg.contfile != NULL) {
909 BIO_free(indata);
910 if ((indata = BIO_new_file(cfg.contfile,
911 "rb")) == NULL) {
912 BIO_printf(bio_err,
913 "Can't read content file %s\n",
914 cfg.contfile);
915 goto end;
916 }
917 }
918 }
919 if (cfg.outfile != NULL) {
920 if ((out = BIO_new_file(cfg.outfile, outmode)) == NULL) {
921 BIO_printf(bio_err,
922 "Can't open output file %s\n",
923 cfg.outfile);
924 goto end;
925 }
926 } else {
927 if ((out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
928 goto end;
929 }
930
931 if (cfg.operation == SMIME_VERIFY) {
932 if ((store = setup_verify(bio_err, cfg.CAfile,
933 cfg.CApath)) == NULL)
934 goto end;
935 if (cfg.vpm != NULL) {
936 if (!X509_STORE_set1_param(store, cfg.vpm))
937 goto end;
938 }
939 }
940 ret = 3;
941
942 if (cfg.operation == SMIME_ENCRYPT) {
943 if (cfg.indef)
944 cfg.flags |= PKCS7_STREAM;
945 p7 = PKCS7_encrypt(encerts, in, cfg.cipher,
946 cfg.flags);
947 } else if (cfg.operation & SMIME_SIGNERS) {
948 int i;
949 /*
950 * If detached data content we only enable streaming if
951 * S/MIME output format.
952 */
953 if (cfg.operation == SMIME_SIGN) {
954 if (cfg.flags & PKCS7_DETACHED) {
955 if (cfg.outformat == FORMAT_SMIME)
956 cfg.flags |= PKCS7_STREAM;
957 } else if (cfg.indef) {
958 cfg.flags |= PKCS7_STREAM;
959 }
960 cfg.flags |= PKCS7_PARTIAL;
961 p7 = PKCS7_sign(NULL, NULL, other, in,
962 cfg.flags);
963 if (p7 == NULL)
964 goto end;
965 } else {
966 cfg.flags |= PKCS7_REUSE_DIGEST;
967 }
968 for (i = 0; i < sk_OPENSSL_STRING_num(cfg.sksigners); i++) {
969 cfg.signerfile =
970 sk_OPENSSL_STRING_value(cfg.sksigners, i);
971 cfg.keyfile =
972 sk_OPENSSL_STRING_value(cfg.skkeys, i);
973 signer = load_cert(bio_err, cfg.signerfile,
974 FORMAT_PEM, NULL, "signer certificate");
975 if (signer == NULL)
976 goto end;
977 key = load_key(bio_err, cfg.keyfile,
978 cfg.keyform, 0, passin,
979 "signing key file");
980 if (key == NULL)
981 goto end;
982 if (PKCS7_sign_add_signer(p7, signer, key,
983 cfg.sign_md, cfg.flags) == NULL)
984 goto end;
985 X509_free(signer);
986 signer = NULL;
987 EVP_PKEY_free(key);
988 key = NULL;
989 }
990 /* If not streaming or resigning finalize structure */
991 if ((cfg.operation == SMIME_SIGN) &&
992 !(cfg.flags & PKCS7_STREAM)) {
993 if (!PKCS7_final(p7, in, cfg.flags))
994 goto end;
995 }
996 }
997 if (p7 == NULL) {
998 BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
999 goto end;
1000 }
1001 ret = 4;
1002
1003 if (cfg.operation == SMIME_DECRYPT) {
1004 if (!PKCS7_decrypt(p7, key, recip, out, cfg.flags)) {
1005 BIO_printf(bio_err,
1006 "Error decrypting PKCS#7 structure\n");
1007 goto end;
1008 }
1009 } else if (cfg.operation == SMIME_VERIFY) {
1010 STACK_OF(X509) *signers;
1011 if (PKCS7_verify(p7, other, store, indata, out,
1012 cfg.flags)) {
1013 BIO_printf(bio_err, "Verification successful\n");
1014 } else {
1015 BIO_printf(bio_err, "Verification failure\n");
1016 goto end;
1017 }
1018 if ((signers = PKCS7_get0_signers(p7, other,
1019 cfg.flags)) == NULL)
1020 goto end;
1021 if (!save_certs(cfg.signerfile, signers)) {
1022 BIO_printf(bio_err, "Error writing signers to %s\n",
1023 cfg.signerfile);
1024 sk_X509_free(signers);
1025 ret = 5;
1026 goto end;
1027 }
1028 sk_X509_free(signers);
1029 } else if (cfg.operation == SMIME_PK7OUT) {
1030 PEM_write_bio_PKCS7(out, p7);
1031 } else {
1032 if (cfg.to != NULL)
1033 BIO_printf(out, "To: %s\n", cfg.to);
1034 if (cfg.from != NULL)
1035 BIO_printf(out, "From: %s\n", cfg.from);
1036 if (cfg.subject != NULL)
1037 BIO_printf(out, "Subject: %s\n", cfg.subject);
1038 if (cfg.outformat == FORMAT_SMIME) {
1039 if (cfg.operation == SMIME_RESIGN) {
1040 if (!SMIME_write_PKCS7(out, p7, indata,
1041 cfg.flags))
1042 goto end;
1043 } else {
1044 if (!SMIME_write_PKCS7(out, p7, in,
1045 cfg.flags))
1046 goto end;
1047 }
1048 } else if (cfg.outformat == FORMAT_PEM) {
1049 if (!PEM_write_bio_PKCS7_stream(out, p7, in,
1050 cfg.flags))
1051 goto end;
1052 } else if (cfg.outformat == FORMAT_ASN1) {
1053 if (!i2d_PKCS7_bio_stream(out, p7, in,
1054 cfg.flags))
1055 goto end;
1056 } else {
1057 BIO_printf(bio_err,
1058 "Bad output format for PKCS#7 file\n");
1059 goto end;
1060 }
1061 }
1062
1063 ret = 0;
1064
1065 end:
1066 if (ret)
1067 ERR_print_errors(bio_err);
1068 sk_X509_pop_free(encerts, X509_free);
1069 sk_X509_pop_free(other, X509_free);
1070 X509_VERIFY_PARAM_free(cfg.vpm);
1071 sk_OPENSSL_STRING_free(cfg.sksigners);
1072 sk_OPENSSL_STRING_free(cfg.skkeys);
1073 X509_STORE_free(store);
1074 X509_free(cert);
1075 X509_free(recip);
1076 X509_free(signer);
1077 EVP_PKEY_free(key);
1078 PKCS7_free(p7);
1079 BIO_free(in);
1080 BIO_free(indata);
1081 BIO_free_all(out);
1082 free(passin);
1083
1084 return (ret);
1085}
1086
1087static int
1088save_certs(char *signerfile, STACK_OF(X509) *signers)
1089{
1090 int i;
1091 BIO *tmp;
1092
1093 if (signerfile == NULL)
1094 return 1;
1095 tmp = BIO_new_file(signerfile, "w");
1096 if (tmp == NULL)
1097 return 0;
1098 for (i = 0; i < sk_X509_num(signers); i++)
1099 PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1100 BIO_free(tmp);
1101
1102 return 1;
1103}
diff --git a/src/usr.bin/openssl/speed.c b/src/usr.bin/openssl/speed.c
deleted file mode 100644
index 9d03c6516e..0000000000
--- a/src/usr.bin/openssl/speed.c
+++ /dev/null
@@ -1,2799 +0,0 @@
1/* $OpenBSD: speed.c,v 1.41 2025/01/02 13:37:43 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the OpenSSL open source
65 * license provided above.
66 *
67 * The ECDH and ECDSA speed test software is originally written by
68 * Sumit Gupta of Sun Microsystems Laboratories.
69 *
70 */
71
72/* most of this code has been pilfered from my libdes speed.c program */
73
74#ifndef OPENSSL_NO_SPEED
75
76#define SECONDS 3
77#define RSA_SECONDS 10
78#define DSA_SECONDS 10
79#define ECDSA_SECONDS 10
80#define ECDH_SECONDS 10
81
82#define MAX_UNALIGN 16
83
84#include <math.h>
85#include <signal.h>
86#include <stdio.h>
87#include <stdlib.h>
88#include <limits.h>
89#include <string.h>
90#include <unistd.h>
91
92#include "apps.h"
93
94#include <openssl/bn.h>
95#include <openssl/crypto.h>
96#include <openssl/err.h>
97#include <openssl/evp.h>
98#include <openssl/modes.h>
99#include <openssl/objects.h>
100#include <openssl/x509.h>
101
102#ifndef OPENSSL_NO_AES
103#include <openssl/aes.h>
104#endif
105#ifndef OPENSSL_NO_BF
106#include <openssl/blowfish.h>
107#endif
108#ifndef OPENSSL_NO_CAST
109#include <openssl/cast.h>
110#endif
111#ifndef OPENSSL_NO_CAMELLIA
112#include <openssl/camellia.h>
113#endif
114#ifndef OPENSSL_NO_DES
115#include <openssl/des.h>
116#endif
117#include <openssl/dsa.h>
118#include <openssl/ecdh.h>
119#include <openssl/ecdsa.h>
120#ifndef OPENSSL_NO_HMAC
121#include <openssl/hmac.h>
122#endif
123#ifndef OPENSSL_NO_IDEA
124#include <openssl/idea.h>
125#endif
126#ifndef OPENSSL_NO_MD4
127#include <openssl/md4.h>
128#endif
129#ifndef OPENSSL_NO_MD5
130#include <openssl/md5.h>
131#endif
132#ifndef OPENSSL_NO_RC2
133#include <openssl/rc2.h>
134#endif
135#ifndef OPENSSL_NO_RC4
136#include <openssl/rc4.h>
137#endif
138#include <openssl/rsa.h>
139#ifndef OPENSSL_NO_RIPEMD
140#include <openssl/ripemd.h>
141#endif
142#ifndef OPENSSL_NO_SHA
143#include <openssl/sha.h>
144#endif
145#ifndef OPENSSL_NO_WHIRLPOOL
146#include <openssl/whrlpool.h>
147#endif
148
149#define BUFSIZE (1024*8+64)
150volatile sig_atomic_t run;
151
152static int mr = 0;
153static int usertime = 1;
154
155static double Time_F(int s);
156static void print_message(const char *s, long num, int length);
157static void
158pkey_print_message(const char *str, const char *str2,
159 long num, int bits, int sec);
160static void print_result(int alg, int run_no, int count, double time_used);
161static int do_multi(int multi);
162
163#define ALGOR_NUM 32
164#define SIZE_NUM 5
165#define RSA_NUM 4
166#define DSA_NUM 3
167
168#define EC_NUM 4
169#define MAX_ECDH_SIZE 256
170
171static const char *names[ALGOR_NUM] = {
172 "md2", "md4", "md5", "hmac(md5)", "sha1", "rmd160",
173 "rc4", "des cbc", "des ede3", "idea cbc", "seed cbc",
174 "rc2 cbc", "rc5-32/12 cbc", "blowfish cbc", "cast cbc",
175 "aes-128 cbc", "aes-192 cbc", "aes-256 cbc",
176 "camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc",
177 "evp", "sha256", "sha512", "whirlpool",
178 "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash",
179 "aes-128 gcm", "aes-256 gcm", "chacha20 poly1305",
180};
181static double results[ALGOR_NUM][SIZE_NUM];
182static int lengths[SIZE_NUM] = {16, 64, 256, 1024, 8 * 1024};
183static double rsa_results[RSA_NUM][2];
184static double dsa_results[DSA_NUM][2];
185static double ecdsa_results[EC_NUM][2];
186static double ecdh_results[EC_NUM][1];
187
188static void sig_done(int sig);
189
190static DSA *
191get_dsa(const unsigned char *priv, size_t priv_size,
192 const unsigned char *pub, size_t pub_size,
193 const unsigned char *p_char, size_t p_size,
194 const unsigned char *q_char, size_t q_size,
195 const unsigned char *g_char, size_t g_size)
196{
197 DSA *dsa;
198 BIGNUM *priv_key = NULL, *pub_key = NULL;
199 BIGNUM *p = NULL, *q = NULL, *g = NULL;
200
201 if ((dsa = DSA_new()) == NULL)
202 return (NULL);
203
204 priv_key = BN_bin2bn(priv, priv_size, NULL);
205 pub_key = BN_bin2bn(pub, pub_size, NULL);
206 if (priv_key == NULL || pub_key == NULL)
207 goto err;
208
209 if (!DSA_set0_key(dsa, pub_key, priv_key))
210 goto err;
211 pub_key = NULL;
212 priv_key = NULL;
213
214 p = BN_bin2bn(p_char, p_size, NULL);
215 q = BN_bin2bn(q_char, q_size, NULL);
216 g = BN_bin2bn(g_char, g_size, NULL);
217 if (p == NULL || q == NULL || g == NULL)
218 goto err;
219
220 if (!DSA_set0_pqg(dsa, p, q, g))
221 goto err;
222 p = NULL;
223 q = NULL;
224 g = NULL;
225
226 return dsa;
227
228 err:
229 DSA_free(dsa);
230 BN_free(priv_key);
231 BN_free(pub_key);
232 BN_free(p);
233 BN_free(q);
234 BN_free(g);
235
236 return NULL;
237}
238
239
240static const unsigned char dsa512_priv[] = {
241 0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
242 0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2,
243};
244
245static const unsigned char dsa512_pub[] = {
246 0x00, 0x95, 0xa7, 0x0d, 0xec, 0x93, 0x68, 0xba, 0x5f, 0xf7, 0x5f, 0x07,
247 0xf2, 0x3b, 0xad, 0x6b, 0x01, 0xdc, 0xbe, 0xec, 0xde, 0x04, 0x7a, 0x3a,
248 0x27, 0xb3, 0xec, 0x49, 0xfd, 0x08, 0x43, 0x3d, 0x7e, 0xa8, 0x2c, 0x5e,
249 0x7b, 0xbb, 0xfc, 0xf4, 0x6e, 0xeb, 0x6c, 0xb0, 0x6e, 0xf8, 0x02, 0x12,
250 0x8c, 0x38, 0x5d, 0x83, 0x56, 0x7d, 0xee, 0x53, 0x05, 0x3e, 0x24, 0x84,
251 0xbe, 0xba, 0x0a, 0x6b, 0xc8,
252};
253
254static const unsigned char dsa512_p[] = {
255 0x9D, 0x1B, 0x69, 0x8E, 0x26, 0xDB, 0xF2, 0x2B, 0x11, 0x70, 0x19, 0x86,
256 0xF6, 0x19, 0xC8, 0xF8, 0x19, 0xF2, 0x18, 0x53, 0x94, 0x46, 0x06, 0xD0,
257 0x62, 0x50, 0x33, 0x4B, 0x02, 0x3C, 0x52, 0x30, 0x03, 0x8B, 0x3B, 0xF9,
258 0x5F, 0xD1, 0x24, 0x06, 0x4F, 0x7B, 0x4C, 0xBA, 0xAA, 0x40, 0x9B, 0xFD,
259 0x96, 0xE4, 0x37, 0x33, 0xBB, 0x2D, 0x5A, 0xD7, 0x5A, 0x11, 0x40, 0x66,
260 0xA2, 0x76, 0x7D, 0x31,
261};
262
263static const unsigned char dsa512_q[] = {
264 0xFB, 0x53, 0xEF, 0x50, 0xB4, 0x40, 0x92, 0x31, 0x56, 0x86, 0x53, 0x7A,
265 0xE8, 0x8B, 0x22, 0x9A, 0x49, 0xFB, 0x71, 0x8F,
266};
267
268static const unsigned char dsa512_g[] = {
269 0x83, 0x3E, 0x88, 0xE5, 0xC5, 0x89, 0x73, 0xCE, 0x3B, 0x6C, 0x01, 0x49,
270 0xBF, 0xB3, 0xC7, 0x9F, 0x0A, 0xEA, 0x44, 0x91, 0xE5, 0x30, 0xAA, 0xD9,
271 0xBE, 0x5B, 0x5F, 0xB7, 0x10, 0xD7, 0x89, 0xB7, 0x8E, 0x74, 0xFB, 0xCF,
272 0x29, 0x1E, 0xEB, 0xA8, 0x2C, 0x54, 0x51, 0xB8, 0x10, 0xDE, 0xA0, 0xCE,
273 0x2F, 0xCC, 0x24, 0x6B, 0x90, 0x77, 0xDE, 0xA2, 0x68, 0xA6, 0x52, 0x12,
274 0xA2, 0x03, 0x9D, 0x20,
275};
276
277static DSA *
278get_dsa512(void)
279{
280 return get_dsa(dsa512_priv, sizeof(dsa512_priv),
281 dsa512_pub, sizeof(dsa512_pub), dsa512_p, sizeof(dsa512_p),
282 dsa512_q, sizeof(dsa512_q), dsa512_g, sizeof(dsa512_g));
283}
284
285static const unsigned char dsa1024_priv[] = {
286 0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
287 0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
288};
289
290static const unsigned char dsa1024_pub[] = {
291 0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63,
292 0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50,
293 0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e,
294 0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5,
295 0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68,
296 0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82,
297 0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04,
298 0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28,
299 0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e,
300 0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97,
301 0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b
302};
303
304static const unsigned char dsa1024_p[] = {
305 0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47,
306 0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D,
307 0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73,
308 0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9,
309 0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5,
310 0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E,
311 0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7,
312 0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95,
313 0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE,
314 0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80,
315 0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49,
316};
317
318static const unsigned char dsa1024_q[] = {
319 0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C,
320 0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F,
321};
322
323static const unsigned char dsa1024_g[] = {
324 0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46,
325 0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D,
326 0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88,
327 0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18,
328 0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61,
329 0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F,
330 0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16,
331 0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6,
332 0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5,
333 0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5,
334 0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
335};
336
337static DSA *
338get_dsa1024(void)
339{
340 return get_dsa(dsa1024_priv, sizeof(dsa1024_priv),
341 dsa1024_pub, sizeof(dsa1024_pub), dsa1024_p, sizeof(dsa1024_p),
342 dsa1024_q, sizeof(dsa1024_q), dsa1024_g, sizeof(dsa1024_g));
343}
344
345static const unsigned char dsa2048_priv[] = {
346 0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
347 0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
348};
349
350static const unsigned char dsa2048_pub[] = {
351 0x17, 0x8f, 0xa8, 0x11, 0x84, 0x92, 0xec, 0x83, 0x47, 0xc7, 0x6a, 0xb0,
352 0x92, 0xaf, 0x5a, 0x20, 0x37, 0xa3, 0x64, 0x79, 0xd2, 0xd0, 0x3d, 0xcd,
353 0xe0, 0x61, 0x88, 0x88, 0x21, 0xcc, 0x74, 0x5d, 0xce, 0x4c, 0x51, 0x47,
354 0xf0, 0xc5, 0x5c, 0x4c, 0x82, 0x7a, 0xaf, 0x72, 0xad, 0xb9, 0xe0, 0x53,
355 0xf2, 0x78, 0xb7, 0xf0, 0xb5, 0x48, 0x7f, 0x8a, 0x3a, 0x18, 0xd1, 0x9f,
356 0x8b, 0x7d, 0xa5, 0x47, 0xb7, 0x95, 0xab, 0x98, 0xf8, 0x7b, 0x74, 0x50,
357 0x56, 0x8e, 0x57, 0xf0, 0xee, 0xf5, 0xb7, 0xba, 0xab, 0x85, 0x86, 0xf9,
358 0x2b, 0xef, 0x41, 0x56, 0xa0, 0xa4, 0x9f, 0xb7, 0x38, 0x00, 0x46, 0x0a,
359 0xa6, 0xf1, 0xfc, 0x1f, 0xd8, 0x4e, 0x85, 0x44, 0x92, 0x43, 0x21, 0x5d,
360 0x6e, 0xcc, 0xc2, 0xcb, 0x26, 0x31, 0x0d, 0x21, 0xc4, 0xbd, 0x8d, 0x24,
361 0xbc, 0xd9, 0x18, 0x19, 0xd7, 0xdc, 0xf1, 0xe7, 0x93, 0x50, 0x48, 0x03,
362 0x2c, 0xae, 0x2e, 0xe7, 0x49, 0x88, 0x5f, 0x93, 0x57, 0x27, 0x99, 0x36,
363 0xb4, 0x20, 0xab, 0xfc, 0xa7, 0x2b, 0xf2, 0xd9, 0x98, 0xd7, 0xd4, 0x34,
364 0x9d, 0x96, 0x50, 0x58, 0x9a, 0xea, 0x54, 0xf3, 0xee, 0xf5, 0x63, 0x14,
365 0xee, 0x85, 0x83, 0x74, 0x76, 0xe1, 0x52, 0x95, 0xc3, 0xf7, 0xeb, 0x04,
366 0x04, 0x7b, 0xa7, 0x28, 0x1b, 0xcc, 0xea, 0x4a, 0x4e, 0x84, 0xda, 0xd8,
367 0x9c, 0x79, 0xd8, 0x9b, 0x66, 0x89, 0x2f, 0xcf, 0xac, 0xd7, 0x79, 0xf9,
368 0xa9, 0xd8, 0x45, 0x13, 0x78, 0xb9, 0x00, 0x14, 0xc9, 0x7e, 0x22, 0x51,
369 0x86, 0x67, 0xb0, 0x9f, 0x26, 0x11, 0x23, 0xc8, 0x38, 0xd7, 0x70, 0x1d,
370 0x15, 0x8e, 0x4d, 0x4f, 0x95, 0x97, 0x40, 0xa1, 0xc2, 0x7e, 0x01, 0x18,
371 0x72, 0xf4, 0x10, 0xe6, 0x8d, 0x52, 0x16, 0x7f, 0xf2, 0xc9, 0xf8, 0x33,
372 0x8b, 0x33, 0xb7, 0xce,
373};
374
375static const unsigned char dsa2048_p[] = {
376 0xA0, 0x25, 0xFA, 0xAD, 0xF4, 0x8E, 0xB9, 0xE5, 0x99, 0xF3, 0x5D, 0x6F,
377 0x4F, 0x83, 0x34, 0xE2, 0x7E, 0xCF, 0x6F, 0xBF, 0x30, 0xAF, 0x6F, 0x81,
378 0xEB, 0xF8, 0xC4, 0x13, 0xD9, 0xA0, 0x5D, 0x8B, 0x5C, 0x8E, 0xDC, 0xC2,
379 0x1D, 0x0B, 0x41, 0x32, 0xB0, 0x1F, 0xFE, 0xEF, 0x0C, 0xC2, 0xA2, 0x7E,
380 0x68, 0x5C, 0x28, 0x21, 0xE9, 0xF5, 0xB1, 0x58, 0x12, 0x63, 0x4C, 0x19,
381 0x4E, 0xFF, 0x02, 0x4B, 0x92, 0xED, 0xD2, 0x07, 0x11, 0x4D, 0x8C, 0x58,
382 0x16, 0x5C, 0x55, 0x8E, 0xAD, 0xA3, 0x67, 0x7D, 0xB9, 0x86, 0x6E, 0x0B,
383 0xE6, 0x54, 0x6F, 0x40, 0xAE, 0x0E, 0x67, 0x4C, 0xF9, 0x12, 0x5B, 0x3C,
384 0x08, 0x7A, 0xF7, 0xFC, 0x67, 0x86, 0x69, 0xE7, 0x0A, 0x94, 0x40, 0xBF,
385 0x8B, 0x76, 0xFE, 0x26, 0xD1, 0xF2, 0xA1, 0x1A, 0x84, 0xA1, 0x43, 0x56,
386 0x28, 0xBC, 0x9A, 0x5F, 0xD7, 0x3B, 0x69, 0x89, 0x8A, 0x36, 0x2C, 0x51,
387 0xDF, 0x12, 0x77, 0x2F, 0x57, 0x7B, 0xA0, 0xAA, 0xDD, 0x7F, 0xA1, 0x62,
388 0x3B, 0x40, 0x7B, 0x68, 0x1A, 0x8F, 0x0D, 0x38, 0xBB, 0x21, 0x5D, 0x18,
389 0xFC, 0x0F, 0x46, 0xF7, 0xA3, 0xB0, 0x1D, 0x23, 0xC3, 0xD2, 0xC7, 0x72,
390 0x51, 0x18, 0xDF, 0x46, 0x95, 0x79, 0xD9, 0xBD, 0xB5, 0x19, 0x02, 0x2C,
391 0x87, 0xDC, 0xE7, 0x57, 0x82, 0x7E, 0xF1, 0x8B, 0x06, 0x3D, 0x00, 0xA5,
392 0x7B, 0x6B, 0x26, 0x27, 0x91, 0x0F, 0x6A, 0x77, 0xE4, 0xD5, 0x04, 0xE4,
393 0x12, 0x2C, 0x42, 0xFF, 0xD2, 0x88, 0xBB, 0xD3, 0x92, 0xA0, 0xF9, 0xC8,
394 0x51, 0x64, 0x14, 0x5C, 0xD8, 0xF9, 0x6C, 0x47, 0x82, 0xB4, 0x1C, 0x7F,
395 0x09, 0xB8, 0xF0, 0x25, 0x83, 0x1D, 0x3F, 0x3F, 0x05, 0xB3, 0x21, 0x0A,
396 0x5D, 0xA7, 0xD8, 0x54, 0xC3, 0x65, 0x7D, 0xC3, 0xB0, 0x1D, 0xBF, 0xAE,
397 0xF8, 0x68, 0xCF, 0x9B,
398};
399
400static const unsigned char dsa2048_q[] = {
401 0x97, 0xE7, 0x33, 0x4D, 0xD3, 0x94, 0x3E, 0x0B, 0xDB, 0x62, 0x74, 0xC6,
402 0xA1, 0x08, 0xDD, 0x19, 0xA3, 0x75, 0x17, 0x1B,
403};
404
405static const unsigned char dsa2048_g[] = {
406 0x2C, 0x78, 0x16, 0x59, 0x34, 0x63, 0xF4, 0xF3, 0x92, 0xFC, 0xB5, 0xA5,
407 0x4F, 0x13, 0xDE, 0x2F, 0x1C, 0xA4, 0x3C, 0xAE, 0xAD, 0x38, 0x3F, 0x7E,
408 0x90, 0xBF, 0x96, 0xA6, 0xAE, 0x25, 0x90, 0x72, 0xF5, 0x8E, 0x80, 0x0C,
409 0x39, 0x1C, 0xD9, 0xEC, 0xBA, 0x90, 0x5B, 0x3A, 0xE8, 0x58, 0x6C, 0x9E,
410 0x30, 0x42, 0x37, 0x02, 0x31, 0x82, 0xBC, 0x6A, 0xDF, 0x6A, 0x09, 0x29,
411 0xE3, 0xC0, 0x46, 0xD1, 0xCB, 0x85, 0xEC, 0x0C, 0x30, 0x5E, 0xEA, 0xC8,
412 0x39, 0x8E, 0x22, 0x9F, 0x22, 0x10, 0xD2, 0x34, 0x61, 0x68, 0x37, 0x3D,
413 0x2E, 0x4A, 0x5B, 0x9A, 0xF5, 0xC1, 0x48, 0xC6, 0xF6, 0xDC, 0x63, 0x1A,
414 0xD3, 0x96, 0x64, 0xBA, 0x34, 0xC9, 0xD1, 0xA0, 0xD1, 0xAE, 0x6C, 0x2F,
415 0x48, 0x17, 0x93, 0x14, 0x43, 0xED, 0xF0, 0x21, 0x30, 0x19, 0xC3, 0x1B,
416 0x5F, 0xDE, 0xA3, 0xF0, 0x70, 0x78, 0x18, 0xE1, 0xA8, 0xE4, 0xEE, 0x2E,
417 0x00, 0xA5, 0xE4, 0xB3, 0x17, 0xC8, 0x0C, 0x7D, 0x6E, 0x42, 0xDC, 0xB7,
418 0x46, 0x00, 0x36, 0x4D, 0xD4, 0x46, 0xAA, 0x3D, 0x3C, 0x46, 0x89, 0x40,
419 0xBF, 0x1D, 0x84, 0x77, 0x0A, 0x75, 0xF3, 0x87, 0x1D, 0x08, 0x4C, 0xA6,
420 0xD1, 0xA9, 0x1C, 0x1E, 0x12, 0x1E, 0xE1, 0xC7, 0x30, 0x28, 0x76, 0xA5,
421 0x7F, 0x6C, 0x85, 0x96, 0x2B, 0x6F, 0xDB, 0x80, 0x66, 0x26, 0xAE, 0xF5,
422 0x93, 0xC7, 0x8E, 0xAE, 0x9A, 0xED, 0xE4, 0xCA, 0x04, 0xEA, 0x3B, 0x72,
423 0xEF, 0xDC, 0x87, 0xED, 0x0D, 0xA5, 0x4C, 0x4A, 0xDD, 0x71, 0x22, 0x64,
424 0x59, 0x69, 0x4E, 0x8E, 0xBF, 0x43, 0xDC, 0xAB, 0x8E, 0x66, 0xBB, 0x01,
425 0xB6, 0xF4, 0xE7, 0xFD, 0xD2, 0xAD, 0x9F, 0x36, 0xC1, 0xA0, 0x29, 0x99,
426 0xD1, 0x96, 0x70, 0x59, 0x06, 0x78, 0x35, 0xBD, 0x65, 0x55, 0x52, 0x9E,
427 0xF8, 0xB2, 0xE5, 0x38,
428};
429
430static DSA *
431get_dsa2048(void)
432{
433 return get_dsa(dsa2048_priv, sizeof(dsa2048_priv),
434 dsa2048_pub, sizeof(dsa2048_pub), dsa2048_p, sizeof(dsa2048_p),
435 dsa2048_q, sizeof(dsa2048_q), dsa2048_g, sizeof(dsa2048_g));
436}
437
438static const unsigned char test512[] = {
439 0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
440 0xd6, 0x33, 0xb9, 0xc8, 0xfb, 0x4f, 0x3c, 0x7d, 0xc0, 0x01,
441 0x86, 0xd0, 0xe7, 0xa0, 0x55, 0xf2, 0x95, 0x93, 0xcc, 0x4f,
442 0xb7, 0x5b, 0x67, 0x5b, 0x94, 0x68, 0xc9, 0x34, 0x15, 0xde,
443 0xa5, 0x2e, 0x1c, 0x33, 0xc2, 0x6e, 0xfc, 0x34, 0x5e, 0x71,
444 0x13, 0xb7, 0xd6, 0xee, 0xd8, 0xa5, 0x65, 0x05, 0x72, 0x87,
445 0xa8, 0xb0, 0x77, 0xfe, 0x57, 0xf5, 0xfc, 0x5f, 0x55, 0x83,
446 0x87, 0xdd, 0x57, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
447 0x41, 0x00, 0xa7, 0xf7, 0x91, 0xc5, 0x0f, 0x84, 0x57, 0xdc,
448 0x07, 0xf7, 0x6a, 0x7f, 0x60, 0x52, 0xb3, 0x72, 0xf1, 0x66,
449 0x1f, 0x7d, 0x97, 0x3b, 0x9e, 0xb6, 0x0a, 0x8f, 0x8c, 0xcf,
450 0x42, 0x23, 0x00, 0x04, 0xd4, 0x28, 0x0e, 0x1c, 0x90, 0xc4,
451 0x11, 0x25, 0x25, 0xa5, 0x93, 0xa5, 0x2f, 0x70, 0x02, 0xdf,
452 0x81, 0x9c, 0x49, 0x03, 0xa0, 0xf8, 0x6d, 0x54, 0x2e, 0x26,
453 0xde, 0xaa, 0x85, 0x59, 0xa8, 0x31, 0x02, 0x21, 0x00, 0xeb,
454 0x47, 0xd7, 0x3b, 0xf6, 0xc3, 0xdd, 0x5a, 0x46, 0xc5, 0xb9,
455 0x2b, 0x9a, 0xa0, 0x09, 0x8f, 0xa6, 0xfb, 0xf3, 0x78, 0x7a,
456 0x33, 0x70, 0x9d, 0x0f, 0x42, 0x6b, 0x13, 0x68, 0x24, 0xd3,
457 0x15, 0x02, 0x21, 0x00, 0xe9, 0x10, 0xb0, 0xb3, 0x0d, 0xe2,
458 0x82, 0x68, 0x77, 0x8a, 0x6e, 0x7c, 0xda, 0xbc, 0x3e, 0x53,
459 0x83, 0xfb, 0xd6, 0x22, 0xe7, 0xb5, 0xae, 0x6e, 0x80, 0xda,
460 0x00, 0x55, 0x97, 0xc1, 0xd0, 0x65, 0x02, 0x20, 0x4c, 0xf8,
461 0x73, 0xb1, 0x6a, 0x49, 0x29, 0x61, 0x1f, 0x46, 0x10, 0x0d,
462 0xf3, 0xc7, 0xe7, 0x58, 0xd7, 0x88, 0x15, 0x5e, 0x94, 0x9b,
463 0xbf, 0x7b, 0xa2, 0x42, 0x58, 0x45, 0x41, 0x0c, 0xcb, 0x01,
464 0x02, 0x20, 0x12, 0x11, 0xba, 0x31, 0x57, 0x9d, 0x3d, 0x11,
465 0x0e, 0x5b, 0x8c, 0x2f, 0x5f, 0xe2, 0x02, 0x4f, 0x05, 0x47,
466 0x8c, 0x15, 0x8e, 0xb3, 0x56, 0x3f, 0xb8, 0xfb, 0xad, 0xd4,
467 0xf4, 0xfc, 0x10, 0xc5, 0x02, 0x20, 0x18, 0xa1, 0x29, 0x99,
468 0x5b, 0xd9, 0xc8, 0xd4, 0xfc, 0x49, 0x7a, 0x2a, 0x21, 0x2c,
469 0x49, 0xe4, 0x4f, 0xeb, 0xef, 0x51, 0xf1, 0xab, 0x6d, 0xfb,
470 0x4b, 0x14, 0xe9, 0x4b, 0x52, 0xb5, 0x82, 0x2c,
471};
472
473static const unsigned char test1024[] = {
474 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
475 0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05,
476 0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5,
477 0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55,
478 0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9,
479 0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96,
480 0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37,
481 0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd,
482 0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24,
483 0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23,
484 0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37,
485 0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94,
486 0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b,
487 0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02,
488 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f,
489 0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0,
490 0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f,
491 0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f,
492 0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88,
493 0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba,
494 0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c,
495 0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43,
496 0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc,
497 0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee,
498 0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d,
499 0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed,
500 0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20,
501 0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c,
502 0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3,
503 0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02,
504 0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4,
505 0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a,
506 0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc,
507 0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2,
508 0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04,
509 0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52,
510 0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38,
511 0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7,
512 0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20,
513 0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4,
514 0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02,
515 0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b,
516 0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52,
517 0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde,
518 0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f,
519 0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66,
520 0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46,
521 0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad,
522 0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80,
523 0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf,
524 0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84,
525 0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60,
526 0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c,
527 0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b,
528 0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c,
529 0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7,
530 0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53,
531 0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9,
532 0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba,
533 0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14,
534 0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45,
535};
536
537static const unsigned char test2048[] = {
538 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
539 0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f,
540 0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27,
541 0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f,
542 0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde,
543 0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a,
544 0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32,
545 0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f,
546 0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab,
547 0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33,
548 0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f,
549 0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4,
550 0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e,
551 0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29,
552 0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b,
553 0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0,
554 0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34,
555 0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1,
556 0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15,
557 0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c,
558 0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66,
559 0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2,
560 0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27,
561 0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15,
562 0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20,
563 0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1,
564 0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03,
565 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3,
566 0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa,
567 0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c,
568 0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac,
569 0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40,
570 0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3,
571 0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d,
572 0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01,
573 0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4,
574 0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5,
575 0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9,
576 0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6,
577 0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3,
578 0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e,
579 0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46,
580 0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53,
581 0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59,
582 0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab,
583 0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48,
584 0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca,
585 0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35,
586 0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9,
587 0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b,
588 0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f,
589 0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0,
590 0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33,
591 0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7,
592 0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50,
593 0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c,
594 0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8,
595 0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56,
596 0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f,
597 0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04,
598 0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14,
599 0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c,
600 0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06,
601 0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c,
602 0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28,
603 0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80,
604 0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1,
605 0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc,
606 0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63,
607 0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61,
608 0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94,
609 0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95,
610 0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4,
611 0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84,
612 0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94,
613 0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e,
614 0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11,
615 0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1,
616 0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb,
617 0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80,
618 0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5,
619 0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a,
620 0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29,
621 0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72,
622 0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54,
623 0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8,
624 0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d,
625 0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90,
626 0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27,
627 0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28,
628 0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82,
629 0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90,
630 0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81,
631 0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf,
632 0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01,
633 0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16,
634 0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5,
635 0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3,
636 0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc,
637 0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1,
638 0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8,
639 0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31,
640 0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c,
641 0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b,
642 0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32,
643 0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02,
644 0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9,
645 0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84,
646 0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04,
647 0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a,
648 0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd,
649 0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43,
650 0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46,
651 0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41,
652 0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5,
653 0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b,
654 0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55,
655 0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d,
656 0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4,
657 0x95,
658};
659
660static const unsigned char test4096[] = {
661 0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02,
662 0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43,
663 0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21,
664 0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44,
665 0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28,
666 0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41,
667 0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7,
668 0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd,
669 0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e,
670 0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b,
671 0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6,
672 0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf,
673 0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d,
674 0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e,
675 0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0,
676 0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99,
677 0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90,
678 0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8,
679 0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a,
680 0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda,
681 0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca,
682 0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28,
683 0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7,
684 0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb,
685 0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26,
686 0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c,
687 0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03,
688 0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1,
689 0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09,
690 0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83,
691 0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95,
692 0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc,
693 0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36,
694 0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5,
695 0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc,
696 0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8,
697 0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa,
698 0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca,
699 0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e,
700 0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56,
701 0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48,
702 0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46,
703 0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b,
704 0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe,
705 0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3,
706 0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69,
707 0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe,
708 0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3,
709 0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f,
710 0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed,
711 0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4,
712 0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3,
713 0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
714 0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f,
715 0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb,
716 0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd,
717 0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5,
718 0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17,
719 0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52,
720 0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c,
721 0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f,
722 0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12,
723 0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61,
724 0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8,
725 0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4,
726 0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e,
727 0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50,
728 0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea,
729 0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16,
730 0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae,
731 0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6,
732 0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c,
733 0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a,
734 0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e,
735 0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb,
736 0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5,
737 0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6,
738 0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe,
739 0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14,
740 0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88,
741 0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7,
742 0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19,
743 0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40,
744 0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b,
745 0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69,
746 0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9,
747 0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c,
748 0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62,
749 0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2,
750 0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9,
751 0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25,
752 0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d,
753 0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab,
754 0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f,
755 0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c,
756 0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda,
757 0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd,
758 0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54,
759 0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41,
760 0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7,
761 0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1,
762 0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d,
763 0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65,
764 0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28,
765 0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01,
766 0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d,
767 0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14,
768 0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc,
769 0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37,
770 0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81,
771 0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94,
772 0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e,
773 0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9,
774 0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c,
775 0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24,
776 0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc,
777 0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1,
778 0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc,
779 0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84,
780 0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77,
781 0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21,
782 0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6,
783 0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa,
784 0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14,
785 0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39,
786 0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06,
787 0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3,
788 0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35,
789 0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97,
790 0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed,
791 0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01,
792 0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8,
793 0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4,
794 0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94,
795 0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4,
796 0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d,
797 0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c,
798 0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e,
799 0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1,
800 0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc,
801 0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55,
802 0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61,
803 0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92,
804 0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80,
805 0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13,
806 0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48,
807 0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed,
808 0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9,
809 0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a,
810 0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35,
811 0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7,
812 0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c,
813 0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47,
814 0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8,
815 0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7,
816 0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc,
817 0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82,
818 0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b,
819 0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef,
820 0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6,
821 0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80,
822 0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac,
823 0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b,
824 0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35,
825 0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c,
826 0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e,
827 0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a,
828 0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd,
829 0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5,
830 0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc,
831 0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30,
832 0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f,
833 0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c,
834 0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe,
835 0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f,
836 0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91,
837 0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9,
838 0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf,
839 0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76,
840 0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0,
841 0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78,
842 0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10,
843 0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82,
844 0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00,
845 0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25,
846 0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3,
847 0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b,
848 0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79,
849 0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94,
850 0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8,
851 0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38,
852 0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0,
853 0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44,
854 0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b,
855 0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf,
856 0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f,
857 0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28,
858 0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97,
859 0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f,
860 0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48,
861 0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35,
862 0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84,
863 0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a,
864 0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b,
865 0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e,
866 0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55,
867 0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16,
868 0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c,
869 0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82,
870 0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05,
871 0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3,
872 0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e,
873 0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43,
874 0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e,
875 0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a,
876 0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed,
877 0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7,
878 0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c,
879 0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b,
880 0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e,
881 0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95,
882 0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11,
883 0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb,
884 0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e,
885 0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a,
886 0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc,
887 0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35,
888 0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21,
889 0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a,
890 0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70,
891 0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01,
892 0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c,
893 0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26,
894 0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55,
895 0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17,
896};
897
898static void
899sig_done(int sig)
900{
901 run = 0;
902}
903
904#define START TM_RESET
905#define STOP TM_GET
906
907
908static double
909Time_F(int s)
910{
911 if (usertime)
912 return app_timer_user(s);
913 else
914 return app_timer_real(s);
915}
916
917
918static const int KDF1_SHA1_len = 20;
919static void *
920KDF1_SHA1(const void *in, size_t inlen, void *out, size_t * outlen)
921{
922#ifndef OPENSSL_NO_SHA
923 if (*outlen < SHA_DIGEST_LENGTH)
924 return NULL;
925 else
926 *outlen = SHA_DIGEST_LENGTH;
927 return SHA1(in, inlen, out);
928#else
929 return NULL;
930#endif /* OPENSSL_NO_SHA */
931}
932
933int
934speed_main(int argc, char **argv)
935{
936 unsigned char *real_buf = NULL, *real_buf2 = NULL;
937 unsigned char *buf = NULL, *buf2 = NULL;
938 size_t unaligned = 0;
939 int mret = 1;
940 long count = 0, save_count = 0;
941 int i, j, k;
942 long rsa_count;
943 unsigned rsa_num;
944 unsigned char md[EVP_MAX_MD_SIZE];
945#ifndef OPENSSL_NO_MD4
946 unsigned char md4[MD4_DIGEST_LENGTH];
947#endif
948#ifndef OPENSSL_NO_MD5
949 unsigned char md5[MD5_DIGEST_LENGTH];
950 unsigned char hmac[MD5_DIGEST_LENGTH];
951#endif
952#ifndef OPENSSL_NO_SHA
953 unsigned char sha[SHA_DIGEST_LENGTH];
954#ifndef OPENSSL_NO_SHA256
955 unsigned char sha256[SHA256_DIGEST_LENGTH];
956#endif
957#ifndef OPENSSL_NO_SHA512
958 unsigned char sha512[SHA512_DIGEST_LENGTH];
959#endif
960#endif
961#ifndef OPENSSL_NO_WHIRLPOOL
962 unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
963#endif
964#ifndef OPENSSL_NO_RIPEMD
965 unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
966#endif
967#ifndef OPENSSL_NO_RC4
968 RC4_KEY rc4_ks;
969#endif
970#ifndef OPENSSL_NO_RC2
971 RC2_KEY rc2_ks;
972#endif
973#ifndef OPENSSL_NO_IDEA
974 IDEA_KEY_SCHEDULE idea_ks;
975#endif
976#ifndef OPENSSL_NO_BF
977 BF_KEY bf_ks;
978#endif
979#ifndef OPENSSL_NO_CAST
980 CAST_KEY cast_ks;
981#endif
982 static const unsigned char key16[16] =
983 {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
984 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12};
985#ifndef OPENSSL_NO_AES
986 static const unsigned char key24[24] =
987 {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
988 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
989 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34};
990 static const unsigned char key32[32] =
991 {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
992 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
993 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
994 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56};
995#endif
996#ifndef OPENSSL_NO_CAMELLIA
997 static const unsigned char ckey24[24] =
998 {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
999 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1000 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34};
1001 static const unsigned char ckey32[32] =
1002 {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1003 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1004 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1005 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56};
1006#endif
1007#ifndef OPENSSL_NO_AES
1008#define MAX_BLOCK_SIZE 128
1009#else
1010#define MAX_BLOCK_SIZE 64
1011#endif
1012 unsigned char DES_iv[8];
1013 unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
1014#ifndef OPENSSL_NO_DES
1015 static DES_cblock key = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
1016 static DES_cblock key2 = {0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12};
1017 static DES_cblock key3 = {0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34};
1018 DES_key_schedule sch;
1019 DES_key_schedule sch2;
1020 DES_key_schedule sch3;
1021#endif
1022#ifndef OPENSSL_NO_AES
1023 AES_KEY aes_ks1, aes_ks2, aes_ks3;
1024#endif
1025#ifndef OPENSSL_NO_CAMELLIA
1026 CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
1027#endif
1028#define D_MD2 0
1029#define D_MD4 1
1030#define D_MD5 2
1031#define D_HMAC 3
1032#define D_SHA1 4
1033#define D_RMD160 5
1034#define D_RC4 6
1035#define D_CBC_DES 7
1036#define D_EDE3_DES 8
1037#define D_CBC_IDEA 9
1038#define D_CBC_SEED 10
1039#define D_CBC_RC2 11
1040#define D_CBC_RC5 12
1041#define D_CBC_BF 13
1042#define D_CBC_CAST 14
1043#define D_CBC_128_AES 15
1044#define D_CBC_192_AES 16
1045#define D_CBC_256_AES 17
1046#define D_CBC_128_CML 18
1047#define D_CBC_192_CML 19
1048#define D_CBC_256_CML 20
1049#define D_EVP 21
1050#define D_SHA256 22
1051#define D_SHA512 23
1052#define D_WHIRLPOOL 24
1053#define D_IGE_128_AES 25
1054#define D_IGE_192_AES 26
1055#define D_IGE_256_AES 27
1056#define D_GHASH 28
1057#define D_AES_128_GCM 29
1058#define D_AES_256_GCM 30
1059#define D_CHACHA20_POLY1305 31
1060 double d = 0.0;
1061 long c[ALGOR_NUM][SIZE_NUM];
1062#define R_DSA_512 0
1063#define R_DSA_1024 1
1064#define R_DSA_2048 2
1065#define R_RSA_512 0
1066#define R_RSA_1024 1
1067#define R_RSA_2048 2
1068#define R_RSA_4096 3
1069
1070#define R_EC_P224 0
1071#define R_EC_P256 1
1072#define R_EC_P384 2
1073#define R_EC_P521 3
1074
1075 RSA *rsa_key[RSA_NUM];
1076 long rsa_c[RSA_NUM][2];
1077 static unsigned int rsa_bits[RSA_NUM] = {512, 1024, 2048, 4096};
1078 static const unsigned char *rsa_data[RSA_NUM] =
1079 {test512, test1024, test2048, test4096};
1080 static int rsa_data_length[RSA_NUM] = {
1081 sizeof(test512), sizeof(test1024),
1082 sizeof(test2048), sizeof(test4096)};
1083 DSA *dsa_key[DSA_NUM];
1084 long dsa_c[DSA_NUM][2];
1085 static unsigned int dsa_bits[DSA_NUM] = {512, 1024, 2048};
1086#ifndef OPENSSL_NO_EC
1087 /*
1088 * We only test over the following curves as they are representative,
1089 * To add tests over more curves, simply add the curve NID and curve
1090 * name to the following arrays and increase the EC_NUM value
1091 * accordingly.
1092 */
1093 static unsigned int test_curves[EC_NUM] = {
1094 NID_secp224r1,
1095 NID_X9_62_prime256v1,
1096 NID_secp384r1,
1097 NID_secp521r1,
1098 };
1099 static const char *test_curves_names[EC_NUM] = {
1100 "nistp224",
1101 "nistp256",
1102 "nistp384",
1103 "nistp521",
1104 };
1105 static int test_curves_bits[EC_NUM] = {
1106 224, 256, 384, 521,
1107 };
1108
1109#endif
1110
1111 unsigned char ecdsasig[256];
1112 unsigned int ecdsasiglen;
1113 EC_KEY *ecdsa[EC_NUM];
1114 long ecdsa_c[EC_NUM][2];
1115
1116 EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
1117 unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
1118 int secret_size_a, secret_size_b;
1119 int ecdh_checks = 0;
1120 int secret_idx = 0;
1121 long ecdh_c[EC_NUM][2];
1122
1123 int rsa_doit[RSA_NUM];
1124 int dsa_doit[DSA_NUM];
1125 int ecdsa_doit[EC_NUM];
1126 int ecdh_doit[EC_NUM];
1127 int doit[ALGOR_NUM];
1128 int pr_header = 0;
1129 const EVP_CIPHER *evp_cipher = NULL;
1130 const EVP_MD *evp_md = NULL;
1131 int decrypt = 0;
1132 int multi = 0;
1133 struct sigaction sa;
1134 const char *errstr = NULL;
1135
1136 if (pledge("stdio proc", NULL) == -1) {
1137 perror("pledge");
1138 exit(1);
1139 }
1140
1141 usertime = -1;
1142
1143 memset(results, 0, sizeof(results));
1144 memset(dsa_key, 0, sizeof(dsa_key));
1145 for (i = 0; i < EC_NUM; i++)
1146 ecdsa[i] = NULL;
1147 for (i = 0; i < EC_NUM; i++) {
1148 ecdh_a[i] = NULL;
1149 ecdh_b[i] = NULL;
1150 }
1151
1152 memset(rsa_key, 0, sizeof(rsa_key));
1153 for (i = 0; i < RSA_NUM; i++)
1154 rsa_key[i] = NULL;
1155
1156 if ((buf = real_buf = malloc(BUFSIZE + MAX_UNALIGN)) == NULL) {
1157 BIO_printf(bio_err, "out of memory\n");
1158 goto end;
1159 }
1160 if ((buf2 = real_buf2 = malloc(BUFSIZE + MAX_UNALIGN)) == NULL) {
1161 BIO_printf(bio_err, "out of memory\n");
1162 goto end;
1163 }
1164 memset(c, 0, sizeof(c));
1165 memset(DES_iv, 0, sizeof(DES_iv));
1166 memset(iv, 0, sizeof(iv));
1167
1168 for (i = 0; i < ALGOR_NUM; i++)
1169 doit[i] = 0;
1170 for (i = 0; i < RSA_NUM; i++)
1171 rsa_doit[i] = 0;
1172 for (i = 0; i < DSA_NUM; i++)
1173 dsa_doit[i] = 0;
1174 for (i = 0; i < EC_NUM; i++)
1175 ecdsa_doit[i] = 0;
1176 for (i = 0; i < EC_NUM; i++)
1177 ecdh_doit[i] = 0;
1178
1179
1180 j = 0;
1181 argc--;
1182 argv++;
1183 while (argc) {
1184 if (argc > 0 && strcmp(*argv, "-elapsed") == 0) {
1185 usertime = 0;
1186 j--; /* Otherwise, -elapsed gets confused with an
1187 * algorithm. */
1188 } else if (argc > 0 && strcmp(*argv, "-evp") == 0) {
1189 argc--;
1190 argv++;
1191 if (argc == 0) {
1192 BIO_printf(bio_err, "no EVP given\n");
1193 goto end;
1194 }
1195 evp_cipher = EVP_get_cipherbyname(*argv);
1196 if (!evp_cipher) {
1197 evp_md = EVP_get_digestbyname(*argv);
1198 }
1199 if (!evp_cipher && !evp_md) {
1200 BIO_printf(bio_err, "%s is an unknown cipher or digest\n", *argv);
1201 goto end;
1202 }
1203 doit[D_EVP] = 1;
1204 } else if (argc > 0 && strcmp(*argv, "-decrypt") == 0) {
1205 decrypt = 1;
1206 j--; /* Otherwise, -decrypt gets confused with an
1207 * algorithm. */
1208 } else if (argc > 0 && strcmp(*argv, "-multi") == 0) {
1209 argc--;
1210 argv++;
1211 if (argc == 0) {
1212 BIO_printf(bio_err, "no multi count given\n");
1213 goto end;
1214 }
1215 multi = strtonum(argv[0], 1, INT_MAX, &errstr);
1216 if (errstr) {
1217 BIO_printf(bio_err, "bad multi count: %s", errstr);
1218 goto end;
1219 }
1220 j--; /* Otherwise, -multi gets confused with an
1221 * algorithm. */
1222 } else if (argc > 0 && strcmp(*argv, "-unaligned") == 0) {
1223 argc--;
1224 argv++;
1225 if (argc == 0) {
1226 BIO_printf(bio_err, "no alignment offset given\n");
1227 goto end;
1228 }
1229 unaligned = strtonum(argv[0], 0, MAX_UNALIGN, &errstr);
1230 if (errstr) {
1231 BIO_printf(bio_err, "bad alignment offset: %s",
1232 errstr);
1233 goto end;
1234 }
1235 buf = real_buf + unaligned;
1236 buf2 = real_buf2 + unaligned;
1237 j--; /* Otherwise, -unaligned gets confused with an
1238 * algorithm. */
1239 } else if (argc > 0 && strcmp(*argv, "-mr") == 0) {
1240 mr = 1;
1241 j--; /* Otherwise, -mr gets confused with an
1242 * algorithm. */
1243 } else
1244#ifndef OPENSSL_NO_MD4
1245 if (strcmp(*argv, "md4") == 0)
1246 doit[D_MD4] = 1;
1247 else
1248#endif
1249#ifndef OPENSSL_NO_MD5
1250 if (strcmp(*argv, "md5") == 0)
1251 doit[D_MD5] = 1;
1252 else
1253#endif
1254#ifndef OPENSSL_NO_MD5
1255 if (strcmp(*argv, "hmac") == 0)
1256 doit[D_HMAC] = 1;
1257 else
1258#endif
1259#ifndef OPENSSL_NO_SHA
1260 if (strcmp(*argv, "sha1") == 0)
1261 doit[D_SHA1] = 1;
1262 else if (strcmp(*argv, "sha") == 0)
1263 doit[D_SHA1] = 1,
1264 doit[D_SHA256] = 1,
1265 doit[D_SHA512] = 1;
1266 else
1267#ifndef OPENSSL_NO_SHA256
1268 if (strcmp(*argv, "sha256") == 0)
1269 doit[D_SHA256] = 1;
1270 else
1271#endif
1272#ifndef OPENSSL_NO_SHA512
1273 if (strcmp(*argv, "sha512") == 0)
1274 doit[D_SHA512] = 1;
1275 else
1276#endif
1277#endif
1278#ifndef OPENSSL_NO_WHIRLPOOL
1279 if (strcmp(*argv, "whirlpool") == 0)
1280 doit[D_WHIRLPOOL] = 1;
1281 else
1282#endif
1283#ifndef OPENSSL_NO_RIPEMD
1284 if (strcmp(*argv, "ripemd") == 0)
1285 doit[D_RMD160] = 1;
1286 else if (strcmp(*argv, "rmd160") == 0)
1287 doit[D_RMD160] = 1;
1288 else if (strcmp(*argv, "ripemd160") == 0)
1289 doit[D_RMD160] = 1;
1290 else
1291#endif
1292#ifndef OPENSSL_NO_RC4
1293 if (strcmp(*argv, "rc4") == 0)
1294 doit[D_RC4] = 1;
1295 else
1296#endif
1297#ifndef OPENSSL_NO_DES
1298 if (strcmp(*argv, "des-cbc") == 0)
1299 doit[D_CBC_DES] = 1;
1300 else if (strcmp(*argv, "des-ede3") == 0)
1301 doit[D_EDE3_DES] = 1;
1302 else
1303#endif
1304#ifndef OPENSSL_NO_AES
1305 if (strcmp(*argv, "aes-128-cbc") == 0)
1306 doit[D_CBC_128_AES] = 1;
1307 else if (strcmp(*argv, "aes-192-cbc") == 0)
1308 doit[D_CBC_192_AES] = 1;
1309 else if (strcmp(*argv, "aes-256-cbc") == 0)
1310 doit[D_CBC_256_AES] = 1;
1311 else if (strcmp(*argv, "aes-128-ige") == 0)
1312 doit[D_IGE_128_AES] = 1;
1313 else if (strcmp(*argv, "aes-192-ige") == 0)
1314 doit[D_IGE_192_AES] = 1;
1315 else if (strcmp(*argv, "aes-256-ige") == 0)
1316 doit[D_IGE_256_AES] = 1;
1317 else
1318#endif
1319#ifndef OPENSSL_NO_CAMELLIA
1320 if (strcmp(*argv, "camellia-128-cbc") == 0)
1321 doit[D_CBC_128_CML] = 1;
1322 else if (strcmp(*argv, "camellia-192-cbc") == 0)
1323 doit[D_CBC_192_CML] = 1;
1324 else if (strcmp(*argv, "camellia-256-cbc") == 0)
1325 doit[D_CBC_256_CML] = 1;
1326 else
1327#endif
1328#ifndef RSA_NULL
1329 if (strcmp(*argv, "openssl") == 0) {
1330 RSA_set_default_method(RSA_PKCS1_SSLeay());
1331 j--;
1332 } else
1333#endif
1334 if (strcmp(*argv, "dsa512") == 0)
1335 dsa_doit[R_DSA_512] = 2;
1336 else if (strcmp(*argv, "dsa1024") == 0)
1337 dsa_doit[R_DSA_1024] = 2;
1338 else if (strcmp(*argv, "dsa2048") == 0)
1339 dsa_doit[R_DSA_2048] = 2;
1340 else if (strcmp(*argv, "rsa512") == 0)
1341 rsa_doit[R_RSA_512] = 2;
1342 else if (strcmp(*argv, "rsa1024") == 0)
1343 rsa_doit[R_RSA_1024] = 2;
1344 else if (strcmp(*argv, "rsa2048") == 0)
1345 rsa_doit[R_RSA_2048] = 2;
1346 else if (strcmp(*argv, "rsa4096") == 0)
1347 rsa_doit[R_RSA_4096] = 2;
1348 else
1349#ifndef OPENSSL_NO_RC2
1350 if (strcmp(*argv, "rc2-cbc") == 0)
1351 doit[D_CBC_RC2] = 1;
1352 else if (strcmp(*argv, "rc2") == 0)
1353 doit[D_CBC_RC2] = 1;
1354 else
1355#endif
1356#ifndef OPENSSL_NO_IDEA
1357 if (strcmp(*argv, "idea-cbc") == 0)
1358 doit[D_CBC_IDEA] = 1;
1359 else if (strcmp(*argv, "idea") == 0)
1360 doit[D_CBC_IDEA] = 1;
1361 else
1362#endif
1363#ifndef OPENSSL_NO_BF
1364 if (strcmp(*argv, "bf-cbc") == 0)
1365 doit[D_CBC_BF] = 1;
1366 else if (strcmp(*argv, "blowfish") == 0)
1367 doit[D_CBC_BF] = 1;
1368 else if (strcmp(*argv, "bf") == 0)
1369 doit[D_CBC_BF] = 1;
1370 else
1371#endif
1372#ifndef OPENSSL_NO_CAST
1373 if (strcmp(*argv, "cast-cbc") == 0)
1374 doit[D_CBC_CAST] = 1;
1375 else if (strcmp(*argv, "cast") == 0)
1376 doit[D_CBC_CAST] = 1;
1377 else if (strcmp(*argv, "cast5") == 0)
1378 doit[D_CBC_CAST] = 1;
1379 else
1380#endif
1381#ifndef OPENSSL_NO_DES
1382 if (strcmp(*argv, "des") == 0) {
1383 doit[D_CBC_DES] = 1;
1384 doit[D_EDE3_DES] = 1;
1385 } else
1386#endif
1387#ifndef OPENSSL_NO_AES
1388 if (strcmp(*argv, "aes") == 0) {
1389 doit[D_CBC_128_AES] = 1;
1390 doit[D_CBC_192_AES] = 1;
1391 doit[D_CBC_256_AES] = 1;
1392 } else if (strcmp(*argv, "ghash") == 0)
1393 doit[D_GHASH] = 1;
1394 else if (strcmp(*argv,"aes-128-gcm") == 0)
1395 doit[D_AES_128_GCM]=1;
1396 else if (strcmp(*argv,"aes-256-gcm") == 0)
1397 doit[D_AES_256_GCM]=1;
1398 else
1399#endif
1400#ifndef OPENSSL_NO_CAMELLIA
1401 if (strcmp(*argv, "camellia") == 0) {
1402 doit[D_CBC_128_CML] = 1;
1403 doit[D_CBC_192_CML] = 1;
1404 doit[D_CBC_256_CML] = 1;
1405 } else
1406#endif
1407#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
1408 if (strcmp(*argv,"chacha20-poly1305") == 0)
1409 doit[D_CHACHA20_POLY1305]=1;
1410 else
1411#endif
1412 if (strcmp(*argv, "rsa") == 0) {
1413 rsa_doit[R_RSA_512] = 1;
1414 rsa_doit[R_RSA_1024] = 1;
1415 rsa_doit[R_RSA_2048] = 1;
1416 rsa_doit[R_RSA_4096] = 1;
1417 } else if (strcmp(*argv, "dsa") == 0) {
1418 dsa_doit[R_DSA_512] = 1;
1419 dsa_doit[R_DSA_1024] = 1;
1420 dsa_doit[R_DSA_2048] = 1;
1421 } else if (strcmp(*argv, "ecdsap224") == 0)
1422 ecdsa_doit[R_EC_P224] = 2;
1423 else if (strcmp(*argv, "ecdsap256") == 0)
1424 ecdsa_doit[R_EC_P256] = 2;
1425 else if (strcmp(*argv, "ecdsap384") == 0)
1426 ecdsa_doit[R_EC_P384] = 2;
1427 else if (strcmp(*argv, "ecdsap521") == 0)
1428 ecdsa_doit[R_EC_P521] = 2;
1429 else if (strcmp(*argv, "ecdsa") == 0) {
1430 for (i = 0; i < EC_NUM; i++)
1431 ecdsa_doit[i] = 1;
1432 } else if (strcmp(*argv, "ecdhp224") == 0)
1433 ecdh_doit[R_EC_P224] = 2;
1434 else if (strcmp(*argv, "ecdhp256") == 0)
1435 ecdh_doit[R_EC_P256] = 2;
1436 else if (strcmp(*argv, "ecdhp384") == 0)
1437 ecdh_doit[R_EC_P384] = 2;
1438 else if (strcmp(*argv, "ecdhp521") == 0)
1439 ecdh_doit[R_EC_P521] = 2;
1440 else if (strcmp(*argv, "ecdh") == 0) {
1441 for (i = 0; i < EC_NUM; i++)
1442 ecdh_doit[i] = 1;
1443 } else {
1444 BIO_printf(bio_err, "Error: bad option or value\n");
1445 BIO_printf(bio_err, "\n");
1446 BIO_printf(bio_err, "Available values:\n");
1447#ifndef OPENSSL_NO_MD4
1448 BIO_printf(bio_err, "md4 ");
1449#endif
1450#ifndef OPENSSL_NO_MD5
1451 BIO_printf(bio_err, "md5 ");
1452#ifndef OPENSSL_NO_HMAC
1453 BIO_printf(bio_err, "hmac ");
1454#endif
1455#endif
1456#ifndef OPENSSL_NO_SHA1
1457 BIO_printf(bio_err, "sha1 ");
1458#endif
1459#ifndef OPENSSL_NO_SHA256
1460 BIO_printf(bio_err, "sha256 ");
1461#endif
1462#ifndef OPENSSL_NO_SHA512
1463 BIO_printf(bio_err, "sha512 ");
1464#endif
1465#ifndef OPENSSL_NO_WHIRLPOOL
1466 BIO_printf(bio_err, "whirlpool");
1467#endif
1468#ifndef OPENSSL_NO_RIPEMD160
1469 BIO_printf(bio_err, "rmd160");
1470#endif
1471#if !defined(OPENSSL_NO_MD2) || \
1472 !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
1473 !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \
1474 !defined(OPENSSL_NO_WHIRLPOOL)
1475 BIO_printf(bio_err, "\n");
1476#endif
1477
1478#ifndef OPENSSL_NO_IDEA
1479 BIO_printf(bio_err, "idea-cbc ");
1480#endif
1481#ifndef OPENSSL_NO_RC2
1482 BIO_printf(bio_err, "rc2-cbc ");
1483#endif
1484#ifndef OPENSSL_NO_BF
1485 BIO_printf(bio_err, "bf-cbc ");
1486#endif
1487#ifndef OPENSSL_NO_DES
1488 BIO_printf(bio_err, "des-cbc des-ede3\n");
1489#endif
1490#ifndef OPENSSL_NO_AES
1491 BIO_printf(bio_err, "aes-128-cbc aes-192-cbc aes-256-cbc ");
1492 BIO_printf(bio_err, "aes-128-ige aes-192-ige aes-256-ige\n");
1493 BIO_printf(bio_err, "aes-128-gcm aes-256-gcm ");
1494#endif
1495#ifndef OPENSSL_NO_CAMELLIA
1496 BIO_printf(bio_err, "\n");
1497 BIO_printf(bio_err, "camellia-128-cbc camellia-192-cbc camellia-256-cbc ");
1498#endif
1499#ifndef OPENSSL_NO_RC4
1500 BIO_printf(bio_err, "rc4");
1501#endif
1502#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
1503 BIO_printf(bio_err," chacha20-poly1305");
1504#endif
1505 BIO_printf(bio_err, "\n");
1506
1507 BIO_printf(bio_err, "rsa512 rsa1024 rsa2048 rsa4096\n");
1508
1509 BIO_printf(bio_err, "dsa512 dsa1024 dsa2048\n");
1510 BIO_printf(bio_err, "ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
1511 BIO_printf(bio_err, "ecdhp224 ecdhp256 ecdhp384 ecdhp521\n");
1512
1513#ifndef OPENSSL_NO_IDEA
1514 BIO_printf(bio_err, "idea ");
1515#endif
1516#ifndef OPENSSL_NO_RC2
1517 BIO_printf(bio_err, "rc2 ");
1518#endif
1519#ifndef OPENSSL_NO_DES
1520 BIO_printf(bio_err, "des ");
1521#endif
1522#ifndef OPENSSL_NO_AES
1523 BIO_printf(bio_err, "aes ");
1524#endif
1525#ifndef OPENSSL_NO_CAMELLIA
1526 BIO_printf(bio_err, "camellia ");
1527#endif
1528 BIO_printf(bio_err, "rsa ");
1529#ifndef OPENSSL_NO_BF
1530 BIO_printf(bio_err, "blowfish");
1531#endif
1532#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
1533 !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
1534 !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
1535 !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
1536 BIO_printf(bio_err, "\n");
1537#endif
1538
1539 BIO_printf(bio_err, "\n");
1540 BIO_printf(bio_err, "Available options:\n");
1541 BIO_printf(bio_err, "-elapsed measure time in real time instead of CPU user time.\n");
1542 BIO_printf(bio_err, "-evp e use EVP e.\n");
1543 BIO_printf(bio_err, "-decrypt time decryption instead of encryption (only EVP).\n");
1544 BIO_printf(bio_err, "-mr produce machine readable output.\n");
1545 BIO_printf(bio_err, "-multi n run n benchmarks in parallel.\n");
1546 BIO_printf(bio_err, "-unaligned n use buffers with offset n from proper alignment.\n");
1547 goto end;
1548 }
1549 argc--;
1550 argv++;
1551 j++;
1552 }
1553
1554 if (multi && do_multi(multi))
1555 goto show_res;
1556
1557 if (j == 0) {
1558 for (i = 0; i < ALGOR_NUM; i++) {
1559 if (i != D_EVP)
1560 doit[i] = 1;
1561 }
1562 for (i = 0; i < RSA_NUM; i++)
1563 rsa_doit[i] = 1;
1564 for (i = 0; i < DSA_NUM; i++)
1565 dsa_doit[i] = 1;
1566 for (i = 0; i < EC_NUM; i++)
1567 ecdsa_doit[i] = 1;
1568 for (i = 0; i < EC_NUM; i++)
1569 ecdh_doit[i] = 1;
1570 }
1571 for (i = 0; i < ALGOR_NUM; i++)
1572 if (doit[i])
1573 pr_header++;
1574
1575 if (usertime == 0 && !mr)
1576 BIO_printf(bio_err, "You have chosen to measure elapsed time instead of user CPU time.\n");
1577
1578 for (i = 0; i < RSA_NUM; i++) {
1579 const unsigned char *p;
1580
1581 p = rsa_data[i];
1582 rsa_key[i] = d2i_RSAPrivateKey(NULL, &p, rsa_data_length[i]);
1583 if (rsa_key[i] == NULL) {
1584 BIO_printf(bio_err, "internal error loading RSA key number %d\n", i);
1585 goto end;
1586 }
1587 }
1588
1589 dsa_key[0] = get_dsa512();
1590 dsa_key[1] = get_dsa1024();
1591 dsa_key[2] = get_dsa2048();
1592
1593#ifndef OPENSSL_NO_DES
1594 DES_set_key_unchecked(&key, &sch);
1595 DES_set_key_unchecked(&key2, &sch2);
1596 DES_set_key_unchecked(&key3, &sch3);
1597#endif
1598#ifndef OPENSSL_NO_AES
1599 AES_set_encrypt_key(key16, 128, &aes_ks1);
1600 AES_set_encrypt_key(key24, 192, &aes_ks2);
1601 AES_set_encrypt_key(key32, 256, &aes_ks3);
1602#endif
1603#ifndef OPENSSL_NO_CAMELLIA
1604 Camellia_set_key(key16, 128, &camellia_ks1);
1605 Camellia_set_key(ckey24, 192, &camellia_ks2);
1606 Camellia_set_key(ckey32, 256, &camellia_ks3);
1607#endif
1608#ifndef OPENSSL_NO_IDEA
1609 idea_set_encrypt_key(key16, &idea_ks);
1610#endif
1611#ifndef OPENSSL_NO_RC4
1612 RC4_set_key(&rc4_ks, 16, key16);
1613#endif
1614#ifndef OPENSSL_NO_RC2
1615 RC2_set_key(&rc2_ks, 16, key16, 128);
1616#endif
1617#ifndef OPENSSL_NO_BF
1618 BF_set_key(&bf_ks, 16, key16);
1619#endif
1620#ifndef OPENSSL_NO_CAST
1621 CAST_set_key(&cast_ks, 16, key16);
1622#endif
1623 memset(rsa_c, 0, sizeof(rsa_c));
1624#define COND(c) (run && count<0x7fffffff)
1625#define COUNT(d) (count)
1626
1627 memset(&sa, 0, sizeof(sa));
1628 sigemptyset(&sa.sa_mask);
1629 sa.sa_flags = SA_RESTART;
1630 sa.sa_handler = sig_done;
1631 sigaction(SIGALRM, &sa, NULL);
1632
1633#ifndef OPENSSL_NO_MD4
1634 if (doit[D_MD4]) {
1635 for (j = 0; j < SIZE_NUM; j++) {
1636 print_message(names[D_MD4], c[D_MD4][j], lengths[j]);
1637 Time_F(START);
1638 for (count = 0, run = 1; COND(c[D_MD4][j]); count++)
1639 EVP_Digest(&(buf[0]), (unsigned long) lengths[j], &(md4[0]), NULL, EVP_md4(), NULL);
1640 d = Time_F(STOP);
1641 print_result(D_MD4, j, count, d);
1642 }
1643 }
1644#endif
1645
1646#ifndef OPENSSL_NO_MD5
1647 if (doit[D_MD5]) {
1648 for (j = 0; j < SIZE_NUM; j++) {
1649 print_message(names[D_MD5], c[D_MD5][j], lengths[j]);
1650 Time_F(START);
1651 for (count = 0, run = 1; COND(c[D_MD5][j]); count++)
1652 EVP_Digest(&(buf[0]), (unsigned long) lengths[j], &(md5[0]), NULL, EVP_get_digestbyname("md5"), NULL);
1653 d = Time_F(STOP);
1654 print_result(D_MD5, j, count, d);
1655 }
1656 }
1657#endif
1658
1659#if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC)
1660 if (doit[D_HMAC]) {
1661 HMAC_CTX *hctx;
1662
1663 if ((hctx = HMAC_CTX_new()) == NULL) {
1664 BIO_printf(bio_err, "Failed to allocate HMAC context.\n");
1665 goto end;
1666 }
1667
1668 HMAC_Init_ex(hctx, (unsigned char *) "This is a key...",
1669 16, EVP_md5(), NULL);
1670
1671 for (j = 0; j < SIZE_NUM; j++) {
1672 print_message(names[D_HMAC], c[D_HMAC][j], lengths[j]);
1673 Time_F(START);
1674 for (count = 0, run = 1; COND(c[D_HMAC][j]); count++) {
1675 if (!HMAC_Init_ex(hctx, NULL, 0, NULL, NULL)) {
1676 HMAC_CTX_free(hctx);
1677 goto end;
1678 }
1679 if (!HMAC_Update(hctx, buf, lengths[j])) {
1680 HMAC_CTX_free(hctx);
1681 goto end;
1682 }
1683 if (!HMAC_Final(hctx, &(hmac[0]), NULL)) {
1684 HMAC_CTX_free(hctx);
1685 goto end;
1686 }
1687 }
1688 d = Time_F(STOP);
1689 print_result(D_HMAC, j, count, d);
1690 }
1691 HMAC_CTX_free(hctx);
1692 }
1693#endif
1694#ifndef OPENSSL_NO_SHA
1695 if (doit[D_SHA1]) {
1696 for (j = 0; j < SIZE_NUM; j++) {
1697 print_message(names[D_SHA1], c[D_SHA1][j], lengths[j]);
1698 Time_F(START);
1699 for (count = 0, run = 1; COND(c[D_SHA1][j]); count++)
1700 EVP_Digest(buf, (unsigned long) lengths[j], &(sha[0]), NULL, EVP_sha1(), NULL);
1701 d = Time_F(STOP);
1702 print_result(D_SHA1, j, count, d);
1703 }
1704 }
1705#ifndef OPENSSL_NO_SHA256
1706 if (doit[D_SHA256]) {
1707 for (j = 0; j < SIZE_NUM; j++) {
1708 print_message(names[D_SHA256], c[D_SHA256][j], lengths[j]);
1709 Time_F(START);
1710 for (count = 0, run = 1; COND(c[D_SHA256][j]); count++)
1711 SHA256(buf, lengths[j], sha256);
1712 d = Time_F(STOP);
1713 print_result(D_SHA256, j, count, d);
1714 }
1715 }
1716#endif
1717
1718#ifndef OPENSSL_NO_SHA512
1719 if (doit[D_SHA512]) {
1720 for (j = 0; j < SIZE_NUM; j++) {
1721 print_message(names[D_SHA512], c[D_SHA512][j], lengths[j]);
1722 Time_F(START);
1723 for (count = 0, run = 1; COND(c[D_SHA512][j]); count++)
1724 SHA512(buf, lengths[j], sha512);
1725 d = Time_F(STOP);
1726 print_result(D_SHA512, j, count, d);
1727 }
1728 }
1729#endif
1730#endif
1731
1732#ifndef OPENSSL_NO_WHIRLPOOL
1733 if (doit[D_WHIRLPOOL]) {
1734 for (j = 0; j < SIZE_NUM; j++) {
1735 print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][j], lengths[j]);
1736 Time_F(START);
1737 for (count = 0, run = 1; COND(c[D_WHIRLPOOL][j]); count++)
1738 WHIRLPOOL(buf, lengths[j], whirlpool);
1739 d = Time_F(STOP);
1740 print_result(D_WHIRLPOOL, j, count, d);
1741 }
1742 }
1743#endif
1744
1745#ifndef OPENSSL_NO_RIPEMD
1746 if (doit[D_RMD160]) {
1747 for (j = 0; j < SIZE_NUM; j++) {
1748 print_message(names[D_RMD160], c[D_RMD160][j], lengths[j]);
1749 Time_F(START);
1750 for (count = 0, run = 1; COND(c[D_RMD160][j]); count++)
1751 EVP_Digest(buf, (unsigned long) lengths[j], &(rmd160[0]), NULL, EVP_ripemd160(), NULL);
1752 d = Time_F(STOP);
1753 print_result(D_RMD160, j, count, d);
1754 }
1755 }
1756#endif
1757#ifndef OPENSSL_NO_RC4
1758 if (doit[D_RC4]) {
1759 for (j = 0; j < SIZE_NUM; j++) {
1760 print_message(names[D_RC4], c[D_RC4][j], lengths[j]);
1761 Time_F(START);
1762 for (count = 0, run = 1; COND(c[D_RC4][j]); count++)
1763 RC4(&rc4_ks, (unsigned int) lengths[j],
1764 buf, buf);
1765 d = Time_F(STOP);
1766 print_result(D_RC4, j, count, d);
1767 }
1768 }
1769#endif
1770#ifndef OPENSSL_NO_DES
1771 if (doit[D_CBC_DES]) {
1772 for (j = 0; j < SIZE_NUM; j++) {
1773 print_message(names[D_CBC_DES], c[D_CBC_DES][j], lengths[j]);
1774 Time_F(START);
1775 for (count = 0, run = 1; COND(c[D_CBC_DES][j]); count++)
1776 DES_ncbc_encrypt(buf, buf, lengths[j], &sch,
1777 &DES_iv, DES_ENCRYPT);
1778 d = Time_F(STOP);
1779 print_result(D_CBC_DES, j, count, d);
1780 }
1781 }
1782 if (doit[D_EDE3_DES]) {
1783 for (j = 0; j < SIZE_NUM; j++) {
1784 print_message(names[D_EDE3_DES], c[D_EDE3_DES][j], lengths[j]);
1785 Time_F(START);
1786 for (count = 0, run = 1; COND(c[D_EDE3_DES][j]); count++)
1787 DES_ede3_cbc_encrypt(buf, buf, lengths[j],
1788 &sch, &sch2, &sch3,
1789 &DES_iv, DES_ENCRYPT);
1790 d = Time_F(STOP);
1791 print_result(D_EDE3_DES, j, count, d);
1792 }
1793 }
1794#endif
1795#ifndef OPENSSL_NO_AES
1796 if (doit[D_CBC_128_AES]) {
1797 for (j = 0; j < SIZE_NUM; j++) {
1798 print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][j], lengths[j]);
1799 Time_F(START);
1800 for (count = 0, run = 1; COND(c[D_CBC_128_AES][j]); count++)
1801 AES_cbc_encrypt(buf, buf,
1802 (unsigned long) lengths[j], &aes_ks1,
1803 iv, AES_ENCRYPT);
1804 d = Time_F(STOP);
1805 print_result(D_CBC_128_AES, j, count, d);
1806 }
1807 }
1808 if (doit[D_CBC_192_AES]) {
1809 for (j = 0; j < SIZE_NUM; j++) {
1810 print_message(names[D_CBC_192_AES], c[D_CBC_192_AES][j], lengths[j]);
1811 Time_F(START);
1812 for (count = 0, run = 1; COND(c[D_CBC_192_AES][j]); count++)
1813 AES_cbc_encrypt(buf, buf,
1814 (unsigned long) lengths[j], &aes_ks2,
1815 iv, AES_ENCRYPT);
1816 d = Time_F(STOP);
1817 print_result(D_CBC_192_AES, j, count, d);
1818 }
1819 }
1820 if (doit[D_CBC_256_AES]) {
1821 for (j = 0; j < SIZE_NUM; j++) {
1822 print_message(names[D_CBC_256_AES], c[D_CBC_256_AES][j], lengths[j]);
1823 Time_F(START);
1824 for (count = 0, run = 1; COND(c[D_CBC_256_AES][j]); count++)
1825 AES_cbc_encrypt(buf, buf,
1826 (unsigned long) lengths[j], &aes_ks3,
1827 iv, AES_ENCRYPT);
1828 d = Time_F(STOP);
1829 print_result(D_CBC_256_AES, j, count, d);
1830 }
1831 }
1832 if (doit[D_IGE_128_AES]) {
1833 for (j = 0; j < SIZE_NUM; j++) {
1834 print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][j], lengths[j]);
1835 Time_F(START);
1836 for (count = 0, run = 1; COND(c[D_IGE_128_AES][j]); count++)
1837 AES_ige_encrypt(buf, buf2,
1838 (unsigned long) lengths[j], &aes_ks1,
1839 iv, AES_ENCRYPT);
1840 d = Time_F(STOP);
1841 print_result(D_IGE_128_AES, j, count, d);
1842 }
1843 }
1844 if (doit[D_IGE_192_AES]) {
1845 for (j = 0; j < SIZE_NUM; j++) {
1846 print_message(names[D_IGE_192_AES], c[D_IGE_192_AES][j], lengths[j]);
1847 Time_F(START);
1848 for (count = 0, run = 1; COND(c[D_IGE_192_AES][j]); count++)
1849 AES_ige_encrypt(buf, buf2,
1850 (unsigned long) lengths[j], &aes_ks2,
1851 iv, AES_ENCRYPT);
1852 d = Time_F(STOP);
1853 print_result(D_IGE_192_AES, j, count, d);
1854 }
1855 }
1856 if (doit[D_IGE_256_AES]) {
1857 for (j = 0; j < SIZE_NUM; j++) {
1858 print_message(names[D_IGE_256_AES], c[D_IGE_256_AES][j], lengths[j]);
1859 Time_F(START);
1860 for (count = 0, run = 1; COND(c[D_IGE_256_AES][j]); count++)
1861 AES_ige_encrypt(buf, buf2,
1862 (unsigned long) lengths[j], &aes_ks3,
1863 iv, AES_ENCRYPT);
1864 d = Time_F(STOP);
1865 print_result(D_IGE_256_AES, j, count, d);
1866 }
1867 }
1868 if (doit[D_GHASH]) {
1869 GCM128_CONTEXT *ctx = CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt);
1870 CRYPTO_gcm128_setiv(ctx, (unsigned char *) "0123456789ab", 12);
1871
1872 for (j = 0; j < SIZE_NUM; j++) {
1873 print_message(names[D_GHASH], c[D_GHASH][j], lengths[j]);
1874 Time_F(START);
1875 for (count = 0, run = 1; COND(c[D_GHASH][j]); count++)
1876 CRYPTO_gcm128_aad(ctx, buf, lengths[j]);
1877 d = Time_F(STOP);
1878 print_result(D_GHASH, j, count, d);
1879 }
1880 CRYPTO_gcm128_release(ctx);
1881 }
1882 if (doit[D_AES_128_GCM]) {
1883 const EVP_AEAD *aead = EVP_aead_aes_128_gcm();
1884 static const unsigned char nonce[32] = {0};
1885 size_t buf_len, nonce_len;
1886 EVP_AEAD_CTX *ctx;
1887
1888 if ((ctx = EVP_AEAD_CTX_new()) == NULL) {
1889 BIO_printf(bio_err,
1890 "Failed to allocate aead context.\n");
1891 goto end;
1892 }
1893
1894 EVP_AEAD_CTX_init(ctx, aead, key32, EVP_AEAD_key_length(aead),
1895 EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
1896 nonce_len = EVP_AEAD_nonce_length(aead);
1897
1898 for (j = 0; j < SIZE_NUM; j++) {
1899 print_message(names[D_AES_128_GCM],c[D_AES_128_GCM][j],lengths[j]);
1900 Time_F(START);
1901 for (count = 0, run = 1; COND(c[D_AES_128_GCM][j]); count++)
1902 EVP_AEAD_CTX_seal(ctx, buf, &buf_len, BUFSIZE, nonce,
1903 nonce_len, buf, lengths[j], NULL, 0);
1904 d=Time_F(STOP);
1905 print_result(D_AES_128_GCM,j,count,d);
1906 }
1907 EVP_AEAD_CTX_free(ctx);
1908 }
1909
1910 if (doit[D_AES_256_GCM]) {
1911 const EVP_AEAD *aead = EVP_aead_aes_256_gcm();
1912 static const unsigned char nonce[32] = {0};
1913 size_t buf_len, nonce_len;
1914 EVP_AEAD_CTX *ctx;
1915
1916 if ((ctx = EVP_AEAD_CTX_new()) == NULL) {
1917 BIO_printf(bio_err,
1918 "Failed to allocate aead context.\n");
1919 goto end;
1920 }
1921
1922 EVP_AEAD_CTX_init(ctx, aead, key32, EVP_AEAD_key_length(aead),
1923 EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
1924 nonce_len = EVP_AEAD_nonce_length(aead);
1925
1926 for (j = 0; j < SIZE_NUM; j++) {
1927 print_message(names[D_AES_256_GCM],c[D_AES_256_GCM][j],lengths[j]);
1928 Time_F(START);
1929 for (count = 0, run = 1; COND(c[D_AES_256_GCM][j]); count++)
1930 EVP_AEAD_CTX_seal(ctx, buf, &buf_len, BUFSIZE, nonce,
1931 nonce_len, buf, lengths[j], NULL, 0);
1932 d=Time_F(STOP);
1933 print_result(D_AES_256_GCM, j, count, d);
1934 }
1935 EVP_AEAD_CTX_free(ctx);
1936 }
1937#endif
1938#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
1939 if (doit[D_CHACHA20_POLY1305]) {
1940 const EVP_AEAD *aead = EVP_aead_chacha20_poly1305();
1941 static const unsigned char nonce[32] = {0};
1942 size_t buf_len, nonce_len;
1943 EVP_AEAD_CTX *ctx;
1944
1945 if ((ctx = EVP_AEAD_CTX_new()) == NULL) {
1946 BIO_printf(bio_err,
1947 "Failed to allocate aead context.\n");
1948 goto end;
1949 }
1950
1951 EVP_AEAD_CTX_init(ctx, aead, key32, EVP_AEAD_key_length(aead),
1952 EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
1953 nonce_len = EVP_AEAD_nonce_length(aead);
1954
1955 for (j = 0; j < SIZE_NUM; j++) {
1956 print_message(names[D_CHACHA20_POLY1305],
1957 c[D_CHACHA20_POLY1305][j], lengths[j]);
1958 Time_F(START);
1959 for (count = 0, run = 1; COND(c[D_CHACHA20_POLY1305][j]); count++)
1960 EVP_AEAD_CTX_seal(ctx, buf, &buf_len, BUFSIZE, nonce,
1961 nonce_len, buf, lengths[j], NULL, 0);
1962 d=Time_F(STOP);
1963 print_result(D_CHACHA20_POLY1305, j, count, d);
1964 }
1965 EVP_AEAD_CTX_free(ctx);
1966 }
1967#endif
1968#ifndef OPENSSL_NO_CAMELLIA
1969 if (doit[D_CBC_128_CML]) {
1970 for (j = 0; j < SIZE_NUM; j++) {
1971 print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][j], lengths[j]);
1972 Time_F(START);
1973 for (count = 0, run = 1; COND(c[D_CBC_128_CML][j]); count++)
1974 Camellia_cbc_encrypt(buf, buf,
1975 (unsigned long) lengths[j], &camellia_ks1,
1976 iv, CAMELLIA_ENCRYPT);
1977 d = Time_F(STOP);
1978 print_result(D_CBC_128_CML, j, count, d);
1979 }
1980 }
1981 if (doit[D_CBC_192_CML]) {
1982 for (j = 0; j < SIZE_NUM; j++) {
1983 print_message(names[D_CBC_192_CML], c[D_CBC_192_CML][j], lengths[j]);
1984 Time_F(START);
1985 for (count = 0, run = 1; COND(c[D_CBC_192_CML][j]); count++)
1986 Camellia_cbc_encrypt(buf, buf,
1987 (unsigned long) lengths[j], &camellia_ks2,
1988 iv, CAMELLIA_ENCRYPT);
1989 d = Time_F(STOP);
1990 print_result(D_CBC_192_CML, j, count, d);
1991 }
1992 }
1993 if (doit[D_CBC_256_CML]) {
1994 for (j = 0; j < SIZE_NUM; j++) {
1995 print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][j], lengths[j]);
1996 Time_F(START);
1997 for (count = 0, run = 1; COND(c[D_CBC_256_CML][j]); count++)
1998 Camellia_cbc_encrypt(buf, buf,
1999 (unsigned long) lengths[j], &camellia_ks3,
2000 iv, CAMELLIA_ENCRYPT);
2001 d = Time_F(STOP);
2002 print_result(D_CBC_256_CML, j, count, d);
2003 }
2004 }
2005#endif
2006#ifndef OPENSSL_NO_IDEA
2007 if (doit[D_CBC_IDEA]) {
2008 for (j = 0; j < SIZE_NUM; j++) {
2009 print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][j], lengths[j]);
2010 Time_F(START);
2011 for (count = 0, run = 1; COND(c[D_CBC_IDEA][j]); count++)
2012 idea_cbc_encrypt(buf, buf,
2013 (unsigned long) lengths[j], &idea_ks,
2014 iv, IDEA_ENCRYPT);
2015 d = Time_F(STOP);
2016 print_result(D_CBC_IDEA, j, count, d);
2017 }
2018 }
2019#endif
2020#ifndef OPENSSL_NO_RC2
2021 if (doit[D_CBC_RC2]) {
2022 for (j = 0; j < SIZE_NUM; j++) {
2023 print_message(names[D_CBC_RC2], c[D_CBC_RC2][j], lengths[j]);
2024 Time_F(START);
2025 for (count = 0, run = 1; COND(c[D_CBC_RC2][j]); count++)
2026 RC2_cbc_encrypt(buf, buf,
2027 (unsigned long) lengths[j], &rc2_ks,
2028 iv, RC2_ENCRYPT);
2029 d = Time_F(STOP);
2030 print_result(D_CBC_RC2, j, count, d);
2031 }
2032 }
2033#endif
2034#ifndef OPENSSL_NO_BF
2035 if (doit[D_CBC_BF]) {
2036 for (j = 0; j < SIZE_NUM; j++) {
2037 print_message(names[D_CBC_BF], c[D_CBC_BF][j], lengths[j]);
2038 Time_F(START);
2039 for (count = 0, run = 1; COND(c[D_CBC_BF][j]); count++)
2040 BF_cbc_encrypt(buf, buf,
2041 (unsigned long) lengths[j], &bf_ks,
2042 iv, BF_ENCRYPT);
2043 d = Time_F(STOP);
2044 print_result(D_CBC_BF, j, count, d);
2045 }
2046 }
2047#endif
2048#ifndef OPENSSL_NO_CAST
2049 if (doit[D_CBC_CAST]) {
2050 for (j = 0; j < SIZE_NUM; j++) {
2051 print_message(names[D_CBC_CAST], c[D_CBC_CAST][j], lengths[j]);
2052 Time_F(START);
2053 for (count = 0, run = 1; COND(c[D_CBC_CAST][j]); count++)
2054 CAST_cbc_encrypt(buf, buf,
2055 (unsigned long) lengths[j], &cast_ks,
2056 iv, CAST_ENCRYPT);
2057 d = Time_F(STOP);
2058 print_result(D_CBC_CAST, j, count, d);
2059 }
2060 }
2061#endif
2062
2063 if (doit[D_EVP]) {
2064 for (j = 0; j < SIZE_NUM; j++) {
2065 if (evp_cipher) {
2066 EVP_CIPHER_CTX *ctx;
2067 int outl;
2068
2069 names[D_EVP] =
2070 OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
2071 /*
2072 * -O3 -fschedule-insns messes up an
2073 * optimization here! names[D_EVP] somehow
2074 * becomes NULL
2075 */
2076 print_message(names[D_EVP], save_count,
2077 lengths[j]);
2078
2079 if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
2080 BIO_printf(bio_err, "Failed to "
2081 "allocate cipher context.\n");
2082 goto end;
2083 }
2084 if (decrypt)
2085 EVP_DecryptInit_ex(ctx, evp_cipher, NULL, key16, iv);
2086 else
2087 EVP_EncryptInit_ex(ctx, evp_cipher, NULL, key16, iv);
2088 EVP_CIPHER_CTX_set_padding(ctx, 0);
2089
2090 Time_F(START);
2091 if (decrypt)
2092 for (count = 0, run = 1; COND(save_count * 4 * lengths[0] / lengths[j]); count++)
2093 EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[j]);
2094 else
2095 for (count = 0, run = 1; COND(save_count * 4 * lengths[0] / lengths[j]); count++)
2096 EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[j]);
2097 if (decrypt)
2098 EVP_DecryptFinal_ex(ctx, buf, &outl);
2099 else
2100 EVP_EncryptFinal_ex(ctx, buf, &outl);
2101 d = Time_F(STOP);
2102 EVP_CIPHER_CTX_free(ctx);
2103 }
2104 if (evp_md) {
2105 names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md));
2106 print_message(names[D_EVP], save_count,
2107 lengths[j]);
2108
2109 Time_F(START);
2110 for (count = 0, run = 1; COND(save_count * 4 * lengths[0] / lengths[j]); count++)
2111 EVP_Digest(buf, lengths[j], &(md[0]), NULL, evp_md, NULL);
2112
2113 d = Time_F(STOP);
2114 }
2115 print_result(D_EVP, j, count, d);
2116 }
2117 }
2118 arc4random_buf(buf, 36);
2119 for (j = 0; j < RSA_NUM; j++) {
2120 int ret;
2121 if (!rsa_doit[j])
2122 continue;
2123 ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, &rsa_num, rsa_key[j]);
2124 if (ret == 0) {
2125 BIO_printf(bio_err, "RSA sign failure. No RSA sign will be done.\n");
2126 ERR_print_errors(bio_err);
2127 rsa_count = 1;
2128 } else {
2129 pkey_print_message("private", "rsa",
2130 rsa_c[j][0], rsa_bits[j],
2131 RSA_SECONDS);
2132/* RSA_blinding_on(rsa_key[j],NULL); */
2133 Time_F(START);
2134 for (count = 0, run = 1; COND(rsa_c[j][0]); count++) {
2135 ret = RSA_sign(NID_md5_sha1, buf, 36, buf2,
2136 &rsa_num, rsa_key[j]);
2137 if (ret == 0) {
2138 BIO_printf(bio_err,
2139 "RSA sign failure\n");
2140 ERR_print_errors(bio_err);
2141 count = 1;
2142 break;
2143 }
2144 }
2145 d = Time_F(STOP);
2146 BIO_printf(bio_err, mr ? "+R1:%ld:%d:%.2f\n"
2147 : "%ld %d bit private RSA in %.2fs\n",
2148 count, rsa_bits[j], d);
2149 rsa_results[j][0] = d / (double) count;
2150 rsa_count = count;
2151 }
2152
2153 ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[j]);
2154 if (ret <= 0) {
2155 BIO_printf(bio_err, "RSA verify failure. No RSA verify will be done.\n");
2156 ERR_print_errors(bio_err);
2157 rsa_doit[j] = 0;
2158 } else {
2159 pkey_print_message("public", "rsa",
2160 rsa_c[j][1], rsa_bits[j],
2161 RSA_SECONDS);
2162 Time_F(START);
2163 for (count = 0, run = 1; COND(rsa_c[j][1]); count++) {
2164 ret = RSA_verify(NID_md5_sha1, buf, 36, buf2,
2165 rsa_num, rsa_key[j]);
2166 if (ret <= 0) {
2167 BIO_printf(bio_err,
2168 "RSA verify failure\n");
2169 ERR_print_errors(bio_err);
2170 count = 1;
2171 break;
2172 }
2173 }
2174 d = Time_F(STOP);
2175 BIO_printf(bio_err, mr ? "+R2:%ld:%d:%.2f\n"
2176 : "%ld %d bit public RSA in %.2fs\n",
2177 count, rsa_bits[j], d);
2178 rsa_results[j][1] = d / (double) count;
2179 }
2180
2181 if (rsa_count <= 1) {
2182 /* if longer than 10s, don't do any more */
2183 for (j++; j < RSA_NUM; j++)
2184 rsa_doit[j] = 0;
2185 }
2186 }
2187
2188 arc4random_buf(buf, 20);
2189 for (j = 0; j < DSA_NUM; j++) {
2190 unsigned int kk;
2191 int ret;
2192
2193 if (!dsa_doit[j])
2194 continue;
2195/* DSA_generate_key(dsa_key[j]); */
2196/* DSA_sign_setup(dsa_key[j],NULL); */
2197 ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2,
2198 &kk, dsa_key[j]);
2199 if (ret == 0) {
2200 BIO_printf(bio_err, "DSA sign failure. No DSA sign will be done.\n");
2201 ERR_print_errors(bio_err);
2202 rsa_count = 1;
2203 } else {
2204 pkey_print_message("sign", "dsa",
2205 dsa_c[j][0], dsa_bits[j],
2206 DSA_SECONDS);
2207 Time_F(START);
2208 for (count = 0, run = 1; COND(dsa_c[j][0]); count++) {
2209 ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2,
2210 &kk, dsa_key[j]);
2211 if (ret == 0) {
2212 BIO_printf(bio_err,
2213 "DSA sign failure\n");
2214 ERR_print_errors(bio_err);
2215 count = 1;
2216 break;
2217 }
2218 }
2219 d = Time_F(STOP);
2220 BIO_printf(bio_err, mr ? "+R3:%ld:%d:%.2f\n"
2221 : "%ld %d bit DSA signs in %.2fs\n",
2222 count, dsa_bits[j], d);
2223 dsa_results[j][0] = d / (double) count;
2224 rsa_count = count;
2225 }
2226
2227 ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2,
2228 kk, dsa_key[j]);
2229 if (ret <= 0) {
2230 BIO_printf(bio_err, "DSA verify failure. No DSA verify will be done.\n");
2231 ERR_print_errors(bio_err);
2232 dsa_doit[j] = 0;
2233 } else {
2234 pkey_print_message("verify", "dsa",
2235 dsa_c[j][1], dsa_bits[j],
2236 DSA_SECONDS);
2237 Time_F(START);
2238 for (count = 0, run = 1; COND(dsa_c[j][1]); count++) {
2239 ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2,
2240 kk, dsa_key[j]);
2241 if (ret <= 0) {
2242 BIO_printf(bio_err,
2243 "DSA verify failure\n");
2244 ERR_print_errors(bio_err);
2245 count = 1;
2246 break;
2247 }
2248 }
2249 d = Time_F(STOP);
2250 BIO_printf(bio_err, mr ? "+R4:%ld:%d:%.2f\n"
2251 : "%ld %d bit DSA verify in %.2fs\n",
2252 count, dsa_bits[j], d);
2253 dsa_results[j][1] = d / (double) count;
2254 }
2255
2256 if (rsa_count <= 1) {
2257 /* if longer than 10s, don't do any more */
2258 for (j++; j < DSA_NUM; j++)
2259 dsa_doit[j] = 0;
2260 }
2261 }
2262
2263 for (j = 0; j < EC_NUM; j++) {
2264 int ret;
2265
2266 if (!ecdsa_doit[j])
2267 continue; /* Ignore Curve */
2268 ecdsa[j] = EC_KEY_new_by_curve_name(test_curves[j]);
2269 if (ecdsa[j] == NULL) {
2270 BIO_printf(bio_err, "ECDSA failure.\n");
2271 ERR_print_errors(bio_err);
2272 rsa_count = 1;
2273 } else {
2274 EC_KEY_precompute_mult(ecdsa[j], NULL);
2275
2276 /* Perform ECDSA signature test */
2277 EC_KEY_generate_key(ecdsa[j]);
2278 ret = ECDSA_sign(0, buf, 20, ecdsasig,
2279 &ecdsasiglen, ecdsa[j]);
2280 if (ret == 0) {
2281 BIO_printf(bio_err, "ECDSA sign failure. No ECDSA sign will be done.\n");
2282 ERR_print_errors(bio_err);
2283 rsa_count = 1;
2284 } else {
2285 pkey_print_message("sign", "ecdsa",
2286 ecdsa_c[j][0],
2287 test_curves_bits[j],
2288 ECDSA_SECONDS);
2289
2290 Time_F(START);
2291 for (count = 0, run = 1; COND(ecdsa_c[j][0]);
2292 count++) {
2293 ret = ECDSA_sign(0, buf, 20,
2294 ecdsasig, &ecdsasiglen,
2295 ecdsa[j]);
2296 if (ret == 0) {
2297 BIO_printf(bio_err, "ECDSA sign failure\n");
2298 ERR_print_errors(bio_err);
2299 count = 1;
2300 break;
2301 }
2302 }
2303 d = Time_F(STOP);
2304
2305 BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
2306 "%ld %d bit ECDSA signs in %.2fs \n",
2307 count, test_curves_bits[j], d);
2308 ecdsa_results[j][0] = d / (double) count;
2309 rsa_count = count;
2310 }
2311
2312 /* Perform ECDSA verification test */
2313 ret = ECDSA_verify(0, buf, 20, ecdsasig,
2314 ecdsasiglen, ecdsa[j]);
2315 if (ret != 1) {
2316 BIO_printf(bio_err, "ECDSA verify failure. No ECDSA verify will be done.\n");
2317 ERR_print_errors(bio_err);
2318 ecdsa_doit[j] = 0;
2319 } else {
2320 pkey_print_message("verify", "ecdsa",
2321 ecdsa_c[j][1],
2322 test_curves_bits[j],
2323 ECDSA_SECONDS);
2324 Time_F(START);
2325 for (count = 0, run = 1; COND(ecdsa_c[j][1]); count++) {
2326 ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
2327 if (ret != 1) {
2328 BIO_printf(bio_err, "ECDSA verify failure\n");
2329 ERR_print_errors(bio_err);
2330 count = 1;
2331 break;
2332 }
2333 }
2334 d = Time_F(STOP);
2335 BIO_printf(bio_err, mr ? "+R6:%ld:%d:%.2f\n"
2336 : "%ld %d bit ECDSA verify in %.2fs\n",
2337 count, test_curves_bits[j], d);
2338 ecdsa_results[j][1] = d / (double) count;
2339 }
2340
2341 if (rsa_count <= 1) {
2342 /* if longer than 10s, don't do any more */
2343 for (j++; j < EC_NUM; j++)
2344 ecdsa_doit[j] = 0;
2345 }
2346 }
2347 }
2348
2349 for (j = 0; j < EC_NUM; j++) {
2350 if (!ecdh_doit[j])
2351 continue;
2352 ecdh_a[j] = EC_KEY_new_by_curve_name(test_curves[j]);
2353 ecdh_b[j] = EC_KEY_new_by_curve_name(test_curves[j]);
2354 if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL)) {
2355 BIO_printf(bio_err, "ECDH failure.\n");
2356 ERR_print_errors(bio_err);
2357 rsa_count = 1;
2358 } else {
2359 /* generate two ECDH key pairs */
2360 if (!EC_KEY_generate_key(ecdh_a[j]) ||
2361 !EC_KEY_generate_key(ecdh_b[j])) {
2362 BIO_printf(bio_err, "ECDH key generation failure.\n");
2363 ERR_print_errors(bio_err);
2364 rsa_count = 1;
2365 } else {
2366 /*
2367 * If field size is not more than 24 octets,
2368 * then use SHA-1 hash of result; otherwise,
2369 * use result (see section 4.8 of
2370 * draft-ietf-tls-ecc-03.txt).
2371 */
2372 int field_size, outlen;
2373 void *(*kdf) (const void *in, size_t inlen, void *out, size_t * xoutlen);
2374 field_size = EC_GROUP_get_degree(EC_KEY_get0_group(ecdh_a[j]));
2375 if (field_size <= 24 * 8) {
2376 outlen = KDF1_SHA1_len;
2377 kdf = KDF1_SHA1;
2378 } else {
2379 outlen = (field_size + 7) / 8;
2380 kdf = NULL;
2381 }
2382 secret_size_a = ECDH_compute_key(secret_a, outlen,
2383 EC_KEY_get0_public_key(ecdh_b[j]),
2384 ecdh_a[j], kdf);
2385 secret_size_b = ECDH_compute_key(secret_b, outlen,
2386 EC_KEY_get0_public_key(ecdh_a[j]),
2387 ecdh_b[j], kdf);
2388 if (secret_size_a != secret_size_b)
2389 ecdh_checks = 0;
2390 else
2391 ecdh_checks = 1;
2392
2393 for (secret_idx = 0;
2394 (secret_idx < secret_size_a)
2395 && (ecdh_checks == 1);
2396 secret_idx++) {
2397 if (secret_a[secret_idx] != secret_b[secret_idx])
2398 ecdh_checks = 0;
2399 }
2400
2401 if (ecdh_checks == 0) {
2402 BIO_printf(bio_err,
2403 "ECDH computations don't match.\n");
2404 ERR_print_errors(bio_err);
2405 rsa_count = 1;
2406 } else {
2407 pkey_print_message("", "ecdh",
2408 ecdh_c[j][0],
2409 test_curves_bits[j],
2410 ECDH_SECONDS);
2411 Time_F(START);
2412 for (count = 0, run = 1;
2413 COND(ecdh_c[j][0]); count++) {
2414 ECDH_compute_key(secret_a,
2415 outlen,
2416 EC_KEY_get0_public_key(ecdh_b[j]),
2417 ecdh_a[j], kdf);
2418 }
2419 d = Time_F(STOP);
2420 BIO_printf(bio_err, mr
2421 ? "+R7:%ld:%d:%.2f\n"
2422 : "%ld %d-bit ECDH ops in %.2fs\n",
2423 count, test_curves_bits[j], d);
2424 ecdh_results[j][0] = d / (double) count;
2425 rsa_count = count;
2426 }
2427 }
2428 }
2429
2430
2431 if (rsa_count <= 1) {
2432 /* if longer than 10s, don't do any more */
2433 for (j++; j < EC_NUM; j++)
2434 ecdh_doit[j] = 0;
2435 }
2436 }
2437show_res:
2438 if (!mr) {
2439 fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_VERSION));
2440 fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_BUILT_ON));
2441 fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_CFLAGS));
2442 }
2443 if (pr_header) {
2444 if (mr)
2445 fprintf(stdout, "+H");
2446 else {
2447 fprintf(stdout, "The 'numbers' are in 1000s of bytes per second processed.\n");
2448 fprintf(stdout, "type ");
2449 }
2450 for (j = 0; j < SIZE_NUM; j++)
2451 fprintf(stdout, mr ? ":%d" : "%7d bytes", lengths[j]);
2452 fprintf(stdout, "\n");
2453 }
2454 for (k = 0; k < ALGOR_NUM; k++) {
2455 if (!doit[k])
2456 continue;
2457 if (mr)
2458 fprintf(stdout, "+F:%d:%s", k, names[k]);
2459 else
2460 fprintf(stdout, "%-13s", names[k]);
2461 for (j = 0; j < SIZE_NUM; j++) {
2462 if (results[k][j] > 10000 && !mr)
2463 fprintf(stdout, " %11.2fk", results[k][j] / 1e3);
2464 else
2465 fprintf(stdout, mr ? ":%.2f" : " %11.2f ", results[k][j]);
2466 }
2467 fprintf(stdout, "\n");
2468 }
2469 j = 1;
2470 for (k = 0; k < RSA_NUM; k++) {
2471 if (!rsa_doit[k])
2472 continue;
2473 if (j && !mr) {
2474 printf("%18ssign verify sign/s verify/s\n", " ");
2475 j = 0;
2476 }
2477 if (mr)
2478 fprintf(stdout, "+F2:%u:%u:%f:%f\n",
2479 k, rsa_bits[k], rsa_results[k][0],
2480 rsa_results[k][1]);
2481 else
2482 fprintf(stdout, "rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
2483 rsa_bits[k], rsa_results[k][0], rsa_results[k][1],
2484 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]);
2485 }
2486 j = 1;
2487 for (k = 0; k < DSA_NUM; k++) {
2488 if (!dsa_doit[k])
2489 continue;
2490 if (j && !mr) {
2491 printf("%18ssign verify sign/s verify/s\n", " ");
2492 j = 0;
2493 }
2494 if (mr)
2495 fprintf(stdout, "+F3:%u:%u:%f:%f\n",
2496 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
2497 else
2498 fprintf(stdout, "dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
2499 dsa_bits[k], dsa_results[k][0], dsa_results[k][1],
2500 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]);
2501 }
2502 j = 1;
2503 for (k = 0; k < EC_NUM; k++) {
2504 if (!ecdsa_doit[k])
2505 continue;
2506 if (j && !mr) {
2507 printf("%30ssign verify sign/s verify/s\n", " ");
2508 j = 0;
2509 }
2510 if (mr)
2511 fprintf(stdout, "+F4:%u:%u:%f:%f\n",
2512 k, test_curves_bits[k],
2513 ecdsa_results[k][0], ecdsa_results[k][1]);
2514 else
2515 fprintf(stdout,
2516 "%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
2517 test_curves_bits[k],
2518 test_curves_names[k],
2519 ecdsa_results[k][0], ecdsa_results[k][1],
2520 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]);
2521 }
2522
2523
2524 j = 1;
2525 for (k = 0; k < EC_NUM; k++) {
2526 if (!ecdh_doit[k])
2527 continue;
2528 if (j && !mr) {
2529 printf("%30sop op/s\n", " ");
2530 j = 0;
2531 }
2532 if (mr)
2533 fprintf(stdout, "+F5:%u:%u:%f:%f\n",
2534 k, test_curves_bits[k],
2535 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
2536
2537 else
2538 fprintf(stdout, "%4u bit ecdh (%s) %8.4fs %8.1f\n",
2539 test_curves_bits[k],
2540 test_curves_names[k],
2541 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
2542 }
2543
2544 mret = 0;
2545
2546 end:
2547 ERR_print_errors(bio_err);
2548 free(real_buf);
2549 free(real_buf2);
2550 for (i = 0; i < RSA_NUM; i++)
2551 if (rsa_key[i] != NULL)
2552 RSA_free(rsa_key[i]);
2553 for (i = 0; i < DSA_NUM; i++)
2554 if (dsa_key[i] != NULL)
2555 DSA_free(dsa_key[i]);
2556
2557 for (i = 0; i < EC_NUM; i++)
2558 if (ecdsa[i] != NULL)
2559 EC_KEY_free(ecdsa[i]);
2560 for (i = 0; i < EC_NUM; i++) {
2561 if (ecdh_a[i] != NULL)
2562 EC_KEY_free(ecdh_a[i]);
2563 if (ecdh_b[i] != NULL)
2564 EC_KEY_free(ecdh_b[i]);
2565 }
2566
2567
2568 return (mret);
2569}
2570
2571static void
2572print_message(const char *s, long num, int length)
2573{
2574 BIO_printf(bio_err, mr ? "+DT:%s:%d:%d\n"
2575 : "Doing %s for %ds on %d size blocks: ", s, SECONDS, length);
2576 (void) BIO_flush(bio_err);
2577 alarm(SECONDS);
2578}
2579
2580static void
2581pkey_print_message(const char *str, const char *str2, long num,
2582 int bits, int tm)
2583{
2584 BIO_printf(bio_err, mr ? "+DTP:%d:%s:%s:%d\n"
2585 : "Doing %d bit %s %s for %ds: ", bits, str, str2, tm);
2586 (void) BIO_flush(bio_err);
2587 alarm(tm);
2588}
2589
2590static void
2591print_result(int alg, int run_no, int count, double time_used)
2592{
2593 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
2594 : "%d %s in %.2fs\n", count, names[alg], time_used);
2595 results[alg][run_no] = ((double) count) / time_used * lengths[run_no];
2596}
2597
2598static char *
2599sstrsep(char **string, const char *delim)
2600{
2601 char isdelim[256];
2602 char *token = *string;
2603
2604 if (**string == 0)
2605 return NULL;
2606
2607 memset(isdelim, 0, sizeof isdelim);
2608 isdelim[0] = 1;
2609
2610 while (*delim) {
2611 isdelim[(unsigned char) (*delim)] = 1;
2612 delim++;
2613 }
2614
2615 while (!isdelim[(unsigned char) (**string)]) {
2616 (*string)++;
2617 }
2618
2619 if (**string) {
2620 **string = 0;
2621 (*string)++;
2622 }
2623 return token;
2624}
2625
2626static int
2627do_multi(int multi)
2628{
2629 int n;
2630 int fd[2];
2631 int *fds;
2632 static char sep[] = ":";
2633 const char *errstr = NULL;
2634
2635 fds = reallocarray(NULL, multi, sizeof *fds);
2636 if (fds == NULL) {
2637 fprintf(stderr, "reallocarray failure\n");
2638 exit(1);
2639 }
2640 for (n = 0; n < multi; ++n) {
2641 if (pipe(fd) == -1) {
2642 fprintf(stderr, "pipe failure\n");
2643 exit(1);
2644 }
2645 fflush(stdout);
2646 fflush(stderr);
2647 if (fork()) {
2648 close(fd[1]);
2649 fds[n] = fd[0];
2650 } else {
2651 close(fd[0]);
2652 close(1);
2653 if (dup(fd[1]) == -1) {
2654 fprintf(stderr, "dup failed\n");
2655 exit(1);
2656 }
2657 close(fd[1]);
2658 mr = 1;
2659 usertime = 0;
2660 free(fds);
2661 return 0;
2662 }
2663 printf("Forked child %d\n", n);
2664 }
2665
2666 /* for now, assume the pipe is long enough to take all the output */
2667 for (n = 0; n < multi; ++n) {
2668 FILE *f;
2669 char buf[1024];
2670 char *p;
2671
2672 f = fdopen(fds[n], "r");
2673 while (fgets(buf, sizeof buf, f)) {
2674 p = strchr(buf, '\n');
2675 if (p)
2676 *p = '\0';
2677 if (buf[0] != '+') {
2678 fprintf(stderr, "Don't understand line '%s' from child %d\n",
2679 buf, n);
2680 continue;
2681 }
2682 printf("Got: %s from %d\n", buf, n);
2683 if (!strncmp(buf, "+F:", 3)) {
2684 int alg;
2685 int j;
2686
2687 p = buf + 3;
2688 alg = strtonum(sstrsep(&p, sep),
2689 0, ALGOR_NUM - 1, &errstr);
2690 sstrsep(&p, sep);
2691 for (j = 0; j < SIZE_NUM; ++j)
2692 results[alg][j] += atof(sstrsep(&p, sep));
2693 } else if (!strncmp(buf, "+F2:", 4)) {
2694 int k;
2695 double d;
2696
2697 p = buf + 4;
2698 k = strtonum(sstrsep(&p, sep),
2699 0, ALGOR_NUM - 1, &errstr);
2700 sstrsep(&p, sep);
2701
2702 d = atof(sstrsep(&p, sep));
2703 if (n)
2704 rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
2705 else
2706 rsa_results[k][0] = d;
2707
2708 d = atof(sstrsep(&p, sep));
2709 if (n)
2710 rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
2711 else
2712 rsa_results[k][1] = d;
2713 } else if (!strncmp(buf, "+F2:", 4)) {
2714 int k;
2715 double d;
2716
2717 p = buf + 4;
2718 k = strtonum(sstrsep(&p, sep),
2719 0, ALGOR_NUM - 1, &errstr);
2720 sstrsep(&p, sep);
2721
2722 d = atof(sstrsep(&p, sep));
2723 if (n)
2724 rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
2725 else
2726 rsa_results[k][0] = d;
2727
2728 d = atof(sstrsep(&p, sep));
2729 if (n)
2730 rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
2731 else
2732 rsa_results[k][1] = d;
2733 } else if (!strncmp(buf, "+F3:", 4)) {
2734 int k;
2735 double d;
2736
2737 p = buf + 4;
2738 k = strtonum(sstrsep(&p, sep),
2739 0, ALGOR_NUM - 1, &errstr);
2740 sstrsep(&p, sep);
2741
2742 d = atof(sstrsep(&p, sep));
2743 if (n)
2744 dsa_results[k][0] = 1 / (1 / dsa_results[k][0] + 1 / d);
2745 else
2746 dsa_results[k][0] = d;
2747
2748 d = atof(sstrsep(&p, sep));
2749 if (n)
2750 dsa_results[k][1] = 1 / (1 / dsa_results[k][1] + 1 / d);
2751 else
2752 dsa_results[k][1] = d;
2753 } else if (!strncmp(buf, "+F4:", 4)) {
2754 int k;
2755 double d;
2756
2757 p = buf + 4;
2758 k = strtonum(sstrsep(&p, sep),
2759 0, ALGOR_NUM - 1, &errstr);
2760 sstrsep(&p, sep);
2761
2762 d = atof(sstrsep(&p, sep));
2763 if (n)
2764 ecdsa_results[k][0] = 1 / (1 / ecdsa_results[k][0] + 1 / d);
2765 else
2766 ecdsa_results[k][0] = d;
2767
2768 d = atof(sstrsep(&p, sep));
2769 if (n)
2770 ecdsa_results[k][1] = 1 / (1 / ecdsa_results[k][1] + 1 / d);
2771 else
2772 ecdsa_results[k][1] = d;
2773 } else if (!strncmp(buf, "+F5:", 4)) {
2774 int k;
2775 double d;
2776
2777 p = buf + 4;
2778 k = strtonum(sstrsep(&p, sep),
2779 0, ALGOR_NUM - 1, &errstr);
2780 sstrsep(&p, sep);
2781
2782 d = atof(sstrsep(&p, sep));
2783 if (n)
2784 ecdh_results[k][0] = 1 / (1 / ecdh_results[k][0] + 1 / d);
2785 else
2786 ecdh_results[k][0] = d;
2787
2788 } else if (!strncmp(buf, "+H:", 3)) {
2789 } else
2790 fprintf(stderr, "Unknown type '%s' from child %d\n", buf, n);
2791 }
2792
2793 fclose(f);
2794 }
2795 free(fds);
2796 return 1;
2797}
2798
2799#endif /* OPENSSL_NO_SPEED */
diff --git a/src/usr.bin/openssl/ts.c b/src/usr.bin/openssl/ts.c
deleted file mode 100644
index 2bb35d84a4..0000000000
--- a/src/usr.bin/openssl/ts.c
+++ /dev/null
@@ -1,1256 +0,0 @@
1/* $OpenBSD: ts.c,v 1.29 2024/08/26 18:40:50 tb Exp $ */
2/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
3 * project 2002.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include "apps.h"
64
65#include <openssl/bio.h>
66#include <openssl/bn.h>
67#include <openssl/err.h>
68#include <openssl/pem.h>
69#include <openssl/ts.h>
70
71/* Length of the nonce of the request in bits (must be a multiple of 8). */
72#define NONCE_LENGTH 64
73
74/* Macro definitions for the configuration file. */
75#define ENV_OID_FILE "oid_file"
76
77/* Local function declarations. */
78
79static ASN1_OBJECT *txt2obj(const char *oid);
80static CONF *load_config_file(const char *configfile);
81
82/* Query related functions. */
83static int query_command(const char *data, char *digest, const EVP_MD *md,
84 const char *policy, int no_nonce, int cert, const char *in, const char *out,
85 int text);
86static BIO *BIO_open_with_default(const char *file, const char *mode,
87 FILE *default_fp);
88static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
89 const char *policy, int no_nonce, int cert);
90static int create_digest(BIO *input, char *digest, const EVP_MD *md,
91 unsigned char **md_value);
92static ASN1_INTEGER *create_nonce(int bits);
93
94/* Reply related functions. */
95static int reply_command(CONF *conf, char *section, char *queryfile,
96 char *passin, char *inkey, char *signer, char *chain, const char *policy,
97 char *in, int token_in, char *out, int token_out, int text);
98static TS_RESP *read_PKCS7(BIO *in_bio);
99static TS_RESP *create_response(CONF *conf, const char *section,
100 char *queryfile, char *passin, char *inkey, char *signer, char *chain,
101 const char *policy);
102static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data);
103static ASN1_INTEGER *next_serial(const char *serialfile);
104static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
105
106/* Verify related functions. */
107static int verify_command(char *data, char *digest, char *queryfile, char *in,
108 int token_in, char *ca_path, char *ca_file, char *untrusted);
109static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
110 char *queryfile, char *ca_path, char *ca_file, char *untrusted);
111static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
112static int verify_cb(int ok, X509_STORE_CTX *ctx);
113
114enum mode {
115 CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
116};
117
118static struct {
119 char *ca_file;
120 char *ca_path;
121 int cert;
122 char *chain;
123 char *configfile;
124 char *data;
125 char *digest;
126 char *in;
127 char *inkey;
128 const EVP_MD *md;
129 int mode;
130 int no_nonce;
131 char *out;
132 char *passin;
133 char *policy;
134 char *queryfile;
135 char *section;
136 char *signer;
137 int text;
138 int token_in;
139 int token_out;
140 char *untrusted;
141} cfg;
142
143static int
144ts_opt_md(int argc, char **argv, int *argsused)
145{
146 char *name = argv[0];
147
148 if (*name++ != '-')
149 return (1);
150
151 if ((cfg.md = EVP_get_digestbyname(name)) == NULL)
152 return (1);
153
154 *argsused = 1;
155 return (0);
156}
157
158static int
159ts_opt_query(void)
160{
161 if (cfg.mode != CMD_NONE)
162 return (1);
163 cfg.mode = CMD_QUERY;
164 return (0);
165}
166
167static int
168ts_opt_reply(void)
169{
170 if (cfg.mode != CMD_NONE)
171 return (1);
172 cfg.mode = CMD_REPLY;
173 return (0);
174}
175
176static int
177ts_opt_verify(void)
178{
179 if (cfg.mode != CMD_NONE)
180 return (1);
181 cfg.mode = CMD_VERIFY;
182 return (0);
183}
184
185static const struct option ts_options[] = {
186 {
187 .name = "CAfile",
188 .argname = "file",
189 .desc = "Certificate Authority file",
190 .type = OPTION_ARG,
191 .opt.arg = &cfg.ca_file,
192 },
193 {
194 .name = "CApath",
195 .argname = "path",
196 .desc = "Certificate Authority path",
197 .type = OPTION_ARG,
198 .opt.arg = &cfg.ca_path,
199 },
200 {
201 .name = "cert",
202 .desc = "Include signing certificate in the response",
203 .type = OPTION_FLAG,
204 .opt.flag = &cfg.cert,
205 },
206 {
207 .name = "chain",
208 .argname = "file",
209 .desc = "PEM certificates that will be included in the response",
210 .type = OPTION_ARG,
211 .opt.arg = &cfg.chain,
212 },
213 {
214 .name = "config",
215 .argname = "file",
216 .desc = "Specify an alternative configuration file",
217 .type = OPTION_ARG,
218 .opt.arg = &cfg.configfile,
219 },
220 {
221 .name = "data",
222 .argname = "file",
223 .desc = "Data file for which the time stamp request needs to be created",
224 .type = OPTION_ARG,
225 .opt.arg = &cfg.data,
226 },
227 {
228 .name = "digest",
229 .argname = "arg",
230 .desc = "Specify the message imprint explicitly without the data file",
231 .type = OPTION_ARG,
232 .opt.arg = &cfg.digest,
233 },
234 {
235 .name = "in",
236 .argname = "file",
237 .desc = "Input file",
238 .type = OPTION_ARG,
239 .opt.arg = &cfg.in,
240 },
241 {
242 .name = "inkey",
243 .argname = "file",
244 .desc = "Input key file",
245 .type = OPTION_ARG,
246 .opt.arg = &cfg.inkey,
247 },
248 {
249 .name = "no_nonce",
250 .desc = "Specify no nonce in the request",
251 .type = OPTION_FLAG,
252 .opt.flag = &cfg.no_nonce,
253 },
254 {
255 .name = "out",
256 .argname = "file",
257 .desc = "Output file",
258 .type = OPTION_ARG,
259 .opt.arg = &cfg.out,
260 },
261 {
262 .name = "passin",
263 .argname = "src",
264 .desc = "Private key password source",
265 .type = OPTION_ARG,
266 .opt.arg = &cfg.passin,
267 },
268 {
269 .name = "policy",
270 .argname = "object_id",
271 .desc = "Policy for the TSA to use when creating the time stamp token",
272 .type = OPTION_ARG,
273 .opt.arg = &cfg.policy,
274 },
275 {
276 .name = "query",
277 .desc = "Create and print a time stamp request",
278 .type = OPTION_FUNC,
279 .opt.func = ts_opt_query,
280 },
281 {
282 .name = "queryfile",
283 .argname = "file",
284 .desc = "File containing a DER-encoded time stamp request",
285 .type = OPTION_ARG,
286 .opt.arg = &cfg.queryfile,
287 },
288 {
289 .name = "reply",
290 .desc = "Create a time stamp response",
291 .type = OPTION_FUNC,
292 .opt.func = ts_opt_reply,
293 },
294 {
295 .name = "section",
296 .argname = "arg",
297 .desc = "TSA section containing the settings for response generation",
298 .type = OPTION_ARG,
299 .opt.arg = &cfg.section,
300 },
301 {
302 .name = "signer",
303 .argname = "file",
304 .desc = "Signer certificate file",
305 .type = OPTION_ARG,
306 .opt.arg = &cfg.signer,
307 },
308 {
309 .name = "text",
310 .desc = "Output in human-readable text format",
311 .type = OPTION_FLAG,
312 .opt.flag = &cfg.text,
313 },
314 {
315 .name = "token_in",
316 .desc = "Input is a DER-encoded time stamp token",
317 .type = OPTION_FLAG,
318 .opt.flag = &cfg.token_in,
319 },
320 {
321 .name = "token_out",
322 .desc = "Output is a DER-encoded time stamp token",
323 .type = OPTION_FLAG,
324 .opt.flag = &cfg.token_out,
325 },
326 {
327 .name = "untrusted",
328 .argname = "file",
329 .desc = "File containing untrusted certificates",
330 .type = OPTION_ARG,
331 .opt.arg = &cfg.untrusted,
332 },
333 {
334 .name = "verify",
335 .desc = "Verify a time stamp response",
336 .type = OPTION_FUNC,
337 .opt.func = ts_opt_verify,
338 },
339 {
340 .name = NULL,
341 .desc = "",
342 .type = OPTION_ARGV_FUNC,
343 .opt.argvfunc = ts_opt_md,
344 },
345 { NULL },
346};
347
348static void
349ts_usage(void)
350{
351 fprintf(stderr, "usage:\n"
352 "ts -query [-md4 | -md5 | -ripemd160 | -sha1] [-cert]\n"
353 " [-config configfile] [-data file_to_hash]\n"
354 " [-digest digest_bytes] [-in request.tsq] [-no_nonce]\n"
355 " [-out request.tsq] [-policy object_id] [-text]\n");
356 fprintf(stderr, "\n"
357 "ts -reply [-chain certs_file.pem] [-config configfile]\n"
358 " [-in response.tsr] [-inkey private.pem] [-out response.tsr]\n"
359 " [-passin arg] [-policy object_id] [-queryfile request.tsq]\n"
360 " [-section tsa_section] [-signer tsa_cert.pem] [-text]\n"
361 " [-token_in] [-token_out]\n");
362 fprintf(stderr, "\n"
363 "ts -verify [-CAfile trusted_certs.pem]\n"
364 " [-CApath trusted_cert_path] [-data file_to_hash]\n"
365 " [-digest digest_bytes] [-in response.tsr]\n"
366 " [-queryfile request.tsq] [-token_in]\n"
367 " [-untrusted cert_file.pem]\n");
368 fprintf(stderr, "\n");
369 options_usage(ts_options);
370 fprintf(stderr, "\n");
371}
372
373int
374ts_main(int argc, char **argv)
375{
376 int ret = 1;
377 CONF *conf = NULL;
378 char *password = NULL; /* Password itself. */
379
380 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
381 perror("pledge");
382 exit(1);
383 }
384
385 memset(&cfg, 0, sizeof(cfg));
386 cfg.mode = CMD_NONE;
387
388 if (options_parse(argc, argv, ts_options, NULL, NULL) != 0)
389 goto usage;
390
391 /* Get the password if required. */
392 if (cfg.mode == CMD_REPLY && cfg.passin != NULL &&
393 !app_passwd(bio_err, cfg.passin, NULL, &password, NULL)) {
394 BIO_printf(bio_err, "Error getting password.\n");
395 goto cleanup;
396 }
397 /*
398 * Check consistency of parameters and execute the appropriate
399 * function.
400 */
401 switch (cfg.mode) {
402 case CMD_NONE:
403 goto usage;
404 case CMD_QUERY:
405 /*
406 * Data file and message imprint cannot be specified at the
407 * same time.
408 */
409 ret = cfg.data != NULL && cfg.digest != NULL;
410 if (ret)
411 goto usage;
412 /* Load the config file for possible policy OIDs. */
413 conf = load_config_file(cfg.configfile);
414 ret = !query_command(cfg.data, cfg.digest,
415 cfg.md, cfg.policy, cfg.no_nonce,
416 cfg.cert, cfg.in, cfg.out,
417 cfg.text);
418 break;
419 case CMD_REPLY:
420 conf = load_config_file(cfg.configfile);
421 if (cfg.in == NULL) {
422 ret = !(cfg.queryfile != NULL && conf != NULL &&
423 !cfg.token_in);
424 if (ret)
425 goto usage;
426 } else {
427 /* 'in' and 'queryfile' are exclusive. */
428 ret = !(cfg.queryfile == NULL);
429 if (ret)
430 goto usage;
431 }
432
433 ret = !reply_command(conf, cfg.section,
434 cfg.queryfile, password, cfg.inkey,
435 cfg.signer, cfg.chain, cfg.policy,
436 cfg.in, cfg.token_in, cfg.out,
437 cfg.token_out, cfg.text);
438 break;
439 case CMD_VERIFY:
440 ret = !(((cfg.queryfile != NULL && cfg.data == NULL &&
441 cfg.digest == NULL) ||
442 (cfg.queryfile == NULL && cfg.data != NULL &&
443 cfg.digest == NULL) ||
444 (cfg.queryfile == NULL && cfg.data == NULL &&
445 cfg.digest != NULL)) &&
446 cfg.in != NULL);
447 if (ret)
448 goto usage;
449
450 ret = !verify_command(cfg.data, cfg.digest,
451 cfg.queryfile, cfg.in, cfg.token_in,
452 cfg.ca_path, cfg.ca_file, cfg.untrusted);
453 }
454
455 goto cleanup;
456
457 usage:
458 ts_usage();
459
460 cleanup:
461 /* Clean up. */
462 NCONF_free(conf);
463 free(password);
464 OBJ_cleanup();
465
466 return (ret);
467}
468
469/*
470 * Configuration file-related function definitions.
471 */
472
473static ASN1_OBJECT *
474txt2obj(const char *oid)
475{
476 ASN1_OBJECT *oid_obj = NULL;
477
478 if ((oid_obj = OBJ_txt2obj(oid, 0)) == NULL)
479 BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
480
481 return oid_obj;
482}
483
484static CONF *
485load_config_file(const char *configfile)
486{
487 CONF *conf = NULL;
488 long errorline = -1;
489
490 if (configfile == NULL)
491 configfile = getenv("OPENSSL_CONF");
492
493 if (configfile != NULL &&
494 ((conf = NCONF_new(NULL)) == NULL ||
495 NCONF_load(conf, configfile, &errorline) <= 0)) {
496 if (errorline <= 0)
497 BIO_printf(bio_err, "error loading the config file "
498 "'%s'\n", configfile);
499 else
500 BIO_printf(bio_err, "error on line %ld of config file "
501 "'%s'\n", errorline, configfile);
502 }
503 if (conf != NULL) {
504 const char *p;
505
506 BIO_printf(bio_err, "Using configuration from %s\n",
507 configfile);
508 p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
509 if (p != NULL) {
510 BIO *oid_bio = BIO_new_file(p, "r");
511 if (oid_bio == NULL)
512 ERR_print_errors(bio_err);
513 else {
514 OBJ_create_objects(oid_bio);
515 BIO_free_all(oid_bio);
516 }
517 } else
518 ERR_clear_error();
519 if (!add_oid_section(bio_err, conf))
520 ERR_print_errors(bio_err);
521 }
522 return conf;
523}
524
525/*
526 * Query-related method definitions.
527 */
528
529static int
530query_command(const char *data, char *digest, const EVP_MD *md,
531 const char *policy, int no_nonce, int cert, const char *in, const char *out,
532 int text)
533{
534 int ret = 0;
535 TS_REQ *query = NULL;
536 BIO *in_bio = NULL;
537 BIO *data_bio = NULL;
538 BIO *out_bio = NULL;
539
540 /* Build query object either from file or from scratch. */
541 if (in != NULL) {
542 if ((in_bio = BIO_new_file(in, "rb")) == NULL)
543 goto end;
544 query = d2i_TS_REQ_bio(in_bio, NULL);
545 } else {
546 /* Open the file if no explicit digest bytes were specified. */
547 if (digest == NULL &&
548 (data_bio = BIO_open_with_default(data, "rb", stdin)) == NULL)
549 goto end;
550 /* Creating the query object. */
551 query = create_query(data_bio, digest, md,
552 policy, no_nonce, cert);
553 /* Saving the random number generator state. */
554 }
555 if (query == NULL)
556 goto end;
557
558 /* Write query either in ASN.1 or in text format. */
559 if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
560 goto end;
561 if (text) {
562 /* Text output. */
563 if (!TS_REQ_print_bio(out_bio, query))
564 goto end;
565 } else {
566 /* ASN.1 output. */
567 if (!i2d_TS_REQ_bio(out_bio, query))
568 goto end;
569 }
570
571 ret = 1;
572
573 end:
574 ERR_print_errors(bio_err);
575
576 /* Clean up. */
577 BIO_free_all(in_bio);
578 BIO_free_all(data_bio);
579 BIO_free_all(out_bio);
580 TS_REQ_free(query);
581
582 return ret;
583}
584
585static BIO *
586BIO_open_with_default(const char *file, const char *mode, FILE *default_fp)
587{
588 return file == NULL ? BIO_new_fp(default_fp, BIO_NOCLOSE) :
589 BIO_new_file(file, mode);
590}
591
592static TS_REQ *
593create_query(BIO *data_bio, char *digest, const EVP_MD *md, const char *policy,
594 int no_nonce, int cert)
595{
596 int ret = 0;
597 TS_REQ *ts_req = NULL;
598 int len;
599 TS_MSG_IMPRINT *msg_imprint = NULL;
600 X509_ALGOR *algo = NULL;
601 unsigned char *data = NULL;
602 ASN1_OBJECT *md_obj = NULL, *policy_obj = NULL;
603 ASN1_INTEGER *nonce_asn1 = NULL;
604
605 /* Setting default message digest. */
606 if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL)
607 goto err;
608
609 /* Creating request object. */
610 if ((ts_req = TS_REQ_new()) == NULL)
611 goto err;
612
613 /* Setting version. */
614 if (!TS_REQ_set_version(ts_req, 1))
615 goto err;
616
617 /* Creating and adding MSG_IMPRINT object. */
618 if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL)
619 goto err;
620
621 /* Adding algorithm. */
622 if ((algo = X509_ALGOR_new()) == NULL)
623 goto err;
624 if ((md_obj = OBJ_nid2obj(EVP_MD_type(md))) == NULL)
625 goto err;
626 /*
627 * This does not use X509_ALGOR_set_md() for historical reasons.
628 * See the comment in PKCS7_SIGNER_INFO_set() for details.
629 */
630 if (!X509_ALGOR_set0(algo, md_obj, V_ASN1_NULL, NULL))
631 goto err;
632 if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo))
633 goto err;
634
635 /* Adding message digest. */
636 if ((len = create_digest(data_bio, digest, md, &data)) == 0)
637 goto err;
638 if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len))
639 goto err;
640
641 if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint))
642 goto err;
643
644 /* Setting policy if requested. */
645 if (policy != NULL && (policy_obj = txt2obj(policy)) == NULL)
646 goto err;
647 if (policy_obj != NULL && !TS_REQ_set_policy_id(ts_req, policy_obj))
648 goto err;
649
650 /* Setting nonce if requested. */
651 if (!no_nonce && (nonce_asn1 = create_nonce(NONCE_LENGTH)) == NULL)
652 goto err;
653 if (nonce_asn1 != NULL && !TS_REQ_set_nonce(ts_req, nonce_asn1))
654 goto err;
655
656 /* Setting certificate request flag if requested. */
657 if (!TS_REQ_set_cert_req(ts_req, cert))
658 goto err;
659
660 ret = 1;
661
662 err:
663 if (!ret) {
664 TS_REQ_free(ts_req);
665 ts_req = NULL;
666 BIO_printf(bio_err, "could not create query\n");
667 }
668 TS_MSG_IMPRINT_free(msg_imprint);
669 X509_ALGOR_free(algo);
670 free(data);
671 ASN1_OBJECT_free(policy_obj);
672 ASN1_INTEGER_free(nonce_asn1);
673
674 return ts_req;
675}
676
677static int
678create_digest(BIO *input, char *digest, const EVP_MD *md,
679 unsigned char **out_md_value)
680{
681 EVP_MD_CTX *md_ctx = NULL;
682 unsigned char *md_value = NULL;
683 int md_value_len;
684 int ret = 0;
685
686 md_value_len = EVP_MD_size(md);
687 if (md_value_len < 0)
688 goto err;
689
690 if (input != NULL) {
691 /* Digest must be computed from an input file. */
692 unsigned char buffer[4096];
693 int length;
694
695 md_value = malloc(md_value_len);
696 if (md_value == NULL)
697 goto err;
698
699 if ((md_ctx = EVP_MD_CTX_new()) == NULL)
700 goto err;
701
702 if (!EVP_DigestInit(md_ctx, md))
703 goto err;
704
705 while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) {
706 if (!EVP_DigestUpdate(md_ctx, buffer, length))
707 goto err;
708 }
709
710 if (!EVP_DigestFinal(md_ctx, md_value, NULL))
711 goto err;
712 } else {
713 /* Digest bytes are specified with digest. */
714 long digest_len;
715
716 md_value = string_to_hex(digest, &digest_len);
717 if (md_value == NULL || md_value_len != digest_len) {
718 BIO_printf(bio_err, "bad digest, %d bytes "
719 "must be specified\n", md_value_len);
720 goto err;
721 }
722 }
723
724 *out_md_value = md_value;
725 md_value = NULL;
726
727 ret = md_value_len;
728
729 err:
730 free(md_value);
731 EVP_MD_CTX_free(md_ctx);
732
733 return ret;
734}
735
736static ASN1_INTEGER *
737create_nonce(int bits)
738{
739 unsigned char buf[20];
740 ASN1_INTEGER *nonce = NULL;
741 int len = (bits - 1) / 8 + 1;
742 int i;
743
744 /* Generating random byte sequence. */
745 if (len > (int) sizeof(buf))
746 goto err;
747 arc4random_buf(buf, len);
748
749 /* Find the first non-zero byte and creating ASN1_INTEGER object. */
750 for (i = 0; i < len && !buf[i]; ++i)
751 ;
752 if ((nonce = ASN1_INTEGER_new()) == NULL)
753 goto err;
754 free(nonce->data);
755 /* Allocate at least one byte. */
756 nonce->length = len - i;
757 if ((nonce->data = malloc(nonce->length + 1)) == NULL)
758 goto err;
759 memcpy(nonce->data, buf + i, nonce->length);
760
761 return nonce;
762
763 err:
764 BIO_printf(bio_err, "could not create nonce\n");
765 ASN1_INTEGER_free(nonce);
766 return NULL;
767}
768
769/*
770 * Reply-related method definitions.
771 */
772
773static int
774reply_command(CONF *conf, char *section, char *queryfile, char *passin,
775 char *inkey, char *signer, char *chain, const char *policy, char *in,
776 int token_in, char *out, int token_out, int text)
777{
778 int ret = 0;
779 TS_RESP *response = NULL;
780 BIO *in_bio = NULL;
781 BIO *query_bio = NULL;
782 BIO *inkey_bio = NULL;
783 BIO *signer_bio = NULL;
784 BIO *out_bio = NULL;
785
786 /* Build response object either from response or query. */
787 if (in != NULL) {
788 if ((in_bio = BIO_new_file(in, "rb")) == NULL)
789 goto end;
790 if (token_in) {
791 /*
792 * We have a ContentInfo (PKCS7) object, add
793 * 'granted' status info around it.
794 */
795 response = read_PKCS7(in_bio);
796 } else {
797 /* We have a ready-made TS_RESP object. */
798 response = d2i_TS_RESP_bio(in_bio, NULL);
799 }
800 } else {
801 response = create_response(conf, section, queryfile, passin,
802 inkey, signer, chain, policy);
803 if (response != NULL)
804 BIO_printf(bio_err, "Response has been generated.\n");
805 else
806 BIO_printf(bio_err, "Response is not generated.\n");
807 }
808 if (response == NULL)
809 goto end;
810
811 /* Write response either in ASN.1 or text format. */
812 if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
813 goto end;
814 if (text) {
815 /* Text output. */
816 if (token_out) {
817 TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
818 if (!TS_TST_INFO_print_bio(out_bio, tst_info))
819 goto end;
820 } else {
821 if (!TS_RESP_print_bio(out_bio, response))
822 goto end;
823 }
824 } else {
825 /* ASN.1 DER output. */
826 if (token_out) {
827 PKCS7 *token = TS_RESP_get_token(response);
828 if (!i2d_PKCS7_bio(out_bio, token))
829 goto end;
830 } else {
831 if (!i2d_TS_RESP_bio(out_bio, response))
832 goto end;
833 }
834 }
835
836 ret = 1;
837
838 end:
839 ERR_print_errors(bio_err);
840
841 /* Clean up. */
842 BIO_free_all(in_bio);
843 BIO_free_all(query_bio);
844 BIO_free_all(inkey_bio);
845 BIO_free_all(signer_bio);
846 BIO_free_all(out_bio);
847 TS_RESP_free(response);
848
849 return ret;
850}
851
852/* Reads a PKCS7 token and adds default 'granted' status info to it. */
853static TS_RESP *
854read_PKCS7(BIO *in_bio)
855{
856 int ret = 0;
857 PKCS7 *token = NULL;
858 TS_TST_INFO *tst_info = NULL;
859 TS_RESP *resp = NULL;
860 TS_STATUS_INFO *si = NULL;
861
862 /* Read PKCS7 object and extract the signed time stamp info. */
863 if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
864 goto end;
865 if ((tst_info = PKCS7_to_TS_TST_INFO(token)) == NULL)
866 goto end;
867
868 /* Creating response object. */
869 if ((resp = TS_RESP_new()) == NULL)
870 goto end;
871
872 /* Create granted status info. */
873 if ((si = TS_STATUS_INFO_new()) == NULL)
874 goto end;
875 if (!TS_STATUS_INFO_set_status(si, TS_STATUS_GRANTED))
876 goto end;
877 if (!TS_RESP_set_status_info(resp, si))
878 goto end;
879
880 /* Setting encapsulated token. */
881 TS_RESP_set_tst_info(resp, token, tst_info);
882 token = NULL; /* Ownership is lost. */
883 tst_info = NULL; /* Ownership is lost. */
884
885 ret = 1;
886 end:
887 PKCS7_free(token);
888 TS_TST_INFO_free(tst_info);
889 if (!ret) {
890 TS_RESP_free(resp);
891 resp = NULL;
892 }
893 TS_STATUS_INFO_free(si);
894 return resp;
895}
896
897static TS_RESP *
898create_response(CONF *conf, const char *section, char *queryfile, char *passin,
899 char *inkey, char *signer, char *chain, const char *policy)
900{
901 int ret = 0;
902 TS_RESP *response = NULL;
903 BIO *query_bio = NULL;
904 TS_RESP_CTX *resp_ctx = NULL;
905
906 if ((query_bio = BIO_new_file(queryfile, "rb")) == NULL)
907 goto end;
908
909 /* Getting TSA configuration section. */
910 if ((section = TS_CONF_get_tsa_section(conf, section)) == NULL)
911 goto end;
912
913 /* Setting up response generation context. */
914 if ((resp_ctx = TS_RESP_CTX_new()) == NULL)
915 goto end;
916
917 /* Setting serial number provider callback. */
918 if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx))
919 goto end;
920
921 /* Setting TSA signer certificate. */
922 if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx))
923 goto end;
924
925 /* Setting TSA signer certificate chain. */
926 if (!TS_CONF_set_certs(conf, section, chain, resp_ctx))
927 goto end;
928
929 /* Setting TSA signer private key. */
930 if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
931 goto end;
932
933 /* Setting default policy OID. */
934 if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
935 goto end;
936
937 /* Setting acceptable policy OIDs. */
938 if (!TS_CONF_set_policies(conf, section, resp_ctx))
939 goto end;
940
941 /* Setting the acceptable one-way hash algorithms. */
942 if (!TS_CONF_set_digests(conf, section, resp_ctx))
943 goto end;
944
945 /* Setting guaranteed time stamp accuracy. */
946 if (!TS_CONF_set_accuracy(conf, section, resp_ctx))
947 goto end;
948
949 /* Setting the precision of the time. */
950 if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
951 goto end;
952
953 /* Setting the ordering flag if requested. */
954 if (!TS_CONF_set_ordering(conf, section, resp_ctx))
955 goto end;
956
957 /* Setting the TSA name required flag if requested. */
958 if (!TS_CONF_set_tsa_name(conf, section, resp_ctx))
959 goto end;
960
961 /* Setting the ESS cert id chain flag if requested. */
962 if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx))
963 goto end;
964
965 /* Creating the response. */
966 if ((response = TS_RESP_create_response(resp_ctx, query_bio)) == NULL)
967 goto end;
968
969 ret = 1;
970 end:
971 if (!ret) {
972 TS_RESP_free(response);
973 response = NULL;
974 }
975 TS_RESP_CTX_free(resp_ctx);
976 BIO_free_all(query_bio);
977
978 return response;
979}
980
981static ASN1_INTEGER *
982serial_cb(TS_RESP_CTX *ctx, void *data)
983{
984 const char *serial_file = (const char *) data;
985 ASN1_INTEGER *serial = next_serial(serial_file);
986
987 if (serial == NULL) {
988 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
989 "Error during serial number "
990 "generation.");
991 TS_RESP_CTX_add_failure_info(ctx,
992 TS_INFO_ADD_INFO_NOT_AVAILABLE);
993 } else
994 save_ts_serial(serial_file, serial);
995
996 return serial;
997}
998
999static ASN1_INTEGER *
1000next_serial(const char *serialfile)
1001{
1002 int ret = 0;
1003 BIO *in = NULL;
1004 ASN1_INTEGER *serial = NULL;
1005 BIGNUM *bn = NULL;
1006
1007 if ((serial = ASN1_INTEGER_new()) == NULL)
1008 goto err;
1009
1010 if ((in = BIO_new_file(serialfile, "r")) == NULL) {
1011 ERR_clear_error();
1012 BIO_printf(bio_err, "Warning: could not open file %s for "
1013 "reading, using serial number: 1\n", serialfile);
1014 if (!ASN1_INTEGER_set(serial, 1))
1015 goto err;
1016 } else {
1017 char buf[1024];
1018 if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) {
1019 BIO_printf(bio_err, "unable to load number from %s\n",
1020 serialfile);
1021 goto err;
1022 }
1023 if ((bn = ASN1_INTEGER_to_BN(serial, NULL)) == NULL)
1024 goto err;
1025 ASN1_INTEGER_free(serial);
1026 serial = NULL;
1027 if (!BN_add_word(bn, 1))
1028 goto err;
1029 if ((serial = BN_to_ASN1_INTEGER(bn, NULL)) == NULL)
1030 goto err;
1031 }
1032 ret = 1;
1033 err:
1034 if (!ret) {
1035 ASN1_INTEGER_free(serial);
1036 serial = NULL;
1037 }
1038 BIO_free_all(in);
1039 BN_free(bn);
1040 return serial;
1041}
1042
1043static int
1044save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
1045{
1046 int ret = 0;
1047 BIO *out = NULL;
1048
1049 if ((out = BIO_new_file(serialfile, "w")) == NULL)
1050 goto err;
1051 if (i2a_ASN1_INTEGER(out, serial) <= 0)
1052 goto err;
1053 if (BIO_puts(out, "\n") <= 0)
1054 goto err;
1055 ret = 1;
1056 err:
1057 if (!ret)
1058 BIO_printf(bio_err, "could not save serial number to %s\n",
1059 serialfile);
1060 BIO_free_all(out);
1061 return ret;
1062}
1063
1064/*
1065 * Verify-related method definitions.
1066 */
1067
1068static int
1069verify_command(char *data, char *digest, char *queryfile, char *in,
1070 int token_in, char *ca_path, char *ca_file, char *untrusted)
1071{
1072 BIO *in_bio = NULL;
1073 PKCS7 *token = NULL;
1074 TS_RESP *response = NULL;
1075 TS_VERIFY_CTX *verify_ctx = NULL;
1076 int ret = 0;
1077
1078 /* Decode the token (PKCS7) or response (TS_RESP) files. */
1079 if ((in_bio = BIO_new_file(in, "rb")) == NULL)
1080 goto end;
1081 if (token_in) {
1082 if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
1083 goto end;
1084 } else {
1085 if ((response = d2i_TS_RESP_bio(in_bio, NULL)) == NULL)
1086 goto end;
1087 }
1088
1089 if ((verify_ctx = create_verify_ctx(data, digest, queryfile,
1090 ca_path, ca_file, untrusted)) == NULL)
1091 goto end;
1092
1093 /* Checking the token or response against the request. */
1094 ret = token_in ?
1095 TS_RESP_verify_token(verify_ctx, token) :
1096 TS_RESP_verify_response(verify_ctx, response);
1097
1098 end:
1099 printf("Verification: ");
1100 if (ret)
1101 printf("OK\n");
1102 else {
1103 printf("FAILED\n");
1104 /* Print errors, if there are any. */
1105 ERR_print_errors(bio_err);
1106 }
1107
1108 /* Clean up. */
1109 BIO_free_all(in_bio);
1110 PKCS7_free(token);
1111 TS_RESP_free(response);
1112 TS_VERIFY_CTX_free(verify_ctx);
1113 return ret;
1114}
1115
1116static TS_VERIFY_CTX *
1117create_verify_ctx(char *data, char *digest, char *queryfile, char *ca_path,
1118 char *ca_file, char *untrusted)
1119{
1120 TS_VERIFY_CTX *ctx = NULL;
1121 BIO *input = NULL;
1122 TS_REQ *request = NULL;
1123 X509_STORE *store;
1124 STACK_OF(X509) *certs;
1125 int ret = 0;
1126
1127 if (data != NULL || digest != NULL) {
1128 if ((ctx = TS_VERIFY_CTX_new()) == NULL)
1129 goto err;
1130 TS_VERIFY_CTX_set_flags(ctx, TS_VFY_VERSION | TS_VFY_SIGNER);
1131 if (data != NULL) {
1132 BIO *data_bio;
1133
1134 TS_VERIFY_CTX_add_flags(ctx, TS_VFY_DATA);
1135 if ((data_bio = BIO_new_file(data, "rb")) == NULL)
1136 goto err;
1137 TS_VERIFY_CTX_set_data(ctx, data_bio);
1138 } else if (digest != NULL) {
1139 unsigned char *imprint;
1140 long imprint_len;
1141
1142 TS_VERIFY_CTX_add_flags(ctx, TS_VFY_IMPRINT);
1143 if ((imprint = string_to_hex(digest,
1144 &imprint_len)) == NULL) {
1145 BIO_printf(bio_err, "invalid digest string\n");
1146 goto err;
1147 }
1148 TS_VERIFY_CTX_set_imprint(ctx, imprint, imprint_len);
1149 }
1150 } else if (queryfile != NULL) {
1151 /*
1152 * The request has just to be read, decoded and converted to
1153 * a verify context object.
1154 */
1155 if ((input = BIO_new_file(queryfile, "rb")) == NULL)
1156 goto err;
1157 if ((request = d2i_TS_REQ_bio(input, NULL)) == NULL)
1158 goto err;
1159 if ((ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)) == NULL)
1160 goto err;
1161 } else
1162 return NULL;
1163
1164 /* Add the signature verification flag and arguments. */
1165 TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE);
1166
1167 /* Initialising the X509_STORE object. */
1168 if ((store = create_cert_store(ca_path, ca_file)) == NULL)
1169 goto err;
1170 TS_VERIFY_CTX_set_store(ctx, store);
1171
1172 /* Loading untrusted certificates. */
1173 if (untrusted != NULL) {
1174 if ((certs = TS_CONF_load_certs(untrusted)) == NULL)
1175 goto err;
1176 TS_VERIFY_CTX_set_certs(ctx, certs);
1177 }
1178
1179 ret = 1;
1180 err:
1181 if (!ret) {
1182 TS_VERIFY_CTX_free(ctx);
1183 ctx = NULL;
1184 }
1185 BIO_free_all(input);
1186 TS_REQ_free(request);
1187 return ctx;
1188}
1189
1190static X509_STORE *
1191create_cert_store(char *ca_path, char *ca_file)
1192{
1193 X509_STORE *cert_ctx = NULL;
1194 X509_LOOKUP *lookup = NULL;
1195 int i;
1196
1197 /* Creating the X509_STORE object. */
1198 if ((cert_ctx = X509_STORE_new()) == NULL)
1199 goto err;
1200
1201 /* Setting the callback for certificate chain verification. */
1202 X509_STORE_set_verify_cb(cert_ctx, verify_cb);
1203
1204 /* Adding a trusted certificate directory source. */
1205 if (ca_path != NULL) {
1206 lookup = X509_STORE_add_lookup(cert_ctx,
1207 X509_LOOKUP_hash_dir());
1208 if (lookup == NULL) {
1209 BIO_printf(bio_err, "memory allocation failure\n");
1210 goto err;
1211 }
1212 i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM);
1213 if (!i) {
1214 BIO_printf(bio_err, "Error loading directory %s\n",
1215 ca_path);
1216 goto err;
1217 }
1218 }
1219 /* Adding a trusted certificate file source. */
1220 if (ca_file != NULL) {
1221 lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
1222 if (lookup == NULL) {
1223 BIO_printf(bio_err, "memory allocation failure\n");
1224 goto err;
1225 }
1226 i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM);
1227 if (!i) {
1228 BIO_printf(bio_err, "Error loading file %s\n", ca_file);
1229 goto err;
1230 }
1231 }
1232 return cert_ctx;
1233 err:
1234 X509_STORE_free(cert_ctx);
1235 return NULL;
1236}
1237
1238static int
1239verify_cb(int ok, X509_STORE_CTX *ctx)
1240{
1241 /*
1242 char buf[256];
1243
1244 if (!ok)
1245 {
1246 X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
1247 buf, sizeof(buf));
1248 printf("%s\n", buf);
1249 printf("error %d at %d depth lookup: %s\n",
1250 ctx->error, ctx->error_depth,
1251 X509_verify_cert_error_string(ctx->error));
1252 }
1253 */
1254
1255 return ok;
1256}
diff --git a/src/usr.bin/openssl/verify.c b/src/usr.bin/openssl/verify.c
deleted file mode 100644
index a87d5d47df..0000000000
--- a/src/usr.bin/openssl/verify.c
+++ /dev/null
@@ -1,457 +0,0 @@
1/* $OpenBSD: verify.c,v 1.18 2023/11/21 17:56:19 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include "apps.h"
64
65#include <openssl/bio.h>
66#include <openssl/err.h>
67#include <openssl/pem.h>
68#include <openssl/x509.h>
69#include <openssl/x509v3.h>
70
71static int cb(int ok, X509_STORE_CTX *ctx);
72static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain,
73 STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls);
74static int vflags = 0;
75
76static struct {
77 char *CAfile;
78 char *CApath;
79 char *crlfile;
80 char *trustfile;
81 char *untfile;
82 int verbose;
83 X509_VERIFY_PARAM *vpm;
84} cfg;
85
86static int
87verify_opt_args(int argc, char **argv, int *argsused)
88{
89 int oargc = argc;
90 int badarg = 0;
91
92 if (!args_verify(&argv, &argc, &badarg, bio_err, &cfg.vpm))
93 return (1);
94 if (badarg)
95 return (1);
96
97 *argsused = oargc - argc;
98
99 return (0);
100}
101
102static const struct option verify_options[] = {
103 {
104 .name = "CAfile",
105 .argname = "file",
106 .desc = "Certificate Authority file",
107 .type = OPTION_ARG,
108 .opt.arg = &cfg.CAfile,
109 },
110 {
111 .name = "CApath",
112 .argname = "path",
113 .desc = "Certificate Authority path",
114 .type = OPTION_ARG,
115 .opt.arg = &cfg.CApath,
116 },
117 {
118 .name = "CRLfile",
119 .argname = "file",
120 .desc = "Certificate Revocation List file",
121 .type = OPTION_ARG,
122 .opt.arg = &cfg.crlfile,
123 },
124 {
125 .name = "trusted",
126 .argname = "file",
127 .desc = "Trusted certificates file",
128 .type = OPTION_ARG,
129 .opt.arg = &cfg.trustfile,
130 },
131 {
132 .name = "untrusted",
133 .argname = "file",
134 .desc = "Untrusted certificates file",
135 .type = OPTION_ARG,
136 .opt.arg = &cfg.untfile,
137 },
138 {
139 .name = "verbose",
140 .desc = "Verbose",
141 .type = OPTION_FLAG,
142 .opt.flag = &cfg.verbose,
143 },
144 {
145 .name = NULL,
146 .desc = "",
147 .type = OPTION_ARGV_FUNC,
148 .opt.argvfunc = verify_opt_args,
149 },
150 { NULL },
151};
152
153static const struct option verify_shared_options[] = {
154 {
155 .name = "attime",
156 .argname = "epoch",
157 .desc = "Use epoch as the verification time",
158 },
159 {
160 .name = "check_ss_sig",
161 .desc = "Check the root CA self-signed certificate signature",
162 },
163 {
164 .name = "crl_check",
165 .desc = "Enable CRL checking for the leaf certificate",
166 },
167 {
168 .name = "crl_check_all",
169 .desc = "Enable CRL checking for the entire certificate chain",
170 },
171 {
172 .name = "explicit_policy",
173 .desc = "Require explicit policy (per RFC 3280)",
174 },
175 {
176 .name = "extended_crl",
177 .desc = "Enable extended CRL support",
178 },
179 {
180 .name = "ignore_critical",
181 .desc = "Disable critical extension checking",
182 },
183 {
184 .name = "inhibit_any",
185 .desc = "Inhibit any policy (per RFC 3280)",
186 },
187 {
188 .name = "inhibit_map",
189 .desc = "Inhibit policy mapping (per RFC 3280)",
190 },
191 {
192 .name = "issuer_checks",
193 .desc = "Enable debugging of certificate issuer checks",
194 },
195 {
196 .name = "legacy_verify",
197 .desc = "Use legacy certificate chain verification",
198 },
199 {
200 .name = "policy",
201 .argname = "name",
202 .desc = "Add given policy to the acceptable set",
203 },
204 {
205 .name = "policy_check",
206 .desc = "Enable certificate policy checking",
207 },
208 {
209 .name = "policy_print",
210 .desc = "Print policy",
211 },
212 {
213 .name = "purpose",
214 .argname = "name",
215 .desc = "Verify for the given purpose",
216 },
217 {
218 .name = "use_deltas",
219 .desc = "Use delta CRLS (if present)",
220 },
221 {
222 .name = "verify_depth",
223 .argname = "num",
224 .desc = "Limit verification to the given depth",
225 },
226 {
227 .name = "x509_strict",
228 .desc = "Use strict X.509 rules (disables workarounds)",
229 },
230 { NULL },
231};
232
233static void
234verify_usage(void)
235{
236 int i;
237
238 fprintf(stderr,
239 "usage: verify [-CAfile file] [-CApath directory] [-check_ss_sig]\n"
240 " [-CRLfile file] [-crl_check] [-crl_check_all]\n"
241 " [-explicit_policy] [-extended_crl]\n"
242 " [-ignore_critical] [-inhibit_any] [-inhibit_map]\n"
243 " [-issuer_checks] [-policy_check] [-purpose purpose]\n"
244 " [-trusted file] [-untrusted file] [-verbose]\n"
245 " [-x509_strict] [certificates]\n\n");
246
247 options_usage(verify_options);
248
249 fprintf(stderr, "\nVerification options:\n\n");
250 options_usage(verify_shared_options);
251
252 fprintf(stderr, "\nValid purposes:\n\n");
253 for (i = 0; i < X509_PURPOSE_get_count(); i++) {
254 const X509_PURPOSE *ptmp = X509_PURPOSE_get0(i);
255 fprintf(stderr, " %-18s%s\n", X509_PURPOSE_get0_sname(ptmp),
256 X509_PURPOSE_get0_name(ptmp));
257 }
258}
259
260int
261verify_main(int argc, char **argv)
262{
263 STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
264 STACK_OF(X509_CRL) *crls = NULL;
265 X509_STORE *cert_ctx = NULL;
266 X509_LOOKUP *lookup = NULL;
267 char **cert_files = NULL;
268 int argsused;
269 int ret = 1;
270
271 if (pledge("stdio rpath", NULL) == -1) {
272 perror("pledge");
273 exit(1);
274 }
275
276 memset(&cfg, 0, sizeof(cfg));
277
278 if (options_parse(argc, argv, verify_options, NULL, &argsused) != 0) {
279 verify_usage();
280 goto end;
281 }
282
283 if (argsused < argc)
284 cert_files = &argv[argsused];
285
286 cert_ctx = X509_STORE_new();
287 if (cert_ctx == NULL)
288 goto end;
289 X509_STORE_set_verify_cb(cert_ctx, cb);
290
291 if (cfg.vpm)
292 X509_STORE_set1_param(cert_ctx, cfg.vpm);
293
294 lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
295 if (lookup == NULL)
296 abort(); /* XXX */
297 if (cfg.CAfile) {
298 if (!X509_LOOKUP_load_file(lookup, cfg.CAfile,
299 X509_FILETYPE_PEM)) {
300 BIO_printf(bio_err, "Error loading file %s\n",
301 cfg.CAfile);
302 ERR_print_errors(bio_err);
303 goto end;
304 }
305 } else
306 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
307
308 lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
309 if (lookup == NULL)
310 abort(); /* XXX */
311 if (cfg.CApath) {
312 if (!X509_LOOKUP_add_dir(lookup, cfg.CApath,
313 X509_FILETYPE_PEM)) {
314 BIO_printf(bio_err, "Error loading directory %s\n",
315 cfg.CApath);
316 ERR_print_errors(bio_err);
317 goto end;
318 }
319 } else
320 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
321
322 ERR_clear_error();
323
324 if (cfg.untfile) {
325 untrusted = load_certs(bio_err, cfg.untfile,
326 FORMAT_PEM, NULL, "untrusted certificates");
327 if (!untrusted)
328 goto end;
329 }
330 if (cfg.trustfile) {
331 trusted = load_certs(bio_err, cfg.trustfile,
332 FORMAT_PEM, NULL, "trusted certificates");
333 if (!trusted)
334 goto end;
335 }
336 if (cfg.crlfile) {
337 crls = load_crls(bio_err, cfg.crlfile, FORMAT_PEM,
338 NULL, "other CRLs");
339 if (!crls)
340 goto end;
341 }
342 ret = 0;
343 if (cert_files == NULL) {
344 if (1 != check(cert_ctx, NULL, untrusted, trusted, crls))
345 ret = -1;
346 } else {
347 do {
348 if (1 != check(cert_ctx, *cert_files++, untrusted,
349 trusted, crls))
350 ret = -1;
351 } while (*cert_files != NULL);
352 }
353
354 end:
355 if (cfg.vpm)
356 X509_VERIFY_PARAM_free(cfg.vpm);
357 if (cert_ctx != NULL)
358 X509_STORE_free(cert_ctx);
359 sk_X509_pop_free(untrusted, X509_free);
360 sk_X509_pop_free(trusted, X509_free);
361 sk_X509_CRL_pop_free(crls, X509_CRL_free);
362
363 return (ret < 0 ? 2 : ret);
364}
365
366static int
367check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain,
368 STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls)
369{
370 X509 *x = NULL;
371 X509_STORE_CTX *csc = NULL;
372 const char *certfile = (file == NULL) ? "stdin" : file;
373 int verify_err;
374 int i = 0, ret = 0;
375
376 x = load_cert(bio_err, file, FORMAT_PEM, NULL, "certificate file");
377 if (x == NULL)
378 goto end;
379
380 if ((csc = X509_STORE_CTX_new()) == NULL)
381 goto end;
382 X509_STORE_set_flags(ctx, vflags);
383 if (!X509_STORE_CTX_init(csc, ctx, x, uchain))
384 goto end;
385 if (tchain)
386 X509_STORE_CTX_trusted_stack(csc, tchain);
387 if (crls)
388 X509_STORE_CTX_set0_crls(csc, crls);
389
390 i = X509_verify_cert(csc);
391 verify_err = X509_STORE_CTX_get_error(csc);
392
393 if (i > 0 && verify_err == X509_V_OK) {
394 fprintf(stdout, "%s: OK\n", certfile);
395 ret = 1;
396 } else {
397 fprintf(stdout, "%s: verification failed: %d (%s)\n", certfile,
398 verify_err, X509_verify_cert_error_string(verify_err));
399 }
400
401 end:
402 if (i <= 0)
403 ERR_print_errors(bio_err);
404 X509_free(x);
405 X509_STORE_CTX_free(csc);
406
407 return (ret);
408}
409
410static int
411cb(int ok, X509_STORE_CTX *ctx)
412{
413 int cert_error = X509_STORE_CTX_get_error(ctx);
414 X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
415
416 if (!ok) {
417 if (current_cert) {
418 X509_NAME_print_ex_fp(stdout,
419 X509_get_subject_name(current_cert),
420 0, XN_FLAG_ONELINE);
421 printf("\n");
422 }
423 printf("%serror %d at %d depth lookup:%s\n",
424 X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
425 cert_error,
426 X509_STORE_CTX_get_error_depth(ctx),
427 X509_verify_cert_error_string(cert_error));
428 switch (cert_error) {
429 case X509_V_ERR_NO_EXPLICIT_POLICY:
430 case X509_V_ERR_CERT_HAS_EXPIRED:
431
432 /*
433 * since we are just checking the certificates, it is
434 * ok if they are self signed. But we should still
435 * warn the user.
436 */
437
438 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
439 /* Continue after extension errors too */
440 case X509_V_ERR_INVALID_CA:
441 case X509_V_ERR_INVALID_NON_CA:
442 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
443 case X509_V_ERR_INVALID_PURPOSE:
444 case X509_V_ERR_CRL_HAS_EXPIRED:
445 case X509_V_ERR_CRL_NOT_YET_VALID:
446 case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
447 ok = 1;
448
449 }
450
451 return ok;
452
453 }
454 if (!cfg.verbose)
455 ERR_clear_error();
456 return (ok);
457}
diff --git a/src/usr.bin/openssl/version.c b/src/usr.bin/openssl/version.c
deleted file mode 100644
index 991e213b82..0000000000
--- a/src/usr.bin/openssl/version.c
+++ /dev/null
@@ -1,249 +0,0 @@
1/* $OpenBSD: version.c,v 1.12 2023/07/27 07:01:50 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <stdio.h>
113#include <stdlib.h>
114#include <string.h>
115
116#include "apps.h"
117
118#include <openssl/bn.h>
119#include <openssl/crypto.h>
120#include <openssl/evp.h>
121
122#ifndef OPENSSL_NO_BF
123#include <openssl/blowfish.h>
124#endif
125
126#ifndef OPENSSL_NO_DES
127#include <openssl/des.h>
128#endif
129
130#ifndef OPENSSL_NO_IDEA
131#include <openssl/idea.h>
132#endif
133
134#ifndef OPENSSL_NO_RC4
135#include <openssl/rc4.h>
136#endif
137
138static struct {
139 int cflags;
140 int date;
141 int dir;
142 int options;
143 int platform;
144 int version;
145} cfg;
146
147static int
148version_all_opts(void)
149{
150 cfg.cflags = 1;
151 cfg.date = 1;
152 cfg.dir= 1;
153 cfg.options = 1;
154 cfg.platform = 1;
155 cfg.version = 1;
156
157 return (0);
158}
159
160static const struct option version_options[] = {
161 {
162 .name = "a",
163 .desc = "All information (same as setting all other flags)",
164 .type = OPTION_FUNC,
165 .opt.func = version_all_opts,
166 },
167 {
168 .name = "b",
169 .desc = "Date the current version of OpenSSL was built",
170 .type = OPTION_FLAG,
171 .opt.flag = &cfg.date,
172 },
173 {
174 .name = "d",
175 .desc = "OPENSSLDIR value",
176 .type = OPTION_FLAG,
177 .opt.flag = &cfg.dir,
178 },
179 {
180 .name = "f",
181 .desc = "Compilation flags",
182 .type = OPTION_FLAG,
183 .opt.flag = &cfg.cflags,
184 },
185 {
186 .name = "o",
187 .type = OPTION_FLAG,
188 .opt.flag = &cfg.options,
189 },
190 {
191 .name = "p",
192 .desc = "Platform settings",
193 .type = OPTION_FLAG,
194 .opt.flag = &cfg.platform,
195 },
196 {
197 .name = "v",
198 .desc = "Current OpenSSL version",
199 .type = OPTION_FLAG,
200 .opt.flag = &cfg.version,
201 },
202 {NULL},
203};
204
205static void
206version_usage(void)
207{
208 fprintf(stderr, "usage: version [-abdfpv]\n");
209 options_usage(version_options);
210}
211
212int
213version_main(int argc, char **argv)
214{
215 if (pledge("stdio", NULL) == -1) {
216 perror("pledge");
217 exit(1);
218 }
219
220 memset(&cfg, 0, sizeof(cfg));
221
222 if (options_parse(argc, argv, version_options, NULL, NULL) != 0) {
223 version_usage();
224 return (1);
225 }
226
227 if (argc == 1)
228 cfg.version = 1;
229
230 if (cfg.version) {
231 if (SSLeay() == SSLEAY_VERSION_NUMBER) {
232 printf("%s\n", SSLeay_version(SSLEAY_VERSION));
233 } else {
234 printf("%s (Library: %s)\n",
235 OPENSSL_VERSION_TEXT,
236 SSLeay_version(SSLEAY_VERSION));
237 }
238 }
239 if (cfg.date)
240 printf("%s\n", SSLeay_version(SSLEAY_BUILT_ON));
241 if (cfg.platform)
242 printf("%s\n", SSLeay_version(SSLEAY_PLATFORM));
243 if (cfg.cflags)
244 printf("%s\n", SSLeay_version(SSLEAY_CFLAGS));
245 if (cfg.dir)
246 printf("%s\n", SSLeay_version(SSLEAY_DIR));
247
248 return (0);
249}
diff --git a/src/usr.bin/openssl/x509.c b/src/usr.bin/openssl/x509.c
deleted file mode 100644
index e430d16f1f..0000000000
--- a/src/usr.bin/openssl/x509.c
+++ /dev/null
@@ -1,1713 +0,0 @@
1/* $OpenBSD: x509.c,v 1.42 2025/01/19 13:14:22 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <assert.h>
60#include <limits.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64
65#include "apps.h"
66
67#include <openssl/asn1.h>
68#include <openssl/bio.h>
69#include <openssl/bn.h>
70#include <openssl/dsa.h>
71#include <openssl/err.h>
72#include <openssl/evp.h>
73#include <openssl/objects.h>
74#include <openssl/pem.h>
75#include <openssl/rsa.h>
76#include <openssl/x509.h>
77#include <openssl/x509v3.h>
78
79#define POSTFIX ".srl"
80#define DEF_DAYS 30
81
82static int callb(int ok, X509_STORE_CTX *ctx);
83static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
84 const EVP_MD *digest, CONF *conf, char *section, X509_NAME *issuer,
85 char *force_pubkey);
86static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
87 X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
88 char *serial, int create, int days, int clrext, CONF *conf, char *section,
89 ASN1_INTEGER *sno, X509_NAME *issuer);
90static int purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt);
91
92static struct {
93 char *alias;
94 int aliasout;
95 int badops;
96 int CA_createserial;
97 int CA_flag;
98 char *CAfile;
99 int CAformat;
100 char *CAkeyfile;
101 int CAkeyformat;
102 char *CAserial;
103 unsigned long certflag;
104 int checkend;
105 int checkoffset;
106 unsigned long chtype;
107 int clrext;
108 int clrreject;
109 int clrtrust;
110 int days;
111 const EVP_MD *digest;
112 int email;
113 int enddate;
114 char *extfile;
115 char *extsect;
116 int fingerprint;
117 char *force_pubkey;
118 char *infile;
119 int informat;
120 int issuer;
121 int issuer_hash;
122#ifndef OPENSSL_NO_MD5
123 int issuer_hash_old;
124#endif
125 char *keyfile;
126 int keyformat;
127 const EVP_MD *md_alg;
128 int modulus;
129 int multirdn;
130 int new;
131 int next_serial;
132 unsigned long nmflag;
133 int noout;
134 int num;
135 int ocspid;
136 ASN1_OBJECT *objtmp;
137 int ocsp_uri;
138 char *outfile;
139 int outformat;
140 char *passargin;
141 int pprint;
142 int pubkey;
143 STACK_OF(ASN1_OBJECT) *reject;
144 int reqfile;
145 int serial;
146 char *set_issuer;
147 char *set_subject;
148 int sign_flag;
149 STACK_OF(OPENSSL_STRING) *sigopts;
150 ASN1_INTEGER *sno;
151 int startdate;
152 int subject;
153 int subject_hash;
154#ifndef OPENSSL_NO_MD5
155 int subject_hash_old;
156#endif
157 int text;
158 STACK_OF(ASN1_OBJECT) *trust;
159 int trustout;
160 int x509req;
161} cfg;
162
163static int
164x509_opt_addreject(char *arg)
165{
166 if ((cfg.objtmp = OBJ_txt2obj(arg, 0)) == NULL) {
167 BIO_printf(bio_err, "Invalid reject object value %s\n", arg);
168 return (1);
169 }
170
171 if (cfg.reject == NULL &&
172 (cfg.reject = sk_ASN1_OBJECT_new_null()) == NULL)
173 return (1);
174
175 if (!sk_ASN1_OBJECT_push(cfg.reject, cfg.objtmp))
176 return (1);
177
178 cfg.trustout = 1;
179 return (0);
180}
181
182static int
183x509_opt_addtrust(char *arg)
184{
185 if ((cfg.objtmp = OBJ_txt2obj(arg, 0)) == NULL) {
186 BIO_printf(bio_err, "Invalid trust object value %s\n", arg);
187 return (1);
188 }
189
190 if (cfg.trust == NULL &&
191 (cfg.trust = sk_ASN1_OBJECT_new_null()) == NULL)
192 return (1);
193
194 if (!sk_ASN1_OBJECT_push(cfg.trust, cfg.objtmp))
195 return (1);
196
197 cfg.trustout = 1;
198 return (0);
199}
200
201static int
202x509_opt_ca(char *arg)
203{
204 cfg.CAfile = arg;
205 cfg.CA_flag = ++cfg.num;
206 return (0);
207}
208
209static int
210x509_opt_certopt(char *arg)
211{
212 if (!set_cert_ex(&cfg.certflag, arg))
213 return (1);
214
215 return (0);
216}
217
218static int
219x509_opt_checkend(char *arg)
220{
221 const char *errstr;
222
223 cfg.checkoffset = strtonum(arg, 0, INT_MAX, &errstr);
224 if (errstr != NULL) {
225 BIO_printf(bio_err, "checkend unusable: %s\n", errstr);
226 return (1);
227 }
228 cfg.checkend = 1;
229 return (0);
230}
231
232static int
233x509_opt_dates(void)
234{
235 cfg.startdate = ++cfg.num;
236 cfg.enddate = ++cfg.num;
237 return (0);
238}
239
240static int
241x509_opt_days(char *arg)
242{
243 const char *errstr;
244
245 cfg.days = strtonum(arg, 1, INT_MAX, &errstr);
246 if (errstr != NULL) {
247 BIO_printf(bio_err, "bad number of days: %s\n", errstr);
248 return (1);
249 }
250 return (0);
251}
252
253static int
254x509_opt_digest(int argc, char **argv, int *argsused)
255{
256 char *name = argv[0];
257
258 if (*name++ != '-')
259 return (1);
260
261 if ((cfg.md_alg = EVP_get_digestbyname(name)) != NULL) {
262 cfg.digest = cfg.md_alg;
263 } else {
264 BIO_printf(bio_err, "unknown option %s\n", *argv);
265 cfg.badops = 1;
266 return (1);
267 }
268
269 *argsused = 1;
270 return (0);
271}
272
273static int
274x509_opt_nameopt(char *arg)
275{
276 if (!set_name_ex(&cfg.nmflag, arg))
277 return (1);
278
279 return (0);
280}
281
282static int
283x509_opt_set_serial(char *arg)
284{
285 ASN1_INTEGER_free(cfg.sno);
286 if ((cfg.sno = s2i_ASN1_INTEGER(NULL, arg)) == NULL)
287 return (1);
288
289 return (0);
290}
291
292static int
293x509_opt_setalias(char *arg)
294{
295 cfg.alias = arg;
296 cfg.trustout = 1;
297 return (0);
298}
299
300static int
301x509_opt_signkey(char *arg)
302{
303 cfg.keyfile = arg;
304 cfg.sign_flag = ++cfg.num;
305 return (0);
306}
307
308static int
309x509_opt_sigopt(char *arg)
310{
311 if (cfg.sigopts == NULL &&
312 (cfg.sigopts = sk_OPENSSL_STRING_new_null()) == NULL)
313 return (1);
314
315 if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
316 return (1);
317
318 return (0);
319}
320
321static int
322x509_opt_utf8(void)
323{
324 cfg.chtype = MBSTRING_UTF8;
325 return (0);
326}
327
328static const struct option x509_options[] = {
329 {
330 .name = "addreject",
331 .argname = "arg",
332 .desc = "Reject certificate for a given purpose",
333 .type = OPTION_ARG_FUNC,
334 .opt.argfunc = x509_opt_addreject,
335 },
336 {
337 .name = "addtrust",
338 .argname = "arg",
339 .desc = "Trust certificate for a given purpose",
340 .type = OPTION_ARG_FUNC,
341 .opt.argfunc = x509_opt_addtrust,
342 },
343 {
344 .name = "alias",
345 .desc = "Output certificate alias",
346 .type = OPTION_ORDER,
347 .opt.order = &cfg.aliasout,
348 .order = &cfg.num,
349 },
350 {
351 .name = "CA",
352 .argname = "file",
353 .desc = "CA certificate in PEM format unless -CAform is specified",
354 .type = OPTION_ARG_FUNC,
355 .opt.argfunc = x509_opt_ca,
356 },
357 {
358 .name = "CAcreateserial",
359 .desc = "Create serial number file if it does not exist",
360 .type = OPTION_ORDER,
361 .opt.order = &cfg.CA_createserial,
362 .order = &cfg.num,
363 },
364 {
365 .name = "CAform",
366 .argname = "fmt",
367 .desc = "CA format - default PEM",
368 .type = OPTION_ARG_FORMAT,
369 .opt.value = &cfg.CAformat,
370 },
371 {
372 .name = "CAkey",
373 .argname = "file",
374 .desc = "CA key in PEM format unless -CAkeyform is specified\n"
375 "if omitted, the key is assumed to be in the CA file",
376 .type = OPTION_ARG,
377 .opt.arg = &cfg.CAkeyfile,
378 },
379 {
380 .name = "CAkeyform",
381 .argname = "fmt",
382 .desc = "CA key format - default PEM",
383 .type = OPTION_ARG_FORMAT,
384 .opt.value = &cfg.CAkeyformat,
385 },
386 {
387 .name = "CAserial",
388 .argname = "file",
389 .desc = "Serial file",
390 .type = OPTION_ARG,
391 .opt.arg = &cfg.CAserial,
392 },
393 {
394 .name = "certopt",
395 .argname = "option",
396 .desc = "Various certificate text options",
397 .type = OPTION_ARG_FUNC,
398 .opt.argfunc = x509_opt_certopt,
399 },
400 {
401 .name = "checkend",
402 .argname = "arg",
403 .desc = "Check whether the cert expires in the next arg seconds\n"
404 "exit 1 if so, 0 if not",
405 .type = OPTION_ARG_FUNC,
406 .opt.argfunc = x509_opt_checkend,
407 },
408 {
409 .name = "clrext",
410 .desc = "Clear all extensions",
411 .type = OPTION_FLAG,
412 .opt.flag = &cfg.clrext,
413 },
414 {
415 .name = "clrreject",
416 .desc = "Clear all rejected purposes",
417 .type = OPTION_ORDER,
418 .opt.order = &cfg.clrreject,
419 .order = &cfg.num,
420 },
421 {
422 .name = "clrtrust",
423 .desc = "Clear all trusted purposes",
424 .type = OPTION_ORDER,
425 .opt.order = &cfg.clrtrust,
426 .order = &cfg.num,
427 },
428 {
429 .name = "dates",
430 .desc = "Both Before and After dates",
431 .type = OPTION_FUNC,
432 .opt.func = x509_opt_dates,
433 },
434 {
435 .name = "days",
436 .argname = "arg",
437 .desc = "How long till expiry of a signed certificate - def 30 days",
438 .type = OPTION_ARG_FUNC,
439 .opt.argfunc = x509_opt_days,
440 },
441 {
442 .name = "email",
443 .desc = "Print email address(es)",
444 .type = OPTION_ORDER,
445 .opt.order = &cfg.email,
446 .order = &cfg.num,
447 },
448 {
449 .name = "enddate",
450 .desc = "Print notAfter field",
451 .type = OPTION_ORDER,
452 .opt.order = &cfg.enddate,
453 .order = &cfg.num,
454 },
455 {
456 .name = "extensions",
457 .argname = "section",
458 .desc = "Section from config file with X509V3 extensions to add",
459 .type = OPTION_ARG,
460 .opt.arg = &cfg.extsect,
461 },
462 {
463 .name = "extfile",
464 .argname = "file",
465 .desc = "Configuration file with X509V3 extensions to add",
466 .type = OPTION_ARG,
467 .opt.arg = &cfg.extfile,
468 },
469 {
470 .name = "fingerprint",
471 .desc = "Print the certificate fingerprint",
472 .type = OPTION_ORDER,
473 .opt.order = &cfg.fingerprint,
474 .order = &cfg.num,
475 },
476 {
477 .name = "force_pubkey",
478 .argname = "key",
479 .desc = "Force the public key to be put in the certificate",
480 .type = OPTION_ARG,
481 .opt.arg = &cfg.force_pubkey,
482 },
483 {
484 .name = "hash",
485 .desc = "Synonym for -subject_hash",
486 .type = OPTION_ORDER,
487 .opt.order = &cfg.subject_hash,
488 .order = &cfg.num,
489 },
490 {
491 .name = "in",
492 .argname = "file",
493 .desc = "Input file - default stdin",
494 .type = OPTION_ARG,
495 .opt.arg = &cfg.infile,
496 },
497 {
498 .name = "inform",
499 .argname = "fmt",
500 .desc = "Input format - default PEM (one of DER, NET or PEM)",
501 .type = OPTION_ARG_FORMAT,
502 .opt.value = &cfg.informat,
503 },
504 {
505 .name = "issuer",
506 .desc = "Print issuer name",
507 .type = OPTION_ORDER,
508 .opt.order = &cfg.issuer,
509 .order = &cfg.num,
510 },
511 {
512 .name = "issuer_hash",
513 .desc = "Print issuer hash value",
514 .type = OPTION_ORDER,
515 .opt.order = &cfg.issuer_hash,
516 .order = &cfg.num,
517 },
518#ifndef OPENSSL_NO_MD5
519 {
520 .name = "issuer_hash_old",
521 .desc = "Print old-style (MD5) issuer hash value",
522 .type = OPTION_ORDER,
523 .opt.order = &cfg.issuer_hash_old,
524 .order = &cfg.num,
525 },
526#endif
527 {
528 .name = "key",
529 .argname = "file",
530 .type = OPTION_ARG_FUNC,
531 .opt.argfunc = x509_opt_signkey,
532 },
533 {
534 .name = "keyform",
535 .argname = "fmt",
536 .desc = "Private key format - default PEM",
537 .type = OPTION_ARG_FORMAT,
538 .opt.value = &cfg.keyformat,
539 },
540 {
541 .name = "modulus",
542 .desc = "Print the RSA key modulus",
543 .type = OPTION_ORDER,
544 .opt.order = &cfg.modulus,
545 .order = &cfg.num,
546 },
547 {
548 .name = "multivalue-rdn",
549 .desc = "Enable support for multivalued RDNs",
550 .type = OPTION_FLAG,
551 .opt.flag = &cfg.multirdn,
552 },
553 {
554 .name = "nameopt",
555 .argname = "option",
556 .desc = "Various certificate name options",
557 .type = OPTION_ARG_FUNC,
558 .opt.argfunc = x509_opt_nameopt,
559 },
560 {
561 .name = "new",
562 .desc = "Generate a new certificate",
563 .type = OPTION_FLAG,
564 .opt.flag = &cfg.new,
565 },
566 {
567 .name = "next_serial",
568 .desc = "Print the next serial number",
569 .type = OPTION_ORDER,
570 .opt.order = &cfg.next_serial,
571 .order = &cfg.num,
572 },
573 {
574 .name = "noout",
575 .desc = "No certificate output",
576 .type = OPTION_ORDER,
577 .opt.order = &cfg.noout,
578 .order = &cfg.num,
579 },
580 {
581 .name = "ocsp_uri",
582 .desc = "Print OCSP Responder URL(s)",
583 .type = OPTION_ORDER,
584 .opt.order = &cfg.ocsp_uri,
585 .order = &cfg.num,
586 },
587 {
588 .name = "ocspid",
589 .desc = "Print OCSP hash values for the subject name and public key",
590 .type = OPTION_ORDER,
591 .opt.order = &cfg.ocspid,
592 .order = &cfg.num,
593 },
594 {
595 .name = "out",
596 .argname = "file",
597 .desc = "Output file - default stdout",
598 .type = OPTION_ARG,
599 .opt.arg = &cfg.outfile,
600 },
601 {
602 .name = "outform",
603 .argname = "fmt",
604 .desc = "Output format - default PEM (one of DER, NET or PEM)",
605 .type = OPTION_ARG_FORMAT,
606 .opt.value = &cfg.outformat,
607 },
608 {
609 .name = "passin",
610 .argname = "src",
611 .desc = "Private key password source",
612 .type = OPTION_ARG,
613 .opt.arg = &cfg.passargin,
614 },
615 {
616 .name = "pubkey",
617 .desc = "Output the public key",
618 .type = OPTION_ORDER,
619 .opt.order = &cfg.pubkey,
620 .order = &cfg.num,
621 },
622 {
623 .name = "purpose",
624 .desc = "Print out certificate purposes",
625 .type = OPTION_ORDER,
626 .opt.order = &cfg.pprint,
627 .order = &cfg.num,
628 },
629 {
630 .name = "req",
631 .desc = "Input is a certificate request, sign and output",
632 .type = OPTION_FLAG,
633 .opt.flag = &cfg.reqfile,
634 },
635 {
636 .name = "serial",
637 .desc = "Print serial number value",
638 .type = OPTION_ORDER,
639 .opt.order = &cfg.serial,
640 .order = &cfg.num,
641 },
642 {
643 .name = "set_issuer",
644 .argname = "name",
645 .desc = "Set the issuer name",
646 .type = OPTION_ARG,
647 .opt.arg = &cfg.set_issuer,
648 },
649 {
650 .name = "set_serial",
651 .argname = "n",
652 .desc = "Serial number to use",
653 .type = OPTION_ARG_FUNC,
654 .opt.argfunc = x509_opt_set_serial,
655 },
656 {
657 .name = "set_subject",
658 .argname = "name",
659 .desc = "Set the subject name",
660 .type = OPTION_ARG,
661 .opt.arg = &cfg.set_subject,
662 },
663 {
664 .name = "setalias",
665 .argname = "arg",
666 .desc = "Set certificate alias",
667 .type = OPTION_ARG_FUNC,
668 .opt.argfunc = x509_opt_setalias,
669 },
670 {
671 .name = "signkey",
672 .argname = "file",
673 .desc = "Self sign cert with arg",
674 .type = OPTION_ARG_FUNC,
675 .opt.argfunc = x509_opt_signkey,
676 },
677 {
678 .name = "sigopt",
679 .argname = "nm:v",
680 .desc = "Various signature algorithm options",
681 .type = OPTION_ARG_FUNC,
682 .opt.argfunc = x509_opt_sigopt,
683 },
684 {
685 .name = "startdate",
686 .desc = "Print notBefore field",
687 .type = OPTION_ORDER,
688 .opt.order = &cfg.startdate,
689 .order = &cfg.num,
690 },
691 {
692 .name = "subj",
693 .type = OPTION_ARG,
694 .opt.arg = &cfg.set_subject,
695 },
696 {
697 .name = "subject",
698 .desc = "Print subject name",
699 .type = OPTION_ORDER,
700 .opt.order = &cfg.subject,
701 .order = &cfg.num,
702 },
703 {
704 .name = "subject_hash",
705 .desc = "Print subject hash value",
706 .type = OPTION_ORDER,
707 .opt.order = &cfg.subject_hash,
708 .order = &cfg.num,
709 },
710#ifndef OPENSSL_NO_MD5
711 {
712 .name = "subject_hash_old",
713 .desc = "Print old-style (MD5) subject hash value",
714 .type = OPTION_ORDER,
715 .opt.order = &cfg.subject_hash_old,
716 .order = &cfg.num,
717 },
718#endif
719 {
720 .name = "text",
721 .desc = "Print the certificate in text form",
722 .type = OPTION_ORDER,
723 .opt.order = &cfg.text,
724 .order = &cfg.num,
725 },
726 {
727 .name = "trustout",
728 .desc = "Output a trusted certificate",
729 .type = OPTION_FLAG,
730 .opt.flag = &cfg.trustout,
731 },
732 {
733 .name = "utf8",
734 .desc = "Input characters are in UTF-8 (default ASCII)",
735 .type = OPTION_FUNC,
736 .opt.func = x509_opt_utf8,
737 },
738 {
739 .name = "x509toreq",
740 .desc = "Output a certification request object",
741 .type = OPTION_ORDER,
742 .opt.order = &cfg.x509req,
743 .order = &cfg.num,
744 },
745 {
746 .name = NULL,
747 .desc = "",
748 .type = OPTION_ARGV_FUNC,
749 .opt.argvfunc = x509_opt_digest,
750 },
751 { NULL },
752};
753
754static void
755x509_usage(void)
756{
757 fprintf(stderr, "usage: x509 "
758 "[-addreject arg] [-addtrust arg] [-alias] [-CA file]\n"
759 " [-CAcreateserial] [-CAform der | pem] [-CAkey file]\n"
760 " [-CAkeyform der | pem] [-CAserial file] [-certopt option]\n"
761 " [-checkend arg] [-clrext] [-clrreject] [-clrtrust] [-dates]\n"
762 " [-days arg] [-email] [-enddate] [-extensions section]\n"
763 " [-extfile file] [-fingerprint] [-force_pubkey key] [-hash]\n"
764 " [-in file] [-inform der | net | pem] [-issuer]\n"
765 " [-issuer_hash] [-issuer_hash_old] [-keyform der | pem]\n"
766 " [-md5 | -sha1] [-modulus] [-multivalue-rdn]\n"
767 " [-nameopt option] [-new] [-next_serial] [-noout] [-ocsp_uri]\n"
768 " [-ocspid] [-out file] [-outform der | net | pem]\n"
769 " [-passin arg] [-pubkey] [-purpose] [-req] [-serial]\n"
770 " [-set_issuer name] [-set_serial n] [-set_subject name]\n"
771 " [-setalias arg] [-signkey file] [-sigopt nm:v] [-startdate]\n"
772 " [-subject] [-subject_hash] [-subject_hash_old] [-text]\n"
773 " [-trustout] [-utf8] [-x509toreq]\n");
774 fprintf(stderr, "\n");
775 options_usage(x509_options);
776 fprintf(stderr, "\n");
777}
778
779int
780x509_main(int argc, char **argv)
781{
782 int ret = 1;
783 X509_REQ *req = NULL;
784 X509 *x = NULL, *xca = NULL;
785 X509_NAME *iname = NULL, *sname = NULL;
786 EVP_PKEY *Fpkey = NULL, *Upkey = NULL, *CApkey = NULL;
787 EVP_PKEY *pkey;
788 int i;
789 BIO *out = NULL;
790 BIO *STDout = NULL;
791 X509_STORE *ctx = NULL;
792 X509_REQ *rq = NULL;
793 CONF *extconf = NULL;
794 char *passin = NULL;
795
796 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
797 perror("pledge");
798 exit(1);
799 }
800
801 memset(&cfg, 0, sizeof(cfg));
802 cfg.chtype = MBSTRING_ASC;
803 cfg.days = DEF_DAYS;
804 cfg.informat = FORMAT_PEM;
805 cfg.outformat = FORMAT_PEM;
806 cfg.keyformat = FORMAT_PEM;
807 cfg.CAformat = FORMAT_PEM;
808 cfg.CAkeyformat = FORMAT_PEM;
809
810 STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
811
812 ctx = X509_STORE_new();
813 if (ctx == NULL)
814 goto end;
815 X509_STORE_set_verify_cb(ctx, callb);
816
817 if (options_parse(argc, argv, x509_options, NULL, NULL) != 0)
818 goto bad;
819
820 if (cfg.badops) {
821 bad:
822 x509_usage();
823 goto end;
824 }
825
826 if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
827 BIO_printf(bio_err, "Error getting password\n");
828 goto end;
829 }
830 if (!X509_STORE_set_default_paths(ctx)) {
831 ERR_print_errors(bio_err);
832 goto end;
833 }
834 if (cfg.CAkeyfile == NULL && cfg.CA_flag && cfg.CAformat == FORMAT_PEM) {
835 cfg.CAkeyfile = cfg.CAfile;
836 } else if (cfg.CA_flag && cfg.CAkeyfile == NULL) {
837 BIO_printf(bio_err,
838 "need to specify a CAkey if using the CA command\n");
839 goto end;
840 }
841 if (cfg.extfile != NULL) {
842 long errorline = -1;
843 X509V3_CTX ctx2;
844 extconf = NCONF_new(NULL);
845 if (!NCONF_load(extconf, cfg.extfile, &errorline)) {
846 if (errorline <= 0)
847 BIO_printf(bio_err,
848 "error loading the config file '%s'\n",
849 cfg.extfile);
850 else
851 BIO_printf(bio_err,
852 "error on line %ld of config file '%s'\n",
853 errorline, cfg.extfile);
854 goto end;
855 }
856 if (cfg.extsect == NULL) {
857 cfg.extsect = NCONF_get_string(extconf, "default",
858 "extensions");
859 if (cfg.extsect == NULL) {
860 ERR_clear_error();
861 cfg.extsect = "default";
862 }
863 }
864 X509V3_set_ctx_test(&ctx2);
865 X509V3_set_nconf(&ctx2, extconf);
866 if (!X509V3_EXT_add_nconf(extconf, &ctx2, cfg.extsect, NULL)) {
867 BIO_printf(bio_err,
868 "Error Loading extension section %s\n", cfg.extsect);
869 ERR_print_errors(bio_err);
870 goto end;
871 }
872 }
873 if (cfg.force_pubkey != NULL) {
874 if ((Fpkey = load_pubkey(bio_err, cfg.force_pubkey,
875 cfg.keyformat, 0, NULL, "Forced key")) == NULL)
876 goto end;
877 }
878 if (cfg.new) {
879 if (cfg.infile != NULL) {
880 BIO_printf(bio_err, "Can't combine -new and -in\n");
881 goto end;
882 }
883 if (cfg.reqfile) {
884 BIO_printf(bio_err, "Can't combine -new and -req\n");
885 goto end;
886 }
887 if (cfg.set_subject == NULL) {
888 BIO_printf(bio_err, "Must use -set_subject with -new\n");
889 goto end;
890 }
891 if (cfg.keyfile == NULL) {
892 BIO_printf(bio_err, "Must use -signkey with -new\n");
893 goto end;
894 }
895 if ((Upkey = load_key(bio_err, cfg.keyfile, cfg.keyformat, 0,
896 passin, "Private key")) == NULL)
897 goto end;
898 }
899 if (cfg.reqfile) {
900 BIO *in;
901
902 if (!cfg.sign_flag && !cfg.CA_flag) {
903 BIO_printf(bio_err,
904 "We need a private key to sign with\n");
905 goto end;
906 }
907 in = BIO_new(BIO_s_file());
908 if (in == NULL) {
909 ERR_print_errors(bio_err);
910 goto end;
911 }
912 if (cfg.infile == NULL)
913 BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
914 else {
915 if (BIO_read_filename(in, cfg.infile) <= 0) {
916 perror(cfg.infile);
917 BIO_free(in);
918 goto end;
919 }
920 }
921 req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
922 BIO_free(in);
923
924 if (req == NULL) {
925 ERR_print_errors(bio_err);
926 goto end;
927 }
928 if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
929 BIO_printf(bio_err, "error unpacking public key\n");
930 goto end;
931 }
932 i = X509_REQ_verify(req, pkey);
933 if (i < 0) {
934 BIO_printf(bio_err, "Signature verification error\n");
935 ERR_print_errors(bio_err);
936 goto end;
937 }
938 if (i == 0) {
939 BIO_printf(bio_err,
940 "Signature did not match the certificate request\n");
941 goto end;
942 } else
943 BIO_printf(bio_err, "Signature ok\n");
944
945 print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
946 cfg.nmflag);
947
948 }
949 if (cfg.reqfile || cfg.new) {
950 if ((x = X509_new()) == NULL)
951 goto end;
952
953 if (cfg.sno == NULL) {
954 cfg.sno = ASN1_INTEGER_new();
955 if (cfg.sno == NULL || !rand_serial(NULL, cfg.sno))
956 goto end;
957 if (!X509_set_serialNumber(x, cfg.sno))
958 goto end;
959 ASN1_INTEGER_free(cfg.sno);
960 cfg.sno = NULL;
961 } else if (!X509_set_serialNumber(x, cfg.sno))
962 goto end;
963
964 if (cfg.set_issuer != NULL) {
965 iname = parse_name(cfg.set_issuer, cfg.chtype,
966 cfg.multirdn);
967 if (iname == NULL)
968 goto end;
969 }
970
971 if (cfg.set_subject != NULL)
972 sname = parse_name(cfg.set_subject, cfg.chtype,
973 cfg.multirdn);
974 else
975 sname = X509_NAME_dup(X509_REQ_get_subject_name(req));
976 if (sname == NULL)
977 goto end;
978 if (!X509_set_subject_name(x, sname))
979 goto end;
980
981 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
982 goto end;
983 if (X509_time_adj_ex(X509_get_notAfter(x), cfg.days, 0,
984 NULL) == NULL)
985 goto end;
986
987 if ((pkey = Fpkey) == NULL)
988 pkey = X509_REQ_get0_pubkey(req);
989 if (pkey == NULL)
990 pkey = Upkey;
991 if (pkey == NULL)
992 goto end;
993 if (!X509_set_pubkey(x, pkey))
994 goto end;
995 } else {
996 x = load_cert(bio_err, cfg.infile, cfg.informat, NULL,
997 "Certificate");
998 }
999 if (x == NULL)
1000 goto end;
1001
1002 if (cfg.CA_flag) {
1003 xca = load_cert(bio_err, cfg.CAfile, cfg.CAformat, NULL,
1004 "CA Certificate");
1005 if (xca == NULL)
1006 goto end;
1007 }
1008 if (!cfg.noout || cfg.text || cfg.next_serial) {
1009 OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
1010
1011 out = BIO_new(BIO_s_file());
1012 if (out == NULL) {
1013 ERR_print_errors(bio_err);
1014 goto end;
1015 }
1016 if (cfg.outfile == NULL) {
1017 BIO_set_fp(out, stdout, BIO_NOCLOSE);
1018 } else {
1019 if (BIO_write_filename(out, cfg.outfile) <= 0) {
1020 perror(cfg.outfile);
1021 goto end;
1022 }
1023 }
1024 }
1025 if (cfg.alias != NULL) {
1026 if (!X509_alias_set1(x, (unsigned char *)cfg.alias, -1))
1027 goto end;
1028 }
1029
1030 if (cfg.clrtrust)
1031 X509_trust_clear(x);
1032 if (cfg.clrreject)
1033 X509_reject_clear(x);
1034
1035 if (cfg.trust != NULL) {
1036 for (i = 0; i < sk_ASN1_OBJECT_num(cfg.trust); i++) {
1037 cfg.objtmp = sk_ASN1_OBJECT_value(cfg.trust, i);
1038 if (!X509_add1_trust_object(x, cfg.objtmp))
1039 goto end;
1040 }
1041 }
1042 if (cfg.reject != NULL) {
1043 for (i = 0; i < sk_ASN1_OBJECT_num(cfg.reject); i++) {
1044 cfg.objtmp = sk_ASN1_OBJECT_value(cfg.reject, i);
1045 if (!X509_add1_reject_object(x, cfg.objtmp))
1046 goto end;
1047 }
1048 }
1049 if (cfg.num) {
1050 for (i = 1; i <= cfg.num; i++) {
1051 if (cfg.issuer == i) {
1052 print_name(STDout, "issuer= ",
1053 X509_get_issuer_name(x), cfg.nmflag);
1054 } else if (cfg.subject == i) {
1055 print_name(STDout, "subject= ",
1056 X509_get_subject_name(x), cfg.nmflag);
1057 } else if (cfg.serial == i) {
1058 BIO_printf(STDout, "serial=");
1059 i2a_ASN1_INTEGER(STDout,
1060 X509_get_serialNumber(x));
1061 BIO_printf(STDout, "\n");
1062 } else if (cfg.next_serial == i) {
1063 BIGNUM *bnser;
1064 ASN1_INTEGER *ser;
1065
1066 ser = X509_get_serialNumber(x);
1067 if (ser == NULL)
1068 goto end;
1069 bnser = ASN1_INTEGER_to_BN(ser, NULL);
1070 if (bnser == NULL)
1071 goto end;
1072 if (!BN_add_word(bnser, 1)) {
1073 BN_free(bnser);
1074 goto end;
1075 }
1076 ser = BN_to_ASN1_INTEGER(bnser, NULL);
1077 if (ser == NULL) {
1078 BN_free(bnser);
1079 goto end;
1080 }
1081 BN_free(bnser);
1082 i2a_ASN1_INTEGER(out, ser);
1083 ASN1_INTEGER_free(ser);
1084 BIO_puts(out, "\n");
1085 } else if (cfg.email == i || cfg.ocsp_uri == i) {
1086 STACK_OF(OPENSSL_STRING) *emlst;
1087 int j;
1088
1089 if (cfg.email == i)
1090 emlst = X509_get1_email(x);
1091 else
1092 emlst = X509_get1_ocsp(x);
1093 for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
1094 BIO_printf(STDout, "%s\n",
1095 sk_OPENSSL_STRING_value(emlst, j));
1096 X509_email_free(emlst);
1097 } else if (cfg.aliasout == i) {
1098 unsigned char *albuf;
1099 int buflen;
1100 albuf = X509_alias_get0(x, &buflen);
1101 if (albuf != NULL)
1102 BIO_printf(STDout, "%.*s\n",
1103 buflen, albuf);
1104 else
1105 BIO_puts(STDout, "<No Alias>\n");
1106 } else if (cfg.subject_hash == i) {
1107 BIO_printf(STDout, "%08lx\n",
1108 X509_subject_name_hash(x));
1109 }
1110#ifndef OPENSSL_NO_MD5
1111 else if (cfg.subject_hash_old == i) {
1112 BIO_printf(STDout, "%08lx\n",
1113 X509_subject_name_hash_old(x));
1114 }
1115#endif
1116 else if (cfg.issuer_hash == i) {
1117 BIO_printf(STDout, "%08lx\n",
1118 X509_issuer_name_hash(x));
1119 }
1120#ifndef OPENSSL_NO_MD5
1121 else if (cfg.issuer_hash_old == i) {
1122 BIO_printf(STDout, "%08lx\n",
1123 X509_issuer_name_hash_old(x));
1124 }
1125#endif
1126 else if (cfg.pprint == i) {
1127 const X509_PURPOSE *ptmp;
1128 int j;
1129
1130 BIO_printf(STDout, "Certificate purposes:\n");
1131 for (j = 0; j < X509_PURPOSE_get_count(); j++) {
1132 ptmp = X509_PURPOSE_get0(j);
1133 purpose_print(STDout, x, ptmp);
1134 }
1135 } else if (cfg.modulus == i) {
1136 EVP_PKEY *pubkey;
1137
1138 if ((pubkey = X509_get0_pubkey(x)) == NULL) {
1139 BIO_printf(bio_err,
1140 "Modulus=unavailable\n");
1141 ERR_print_errors(bio_err);
1142 goto end;
1143 }
1144 BIO_printf(STDout, "Modulus=");
1145 if (EVP_PKEY_id(pubkey) == EVP_PKEY_RSA) {
1146 RSA *rsa = EVP_PKEY_get0_RSA(pubkey);
1147 const BIGNUM *n = NULL;
1148
1149 RSA_get0_key(rsa, &n, NULL, NULL);
1150 BN_print(STDout, n);
1151 } else if (EVP_PKEY_id(pubkey) == EVP_PKEY_DSA) {
1152 DSA *dsa = EVP_PKEY_get0_DSA(pubkey);
1153 const BIGNUM *dsa_pub_key = NULL;
1154
1155 DSA_get0_key(dsa, &dsa_pub_key, NULL);
1156
1157 BN_print(STDout, dsa_pub_key);
1158 } else
1159 BIO_printf(STDout,
1160 "Wrong Algorithm type");
1161 BIO_printf(STDout, "\n");
1162 } else if (cfg.pubkey == i) {
1163 EVP_PKEY *pubkey;
1164
1165 if ((pubkey = X509_get0_pubkey(x)) == NULL) {
1166 BIO_printf(bio_err,
1167 "Error getting public key\n");
1168 ERR_print_errors(bio_err);
1169 goto end;
1170 }
1171 PEM_write_bio_PUBKEY(STDout, pubkey);
1172 } else if (cfg.text == i) {
1173 if(!X509_print_ex(STDout, x, cfg.nmflag,
1174 cfg.certflag))
1175 goto end;
1176 } else if (cfg.startdate == i) {
1177 ASN1_TIME *nB = X509_get_notBefore(x);
1178
1179 BIO_puts(STDout, "notBefore=");
1180 if (!ASN1_TIME_to_tm(nB, NULL))
1181 BIO_puts(STDout,
1182 "INVALID RFC5280 TIME");
1183 else
1184 ASN1_TIME_print(STDout, nB);
1185 BIO_puts(STDout, "\n");
1186 } else if (cfg.enddate == i) {
1187 ASN1_TIME *nA = X509_get_notAfter(x);
1188
1189 BIO_puts(STDout, "notAfter=");
1190 if (!ASN1_TIME_to_tm(nA, NULL))
1191 BIO_puts(STDout,
1192 "INVALID RFC5280 TIME");
1193 else
1194 ASN1_TIME_print(STDout, nA);
1195 BIO_puts(STDout, "\n");
1196 } else if (cfg.fingerprint == i) {
1197 int j;
1198 unsigned int n;
1199 unsigned char md[EVP_MAX_MD_SIZE];
1200 const EVP_MD *fdig = cfg.digest;
1201
1202 if (fdig == NULL)
1203 fdig = EVP_sha256();
1204
1205 if (!X509_digest(x, fdig, md, &n)) {
1206 BIO_printf(bio_err, "out of memory\n");
1207 goto end;
1208 }
1209 BIO_printf(STDout, "%s Fingerprint=",
1210 OBJ_nid2sn(EVP_MD_type(fdig)));
1211 for (j = 0; j < (int) n; j++) {
1212 BIO_printf(STDout, "%02X%c", md[j],
1213 (j + 1 == (int)n) ? '\n' : ':');
1214 }
1215 } else if (cfg.sign_flag == i && cfg.x509req == 0) {
1216 if (Upkey == NULL) {
1217 Upkey = load_key(bio_err, cfg.keyfile,
1218 cfg.keyformat, 0, passin,
1219 "Private key");
1220 if (Upkey == NULL)
1221 goto end;
1222 }
1223 if (!sign(x, Upkey, cfg.days,
1224 cfg.clrext, cfg.digest,
1225 extconf, cfg.extsect, iname,
1226 cfg.force_pubkey))
1227 goto end;
1228 } else if (cfg.CA_flag == i) {
1229 if (cfg.CAkeyfile != NULL) {
1230 CApkey = load_key(bio_err, cfg.CAkeyfile,
1231 cfg.CAkeyformat, 0, passin,
1232 "CA Private Key");
1233 if (CApkey == NULL)
1234 goto end;
1235 }
1236 if (!x509_certify(ctx, cfg.CAfile, cfg.digest,
1237 x, xca, CApkey, cfg.sigopts, cfg.CAserial,
1238 cfg.CA_createserial, cfg.days, cfg.clrext,
1239 extconf, cfg.extsect, cfg.sno, iname))
1240 goto end;
1241 } else if (cfg.x509req == i) {
1242 EVP_PKEY *pk;
1243
1244 BIO_printf(bio_err,
1245 "Getting request Private Key\n");
1246 if (cfg.keyfile == NULL) {
1247 BIO_printf(bio_err,
1248 "no request key file specified\n");
1249 goto end;
1250 } else {
1251 pk = load_key(bio_err, cfg.keyfile,
1252 cfg.keyformat, 0, passin,
1253 "request key");
1254 if (pk == NULL)
1255 goto end;
1256 }
1257
1258 BIO_printf(bio_err,
1259 "Generating certificate request\n");
1260
1261 rq = X509_to_X509_REQ(x, pk, cfg.digest);
1262 EVP_PKEY_free(pk);
1263 if (rq == NULL) {
1264 ERR_print_errors(bio_err);
1265 goto end;
1266 }
1267 if (!cfg.noout) {
1268 if (!X509_REQ_print(out, rq))
1269 goto end;
1270 if (!PEM_write_bio_X509_REQ(out, rq))
1271 goto end;
1272 }
1273 cfg.noout = 1;
1274 } else if (cfg.ocspid == i) {
1275 if (!X509_ocspid_print(out, x))
1276 goto end;
1277 }
1278 }
1279 }
1280 if (cfg.checkend) {
1281 time_t tcheck = time(NULL) + cfg.checkoffset;
1282 int timecheck = X509_cmp_time(X509_get_notAfter(x), &tcheck);
1283 if (timecheck == 0) {
1284 BIO_printf(out, "Certificate expiry time is invalid\n");
1285 ret = 1;
1286 } else if (timecheck < 0) {
1287 BIO_printf(out, "Certificate will expire\n");
1288 ret = 1;
1289 } else {
1290 BIO_printf(out, "Certificate will not expire\n");
1291 ret = 0;
1292 }
1293 goto end;
1294 }
1295 if (cfg.noout) {
1296 ret = 0;
1297 goto end;
1298 }
1299 if (cfg.outformat == FORMAT_ASN1)
1300 i = i2d_X509_bio(out, x);
1301 else if (cfg.outformat == FORMAT_PEM) {
1302 if (cfg.trustout)
1303 i = PEM_write_bio_X509_AUX(out, x);
1304 else
1305 i = PEM_write_bio_X509(out, x);
1306 } else {
1307 BIO_printf(bio_err,
1308 "bad output format specified for outfile\n");
1309 goto end;
1310 }
1311 if (!i) {
1312 BIO_printf(bio_err, "unable to write certificate\n");
1313 ERR_print_errors(bio_err);
1314 goto end;
1315 }
1316 ret = 0;
1317
1318 end:
1319 OBJ_cleanup();
1320 NCONF_free(extconf);
1321 BIO_free_all(out);
1322 BIO_free_all(STDout);
1323 X509_NAME_free(iname);
1324 X509_NAME_free(sname);
1325 X509_STORE_free(ctx);
1326 X509_REQ_free(req);
1327 X509_free(x);
1328 X509_free(xca);
1329 EVP_PKEY_free(Fpkey);
1330 EVP_PKEY_free(Upkey);
1331 EVP_PKEY_free(CApkey);
1332 sk_OPENSSL_STRING_free(cfg.sigopts);
1333 X509_REQ_free(rq);
1334 ASN1_INTEGER_free(cfg.sno);
1335 sk_ASN1_OBJECT_pop_free(cfg.trust, ASN1_OBJECT_free);
1336 sk_ASN1_OBJECT_pop_free(cfg.reject, ASN1_OBJECT_free);
1337 free(passin);
1338
1339 return (ret);
1340}
1341
1342static ASN1_INTEGER *
1343x509_load_serial(char *CAfile, char *serialfile, int create)
1344{
1345 char *buf = NULL, *p;
1346 ASN1_INTEGER *bs = NULL;
1347 BIGNUM *serial = NULL;
1348 size_t len;
1349
1350 len = ((serialfile == NULL) ? (strlen(CAfile) + strlen(POSTFIX) + 1) :
1351 (strlen(serialfile))) + 1;
1352 buf = malloc(len);
1353 if (buf == NULL) {
1354 BIO_printf(bio_err, "out of mem\n");
1355 goto end;
1356 }
1357 if (serialfile == NULL) {
1358 strlcpy(buf, CAfile, len);
1359 for (p = buf; *p; p++)
1360 if (*p == '.') {
1361 *p = '\0';
1362 break;
1363 }
1364 strlcat(buf, POSTFIX, len);
1365 } else
1366 strlcpy(buf, serialfile, len);
1367
1368 serial = load_serial(buf, create, NULL);
1369 if (serial == NULL)
1370 goto end;
1371
1372 if (!BN_add_word(serial, 1)) {
1373 BIO_printf(bio_err, "add_word failure\n");
1374 goto end;
1375 }
1376 if (!save_serial(buf, NULL, serial, &bs))
1377 goto end;
1378
1379 end:
1380 free(buf);
1381 BN_free(serial);
1382
1383 return bs;
1384}
1385
1386static int
1387x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x,
1388 X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
1389 char *serialfile, int create, int days, int clrext, CONF *conf,
1390 char *section, ASN1_INTEGER *sno, X509_NAME *issuer)
1391{
1392 int ret = 0;
1393 ASN1_INTEGER *bs = NULL;
1394 X509_STORE_CTX *xsc = NULL;
1395 EVP_PKEY *upkey;
1396
1397 upkey = X509_get0_pubkey(xca);
1398 if (upkey == NULL)
1399 goto end;
1400 EVP_PKEY_copy_parameters(upkey, pkey);
1401
1402 if ((xsc = X509_STORE_CTX_new()) == NULL)
1403 goto end;
1404 if (!X509_STORE_CTX_init(xsc, ctx, x, NULL)) {
1405 BIO_printf(bio_err, "Error initialising X509 store\n");
1406 goto end;
1407 }
1408 if (sno != NULL)
1409 bs = sno;
1410 else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)
1411 goto end;
1412
1413/* if (!X509_STORE_add_cert(ctx,x)) goto end;*/
1414
1415 /*
1416 * NOTE: this certificate can/should be self signed, unless it was a
1417 * certificate request in which case it is not.
1418 */
1419 X509_STORE_CTX_set_cert(xsc, x);
1420 X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
1421 if (!cfg.reqfile && X509_verify_cert(xsc) <= 0)
1422 goto end;
1423
1424 if (!X509_check_private_key(xca, pkey)) {
1425 BIO_printf(bio_err,
1426 "CA certificate and CA private key do not match\n");
1427 goto end;
1428 }
1429
1430 if (issuer == NULL)
1431 issuer = X509_get_subject_name(xca);
1432 if (issuer == NULL)
1433 goto end;
1434 if (!X509_set_issuer_name(x, issuer))
1435 goto end;
1436
1437 if (!X509_set_serialNumber(x, bs))
1438 goto end;
1439
1440 if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
1441 goto end;
1442
1443 /* hardwired expired */
1444 if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
1445 goto end;
1446
1447 if (clrext) {
1448 while (X509_get_ext_count(x) > 0) {
1449 if (X509_delete_ext(x, 0) == NULL)
1450 goto end;
1451 }
1452 }
1453 if (conf != NULL) {
1454 X509V3_CTX ctx2;
1455 if (!X509_set_version(x, 2)) /* version 3 certificate */
1456 goto end;
1457 X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
1458 X509V3_set_nconf(&ctx2, conf);
1459 if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
1460 goto end;
1461 }
1462 if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
1463 goto end;
1464
1465 ret = 1;
1466 end:
1467 X509_STORE_CTX_free(xsc);
1468 if (!ret)
1469 ERR_print_errors(bio_err);
1470 if (sno == NULL)
1471 ASN1_INTEGER_free(bs);
1472 return ret;
1473}
1474
1475static int
1476callb(int ok, X509_STORE_CTX *ctx)
1477{
1478 int err;
1479 X509 *err_cert;
1480
1481 /*
1482 * it is ok to use a self signed certificate This case will catch
1483 * both the initial ok == 0 and the final ok == 1 calls to this
1484 * function
1485 */
1486 err = X509_STORE_CTX_get_error(ctx);
1487 if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
1488 return 1;
1489
1490 /*
1491 * BAD we should have gotten an error. Normally if everything worked
1492 * X509_STORE_CTX_get_error(ctx) will still be set to
1493 * DEPTH_ZERO_SELF_....
1494 */
1495 if (ok) {
1496 BIO_printf(bio_err,
1497 "error with certificate to be certified - should be self signed\n");
1498 return 0;
1499 } else {
1500 err_cert = X509_STORE_CTX_get_current_cert(ctx);
1501 print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
1502 BIO_printf(bio_err,
1503 "error with certificate - error %d at depth %d\n%s\n",
1504 err, X509_STORE_CTX_get_error_depth(ctx),
1505 X509_verify_cert_error_string(err));
1506 return 1;
1507 }
1508}
1509
1510static int
1511key_identifier_hash(EVP_PKEY *pkey, unsigned char *md, unsigned int *md_len)
1512{
1513 X509_PUBKEY *x509_pubkey = NULL;
1514 const unsigned char *der;
1515 int der_len;
1516 int ret = 0;
1517
1518 if (*md_len < SHA_DIGEST_LENGTH)
1519 goto err;
1520
1521 if (!X509_PUBKEY_set(&x509_pubkey, pkey))
1522 goto err;
1523 if (!X509_PUBKEY_get0_param(NULL, &der, &der_len, NULL, x509_pubkey))
1524 goto err;
1525 if (!EVP_Digest(der, der_len, md, md_len, EVP_sha1(), NULL))
1526 goto err;
1527
1528 ret = 1;
1529
1530 err:
1531 X509_PUBKEY_free(x509_pubkey);
1532
1533 return ret;
1534}
1535
1536static ASN1_OCTET_STRING *
1537compute_key_identifier(EVP_PKEY *pkey)
1538{
1539 ASN1_OCTET_STRING *ki = NULL;
1540 unsigned char md[EVP_MAX_MD_SIZE];
1541 unsigned int md_len = EVP_MAX_MD_SIZE;
1542
1543 if (!key_identifier_hash(pkey, md, &md_len))
1544 goto err;
1545
1546 if ((ki = ASN1_OCTET_STRING_new()) == NULL)
1547 goto err;
1548 if (!ASN1_STRING_set(ki, md, md_len))
1549 goto err;
1550
1551 return ki;
1552
1553 err:
1554 ASN1_OCTET_STRING_free(ki);
1555
1556 return NULL;
1557}
1558
1559static ASN1_OCTET_STRING *
1560compute_subject_key_identifier(EVP_PKEY *subject_key)
1561{
1562 return compute_key_identifier(subject_key);
1563}
1564
1565static AUTHORITY_KEYID *
1566compute_authority_key_identifier(EVP_PKEY *issuer_key)
1567{
1568 AUTHORITY_KEYID *aki = NULL;
1569
1570 if ((aki = AUTHORITY_KEYID_new()) == NULL)
1571 goto err;
1572 if ((aki->keyid = compute_key_identifier(issuer_key)) == NULL)
1573 goto err;
1574
1575 return aki;
1576
1577 err:
1578 AUTHORITY_KEYID_free(aki);
1579
1580 return NULL;
1581}
1582
1583static int
1584set_key_identifiers(X509 *cert, EVP_PKEY *issuer_key)
1585{
1586 EVP_PKEY *subject_key;
1587 ASN1_OCTET_STRING *ski = NULL;
1588 AUTHORITY_KEYID *aki = NULL;
1589 int ret = 0;
1590
1591 if ((subject_key = X509_get0_pubkey(cert)) == NULL)
1592 goto err;
1593
1594 if ((ski = compute_subject_key_identifier(subject_key)) == NULL)
1595 goto err;
1596 if (!X509_add1_ext_i2d(cert, NID_subject_key_identifier, ski, 0,
1597 X509V3_ADD_REPLACE))
1598 goto err;
1599
1600 /*
1601 * Historical OpenSSL behavior: don't set AKI if we're self-signing.
1602 * RFC 5280 says we MAY omit it, so this is ok.
1603 */
1604 if (EVP_PKEY_cmp(subject_key, issuer_key) == 1)
1605 goto done;
1606
1607 if ((aki = compute_authority_key_identifier(issuer_key)) == NULL)
1608 goto err;
1609 if (!X509_add1_ext_i2d(cert, NID_authority_key_identifier, aki, 0,
1610 X509V3_ADD_REPLACE))
1611 goto err;
1612
1613 done:
1614 ret = 1;
1615
1616 err:
1617 ASN1_OCTET_STRING_free(ski);
1618 AUTHORITY_KEYID_free(aki);
1619
1620 return ret;
1621}
1622
1623static int
1624sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
1625 CONF *conf, char *section, X509_NAME *issuer, char *force_pubkey)
1626{
1627 EVP_PKEY *pktmp;
1628
1629 pktmp = X509_get0_pubkey(x);
1630 if (pktmp == NULL)
1631 goto err;
1632 EVP_PKEY_copy_parameters(pktmp, pkey);
1633 EVP_PKEY_save_parameters(pktmp, 1);
1634
1635 if (issuer == NULL)
1636 issuer = X509_get_subject_name(x);
1637 if (issuer == NULL)
1638 goto err;
1639 if (!X509_set_issuer_name(x, issuer))
1640 goto err;
1641 if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
1642 goto err;
1643
1644 if (X509_gmtime_adj(X509_get_notAfter(x), 60L * 60 * 24 * days) == NULL)
1645 goto err;
1646
1647 if (force_pubkey == NULL) {
1648 if (!X509_set_pubkey(x, pkey))
1649 goto err;
1650 }
1651 if (clrext) {
1652 while (X509_get_ext_count(x) > 0) {
1653 if (X509_delete_ext(x, 0) == NULL)
1654 goto err;
1655 }
1656 }
1657 if (conf != NULL) {
1658 X509V3_CTX ctx;
1659
1660 if (!X509_set_version(x, 2)) /* version 3 certificate */
1661 goto err;
1662 X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
1663 X509V3_set_nconf(&ctx, conf);
1664 if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
1665 goto err;
1666 if (force_pubkey != NULL) {
1667 /*
1668 * Set or fix up SKI and AKI.
1669 *
1670 * XXX - Doing this in a fully OpenSSL 3 compatible way
1671 * is extremely nasty: they hang an issuer_pubkey off
1672 * the X509V3_CTX and adjusted v2i_AUTHORITY_KEYID().
1673 * Punt on this and make things work in the specific
1674 * situation we're interested in. Like OpenSSL, we only
1675 * support the keyid form of the AKI, which is what
1676 * RFC 5280 recommends, but unlike OpenSSL we replace
1677 * existing SKI and AKI rather than honoring the most
1678 * likely outdated ones already present in the cert.
1679 */
1680 if (!set_key_identifiers(x, pkey))
1681 goto err;
1682 }
1683 }
1684 if (!X509_sign(x, pkey, digest))
1685 goto err;
1686
1687 return 1;
1688
1689 err:
1690 ERR_print_errors(bio_err);
1691 return 0;
1692}
1693
1694static int
1695purpose_print(BIO *bio, X509 *cert, const X509_PURPOSE *pt)
1696{
1697 int id, i, idret;
1698 const char *pname;
1699
1700 id = X509_PURPOSE_get_id(pt);
1701 pname = X509_PURPOSE_get0_name(pt);
1702 for (i = 0; i < 2; i++) {
1703 idret = X509_check_purpose(cert, id, i);
1704 BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
1705 if (idret == 1)
1706 BIO_printf(bio, "Yes\n");
1707 else if (idret == 0)
1708 BIO_printf(bio, "No\n");
1709 else
1710 BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
1711 }
1712 return 1;
1713}