1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/ex_data.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Overhaul notes;
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This code is now *mostly* thread-safe. It is now easier to understand in what
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ways it is safe and in what ways it is not, which is an improvement. Firstly,
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * all per-class stacks and index-counters for ex_data are stored in the same
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * global LHASH table (keyed by class). This hash table uses locking for all
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * called when no other threads can possibly race against it (even if it was
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * locked, the race would mean it's possible the hash table might have been
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * recreated after the cleanup). As classes can only be added to the hash table,
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and within each class, the stack of methods can only be incremented, the
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * locking mechanics are simpler than they would otherwise be. For example, the
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * new/dup/free ex_data functions will lock the hash table, copy the method
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * pointers it needs from the relevant class, then unlock the hash table before
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * actually applying those method pointers to the task of the new/dup/free
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * operations. As they can't be removed from the method-stack, only
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * supplemented, there's no race conditions associated with using them outside
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the lock. The get/set_ex_data functions are not locked because they do not
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * involve this global state at all - they operate directly with a previously
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * obtained per-class method index and a particular "ex_data" variable. These
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * variables are usually instantiated per-context (eg. each RSA structure has
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * one) so locking on read/write access to that variable can be locked locally
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * if required (eg. using the "RSA" lock to synchronise access to a
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * per-RSA-structure ex_data variable if required).
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [Geoff]
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/lhash.h>
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* What an "implementation of ex_data functionality" looks like */
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct st_CRYPTO_EX_DATA_IMPL
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*********************/
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* GLOBAL OPERATIONS */
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Return a new class index */
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int (*cb_new_class)(void);
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Cleanup all state used by the implementation */
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void (*cb_cleanup)(void);
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/************************/
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* PER-CLASS OPERATIONS */
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Get a new method index within a class */
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int (*cb_get_new_index)(int class_index, long argl, void *argp,
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTO_EX_free *free_func);
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Initialise a new CRYPTO_EX_DATA of a given class */
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int (*cb_new_ex_data)(int class_index, void *obj,
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTO_EX_DATA *ad);
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int (*cb_dup_ex_data)(int class_index, CRYPTO_EX_DATA *to,
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTO_EX_DATA *from);
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Cleanup a CRYPTO_EX_DATA of a given class */
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void (*cb_free_ex_data)(int class_index, void *obj,
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTO_EX_DATA *ad);
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The implementation we use at run-time */
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const CRYPTO_EX_DATA_IMPL *impl = NULL;
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* To call "impl" functions, use this macro rather than referring to 'impl' directly, eg.
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EX_IMPL(get_new_index)(...); */
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define EX_IMPL(a) impl->cb_##a
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Predeclare the "default" ex_data implementation */
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_new_class(void);
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void int_cleanup(void);
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_get_new_index(int class_index, long argl, void *argp,
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_free *free_func);
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_new_ex_data(int class_index, void *obj,
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_DATA *ad);
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_DATA *from);
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void int_free_ex_data(int class_index, void *obj,
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_DATA *ad);
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic CRYPTO_EX_DATA_IMPL impl_default =
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int_new_class,
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int_cleanup,
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int_get_new_index,
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int_new_ex_data,
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int_dup_ex_data,
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int_free_ex_data
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Internal function that checks whether "impl" is set and if not, sets it to
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the default. */
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void impl_check(void)
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!impl)
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		impl = &impl_default;
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* A macro wrapper for impl_check that first uses a non-locked test before
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * invoking the function (which checks again inside a lock). */
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define IMPL_CHECK if(!impl) impl_check();
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* API functions to get/set the "ex_data" implementation */
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void)
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	IMPL_CHECK
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return impl;
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i)
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int toret = 0;
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!impl)
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		impl = i;
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		toret = 1;
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return toret;
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/****************************************************************************/
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Interal (default) implementation of "ex_data" support. API functions are
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * further down. */
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The type that represents what each "class" used to implement locally. A STACK
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is the global
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * value representing the class that is used to distinguish these items. */
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct st_ex_class_item {
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int class_index;
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int meth_num;
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} EX_CLASS_ITEM;
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* When assigning new class indexes, this is our counter */
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ex_class = CRYPTO_EX_INDEX_USER;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The global hash table of EX_CLASS_ITEM items */
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_LHASH_OF(EX_CLASS_ITEM);
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The callbacks required in the "ex_data" hash table */
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a)
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return a->class_index;
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return a->class_index - b->class_index;
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Internal functions used by the "impl_default" implementation to access the
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * state */
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ex_data_check(void)
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int toret = 1;
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if(!ex_data
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	   && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		toret = 0;
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return toret;
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This macros helps reduce the locking from repeated checks because the
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ex_data_check() function checks ex_data again inside a lock. */
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This "inner" callback is used by the callback function that follows it */
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs)
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(funcs);
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't do
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * any locking. */
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void def_cleanup_cb(void *a_void)
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void;
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb);
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(item);
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to a
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * given class. Handles locking. */
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic EX_CLASS_ITEM *def_get_class(int class_index)
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_CLASS_ITEM d, *p, *gen;
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_DATA_CHECK(return NULL;)
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	d.class_index = class_index;
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!p)
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(gen)
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			gen->class_index = class_index;
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			gen->meth_num = 0;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(!gen->meth)
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				OPENSSL_free(gen);
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* Because we're inside the ex_data lock, the
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				 * return value from the insert will be NULL */
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				(void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				p = gen;
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!p)
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTOerr(CRYPTO_F_DEF_GET_CLASS,ERR_R_MALLOC_FAILURE);
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return p;
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Add a new method to the given EX_CLASS_ITEM and return the corresponding
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * index (or -1 for error). Handles locking. */
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_free *free_func)
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int toret = -1;
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_EX_DATA_FUNCS *a = (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					sizeof(CRYPTO_EX_DATA_FUNCS));
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!a)
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->argl=argl;
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->argp=argp;
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->new_func=new_func;
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->dup_func=dup_func;
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a->free_func=free_func;
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num)
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL))
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX,ERR_R_MALLOC_FAILURE);
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_free(a);
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	toret = item->meth_num++;
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return toret;
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/**************************************************************/
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The functions in the default CRYPTO_EX_DATA_IMPL structure */
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_new_class(void)
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int toret;
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	toret = ex_class++;
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return toret;
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void int_cleanup(void)
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_DATA_CHECK(return;)
382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	lh_EX_CLASS_ITEM_free(ex_data);
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ex_data = NULL;
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	impl = NULL;
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_get_new_index(int class_index, long argl, void *argp,
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_free *free_func)
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_CLASS_ITEM *item = def_get_class(class_index);
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!item)
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return def_add_index(item, argl, argp, new_func, dup_func, free_func);
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the lock, then using them outside the lock. NB: Thread-safety only applies to
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad'
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * itself. */
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_new_ex_data(int class_index, void *obj,
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_DATA *ad)
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int mx,i;
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *ptr;
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_EX_DATA_FUNCS **storage = NULL;
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_CLASS_ITEM *item = def_get_class(class_index);
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!item)
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* error is already set */
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ad->sk = NULL;
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(mx > 0)
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!storage)
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto skip;
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for(i = 0; i < mx; i++)
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectskip:
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((mx > 0) && !storage)
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA,ERR_R_MALLOC_FAILURE);
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(i = 0; i < mx; i++)
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(storage[i] && storage[i]->new_func)
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ptr = CRYPTO_get_ex_data(ad, i);
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			storage[i]->new_func(obj,ptr,ad,i,
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				storage[i]->argl,storage[i]->argp);
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(storage)
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(storage);
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Same thread-safety notes as for "int_new_ex_data" */
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_DATA *from)
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int mx, j, i;
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *ptr;
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_EX_DATA_FUNCS **storage = NULL;
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_CLASS_ITEM *item;
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!from->sk)
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* 'to' should be "blank" which *is* just like 'from' */
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((item = def_get_class(class_index)) == NULL)
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	j = sk_void_num(from->sk);
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(j < mx)
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		mx = j;
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(mx > 0)
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!storage)
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto skip;
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for(i = 0; i < mx; i++)
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectskip:
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((mx > 0) && !storage)
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA,ERR_R_MALLOC_FAILURE);
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(i = 0; i < mx; i++)
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ptr = CRYPTO_get_ex_data(from, i);
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(storage[i] && storage[i]->dup_func)
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			storage[i]->dup_func(to,from,&ptr,i,
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				storage[i]->argl,storage[i]->argp);
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_set_ex_data(to,i,ptr);
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(storage)
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(storage);
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Same thread-safety notes as for "int_new_ex_data" */
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void int_free_ex_data(int class_index, void *obj,
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_DATA *ad)
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int mx,i;
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_CLASS_ITEM *item;
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *ptr;
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_EX_DATA_FUNCS **storage = NULL;
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((item = def_get_class(class_index)) == NULL)
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(mx > 0)
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS*));
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!storage)
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto skip;
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for(i = 0; i < mx; i++)
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth,i);
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectskip:
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((mx > 0) && !storage)
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA,ERR_R_MALLOC_FAILURE);
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(i = 0; i < mx; i++)
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(storage[i] && storage[i]->free_func)
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ptr = CRYPTO_get_ex_data(ad,i);
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			storage[i]->free_func(obj,ptr,ad,i,
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				storage[i]->argl,storage[i]->argp);
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(storage)
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(storage);
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ad->sk)
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
530221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		sk_void_free(ad->sk);
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ad->sk=NULL;
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/********************************************************************/
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* API functions that defer all "state" operations to the "ex_data"
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * implementation we have set. */
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Obtain an index for a new class (not the same as getting a new index within
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * an existing class - this is actually getting a new *class*) */
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint CRYPTO_ex_data_new_class(void)
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	IMPL_CHECK
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return EX_IMPL(new_class)();
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Release all "ex_data" state to prevent memory leaks. This can't be made
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * thread-safe without overhauling a lot of stuff, and shouldn't really be
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * called under potential race-conditions anyway (it's for program shutdown
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * after all). */
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid CRYPTO_cleanup_all_ex_data(void)
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	IMPL_CHECK
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_IMPL(cleanup)();
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Inside an existing class, get/register a new index. */
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_EX_free *free_func)
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = -1;
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	IMPL_CHECK
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = EX_IMPL(get_new_index)(class_index,
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			argl, argp, new_func, dup_func, free_func);
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * calling new() callbacks for each index in the class used by this variable */
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	IMPL_CHECK
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return EX_IMPL(new_ex_data)(class_index, obj, ad);
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * each index in the class used by this variable */
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     CRYPTO_EX_DATA *from)
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	IMPL_CHECK
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return EX_IMPL(dup_ex_data)(class_index, to, from);
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * each index in the class used by this variable */
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	IMPL_CHECK
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EX_IMPL(free_ex_data)(class_index, obj, ad);
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * particular index in the class used by this variable */
597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ad->sk == NULL)
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
603221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if ((ad->sk=sk_void_new_null()) == NULL)
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(0);
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
609221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	i=sk_void_num(ad->sk);
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (i <= idx)
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
613221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!sk_void_push(ad->sk,NULL))
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(0);
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i++;
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
620221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sk_void_set(ad->sk,idx,val);
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * particular index in the class used by this variable */
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ad->sk == NULL)
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
630221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else if (idx >= sk_void_num(ad->sk))
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
633221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return(sk_void_value(ad->sk,idx));
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
637