1/* 2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please obtain 7 * a copy of the License at http://www.apple.com/publicsource and read it before 8 * using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 15 * specific language governing rights and limitations under the License. 16 */ 17 18 19/* crypto/ex_data.c */ 20/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 21 * All rights reserved. 22 * 23 * This package is an SSL implementation written 24 * by Eric Young (eay@cryptsoft.com). 25 * The implementation was written so as to conform with Netscapes SSL. 26 * 27 * This library is free for commercial and non-commercial use as long as 28 * the following conditions are aheared to. The following conditions 29 * apply to all code found in this distribution, be it the RC4, RSA, 30 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 31 * included with this distribution is covered by the same copyright terms 32 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 33 * 34 * Copyright remains Eric Young's, and as such any Copyright notices in 35 * the code are not to be removed. 36 * If this package is used in a product, Eric Young should be given attribution 37 * as the author of the parts of the library used. 38 * This can be in the form of a textual message at program startup or 39 * in documentation (online or textual) provided with the package. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. All advertising materials mentioning features or use of this software 50 * must display the following acknowledgement: 51 * "This product includes cryptographic software written by 52 * Eric Young (eay@cryptsoft.com)" 53 * The word 'cryptographic' can be left out if the rouines from the library 54 * being used are not cryptographic related :-). 55 * 4. If you include any Windows specific code (or a derivative thereof) from 56 * the apps directory (application code) you must include an acknowledgement: 57 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 58 * 59 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * The licence and distribution terms for any publically available version or 72 * derivative of this code cannot be changed. i.e. this code cannot simply be 73 * copied and put under another distribution licence 74 * [including the GNU Public Licence.] 75 */ 76 77#include <stdio.h> 78#include <stdlib.h> 79#include <openssl/buffer.h> 80#include <openssl/bio.h> 81#include <openssl/lhash.h> 82#include "cryptlib.h" 83 84int CRYPTO_get_ex_new_index(int idx, STACK_OF(CRYPTO_EX_DATA_FUNCS) **skp, long argl, void *argp, 85 CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 86 { 87 int ret= -1; 88 CRYPTO_EX_DATA_FUNCS *a; 89 90 MemCheck_off(); 91 if (*skp == NULL) 92 *skp=sk_CRYPTO_EX_DATA_FUNCS_new_null(); 93 if (*skp == NULL) 94 { 95 CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX,ERR_R_MALLOC_FAILURE); 96 goto err; 97 } 98 a=(CRYPTO_EX_DATA_FUNCS *)Malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); 99 if (a == NULL) 100 { 101 CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX,ERR_R_MALLOC_FAILURE); 102 goto err; 103 } 104 a->argl=argl; 105 a->argp=argp; 106 a->new_func=new_func; 107 a->dup_func=dup_func; 108 a->free_func=free_func; 109 while (sk_CRYPTO_EX_DATA_FUNCS_num(*skp) <= idx) 110 { 111 if (!sk_CRYPTO_EX_DATA_FUNCS_push(*skp,NULL)) 112 { 113 CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX,ERR_R_MALLOC_FAILURE); 114 Free(a); 115 goto err; 116 } 117 } 118 sk_CRYPTO_EX_DATA_FUNCS_set(*skp,idx, a); 119 ret=idx; 120err: 121 MemCheck_on(); 122 return(idx); 123 } 124 125int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) 126 { 127 int i; 128 129 if (ad->sk == NULL) 130 { 131 if ((ad->sk=sk_new_null()) == NULL) 132 { 133 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); 134 return(0); 135 } 136 } 137 i=sk_num(ad->sk); 138 139 while (i <= idx) 140 { 141 if (!sk_push(ad->sk,NULL)) 142 { 143 CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE); 144 return(0); 145 } 146 i++; 147 } 148 sk_set(ad->sk,idx,val); 149 return(1); 150 } 151 152void *CRYPTO_get_ex_data(CRYPTO_EX_DATA *ad, int idx) 153 { 154 if (ad->sk == NULL) 155 return(0); 156 else if (idx >= sk_num(ad->sk)) 157 return(0); 158 else 159 return(sk_value(ad->sk,idx)); 160 } 161 162/* The callback is called with the 'object', which is the original data object 163 * being duplicated, a pointer to the 164 * 'new' object to be inserted, the index, and the argi/argp 165 */ 166int CRYPTO_dup_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, CRYPTO_EX_DATA *to, 167 CRYPTO_EX_DATA *from) 168 { 169 int i,j,m,r; 170 CRYPTO_EX_DATA_FUNCS *mm; 171 char *from_d; 172 173 if (meth == NULL) return(1); 174 if (from->sk == NULL) return(1); 175 m=sk_CRYPTO_EX_DATA_FUNCS_num(meth); 176 j=sk_num(from->sk); 177 for (i=0; i<j; i++) 178 { 179 from_d=CRYPTO_get_ex_data(from,i); 180 if (i < m) 181 { 182 mm=sk_CRYPTO_EX_DATA_FUNCS_value(meth,i); 183 if (mm->dup_func != NULL) 184 r=mm->dup_func(to,from,(char **)&from_d,i, 185 mm->argl,mm->argp); 186 } 187 CRYPTO_set_ex_data(to,i,from_d); 188 } 189 return(1); 190 } 191 192/* Call each free callback */ 193void CRYPTO_free_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, void *obj, CRYPTO_EX_DATA *ad) 194 { 195 CRYPTO_EX_DATA_FUNCS *m; 196 void *ptr; 197 int i,max; 198 199 if (meth != NULL) 200 { 201 max=sk_CRYPTO_EX_DATA_FUNCS_num(meth); 202 for (i=0; i<max; i++) 203 { 204 m=sk_CRYPTO_EX_DATA_FUNCS_value(meth,i); 205 if ((m != NULL) && (m->free_func != NULL)) 206 { 207 ptr=CRYPTO_get_ex_data(ad,i); 208 m->free_func(obj,ptr,ad,i,m->argl,m->argp); 209 } 210 } 211 } 212 if (ad->sk != NULL) 213 { 214 sk_free(ad->sk); 215 ad->sk=NULL; 216 } 217 } 218 219void CRYPTO_new_ex_data(STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth, void *obj, CRYPTO_EX_DATA *ad) 220 { 221 CRYPTO_EX_DATA_FUNCS *m; 222 void *ptr; 223 int i,max; 224 225 ad->sk=NULL; 226 if (meth != NULL) 227 { 228 max=sk_CRYPTO_EX_DATA_FUNCS_num(meth); 229 for (i=0; i<max; i++) 230 { 231 m=sk_CRYPTO_EX_DATA_FUNCS_value(meth,i); 232 if ((m != NULL) && (m->new_func != NULL)) 233 { 234 ptr=CRYPTO_get_ex_data(ad,i); 235 m->new_func(obj,ptr,ad,i,m->argl,m->argp); 236 } 237 } 238 } 239 } 240 241IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS) 242