195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com). 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL. 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to. The following conditions 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA, 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed. 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used. 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package. 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * must display the following acknowledgement: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes cryptographic software written by 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Eric Young (eay@cryptsoft.com)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The word 'cryptographic' can be left out if the rouines from the library 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * being used are not cryptographic related :-). 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the apps directory (application code) you must include an acknowledgement: 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* ==================================================================== 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the above copyright 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the documentation and/or other materials provided with the 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * distribution. 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * software must display the following acknowledgment: 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * endorse or promote products derived from this software without 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * prior written permission. For written permission, please contact 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * openssl-core@openssl.org. 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5. Products derived from this software may not be called "OpenSSL" 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * nor may "OpenSSL" appear in their names without prior written 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * permission of the OpenSSL Project. 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 6. Redistributions of any form whatsoever must retain the following 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * acknowledgment: 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software developed by the OpenSSL Project 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ==================================================================== 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This product includes cryptographic software written by Eric Young 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * (eay@cryptsoft.com). This product includes software written by Tim 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Hudson (tjh@cryptsoft.com). */ 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/err.h> 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <assert.h> 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/lhash.h> 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDEFINE_LHASH_OF(ERR_STATE); 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDEFINE_LHASH_OF(ERR_STRING_DATA); 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* state_hash is a map from thread ID to ERR_STATE. It works like thread-local 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * storage. */ 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic LHASH_OF(ERR_STATE) *state_hash = NULL; 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* error_hash maps from a packed error to the string for that library / 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * function / reason. */ 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic LHASH_OF(ERR_STRING_DATA) *error_hash = NULL; 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1284042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley/* global_next_library contains the next custom library value to return. */ 1294042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langleystatic int global_next_library = ERR_NUM_LIBS; 1304042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* err_string_data_hash is an lhash hash function for ERR_STRING_DATA. */ 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic uint32_t err_string_data_hash(const ERR_STRING_DATA *a) { 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return OPENSSL_hash32(&a->error, sizeof(a->error)); 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* err_string_data_cmp is an lhash compare function for ERR_STRING_DATA. */ 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int err_string_data_cmp(const ERR_STRING_DATA *a, 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ERR_STRING_DATA *b) { 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ((int)a->error) - ((int)b->error); 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* error_hash_get_write_locked returns the hash that maps from packed error to 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * error string and creates it if need be. The caller must hold a write lock on 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LOCK_ERR. */ 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic LHASH_OF(ERR_STRING_DATA) * error_hash_get_write_locked(void) { 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!error_hash) { 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley error_hash = lh_ERR_STRING_DATA_new(err_string_data_hash, err_string_data_cmp); 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return error_hash; 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* err_get_item returns an ERR_STRING_DATA with an |error| member that 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * equals |packed_error|, or NULL if none can be found. */ 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic ERR_STRING_DATA *err_get_item(uint32_t packed_error) { 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ERR_STRING_DATA *ret = NULL, pattern; 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pattern.error = packed_error; 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_ERR); 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (error_hash) { 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = lh_ERR_STRING_DATA_retrieve(error_hash, &pattern); 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* err_set_item adds an ERR_STRING_DATA to the global hash of error strings and 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * returns the previous entry with the same |err->error| value, if any. */ 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic ERR_STRING_DATA *err_set_item(const ERR_STRING_DATA *err) { 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ERR_STRING_DATA *old_item = NULL; 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley LHASH_OF(ERR_STRING_DATA) *hash; 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_ERR); 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley hash = error_hash_get_write_locked(); 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (hash) { 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley lh_ERR_STRING_DATA_insert(hash, &old_item, (ERR_STRING_DATA*) err); 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return old_item; 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* err_set_item removes an item from the global hash of error strings for 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * |packed_error| and returns the removed entry, if any. */ 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic ERR_STRING_DATA *err_del_item(uint32_t packed_error) { 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ERR_STRING_DATA *old_item = NULL, pattern; 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pattern.error = packed_error; 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_ERR); 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (error_hash) { 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley old_item = lh_ERR_STRING_DATA_delete(error_hash, &pattern); 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return old_item; 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* err_state_hash is an lhash hash function for ERR_STATE. */ 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic uint32_t err_state_hash(const ERR_STATE *a) { 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return CRYPTO_THREADID_hash(&a->tid); 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* err_state_cmp is an lhash compare function for ERR_STATE. */ 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) { 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return CRYPTO_THREADID_cmp(&a->tid, &b->tid); 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic ERR_STATE *err_get_state(void) { 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_THREADID tid; 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ERR_STATE pattern, *state, *race_state; 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int insert_result; 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley static ERR_STATE fallback; 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_THREADID_current(&tid); 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(&pattern, 0, sizeof(pattern)); 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_THREADID_cpy(&pattern.tid, &tid); 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_ERR); 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (state_hash == NULL) { 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_ERR); 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (state_hash == NULL) { 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley state_hash = lh_ERR_STATE_new(err_state_hash, err_state_cmp); 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_lock(CRYPTO_LOCK_ERR); 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley state = lh_ERR_STATE_retrieve(state_hash, &pattern); 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (state != NULL) { 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return state; 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley state = OPENSSL_malloc(sizeof(ERR_STATE)); 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (state == NULL) { 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* The other error functions don't cope with a failure to get the error 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * state, so we return a dummy value. */ 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return &fallback; 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(state, 0, sizeof(ERR_STATE)); 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_THREADID_cpy(&state->tid, &tid); 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_ERR); 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley insert_result = lh_ERR_STATE_insert(state_hash, &race_state, state); 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!insert_result) { 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Insertion failed because of malloc failure. */ 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(state); 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return &fallback; 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We cannot have raced with another thread to insert an ERR_STATE because no 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * other thread should be inserting values for this thread. */ 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(race_state == NULL); 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return state; 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26803d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langleystatic ERR_STATE *err_release_state(const CRYPTO_THREADID *tid) { 26903d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley ERR_STATE pattern, *state; 27003d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley 27103d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley CRYPTO_THREADID_cpy(&pattern.tid, tid); 27203d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley 27303d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley CRYPTO_r_lock(CRYPTO_LOCK_ERR); 27403d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley if (state_hash == NULL) { 27503d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 27603d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley return NULL; 27703d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley } 27803d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley 27903d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley state = lh_ERR_STATE_delete(state_hash, &pattern); 28003d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 28103d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley 28203d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley return state; 28303d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley} 28403d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic void err_shutdown(void) { 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_ERR); 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (error_hash) { 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley lh_ERR_STRING_DATA_free(error_hash); 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley error_hash = NULL; 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2944042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langleystatic int err_get_next_library(void) { 2954042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley int ret; 2964042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley 2974042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_ERR); 2984042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley ret = global_next_library++; 2994042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 3004042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley 3014042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley return ret; 3024042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley} 3034042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst struct ERR_FNS_st openssl_err_default_impl = { 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err_shutdown, 30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err_get_item, 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err_set_item, 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err_del_item, 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley err_get_state, 31003d31ed3e49a71e9ea09232d817cb1200b7a9149Adam Langley err_release_state, 3114042667eb90b5619e6ba2d8f6f407cb55f71c05aAdam Langley err_get_next_library, 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 313