1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/engine/eng_list.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 2000.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ECDH support in OpenSSL originally developed by
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "eng_int.h"
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The linked-list of pointers to engine types. engine_list_head
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * incorporates an implicit structural reference but engine_list_tail
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * does not - the latter is a computational niceity and only points
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * to something that is already pointed to by its predecessor in the
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * list (or engine_list_head itself). In the same way, the use of the
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "prev" pointer in each ENGINE is to save excessive list iteration,
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * it doesn't correspond to an extra structural reference. Hence,
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * engine_list_head, and each non-null "next" pointer account for
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the list itself assuming exactly 1 structural reference on each
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * list member. */
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ENGINE *engine_list_head = NULL;
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ENGINE *engine_list_tail = NULL;
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This cleanup function is only needed internally. If it should be called, we
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void engine_list_cleanup(void)
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *iterator = engine_list_head;
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(iterator != NULL)
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINE_remove(iterator);
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		iterator = engine_list_head;
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return;
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* These static functions starting with a lower case "engine_" always
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * take place when CRYPTO_LOCK_ENGINE has been locked up. */
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int engine_list_add(ENGINE *e)
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int conflict = 0;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *iterator = NULL;
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e == NULL)
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	iterator = engine_list_head;
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(iterator && !conflict)
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		conflict = (strcmp(iterator->id, e->id) == 0);
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		iterator = iterator->next;
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(conflict)
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_CONFLICTING_ENGINE_ID);
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(engine_list_head == NULL)
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* We are adding to an empty list. */
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(engine_list_tail)
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ENGINE_R_INTERNAL_LIST_ERROR);
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_list_head = e;
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		e->prev = NULL;
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* The first time the list allocates, we should register the
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * cleanup. */
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_cleanup_add_last(engine_list_cleanup);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* We are adding to the tail of an existing list. */
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if((engine_list_tail == NULL) ||
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(engine_list_tail->next != NULL))
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ENGINE_R_INTERNAL_LIST_ERROR);
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_list_tail->next = e;
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		e->prev = engine_list_tail;
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Having the engine in the list assumes a structural
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * reference. */
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	e->struct_ref++;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	engine_ref_debug(e, 0, 1)
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* However it came to be, e is the last item in the list. */
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	engine_list_tail = e;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	e->next = NULL;
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int engine_list_remove(ENGINE *e)
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *iterator;
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e == NULL)
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* We need to check that e is in our linked list! */
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	iterator = engine_list_head;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(iterator && (iterator != e))
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		iterator = iterator->next;
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(iterator == NULL)
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_ENGINE_IS_NOT_IN_LIST);
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* un-link e from the chain. */
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e->next)
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		e->next->prev = e->prev;
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e->prev)
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		e->prev->next = e->next;
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Correct our head/tail if necessary. */
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(engine_list_head == e)
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_list_head = e->next;
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(engine_list_tail == e)
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_list_tail = e->prev;
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	engine_free_util(e, 0);
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Get the first/last "ENGINE" type available. */
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE *ENGINE_get_first(void)
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *ret;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = engine_list_head;
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret)
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->struct_ref++;
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_ref_debug(ret, 0, 1)
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE *ENGINE_get_last(void)
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *ret;
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = engine_list_tail;
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret)
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->struct_ref++;
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_ref_debug(ret, 0, 1)
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE *ENGINE_get_next(ENGINE *e)
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *ret = NULL;
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e == NULL)
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = e->next;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret)
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Return a valid structural refernce to the next ENGINE */
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->struct_ref++;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_ref_debug(ret, 0, 1)
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Release the structural reference to the previous ENGINE */
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE_free(e);
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE *ENGINE_get_prev(ENGINE *e)
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *ret = NULL;
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e == NULL)
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = e->prev;
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret)
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Return a valid structural reference to the next ENGINE */
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->struct_ref++;
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		engine_ref_debug(ret, 0, 1)
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Release the structural reference to the previous ENGINE */
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE_free(e);
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Add another "ENGINE" type into the list. */
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ENGINE_add(ENGINE *e)
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int to_return = 1;
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e == NULL)
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_ADD,
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((e->id == NULL) || (e->name == NULL))
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_ADD,
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_ID_OR_NAME_MISSING);
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!engine_list_add(e))
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_ADD,
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INTERNAL_LIST_ERROR);
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		to_return = 0;
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return to_return;
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Remove an existing "ENGINE" type from the array. */
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ENGINE_remove(ENGINE *e)
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int to_return = 1;
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(e == NULL)
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!engine_list_remove(e))
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_INTERNAL_LIST_ERROR);
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		to_return = 0;
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return to_return;
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void engine_cpy(ENGINE *dest, const ENGINE *src)
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->id = src->id;
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->name = src->name;
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RSA
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->rsa_meth = src->rsa_meth;
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DSA
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->dsa_meth = src->dsa_meth;
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DH
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->dh_meth = src->dh_meth;
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ECDH
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->ecdh_meth = src->ecdh_meth;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ECDSA
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->ecdsa_meth = src->ecdsa_meth;
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->rand_meth = src->rand_meth;
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->store_meth = src->store_meth;
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->ciphers = src->ciphers;
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->digests = src->digests;
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dest->pkey_meths = src->pkey_meths;
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->destroy = src->destroy;
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->init = src->init;
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->finish = src->finish;
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->ctrl = src->ctrl;
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->load_privkey = src->load_privkey;
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->load_pubkey = src->load_pubkey;
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->cmd_defns = src->cmd_defns;
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->flags = src->flags;
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE *ENGINE_by_id(const char *id)
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *iterator;
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *load_dir = NULL;
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(id == NULL)
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_R_PASSED_NULL_PARAMETER);
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	iterator = engine_list_head;
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(iterator && (strcmp(id, iterator->id) != 0))
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		iterator = iterator->next;
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(iterator)
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* We need to return a structural reference. If this is an
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * ENGINE type that returns copies, make a duplicate - otherwise
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * increment the existing ENGINE's reference count. */
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE *cp = ENGINE_new();
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(!cp)
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				iterator = NULL;
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				engine_cpy(cp, iterator);
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				iterator = cp;
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			iterator->struct_ref++;
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			engine_ref_debug(iterator, 0, 1)
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(iterator == NULL)
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_R_NO_SUCH_ENGINE);
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(2, "id=", id);
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return iterator;
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* EEK! Experimental code starts */
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(iterator) return iterator;
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Prevent infinite recusrion if we're looking for the dynamic engine. */
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (strcmp(id, "dynamic"))
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef OPENSSL_SYS_VMS
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		iterator = ENGINE_by_id("dynamic");
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					load_dir, 0) ||
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto notfound;
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return iterator;
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectnotfound:
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ENGINE_free(iterator);
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_add_error_data(2, "id=", id);
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return NULL;
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* EEK! Experimental code ends */
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ENGINE_up_ref(ENGINE *e)
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (e == NULL)
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE);
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
434