1*0Sstevel@tonic-gate /* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */ 2*0Sstevel@tonic-gate /* Written by Richard Levitte <richard@levitte.org> for the OpenSSL 3*0Sstevel@tonic-gate * project 2000. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate /* ==================================================================== 6*0Sstevel@tonic-gate * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7*0Sstevel@tonic-gate * 8*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 9*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 10*0Sstevel@tonic-gate * are met: 11*0Sstevel@tonic-gate * 12*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 13*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 14*0Sstevel@tonic-gate * 15*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 16*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 17*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 18*0Sstevel@tonic-gate * distribution. 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 21*0Sstevel@tonic-gate * software must display the following acknowledgment: 22*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 23*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26*0Sstevel@tonic-gate * endorse or promote products derived from this software without 27*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 28*0Sstevel@tonic-gate * licensing@OpenSSL.org. 29*0Sstevel@tonic-gate * 30*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 31*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 32*0Sstevel@tonic-gate * permission of the OpenSSL Project. 33*0Sstevel@tonic-gate * 34*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 35*0Sstevel@tonic-gate * acknowledgment: 36*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 37*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 51*0Sstevel@tonic-gate * ==================================================================== 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 54*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 55*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 56*0Sstevel@tonic-gate * 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate #include <stdio.h> 62*0Sstevel@tonic-gate #include <stdlib.h> 63*0Sstevel@tonic-gate #include <string.h> 64*0Sstevel@tonic-gate #ifdef OPENSSL_NO_STDIO 65*0Sstevel@tonic-gate #define APPS_WIN16 66*0Sstevel@tonic-gate #endif 67*0Sstevel@tonic-gate #include "apps.h" 68*0Sstevel@tonic-gate #include <openssl/err.h> 69*0Sstevel@tonic-gate #include <openssl/engine.h> 70*0Sstevel@tonic-gate #include <openssl/ssl.h> 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate #undef PROG 73*0Sstevel@tonic-gate #define PROG engine_main 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate static char *engine_usage[]={ 76*0Sstevel@tonic-gate "usage: engine opts [engine ...]\n", 77*0Sstevel@tonic-gate " -v[v[v[v]]] - verbose mode, for each engine, list its 'control commands'\n", 78*0Sstevel@tonic-gate " -vv will additionally display each command's description\n", 79*0Sstevel@tonic-gate " -vvv will also add the input flags for each command\n", 80*0Sstevel@tonic-gate " -vvvv will also show internal input flags\n", 81*0Sstevel@tonic-gate " -c - for each engine, also list the capabilities\n", 82*0Sstevel@tonic-gate " -t - for each engine, check that they are really available\n", 83*0Sstevel@tonic-gate " -pre <cmd> - runs command 'cmd' against the ENGINE before any attempts\n", 84*0Sstevel@tonic-gate " to load it (if -t is used)\n", 85*0Sstevel@tonic-gate " -post <cmd> - runs command 'cmd' against the ENGINE after loading it\n", 86*0Sstevel@tonic-gate " (only used if -t is also provided)\n", 87*0Sstevel@tonic-gate " NB: -pre and -post will be applied to all ENGINEs supplied on the command\n", 88*0Sstevel@tonic-gate " line, or all supported ENGINEs if none are specified.\n", 89*0Sstevel@tonic-gate " Eg. '-pre \"SO_PATH:/lib/libdriver.so\"' calls command \"SO_PATH\" with\n", 90*0Sstevel@tonic-gate " argument \"/lib/libdriver.so\".\n", 91*0Sstevel@tonic-gate NULL 92*0Sstevel@tonic-gate }; 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate static void identity(void *ptr) 95*0Sstevel@tonic-gate { 96*0Sstevel@tonic-gate return; 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate static int append_buf(char **buf, const char *s, int *size, int step) 100*0Sstevel@tonic-gate { 101*0Sstevel@tonic-gate int l = strlen(s); 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate if (*buf == NULL) 104*0Sstevel@tonic-gate { 105*0Sstevel@tonic-gate *size = step; 106*0Sstevel@tonic-gate *buf = OPENSSL_malloc(*size); 107*0Sstevel@tonic-gate if (*buf == NULL) 108*0Sstevel@tonic-gate return 0; 109*0Sstevel@tonic-gate **buf = '\0'; 110*0Sstevel@tonic-gate } 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate if (**buf != '\0') 113*0Sstevel@tonic-gate l += 2; /* ", " */ 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate if (strlen(*buf) + strlen(s) >= (unsigned int)*size) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate *size += step; 118*0Sstevel@tonic-gate *buf = OPENSSL_realloc(*buf, *size); 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate if (*buf == NULL) 122*0Sstevel@tonic-gate return 0; 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate if (**buf != '\0') 125*0Sstevel@tonic-gate BUF_strlcat(*buf, ", ", *size); 126*0Sstevel@tonic-gate BUF_strlcat(*buf, s, *size); 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate return 1; 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate static int util_flags(BIO *bio_out, unsigned int flags, const char *indent) 132*0Sstevel@tonic-gate { 133*0Sstevel@tonic-gate int started = 0, err = 0; 134*0Sstevel@tonic-gate /* Indent before displaying input flags */ 135*0Sstevel@tonic-gate BIO_printf(bio_out, "%s%s(input flags): ", indent, indent); 136*0Sstevel@tonic-gate if(flags == 0) 137*0Sstevel@tonic-gate { 138*0Sstevel@tonic-gate BIO_printf(bio_out, "<no flags>\n"); 139*0Sstevel@tonic-gate return 1; 140*0Sstevel@tonic-gate } 141*0Sstevel@tonic-gate /* If the object is internal, mark it in a way that shows instead of 142*0Sstevel@tonic-gate * having it part of all the other flags, even if it really is. */ 143*0Sstevel@tonic-gate if(flags & ENGINE_CMD_FLAG_INTERNAL) 144*0Sstevel@tonic-gate { 145*0Sstevel@tonic-gate BIO_printf(bio_out, "[Internal] "); 146*0Sstevel@tonic-gate } 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate if(flags & ENGINE_CMD_FLAG_NUMERIC) 149*0Sstevel@tonic-gate { 150*0Sstevel@tonic-gate if(started) 151*0Sstevel@tonic-gate { 152*0Sstevel@tonic-gate BIO_printf(bio_out, "|"); 153*0Sstevel@tonic-gate err = 1; 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate BIO_printf(bio_out, "NUMERIC"); 156*0Sstevel@tonic-gate started = 1; 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate /* Now we check that no combinations of the mutually exclusive NUMERIC, 159*0Sstevel@tonic-gate * STRING, and NO_INPUT flags have been used. Future flags that can be 160*0Sstevel@tonic-gate * OR'd together with these would need to added after these to preserve 161*0Sstevel@tonic-gate * the testing logic. */ 162*0Sstevel@tonic-gate if(flags & ENGINE_CMD_FLAG_STRING) 163*0Sstevel@tonic-gate { 164*0Sstevel@tonic-gate if(started) 165*0Sstevel@tonic-gate { 166*0Sstevel@tonic-gate BIO_printf(bio_out, "|"); 167*0Sstevel@tonic-gate err = 1; 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate BIO_printf(bio_out, "STRING"); 170*0Sstevel@tonic-gate started = 1; 171*0Sstevel@tonic-gate } 172*0Sstevel@tonic-gate if(flags & ENGINE_CMD_FLAG_NO_INPUT) 173*0Sstevel@tonic-gate { 174*0Sstevel@tonic-gate if(started) 175*0Sstevel@tonic-gate { 176*0Sstevel@tonic-gate BIO_printf(bio_out, "|"); 177*0Sstevel@tonic-gate err = 1; 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate BIO_printf(bio_out, "NO_INPUT"); 180*0Sstevel@tonic-gate started = 1; 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate /* Check for unknown flags */ 183*0Sstevel@tonic-gate flags = flags & ~ENGINE_CMD_FLAG_NUMERIC & 184*0Sstevel@tonic-gate ~ENGINE_CMD_FLAG_STRING & 185*0Sstevel@tonic-gate ~ENGINE_CMD_FLAG_NO_INPUT & 186*0Sstevel@tonic-gate ~ENGINE_CMD_FLAG_INTERNAL; 187*0Sstevel@tonic-gate if(flags) 188*0Sstevel@tonic-gate { 189*0Sstevel@tonic-gate if(started) BIO_printf(bio_out, "|"); 190*0Sstevel@tonic-gate BIO_printf(bio_out, "<0x%04X>", flags); 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate if(err) 193*0Sstevel@tonic-gate BIO_printf(bio_out, " <illegal flags!>"); 194*0Sstevel@tonic-gate BIO_printf(bio_out, "\n"); 195*0Sstevel@tonic-gate return 1; 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent) 199*0Sstevel@tonic-gate { 200*0Sstevel@tonic-gate static const int line_wrap = 78; 201*0Sstevel@tonic-gate int num; 202*0Sstevel@tonic-gate int ret = 0; 203*0Sstevel@tonic-gate char *name = NULL; 204*0Sstevel@tonic-gate char *desc = NULL; 205*0Sstevel@tonic-gate int flags; 206*0Sstevel@tonic-gate int xpos = 0; 207*0Sstevel@tonic-gate STACK *cmds = NULL; 208*0Sstevel@tonic-gate if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) || 209*0Sstevel@tonic-gate ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE, 210*0Sstevel@tonic-gate 0, NULL, NULL)) <= 0)) 211*0Sstevel@tonic-gate { 212*0Sstevel@tonic-gate #if 0 213*0Sstevel@tonic-gate BIO_printf(bio_out, "%s<no control commands>\n", indent); 214*0Sstevel@tonic-gate #endif 215*0Sstevel@tonic-gate return 1; 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate cmds = sk_new_null(); 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate if(!cmds) 221*0Sstevel@tonic-gate goto err; 222*0Sstevel@tonic-gate do { 223*0Sstevel@tonic-gate int len; 224*0Sstevel@tonic-gate /* Get the command input flags */ 225*0Sstevel@tonic-gate if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, 226*0Sstevel@tonic-gate NULL, NULL)) < 0) 227*0Sstevel@tonic-gate goto err; 228*0Sstevel@tonic-gate if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4) 229*0Sstevel@tonic-gate { 230*0Sstevel@tonic-gate /* Get the command name */ 231*0Sstevel@tonic-gate if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num, 232*0Sstevel@tonic-gate NULL, NULL)) <= 0) 233*0Sstevel@tonic-gate goto err; 234*0Sstevel@tonic-gate if((name = OPENSSL_malloc(len + 1)) == NULL) 235*0Sstevel@tonic-gate goto err; 236*0Sstevel@tonic-gate if(ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name, 237*0Sstevel@tonic-gate NULL) <= 0) 238*0Sstevel@tonic-gate goto err; 239*0Sstevel@tonic-gate /* Get the command description */ 240*0Sstevel@tonic-gate if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num, 241*0Sstevel@tonic-gate NULL, NULL)) < 0) 242*0Sstevel@tonic-gate goto err; 243*0Sstevel@tonic-gate if(len > 0) 244*0Sstevel@tonic-gate { 245*0Sstevel@tonic-gate if((desc = OPENSSL_malloc(len + 1)) == NULL) 246*0Sstevel@tonic-gate goto err; 247*0Sstevel@tonic-gate if(ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc, 248*0Sstevel@tonic-gate NULL) <= 0) 249*0Sstevel@tonic-gate goto err; 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate /* Now decide on the output */ 252*0Sstevel@tonic-gate if(xpos == 0) 253*0Sstevel@tonic-gate /* Do an indent */ 254*0Sstevel@tonic-gate xpos = BIO_printf(bio_out, indent); 255*0Sstevel@tonic-gate else 256*0Sstevel@tonic-gate /* Otherwise prepend a ", " */ 257*0Sstevel@tonic-gate xpos += BIO_printf(bio_out, ", "); 258*0Sstevel@tonic-gate if(verbose == 1) 259*0Sstevel@tonic-gate { 260*0Sstevel@tonic-gate /* We're just listing names, comma-delimited */ 261*0Sstevel@tonic-gate if((xpos > (int)strlen(indent)) && 262*0Sstevel@tonic-gate (xpos + (int)strlen(name) > line_wrap)) 263*0Sstevel@tonic-gate { 264*0Sstevel@tonic-gate BIO_printf(bio_out, "\n"); 265*0Sstevel@tonic-gate xpos = BIO_printf(bio_out, indent); 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate xpos += BIO_printf(bio_out, "%s", name); 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate else 270*0Sstevel@tonic-gate { 271*0Sstevel@tonic-gate /* We're listing names plus descriptions */ 272*0Sstevel@tonic-gate BIO_printf(bio_out, "%s: %s\n", name, 273*0Sstevel@tonic-gate (desc == NULL) ? "<no description>" : desc); 274*0Sstevel@tonic-gate /* ... and sometimes input flags */ 275*0Sstevel@tonic-gate if((verbose >= 3) && !util_flags(bio_out, flags, 276*0Sstevel@tonic-gate indent)) 277*0Sstevel@tonic-gate goto err; 278*0Sstevel@tonic-gate xpos = 0; 279*0Sstevel@tonic-gate } 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate OPENSSL_free(name); name = NULL; 282*0Sstevel@tonic-gate if(desc) { OPENSSL_free(desc); desc = NULL; } 283*0Sstevel@tonic-gate /* Move to the next command */ 284*0Sstevel@tonic-gate num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, 285*0Sstevel@tonic-gate num, NULL, NULL); 286*0Sstevel@tonic-gate } while(num > 0); 287*0Sstevel@tonic-gate if(xpos > 0) 288*0Sstevel@tonic-gate BIO_printf(bio_out, "\n"); 289*0Sstevel@tonic-gate ret = 1; 290*0Sstevel@tonic-gate err: 291*0Sstevel@tonic-gate if(cmds) sk_pop_free(cmds, identity); 292*0Sstevel@tonic-gate if(name) OPENSSL_free(name); 293*0Sstevel@tonic-gate if(desc) OPENSSL_free(desc); 294*0Sstevel@tonic-gate return ret; 295*0Sstevel@tonic-gate } 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate static void util_do_cmds(ENGINE *e, STACK *cmds, BIO *bio_out, const char *indent) 298*0Sstevel@tonic-gate { 299*0Sstevel@tonic-gate int loop, res, num = sk_num(cmds); 300*0Sstevel@tonic-gate if(num < 0) 301*0Sstevel@tonic-gate { 302*0Sstevel@tonic-gate BIO_printf(bio_out, "[Error]: internal stack error\n"); 303*0Sstevel@tonic-gate return; 304*0Sstevel@tonic-gate } 305*0Sstevel@tonic-gate for(loop = 0; loop < num; loop++) 306*0Sstevel@tonic-gate { 307*0Sstevel@tonic-gate char buf[256]; 308*0Sstevel@tonic-gate const char *cmd, *arg; 309*0Sstevel@tonic-gate cmd = sk_value(cmds, loop); 310*0Sstevel@tonic-gate res = 1; /* assume success */ 311*0Sstevel@tonic-gate /* Check if this command has no ":arg" */ 312*0Sstevel@tonic-gate if((arg = strstr(cmd, ":")) == NULL) 313*0Sstevel@tonic-gate { 314*0Sstevel@tonic-gate if(!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0)) 315*0Sstevel@tonic-gate res = 0; 316*0Sstevel@tonic-gate } 317*0Sstevel@tonic-gate else 318*0Sstevel@tonic-gate { 319*0Sstevel@tonic-gate if((int)(arg - cmd) > 254) 320*0Sstevel@tonic-gate { 321*0Sstevel@tonic-gate BIO_printf(bio_out,"[Error]: command name too long\n"); 322*0Sstevel@tonic-gate return; 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate memcpy(buf, cmd, (int)(arg - cmd)); 325*0Sstevel@tonic-gate buf[arg-cmd] = '\0'; 326*0Sstevel@tonic-gate arg++; /* Move past the ":" */ 327*0Sstevel@tonic-gate /* Call the command with the argument */ 328*0Sstevel@tonic-gate if(!ENGINE_ctrl_cmd_string(e, buf, arg, 0)) 329*0Sstevel@tonic-gate res = 0; 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate if(res) 332*0Sstevel@tonic-gate BIO_printf(bio_out, "[Success]: %s\n", cmd); 333*0Sstevel@tonic-gate else 334*0Sstevel@tonic-gate { 335*0Sstevel@tonic-gate BIO_printf(bio_out, "[Failure]: %s\n", cmd); 336*0Sstevel@tonic-gate ERR_print_errors(bio_out); 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate } 339*0Sstevel@tonic-gate } 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate int MAIN(int, char **); 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate int MAIN(int argc, char **argv) 344*0Sstevel@tonic-gate { 345*0Sstevel@tonic-gate int ret=1,i; 346*0Sstevel@tonic-gate char **pp; 347*0Sstevel@tonic-gate int verbose=0, list_cap=0, test_avail=0; 348*0Sstevel@tonic-gate ENGINE *e; 349*0Sstevel@tonic-gate STACK *engines = sk_new_null(); 350*0Sstevel@tonic-gate STACK *pre_cmds = sk_new_null(); 351*0Sstevel@tonic-gate STACK *post_cmds = sk_new_null(); 352*0Sstevel@tonic-gate int badops=1; 353*0Sstevel@tonic-gate BIO *bio_out=NULL; 354*0Sstevel@tonic-gate const char *indent = " "; 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate apps_startup(); 357*0Sstevel@tonic-gate SSL_load_error_strings(); 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate if (bio_err == NULL) 360*0Sstevel@tonic-gate bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate if (!load_config(bio_err, NULL)) 363*0Sstevel@tonic-gate goto end; 364*0Sstevel@tonic-gate bio_out=BIO_new_fp(stdout,BIO_NOCLOSE); 365*0Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS 366*0Sstevel@tonic-gate { 367*0Sstevel@tonic-gate BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 368*0Sstevel@tonic-gate bio_out = BIO_push(tmpbio, bio_out); 369*0Sstevel@tonic-gate } 370*0Sstevel@tonic-gate #endif 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate argc--; 373*0Sstevel@tonic-gate argv++; 374*0Sstevel@tonic-gate while (argc >= 1) 375*0Sstevel@tonic-gate { 376*0Sstevel@tonic-gate if (strncmp(*argv,"-v",2) == 0) 377*0Sstevel@tonic-gate { 378*0Sstevel@tonic-gate if(strspn(*argv + 1, "v") < strlen(*argv + 1)) 379*0Sstevel@tonic-gate goto skip_arg_loop; 380*0Sstevel@tonic-gate if((verbose=strlen(*argv + 1)) > 4) 381*0Sstevel@tonic-gate goto skip_arg_loop; 382*0Sstevel@tonic-gate } 383*0Sstevel@tonic-gate else if (strcmp(*argv,"-c") == 0) 384*0Sstevel@tonic-gate list_cap=1; 385*0Sstevel@tonic-gate else if (strcmp(*argv,"-t") == 0) 386*0Sstevel@tonic-gate test_avail=1; 387*0Sstevel@tonic-gate else if (strcmp(*argv,"-pre") == 0) 388*0Sstevel@tonic-gate { 389*0Sstevel@tonic-gate argc--; argv++; 390*0Sstevel@tonic-gate sk_push(pre_cmds,*argv); 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate else if (strcmp(*argv,"-post") == 0) 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate argc--; argv++; 395*0Sstevel@tonic-gate sk_push(post_cmds,*argv); 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate else if ((strncmp(*argv,"-h",2) == 0) || 398*0Sstevel@tonic-gate (strcmp(*argv,"-?") == 0)) 399*0Sstevel@tonic-gate goto skip_arg_loop; 400*0Sstevel@tonic-gate else 401*0Sstevel@tonic-gate sk_push(engines,*argv); 402*0Sstevel@tonic-gate argc--; 403*0Sstevel@tonic-gate argv++; 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate /* Looks like everything went OK */ 406*0Sstevel@tonic-gate badops = 0; 407*0Sstevel@tonic-gate skip_arg_loop: 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate if (badops) 410*0Sstevel@tonic-gate { 411*0Sstevel@tonic-gate for (pp=engine_usage; (*pp != NULL); pp++) 412*0Sstevel@tonic-gate BIO_printf(bio_err,"%s",*pp); 413*0Sstevel@tonic-gate goto end; 414*0Sstevel@tonic-gate } 415*0Sstevel@tonic-gate 416*0Sstevel@tonic-gate if (sk_num(engines) == 0) 417*0Sstevel@tonic-gate { 418*0Sstevel@tonic-gate for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) 419*0Sstevel@tonic-gate { 420*0Sstevel@tonic-gate sk_push(engines,(char *)ENGINE_get_id(e)); 421*0Sstevel@tonic-gate } 422*0Sstevel@tonic-gate } 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate for (i=0; i<sk_num(engines); i++) 425*0Sstevel@tonic-gate { 426*0Sstevel@tonic-gate const char *id = sk_value(engines,i); 427*0Sstevel@tonic-gate if ((e = ENGINE_by_id(id)) != NULL) 428*0Sstevel@tonic-gate { 429*0Sstevel@tonic-gate const char *name = ENGINE_get_name(e); 430*0Sstevel@tonic-gate /* Do "id" first, then "name". Easier to auto-parse. */ 431*0Sstevel@tonic-gate BIO_printf(bio_out, "(%s) %s\n", id, name); 432*0Sstevel@tonic-gate util_do_cmds(e, pre_cmds, bio_out, indent); 433*0Sstevel@tonic-gate if (strcmp(ENGINE_get_id(e), id) != 0) 434*0Sstevel@tonic-gate { 435*0Sstevel@tonic-gate BIO_printf(bio_out, "Loaded: (%s) %s\n", 436*0Sstevel@tonic-gate ENGINE_get_id(e), ENGINE_get_name(e)); 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate if (list_cap) 439*0Sstevel@tonic-gate { 440*0Sstevel@tonic-gate int cap_size = 256; 441*0Sstevel@tonic-gate char *cap_buf = NULL; 442*0Sstevel@tonic-gate int k,n; 443*0Sstevel@tonic-gate const int *nids; 444*0Sstevel@tonic-gate ENGINE_CIPHERS_PTR fn_c; 445*0Sstevel@tonic-gate ENGINE_DIGESTS_PTR fn_d; 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate if (ENGINE_get_RSA(e) != NULL 448*0Sstevel@tonic-gate && !append_buf(&cap_buf, "RSA", 449*0Sstevel@tonic-gate &cap_size, 256)) 450*0Sstevel@tonic-gate goto end; 451*0Sstevel@tonic-gate if (ENGINE_get_DSA(e) != NULL 452*0Sstevel@tonic-gate && !append_buf(&cap_buf, "DSA", 453*0Sstevel@tonic-gate &cap_size, 256)) 454*0Sstevel@tonic-gate goto end; 455*0Sstevel@tonic-gate if (ENGINE_get_DH(e) != NULL 456*0Sstevel@tonic-gate && !append_buf(&cap_buf, "DH", 457*0Sstevel@tonic-gate &cap_size, 256)) 458*0Sstevel@tonic-gate goto end; 459*0Sstevel@tonic-gate if (ENGINE_get_RAND(e) != NULL 460*0Sstevel@tonic-gate && !append_buf(&cap_buf, "RAND", 461*0Sstevel@tonic-gate &cap_size, 256)) 462*0Sstevel@tonic-gate goto end; 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate fn_c = ENGINE_get_ciphers(e); 465*0Sstevel@tonic-gate if(!fn_c) goto skip_ciphers; 466*0Sstevel@tonic-gate n = fn_c(e, NULL, &nids, 0); 467*0Sstevel@tonic-gate for(k=0 ; k < n ; ++k) 468*0Sstevel@tonic-gate if(!append_buf(&cap_buf, 469*0Sstevel@tonic-gate OBJ_nid2sn(nids[k]), 470*0Sstevel@tonic-gate &cap_size, 256)) 471*0Sstevel@tonic-gate goto end; 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate skip_ciphers: 474*0Sstevel@tonic-gate fn_d = ENGINE_get_digests(e); 475*0Sstevel@tonic-gate if(!fn_d) goto skip_digests; 476*0Sstevel@tonic-gate n = fn_d(e, NULL, &nids, 0); 477*0Sstevel@tonic-gate for(k=0 ; k < n ; ++k) 478*0Sstevel@tonic-gate if(!append_buf(&cap_buf, 479*0Sstevel@tonic-gate OBJ_nid2sn(nids[k]), 480*0Sstevel@tonic-gate &cap_size, 256)) 481*0Sstevel@tonic-gate goto end; 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate skip_digests: 484*0Sstevel@tonic-gate if (cap_buf && (*cap_buf != '\0')) 485*0Sstevel@tonic-gate BIO_printf(bio_out, " [%s]\n", cap_buf); 486*0Sstevel@tonic-gate 487*0Sstevel@tonic-gate OPENSSL_free(cap_buf); 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate if(test_avail) 490*0Sstevel@tonic-gate { 491*0Sstevel@tonic-gate BIO_printf(bio_out, "%s", indent); 492*0Sstevel@tonic-gate if (ENGINE_init(e)) 493*0Sstevel@tonic-gate { 494*0Sstevel@tonic-gate BIO_printf(bio_out, "[ available ]\n"); 495*0Sstevel@tonic-gate util_do_cmds(e, post_cmds, bio_out, indent); 496*0Sstevel@tonic-gate ENGINE_finish(e); 497*0Sstevel@tonic-gate } 498*0Sstevel@tonic-gate else 499*0Sstevel@tonic-gate { 500*0Sstevel@tonic-gate BIO_printf(bio_out, "[ unavailable ]\n"); 501*0Sstevel@tonic-gate ERR_print_errors_fp(stdout); 502*0Sstevel@tonic-gate ERR_clear_error(); 503*0Sstevel@tonic-gate } 504*0Sstevel@tonic-gate } 505*0Sstevel@tonic-gate if((verbose > 0) && !util_verbose(e, verbose, bio_out, indent)) 506*0Sstevel@tonic-gate goto end; 507*0Sstevel@tonic-gate ENGINE_free(e); 508*0Sstevel@tonic-gate } 509*0Sstevel@tonic-gate else 510*0Sstevel@tonic-gate ERR_print_errors(bio_err); 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate 513*0Sstevel@tonic-gate ret=0; 514*0Sstevel@tonic-gate end: 515*0Sstevel@tonic-gate ERR_print_errors(bio_err); 516*0Sstevel@tonic-gate sk_pop_free(engines, identity); 517*0Sstevel@tonic-gate sk_pop_free(pre_cmds, identity); 518*0Sstevel@tonic-gate sk_pop_free(post_cmds, identity); 519*0Sstevel@tonic-gate if (bio_out != NULL) BIO_free_all(bio_out); 520*0Sstevel@tonic-gate apps_shutdown(); 521*0Sstevel@tonic-gate OPENSSL_EXIT(ret); 522*0Sstevel@tonic-gate } 523*0Sstevel@tonic-gate #else 524*0Sstevel@tonic-gate 525*0Sstevel@tonic-gate # if PEDANTIC 526*0Sstevel@tonic-gate static void *dummy=&dummy; 527*0Sstevel@tonic-gate # endif 528*0Sstevel@tonic-gate 529*0Sstevel@tonic-gate #endif 530