OLD | NEW |
1 /* crypto/x509/by_dir.c */ | 1 /* crypto/x509/by_dir.c */ |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
8 * | 8 * |
9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 | 58 |
59 #include <stdio.h> | 59 #include <stdio.h> |
60 #include <time.h> | 60 #include <time.h> |
61 #include <errno.h> | 61 #include <errno.h> |
62 | 62 |
63 #include "cryptlib.h" | 63 #include "cryptlib.h" |
64 | 64 |
65 #ifndef NO_SYS_TYPES_H | 65 #ifndef NO_SYS_TYPES_H |
66 # include <sys/types.h> | 66 # include <sys/types.h> |
67 #endif | 67 #endif |
68 #ifdef MAC_OS_pre_X | 68 #ifndef OPENSSL_NO_POSIX_IO |
69 # include <stat.h> | |
70 #else | |
71 # include <sys/stat.h> | 69 # include <sys/stat.h> |
72 #endif | 70 #endif |
73 | 71 |
74 #include <openssl/lhash.h> | 72 #include <openssl/lhash.h> |
75 #include <openssl/x509.h> | 73 #include <openssl/x509.h> |
76 | 74 |
77 #ifdef _WIN32 | 75 |
78 #define stat» _stat | 76 typedef struct lookup_dir_hashes_st |
79 #endif | 77 » { |
| 78 » unsigned long hash; |
| 79 » int suffix; |
| 80 » } BY_DIR_HASH; |
| 81 |
| 82 typedef struct lookup_dir_entry_st |
| 83 » { |
| 84 » char *dir; |
| 85 » int dir_type; |
| 86 » STACK_OF(BY_DIR_HASH) *hashes; |
| 87 » } BY_DIR_ENTRY; |
80 | 88 |
81 typedef struct lookup_dir_st | 89 typedef struct lookup_dir_st |
82 { | 90 { |
83 BUF_MEM *buffer; | 91 BUF_MEM *buffer; |
84 » int num_dirs; | 92 » STACK_OF(BY_DIR_ENTRY) *dirs; |
85 » char **dirs; | |
86 » int *dirs_type; | |
87 » int num_dirs_alloced; | |
88 } BY_DIR; | 93 } BY_DIR; |
89 | 94 |
| 95 DECLARE_STACK_OF(BY_DIR_HASH) |
| 96 DECLARE_STACK_OF(BY_DIR_ENTRY) |
| 97 |
90 static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, | 98 static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, |
91 char **ret); | 99 char **ret); |
92 static int new_dir(X509_LOOKUP *lu); | 100 static int new_dir(X509_LOOKUP *lu); |
93 static void free_dir(X509_LOOKUP *lu); | 101 static void free_dir(X509_LOOKUP *lu); |
94 static int add_cert_dir(BY_DIR *ctx,const char *dir,int type); | 102 static int add_cert_dir(BY_DIR *ctx,const char *dir,int type); |
95 static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name, | 103 static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name, |
96 X509_OBJECT *ret); | 104 X509_OBJECT *ret); |
97 X509_LOOKUP_METHOD x509_dir_lookup= | 105 X509_LOOKUP_METHOD x509_dir_lookup= |
98 { | 106 { |
99 "Load certs from files in a directory", | 107 "Load certs from files in a directory", |
(...skipping 20 matching lines...) Expand all Loading... |
120 BY_DIR *ld; | 128 BY_DIR *ld; |
121 char *dir = NULL; | 129 char *dir = NULL; |
122 | 130 |
123 ld=(BY_DIR *)ctx->method_data; | 131 ld=(BY_DIR *)ctx->method_data; |
124 | 132 |
125 switch (cmd) | 133 switch (cmd) |
126 { | 134 { |
127 case X509_L_ADD_DIR: | 135 case X509_L_ADD_DIR: |
128 if (argl == X509_FILETYPE_DEFAULT) | 136 if (argl == X509_FILETYPE_DEFAULT) |
129 { | 137 { |
130 » » » dir=(char *)Getenv(X509_get_default_cert_dir_env()); | 138 » » » dir=(char *)getenv(X509_get_default_cert_dir_env()); |
131 if (dir) | 139 if (dir) |
132 ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM); | 140 ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM); |
133 else | 141 else |
134 ret=add_cert_dir(ld,X509_get_default_cert_dir(), | 142 ret=add_cert_dir(ld,X509_get_default_cert_dir(), |
135 X509_FILETYPE_PEM); | 143 X509_FILETYPE_PEM); |
136 if (!ret) | 144 if (!ret) |
137 { | 145 { |
138 X509err(X509_F_DIR_CTRL,X509_R_LOADING_CERT_DIR)
; | 146 X509err(X509_F_DIR_CTRL,X509_R_LOADING_CERT_DIR)
; |
139 } | 147 } |
140 } | 148 } |
141 else | 149 else |
142 ret=add_cert_dir(ld,argp,(int)argl); | 150 ret=add_cert_dir(ld,argp,(int)argl); |
143 break; | 151 break; |
144 } | 152 } |
145 return(ret); | 153 return(ret); |
146 } | 154 } |
147 | 155 |
148 static int new_dir(X509_LOOKUP *lu) | 156 static int new_dir(X509_LOOKUP *lu) |
149 { | 157 { |
150 BY_DIR *a; | 158 BY_DIR *a; |
151 | 159 |
152 if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) | 160 if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) |
153 return(0); | 161 return(0); |
154 if ((a->buffer=BUF_MEM_new()) == NULL) | 162 if ((a->buffer=BUF_MEM_new()) == NULL) |
155 { | 163 { |
156 OPENSSL_free(a); | 164 OPENSSL_free(a); |
157 return(0); | 165 return(0); |
158 } | 166 } |
159 a->num_dirs=0; | |
160 a->dirs=NULL; | 167 a->dirs=NULL; |
161 a->dirs_type=NULL; | |
162 a->num_dirs_alloced=0; | |
163 lu->method_data=(char *)a; | 168 lu->method_data=(char *)a; |
164 return(1); | 169 return(1); |
165 } | 170 } |
166 | 171 |
| 172 static void by_dir_hash_free(BY_DIR_HASH *hash) |
| 173 { |
| 174 OPENSSL_free(hash); |
| 175 } |
| 176 |
| 177 static int by_dir_hash_cmp(const BY_DIR_HASH * const *a, |
| 178 const BY_DIR_HASH * const *b) |
| 179 { |
| 180 if ((*a)->hash > (*b)->hash) |
| 181 return 1; |
| 182 if ((*a)->hash < (*b)->hash) |
| 183 return -1; |
| 184 return 0; |
| 185 } |
| 186 |
| 187 static void by_dir_entry_free(BY_DIR_ENTRY *ent) |
| 188 { |
| 189 if (ent->dir) |
| 190 OPENSSL_free(ent->dir); |
| 191 if (ent->hashes) |
| 192 sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); |
| 193 OPENSSL_free(ent); |
| 194 } |
| 195 |
167 static void free_dir(X509_LOOKUP *lu) | 196 static void free_dir(X509_LOOKUP *lu) |
168 { | 197 { |
169 BY_DIR *a; | 198 BY_DIR *a; |
170 int i; | |
171 | 199 |
172 a=(BY_DIR *)lu->method_data; | 200 a=(BY_DIR *)lu->method_data; |
173 » for (i=0; i<a->num_dirs; i++) | 201 » if (a->dirs != NULL) |
174 » » if (a->dirs[i] != NULL) OPENSSL_free(a->dirs[i]); | 202 » » sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); |
175 » if (a->dirs != NULL) OPENSSL_free(a->dirs); | 203 » if (a->buffer != NULL) |
176 » if (a->dirs_type != NULL) OPENSSL_free(a->dirs_type); | 204 » » BUF_MEM_free(a->buffer); |
177 » if (a->buffer != NULL) BUF_MEM_free(a->buffer); | |
178 OPENSSL_free(a); | 205 OPENSSL_free(a); |
179 } | 206 } |
180 | 207 |
181 static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) | 208 static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) |
182 { | 209 { |
183 int j,len; | 210 int j,len; |
184 int *ip; | |
185 const char *s,*ss,*p; | 211 const char *s,*ss,*p; |
186 char **pp; | |
187 | 212 |
188 if (dir == NULL || !*dir) | 213 if (dir == NULL || !*dir) |
189 { | 214 { |
190 X509err(X509_F_ADD_CERT_DIR,X509_R_INVALID_DIRECTORY); | 215 X509err(X509_F_ADD_CERT_DIR,X509_R_INVALID_DIRECTORY); |
191 return 0; | 216 return 0; |
192 } | 217 } |
193 | 218 |
194 s=dir; | 219 s=dir; |
195 p=s; | 220 p=s; |
196 for (;;p++) | 221 for (;;p++) |
197 { | 222 { |
198 if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) | 223 if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) |
199 { | 224 { |
| 225 BY_DIR_ENTRY *ent; |
200 ss=s; | 226 ss=s; |
201 s=p+1; | 227 s=p+1; |
202 len=(int)(p-ss); | 228 len=(int)(p-ss); |
203 if (len == 0) continue; | 229 if (len == 0) continue; |
204 » » » for (j=0; j<ctx->num_dirs; j++) | 230 » » » for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) |
205 » » » » if (strlen(ctx->dirs[j]) == (size_t)len && | 231 » » » » { |
206 » » » » strncmp(ctx->dirs[j],ss,(unsigned int)len) =
= 0) | 232 » » » » ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); |
| 233 » » » » if (strlen(ent->dir) == (size_t)len && |
| 234 » » » » strncmp(ent->dir,ss,(unsigned int)len) == 0) |
207 break; | 235 break; |
208 » » » if (j<ctx->num_dirs) | 236 » » » » } |
| 237 » » » if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) |
209 continue; | 238 continue; |
210 » » » if (ctx->num_dirs_alloced < (ctx->num_dirs+1)) | 239 » » » if (ctx->dirs == NULL) |
211 { | 240 { |
212 » » » » ctx->num_dirs_alloced+=10; | 241 » » » » ctx->dirs = sk_BY_DIR_ENTRY_new_null(); |
213 » » » » pp=(char **)OPENSSL_malloc(ctx->num_dirs_alloced
* | 242 » » » » if (!ctx->dirs) |
214 » » » » » sizeof(char *)); | |
215 » » » » ip=(int *)OPENSSL_malloc(ctx->num_dirs_alloced* | |
216 » » » » » sizeof(int)); | |
217 » » » » if ((pp == NULL) || (ip == NULL)) | |
218 { | 243 { |
219 X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC
_FAILURE); | 244 X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC
_FAILURE); |
220 » » » » » return(0); | 245 » » » » » return 0; |
221 } | 246 } |
222 memcpy(pp,ctx->dirs,(ctx->num_dirs_alloced-10)* | |
223 sizeof(char *)); | |
224 memcpy(ip,ctx->dirs_type,(ctx->num_dirs_alloced-
10)* | |
225 sizeof(int)); | |
226 if (ctx->dirs != NULL) | |
227 OPENSSL_free(ctx->dirs); | |
228 if (ctx->dirs_type != NULL) | |
229 OPENSSL_free(ctx->dirs_type); | |
230 ctx->dirs=pp; | |
231 ctx->dirs_type=ip; | |
232 } | 247 } |
233 » » » ctx->dirs_type[ctx->num_dirs]=type; | 248 » » » ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); |
234 » » » ctx->dirs[ctx->num_dirs]=(char *)OPENSSL_malloc((unsigne
d int)len+1); | 249 » » » if (!ent) |
235 » » » if (ctx->dirs[ctx->num_dirs] == NULL) return(0); | 250 » » » » return 0; |
236 » » » strncpy(ctx->dirs[ctx->num_dirs],ss,(unsigned int)len); | 251 » » » ent->dir_type = type; |
237 » » » ctx->dirs[ctx->num_dirs][len]='\0'; | 252 » » » ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); |
238 » » » ctx->num_dirs++; | 253 » » » ent->dir = OPENSSL_malloc((unsigned int)len+1); |
| 254 » » » if (!ent->dir || !ent->hashes) |
| 255 » » » » { |
| 256 » » » » by_dir_entry_free(ent); |
| 257 » » » » return 0; |
| 258 » » » » } |
| 259 » » » strncpy(ent->dir,ss,(unsigned int)len); |
| 260 » » » ent->dir[len] = '\0'; |
| 261 » » » if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) |
| 262 » » » » { |
| 263 » » » » by_dir_entry_free(ent); |
| 264 » » » » return 0; |
| 265 » » » » } |
239 } | 266 } |
240 » » if (*p == '\0') break; | 267 » » if (*p == '\0') |
| 268 » » » break; |
241 } | 269 } |
242 » return(1); | 270 » return 1; |
243 } | 271 } |
244 | 272 |
245 static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, | 273 static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, |
246 X509_OBJECT *ret) | 274 X509_OBJECT *ret) |
247 { | 275 { |
248 BY_DIR *ctx; | 276 BY_DIR *ctx; |
249 union { | 277 union { |
250 struct { | 278 struct { |
251 X509 st_x509; | 279 X509 st_x509; |
252 X509_CINF st_x509_cinf; | 280 X509_CINF st_x509_cinf; |
253 } x509; | 281 } x509; |
254 struct { | 282 struct { |
255 X509_CRL st_crl; | 283 X509_CRL st_crl; |
256 X509_CRL_INFO st_crl_info; | 284 X509_CRL_INFO st_crl_info; |
257 } crl; | 285 } crl; |
258 } data; | 286 } data; |
259 int ok=0; | 287 int ok=0; |
260 int i,j,k; | 288 int i,j,k; |
261 unsigned long h; | 289 unsigned long h; |
| 290 unsigned long hash_array[2]; |
| 291 int hash_index; |
262 BUF_MEM *b=NULL; | 292 BUF_MEM *b=NULL; |
263 struct stat st; | |
264 X509_OBJECT stmp,*tmp; | 293 X509_OBJECT stmp,*tmp; |
265 const char *postfix=""; | 294 const char *postfix=""; |
266 | 295 |
267 if (name == NULL) return(0); | 296 if (name == NULL) return(0); |
268 | 297 |
269 stmp.type=type; | 298 stmp.type=type; |
270 if (type == X509_LU_X509) | 299 if (type == X509_LU_X509) |
271 { | 300 { |
272 data.x509.st_x509.cert_info= &data.x509.st_x509_cinf; | 301 data.x509.st_x509.cert_info= &data.x509.st_x509_cinf; |
273 data.x509.st_x509_cinf.subject=name; | 302 data.x509.st_x509_cinf.subject=name; |
(...skipping 15 matching lines...) Expand all Loading... |
289 | 318 |
290 if ((b=BUF_MEM_new()) == NULL) | 319 if ((b=BUF_MEM_new()) == NULL) |
291 { | 320 { |
292 X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_BUF_LIB); | 321 X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_BUF_LIB); |
293 goto finish; | 322 goto finish; |
294 } | 323 } |
295 | 324 |
296 ctx=(BY_DIR *)xl->method_data; | 325 ctx=(BY_DIR *)xl->method_data; |
297 | 326 |
298 h=X509_NAME_hash(name); | 327 h=X509_NAME_hash(name); |
299 » for (i=0; i<ctx->num_dirs; i++) | 328 » hash_array[0]=h; |
| 329 » hash_array[1]=X509_NAME_hash_old(name); |
| 330 » for (hash_index=0; hash_index < 2; hash_index++) |
300 { | 331 { |
301 » » j=strlen(ctx->dirs[i])+1+8+6+1+1; | 332 » » h=hash_array[hash_index]; |
| 333 » for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) |
| 334 » » { |
| 335 » » BY_DIR_ENTRY *ent; |
| 336 » » int idx; |
| 337 » » BY_DIR_HASH htmp, *hent; |
| 338 » » ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); |
| 339 » » j=strlen(ent->dir)+1+8+6+1+1; |
302 if (!BUF_MEM_grow(b,j)) | 340 if (!BUF_MEM_grow(b,j)) |
303 { | 341 { |
304 X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE)
; | 342 X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE)
; |
305 goto finish; | 343 goto finish; |
306 } | 344 } |
307 » » k=0; | 345 » » if (type == X509_LU_CRL && ent->hashes) |
| 346 » » » { |
| 347 » » » htmp.hash = h; |
| 348 » » » CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); |
| 349 » » » idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); |
| 350 » » » if (idx >= 0) |
| 351 » » » » { |
| 352 » » » » hent = sk_BY_DIR_HASH_value(ent->hashes, idx); |
| 353 » » » » k = hent->suffix; |
| 354 » » » » } |
| 355 » » » else |
| 356 » » » » { |
| 357 » » » » hent = NULL; |
| 358 » » » » k=0; |
| 359 » » » » } |
| 360 » » » CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); |
| 361 » » » } |
| 362 » » else |
| 363 » » » { |
| 364 » » » k = 0; |
| 365 » » » hent = NULL; |
| 366 » » » } |
308 for (;;) | 367 for (;;) |
309 { | 368 { |
310 char c = '/'; | 369 char c = '/'; |
311 #ifdef OPENSSL_SYS_VMS | 370 #ifdef OPENSSL_SYS_VMS |
312 » » » c = ctx->dirs[i][strlen(ctx->dirs[i])-1]; | 371 » » » c = ent->dir[strlen(ent->dir)-1]; |
313 if (c != ':' && c != '>' && c != ']') | 372 if (c != ':' && c != '>' && c != ']') |
314 { | 373 { |
315 /* If no separator is present, we assume the | 374 /* If no separator is present, we assume the |
316 directory specifier is a logical name, and | 375 directory specifier is a logical name, and |
317 add a colon. We really should use better | 376 add a colon. We really should use better |
318 VMS routines for merging things like this, | 377 VMS routines for merging things like this, |
319 but this will do for now... | 378 but this will do for now... |
320 -- Richard Levitte */ | 379 -- Richard Levitte */ |
321 c = ':'; | 380 c = ':'; |
322 } | 381 } |
323 else | 382 else |
324 { | 383 { |
325 c = '\0'; | 384 c = '\0'; |
326 } | 385 } |
327 #endif | 386 #endif |
328 if (c == '\0') | 387 if (c == '\0') |
329 { | 388 { |
330 /* This is special. When c == '\0', no | 389 /* This is special. When c == '\0', no |
331 directory separator should be added. */ | 390 directory separator should be added. */ |
332 BIO_snprintf(b->data,b->max, | 391 BIO_snprintf(b->data,b->max, |
333 » » » » » "%s%08lx.%s%d",ctx->dirs[i],h, | 392 » » » » » "%s%08lx.%s%d",ent->dir,h, |
334 postfix,k); | 393 postfix,k); |
335 } | 394 } |
336 else | 395 else |
337 { | 396 { |
338 BIO_snprintf(b->data,b->max, | 397 BIO_snprintf(b->data,b->max, |
339 » » » » » "%s%c%08lx.%s%d",ctx->dirs[i],c,h, | 398 » » » » » "%s%c%08lx.%s%d",ent->dir,c,h, |
340 postfix,k); | 399 postfix,k); |
341 } | 400 } |
342 » » » k++; | 401 #ifndef OPENSSL_NO_POSIX_IO |
| 402 #ifdef _WIN32 |
| 403 #define stat _stat |
| 404 #endif |
| 405 » » » { |
| 406 » » » struct stat st; |
343 if (stat(b->data,&st) < 0) | 407 if (stat(b->data,&st) < 0) |
344 break; | 408 break; |
| 409 } |
| 410 #endif |
345 /* found one. */ | 411 /* found one. */ |
346 if (type == X509_LU_X509) | 412 if (type == X509_LU_X509) |
347 { | 413 { |
348 if ((X509_load_cert_file(xl,b->data, | 414 if ((X509_load_cert_file(xl,b->data, |
349 » » » » » ctx->dirs_type[i])) == 0) | 415 » » » » » ent->dir_type)) == 0) |
350 break; | 416 break; |
351 } | 417 } |
352 else if (type == X509_LU_CRL) | 418 else if (type == X509_LU_CRL) |
353 { | 419 { |
354 if ((X509_load_crl_file(xl,b->data, | 420 if ((X509_load_crl_file(xl,b->data, |
355 » » » » » ctx->dirs_type[i])) == 0) | 421 » » » » » ent->dir_type)) == 0) |
356 break; | 422 break; |
357 } | 423 } |
358 /* else case will caught higher up */ | 424 /* else case will caught higher up */ |
| 425 k++; |
359 } | 426 } |
360 | 427 |
361 /* we have added it to the cache so now pull | 428 /* we have added it to the cache so now pull |
362 * it out again */ | 429 * it out again */ |
363 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); | 430 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
364 j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp); | 431 j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp); |
365 if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j); | 432 if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j); |
366 else tmp = NULL; | 433 else tmp = NULL; |
367 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); | 434 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
368 | 435 |
| 436 |
| 437 /* If a CRL, update the last file suffix added for this */ |
| 438 |
| 439 if (type == X509_LU_CRL) |
| 440 { |
| 441 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); |
| 442 /* Look for entry again in case another thread added |
| 443 * an entry first. |
| 444 */ |
| 445 if (!hent) |
| 446 { |
| 447 htmp.hash = h; |
| 448 idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); |
| 449 if (idx >= 0) |
| 450 hent = |
| 451 sk_BY_DIR_HASH_value(ent->hashes, idx); |
| 452 } |
| 453 if (!hent) |
| 454 { |
| 455 hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); |
| 456 hent->hash = h; |
| 457 hent->suffix = k; |
| 458 if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) |
| 459 { |
| 460 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 461 OPENSSL_free(hent); |
| 462 ok = 0; |
| 463 goto finish; |
| 464 } |
| 465 } |
| 466 else if (hent->suffix < k) |
| 467 hent->suffix = k; |
| 468 |
| 469 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); |
| 470 |
| 471 } |
| 472 |
369 if (tmp != NULL) | 473 if (tmp != NULL) |
370 { | 474 { |
371 ok=1; | 475 ok=1; |
372 ret->type=tmp->type; | 476 ret->type=tmp->type; |
373 memcpy(&ret->data,&tmp->data,sizeof(ret->data)); | 477 memcpy(&ret->data,&tmp->data,sizeof(ret->data)); |
374 /* If we were going to up the reference count, | 478 /* If we were going to up the reference count, |
375 * we would need to do it on a perl 'type' | 479 * we would need to do it on a perl 'type' |
376 * basis */ | 480 * basis */ |
377 /* CRYPTO_add(&tmp->data.x509->references,1, | 481 /* CRYPTO_add(&tmp->data.x509->references,1, |
378 CRYPTO_LOCK_X509);*/ | 482 CRYPTO_LOCK_X509);*/ |
379 goto finish; | 483 goto finish; |
380 } | 484 } |
381 } | 485 } |
| 486 } |
382 finish: | 487 finish: |
383 if (b != NULL) BUF_MEM_free(b); | 488 if (b != NULL) BUF_MEM_free(b); |
384 return(ok); | 489 return(ok); |
385 } | 490 } |
OLD | NEW |