/* crypto/engine/eng_ctrl.c */
/* ====================================================================
 * Copyright (c) 1999-2001 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).
 *
 */

#include "eng_int.h"

/* When querying a ENGINE-specific control command's 'description', this string
 * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
static const char *int_no_description = "";

/* These internal functions handle 'CMD'-related control commands when the
 * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
 * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */

static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
	{
	if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
		return 1;
	return 0;
	}

static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
	{
	int idx = 0;
	while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
		{
		idx++;
		defn++;
		}
	if(int_ctrl_cmd_is_null(defn))
		/* The given name wasn't found */
		return -1;
	return idx;
	}

static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
	{
	int idx = 0;
	/* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
	 * our searches don't need to take any longer than necessary. */
	while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
		{
		idx++;
		defn++;
		}
	if(defn->cmd_num == num)
		return idx;
	/* The given cmd_num wasn't found */
	return -1;
	}

static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
			   void (*f)(void))
	{
	int idx;
	char *s = (char *)p;
	/* Take care of the easy one first (eg. it requires no searches) */
	if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
		{
		if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
			return 0;
		return e->cmd_defns->cmd_num;
		}
	/* One or two commands require that "p" be a valid string buffer */
	if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
			(cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
			(cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
		{
		if(s == NULL)
			{
			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
				ERR_R_PASSED_NULL_PARAMETER);
			return -1;
			}
		}
	/* Now handle cmd_name -> cmd_num conversion */
	if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
		{
		if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
						e->cmd_defns, s)) < 0))
			{
			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
				ENGINE_R_INVALID_CMD_NAME);
			return -1;
			}
		return e->cmd_defns[idx].cmd_num;
		}
	/* For the rest of the commands, the 'long' argument must specify a
	 * valie command number - so we need to conduct a search. */
	if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
					(unsigned int)i)) < 0))
		{
		ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
			ENGINE_R_INVALID_CMD_NUMBER);
		return -1;
		}
	/* Now the logic splits depending on command type */
	switch(cmd)
		{
	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
		idx++;
		if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
			/* end-of-list */
			return 0;
		else
			return e->cmd_defns[idx].cmd_num;
	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
		return strlen(e->cmd_defns[idx].cmd_name);
	case ENGINE_CTRL_GET_NAME_FROM_CMD:
		return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
				    "%s", e->cmd_defns[idx].cmd_name);
	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
		if(e->cmd_defns[idx].cmd_desc)
			return strlen(e->cmd_defns[idx].cmd_desc);
		return strlen(int_no_description);
	case ENGINE_CTRL_GET_DESC_FROM_CMD:
		if(e->cmd_defns[idx].cmd_desc)
			return BIO_snprintf(s,
					    strlen(e->cmd_defns[idx].cmd_desc) + 1,
					    "%s", e->cmd_defns[idx].cmd_desc);
		return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
				    int_no_description);
	case ENGINE_CTRL_GET_CMD_FLAGS:
		return e->cmd_defns[idx].cmd_flags;
		}
	/* Shouldn't really be here ... */
	ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
	return -1;
	}

int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
	{
	int ctrl_exists, ref_exists;
	if(e == NULL)
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}
	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
	ref_exists = ((e->struct_ref > 0) ? 1 : 0);
	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
	ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
	if(!ref_exists)
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
		return 0;
		}
	/* Intercept any "root-level" commands before trying to hand them on to
	 * ctrl() handlers. */
	switch(cmd)
		{
	case ENGINE_CTRL_HAS_CTRL_FUNCTION:
		return ctrl_exists;
	case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
	case ENGINE_CTRL_GET_CMD_FROM_NAME:
	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
	case ENGINE_CTRL_GET_NAME_FROM_CMD:
	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
	case ENGINE_CTRL_GET_DESC_FROM_CMD:
	case ENGINE_CTRL_GET_CMD_FLAGS:
		if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
			return int_ctrl_helper(e,cmd,i,p,f);
		if(!ctrl_exists)
			{
			ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
			/* For these cmd-related functions, failure is indicated
			 * by a -1 return value (because 0 is used as a valid
			 * return in some places). */
			return -1;
			}
	default:
		break;
		}
	/* Anything else requires a ctrl() handler to exist. */
	if(!ctrl_exists)
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
		return 0;
		}
	return e->ctrl(e, cmd, i, p, f);
	}

int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
	{
	int flags;
	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
		{
		ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
			ENGINE_R_INVALID_CMD_NUMBER);
		return 0;
		}
	if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
			!(flags & ENGINE_CMD_FLAG_NUMERIC) &&
			!(flags & ENGINE_CMD_FLAG_STRING))
		return 0;
	return 1;
	}

int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
        long i, void *p, void (*f)(void), int cmd_optional)
        {
	int num;

	if((e == NULL) || (cmd_name == NULL))
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
			ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}
	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
					ENGINE_CTRL_GET_CMD_FROM_NAME,
					0, (void *)cmd_name, NULL)) <= 0))
		{
		/* If the command didn't *have* to be supported, we fake
		 * success. This allows certain settings to be specified for
		 * multiple ENGINEs and only require a change of ENGINE id
		 * (without having to selectively apply settings). Eg. changing
		 * from a hardware device back to the regular software ENGINE
		 * without editing the config file, etc. */
		if(cmd_optional)
			{
			ERR_clear_error();
			return 1;
			}
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
			ENGINE_R_INVALID_CMD_NAME);
		return 0;
		}
	/* Force the result of the control command to 0 or 1, for the reasons
	 * mentioned before. */
        if (ENGINE_ctrl(e, num, i, p, f))
                return 1;
        return 0;
        }

int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
				int cmd_optional)
	{
	int num, flags;
	long l;
	char *ptr;
	if((e == NULL) || (cmd_name == NULL))
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
			ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}
	if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
					ENGINE_CTRL_GET_CMD_FROM_NAME,
					0, (void *)cmd_name, NULL)) <= 0))
		{
		/* If the command didn't *have* to be supported, we fake
		 * success. This allows certain settings to be specified for
		 * multiple ENGINEs and only require a change of ENGINE id
		 * (without having to selectively apply settings). Eg. changing
		 * from a hardware device back to the regular software ENGINE
		 * without editing the config file, etc. */
		if(cmd_optional)
			{
			ERR_clear_error();
			return 1;
			}
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
			ENGINE_R_INVALID_CMD_NAME);
		return 0;
		}
	if(!ENGINE_cmd_is_executable(e, num))
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
			ENGINE_R_CMD_NOT_EXECUTABLE);
		return 0;
		}
	if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
		{
		/* Shouldn't happen, given that ENGINE_cmd_is_executable()
		 * returned success. */
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
			ENGINE_R_INTERNAL_LIST_ERROR);
		return 0;
		}
	/* If the command takes no input, there must be no input. And vice
	 * versa. */
	if(flags & ENGINE_CMD_FLAG_NO_INPUT)
		{
		if(arg != NULL)
			{
			ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
				ENGINE_R_COMMAND_TAKES_NO_INPUT);
			return 0;
			}
		/* We deliberately force the result of ENGINE_ctrl() to 0 or 1
		 * rather than returning it as "return data". This is to ensure
		 * usage of these commands is consistent across applications and
		 * that certain applications don't understand it one way, and
		 * others another. */
		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
			return 1;
		return 0;
		}
	/* So, we require input */
	if(arg == NULL)
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
			ENGINE_R_COMMAND_TAKES_INPUT);
		return 0;
		}
	/* If it takes string input, that's easy */
	if(flags & ENGINE_CMD_FLAG_STRING)
		{
		/* Same explanation as above */
		if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
			return 1;
		return 0;
		}
	/* If it doesn't take numeric either, then it is unsupported for use in
	 * a config-setting situation, which is what this function is for. This
	 * should never happen though, because ENGINE_cmd_is_executable() was
	 * used. */
	if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
			ENGINE_R_INTERNAL_LIST_ERROR);
		return 0;
		}
	l = strtol(arg, &ptr, 10);
	if((arg == ptr) || (*ptr != '\0'))
		{
		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
			ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
		return 0;
		}
	/* Force the result of the control command to 0 or 1, for the reasons
	 * mentioned before. */
	if(ENGINE_ctrl(e, num, l, NULL, NULL))
		return 1;
	return 0;
	}
