X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fengine.c;h=ffd3137426de1fb6fe4a734076d78d141ed8e737;hp=448802bc611ea90b7e12a31b3b61603c0ede2d57;hb=fb2141c773ab0c5dfc78cc97d2445362b8048389;hpb=68dc682499ea3fe27d909c946d7abd39062d6efd diff --git a/apps/engine.c b/apps/engine.c index 448802bc61..ffd3137426 100644 --- a/apps/engine.c +++ b/apps/engine.c @@ -1,67 +1,22 @@ /* - * Written by Richard Levitte for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ -#include -#include -#include -#include "apps.h" -#include -#ifndef OPENSSL_NO_ENGINE +#include +#ifdef OPENSSL_NO_ENGINE +NON_EMPTY_TRANSLATION_UNIT +#else + +# include "apps.h" +# include +# include +# include +# include # include # include @@ -72,13 +27,16 @@ typedef enum OPTION_choice { } OPTION_CHOICE; OPTIONS engine_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] engine...\n"}, + {OPT_HELP_STR, 1, '-', + " engine... Engines to load\n"}, {"help", OPT_HELP, '-', "Display this summary"}, - {"vvvv", OPT_VVVV, '-', "Also show internal input flags"}, - {"vvv", OPT_VVV, '-', "Also add the input flags for each command"}, + {"v", OPT_V, '-', "List 'control commands' For each specified engine"}, {"vv", OPT_VV, '-', "Also display each command's description"}, - {"v", OPT_V, '-', "For each engine, list its 'control commands'"}, - {"c", OPT_C, '-', "List the capabilities of each engine"}, - {"t", OPT_T, '-', "Check that each engine is available"}, + {"vvv", OPT_VVV, '-', "Also add the input flags for each command"}, + {"vvvv", OPT_VVVV, '-', "Also show internal input flags"}, + {"c", OPT_C, '-', "List the capabilities of specified engine"}, + {"t", OPT_T, '-', "Check that specified engine is available"}, {"tt", OPT_TT, '-', "Display error trace for unavailable engines"}, {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"}, {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"}, @@ -87,35 +45,29 @@ OPTIONS engine_options[] = { {NULL} }; -static void identity(char *ptr) +static int append_buf(char **buf, int *size, const char *s) { - return; -} - -static int append_buf(char **buf, const char *s, int *size, int step) -{ - int l = strlen(s); - if (*buf == NULL) { - *size = step; + *size = 256; *buf = app_malloc(*size, "engine buffer"); **buf = '\0'; } - if (**buf != '\0') - l += 2; /* ", " */ - if (strlen(*buf) + strlen(s) >= (unsigned int)*size) { - *size += step; - *buf = OPENSSL_realloc(*buf, *size); + char *tmp; + *size += 256; + tmp = OPENSSL_realloc(*buf, *size); + if (tmp == NULL) { + OPENSSL_free(*buf); + *buf = NULL; + return 0; + } + *buf = tmp; } - if (*buf == NULL) - return 0; - if (**buf != '\0') - BUF_strlcat(*buf, ", ", *size); - BUF_strlcat(*buf, s, *size); + OPENSSL_strlcat(*buf, ", ", *size); + OPENSSL_strlcat(*buf, s, *size); return 1; } @@ -252,10 +204,8 @@ static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent) } OPENSSL_free(name); name = NULL; - if (desc) { - OPENSSL_free(desc); - desc = NULL; - } + OPENSSL_free(desc); + desc = NULL; /* Move to the next command */ num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, num, NULL, NULL); } while (num > 0); @@ -263,12 +213,9 @@ static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent) BIO_printf(out, "\n"); ret = 1; err: - if (cmds) - sk_OPENSSL_STRING_pop_free(cmds, identity); - if (name) - OPENSSL_free(name); - if (desc) - OPENSSL_free(desc); + sk_OPENSSL_STRING_free(cmds); + OPENSSL_free(name); + OPENSSL_free(desc); return ret; } @@ -316,18 +263,30 @@ int engine_main(int argc, char **argv) int ret = 1, i; int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0; ENGINE *e; - STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null(); + STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null(); STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null(); STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null(); BIO *out; const char *indent = " "; OPTION_CHOICE o; char *prog; + char *argv1; - out = dup_bio_out(); - prog = opt_init(argc, argv, engine_options); - if (!engines || !pre_cmds || !post_cmds) + out = dup_bio_out(FORMAT_TEXT); + if (engines == NULL || pre_cmds == NULL || post_cmds == NULL) goto end; + + /* Remember the original command name, parse/skip any leading engine + * names, and then setup to parse the rest of the line as flags. */ + prog = argv[0]; + while ((argv1 = argv[1]) != NULL && *argv1 != '-') { + sk_OPENSSL_CSTRING_push(engines, argv1); + argc--; + argv++; + } + argv[0] = prog; + opt_init(argc, argv, engine_options); + while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: @@ -363,19 +322,29 @@ int engine_main(int argc, char **argv) break; } } + + /* Allow any trailing parameters as engine names. */ argc = opt_num_rest(); argv = opt_rest(); - for ( ; *argv; argv++) - sk_OPENSSL_STRING_push(engines, *argv); + for ( ; *argv; argv++) { + if (**argv == '-') { + BIO_printf(bio_err, "%s: Cannot mix flags and engine names.\n", + prog); + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + } + sk_OPENSSL_CSTRING_push(engines, *argv); + } - if (sk_OPENSSL_STRING_num(engines) == 0) { + if (sk_OPENSSL_CSTRING_num(engines) == 0) { for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) { - sk_OPENSSL_STRING_push(engines, (char *)ENGINE_get_id(e)); + sk_OPENSSL_CSTRING_push(engines, ENGINE_get_id(e)); } } - for (i = 0; i < sk_OPENSSL_STRING_num(engines); i++) { - const char *id = sk_OPENSSL_STRING_value(engines, i); + ret = 0; + for (i = 0; i < sk_OPENSSL_CSTRING_num(engines); i++) { + const char *id = sk_OPENSSL_CSTRING_value(engines, i); if ((e = ENGINE_by_id(id)) != NULL) { const char *name = ENGINE_get_name(e); /* @@ -397,16 +366,16 @@ int engine_main(int argc, char **argv) ENGINE_PKEY_METHS_PTR fn_pk; if (ENGINE_get_RSA(e) != NULL - && !append_buf(&cap_buf, "RSA", &cap_size, 256)) + && !append_buf(&cap_buf, &cap_size, "RSA")) goto end; if (ENGINE_get_DSA(e) != NULL - && !append_buf(&cap_buf, "DSA", &cap_size, 256)) + && !append_buf(&cap_buf, &cap_size, "DSA")) goto end; if (ENGINE_get_DH(e) != NULL - && !append_buf(&cap_buf, "DH", &cap_size, 256)) + && !append_buf(&cap_buf, &cap_size, "DH")) goto end; if (ENGINE_get_RAND(e) != NULL - && !append_buf(&cap_buf, "RAND", &cap_size, 256)) + && !append_buf(&cap_buf, &cap_size, "RAND")) goto end; fn_c = ENGINE_get_ciphers(e); @@ -414,8 +383,7 @@ int engine_main(int argc, char **argv) goto skip_ciphers; n = fn_c(e, NULL, &nids, 0); for (k = 0; k < n; ++k) - if (!append_buf(&cap_buf, - OBJ_nid2sn(nids[k]), &cap_size, 256)) + if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k]))) goto end; skip_ciphers: @@ -424,8 +392,7 @@ int engine_main(int argc, char **argv) goto skip_digests; n = fn_d(e, NULL, &nids, 0); for (k = 0; k < n; ++k) - if (!append_buf(&cap_buf, - OBJ_nid2sn(nids[k]), &cap_size, 256)) + if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k]))) goto end; skip_digests: @@ -434,8 +401,7 @@ int engine_main(int argc, char **argv) goto skip_pmeths; n = fn_pk(e, NULL, &nids, 0); for (k = 0; k < n; ++k) - if (!append_buf(&cap_buf, - OBJ_nid2sn(nids[k]), &cap_size, 256)) + if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k]))) goto end; skip_pmeths: if (cap_buf && (*cap_buf != '\0')) @@ -459,24 +425,21 @@ int engine_main(int argc, char **argv) if ((verbose > 0) && !util_verbose(e, verbose, out, indent)) goto end; ENGINE_free(e); - } else + } else { ERR_print_errors(bio_err); + /* because exit codes above 127 have special meaning on Unix */ + if (++ret > 127) + ret = 127; + } } - ret = 0; end: ERR_print_errors(bio_err); - sk_OPENSSL_STRING_pop_free(engines, identity); - sk_OPENSSL_STRING_pop_free(pre_cmds, identity); - sk_OPENSSL_STRING_pop_free(post_cmds, identity); + sk_OPENSSL_CSTRING_free(engines); + sk_OPENSSL_STRING_free(pre_cmds); + sk_OPENSSL_STRING_free(post_cmds); BIO_free_all(out); return (ret); } -#else - -# if PEDANTIC -static void *dummy = &dummy; -# endif - #endif