LCOV - code coverage report
Current view: top level - err - err.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 329 395 83.3 %
Date: 2014-08-02 Functions: 45 58 77.6 %
Branches: 129 200 64.5 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/err/err.c */
       2                 :            : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3                 :            :  * All rights reserved.
       4                 :            :  *
       5                 :            :  * This package is an SSL implementation written
       6                 :            :  * by Eric Young (eay@cryptsoft.com).
       7                 :            :  * The implementation was written so as to conform with Netscapes SSL.
       8                 :            :  * 
       9                 :            :  * This library is free for commercial and non-commercial use as long as
      10                 :            :  * the following conditions are aheared to.  The following conditions
      11                 :            :  * apply to all code found in this distribution, be it the RC4, RSA,
      12                 :            :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13                 :            :  * included with this distribution is covered by the same copyright terms
      14                 :            :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15                 :            :  * 
      16                 :            :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17                 :            :  * the code are not to be removed.
      18                 :            :  * If this package is used in a product, Eric Young should be given attribution
      19                 :            :  * as the author of the parts of the library used.
      20                 :            :  * This can be in the form of a textual message at program startup or
      21                 :            :  * in documentation (online or textual) provided with the package.
      22                 :            :  * 
      23                 :            :  * Redistribution and use in source and binary forms, with or without
      24                 :            :  * modification, are permitted provided that the following conditions
      25                 :            :  * are met:
      26                 :            :  * 1. Redistributions of source code must retain the copyright
      27                 :            :  *    notice, this list of conditions and the following disclaimer.
      28                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      29                 :            :  *    notice, this list of conditions and the following disclaimer in the
      30                 :            :  *    documentation and/or other materials provided with the distribution.
      31                 :            :  * 3. All advertising materials mentioning features or use of this software
      32                 :            :  *    must display the following acknowledgement:
      33                 :            :  *    "This product includes cryptographic software written by
      34                 :            :  *     Eric Young (eay@cryptsoft.com)"
      35                 :            :  *    The word 'cryptographic' can be left out if the rouines from the library
      36                 :            :  *    being used are not cryptographic related :-).
      37                 :            :  * 4. If you include any Windows specific code (or a derivative thereof) from 
      38                 :            :  *    the apps directory (application code) you must include an acknowledgement:
      39                 :            :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40                 :            :  * 
      41                 :            :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51                 :            :  * SUCH DAMAGE.
      52                 :            :  * 
      53                 :            :  * The licence and distribution terms for any publically available version or
      54                 :            :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55                 :            :  * copied and put under another distribution licence
      56                 :            :  * [including the GNU Public Licence.]
      57                 :            :  */
      58                 :            : /* ====================================================================
      59                 :            :  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
      60                 :            :  *
      61                 :            :  * Redistribution and use in source and binary forms, with or without
      62                 :            :  * modification, are permitted provided that the following conditions
      63                 :            :  * are met:
      64                 :            :  *
      65                 :            :  * 1. Redistributions of source code must retain the above copyright
      66                 :            :  *    notice, this list of conditions and the following disclaimer. 
      67                 :            :  *
      68                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      69                 :            :  *    notice, this list of conditions and the following disclaimer in
      70                 :            :  *    the documentation and/or other materials provided with the
      71                 :            :  *    distribution.
      72                 :            :  *
      73                 :            :  * 3. All advertising materials mentioning features or use of this
      74                 :            :  *    software must display the following acknowledgment:
      75                 :            :  *    "This product includes software developed by the OpenSSL Project
      76                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      77                 :            :  *
      78                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      79                 :            :  *    endorse or promote products derived from this software without
      80                 :            :  *    prior written permission. For written permission, please contact
      81                 :            :  *    openssl-core@openssl.org.
      82                 :            :  *
      83                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      84                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      85                 :            :  *    permission of the OpenSSL Project.
      86                 :            :  *
      87                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      88                 :            :  *    acknowledgment:
      89                 :            :  *    "This product includes software developed by the OpenSSL Project
      90                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      91                 :            :  *
      92                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      93                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      94                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      95                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      96                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      97                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      98                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      99                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     100                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     101                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     102                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     103                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
     104                 :            :  * ====================================================================
     105                 :            :  *
     106                 :            :  * This product includes cryptographic software written by Eric Young
     107                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
     108                 :            :  * Hudson (tjh@cryptsoft.com).
     109                 :            :  *
     110                 :            :  */
     111                 :            : 
     112                 :            : #define OPENSSL_NO_FIPS_ERR
     113                 :            : 
     114                 :            : #include <stdio.h>
     115                 :            : #include <stdarg.h>
     116                 :            : #include <string.h>
     117                 :            : #include "cryptlib.h"
     118                 :            : #include <openssl/lhash.h>
     119                 :            : #include <openssl/crypto.h>
     120                 :            : #include <openssl/buffer.h>
     121                 :            : #include <openssl/bio.h>
     122                 :            : #include <openssl/err.h>
     123                 :            : 
     124                 :            : DECLARE_LHASH_OF(ERR_STRING_DATA);
     125                 :            : DECLARE_LHASH_OF(ERR_STATE);
     126                 :            : 
     127                 :            : static void err_load_strings(int lib, ERR_STRING_DATA *str);
     128                 :            : 
     129                 :            : static void ERR_STATE_free(ERR_STATE *s);
     130                 :            : #ifndef OPENSSL_NO_ERR
     131                 :            : static ERR_STRING_DATA ERR_str_libraries[]=
     132                 :            :         {
     133                 :            : {ERR_PACK(ERR_LIB_NONE,0,0)             ,"unknown library"},
     134                 :            : {ERR_PACK(ERR_LIB_SYS,0,0)              ,"system library"},
     135                 :            : {ERR_PACK(ERR_LIB_BN,0,0)               ,"bignum routines"},
     136                 :            : {ERR_PACK(ERR_LIB_RSA,0,0)              ,"rsa routines"},
     137                 :            : {ERR_PACK(ERR_LIB_DH,0,0)               ,"Diffie-Hellman routines"},
     138                 :            : {ERR_PACK(ERR_LIB_EVP,0,0)              ,"digital envelope routines"},
     139                 :            : {ERR_PACK(ERR_LIB_BUF,0,0)              ,"memory buffer routines"},
     140                 :            : {ERR_PACK(ERR_LIB_OBJ,0,0)              ,"object identifier routines"},
     141                 :            : {ERR_PACK(ERR_LIB_PEM,0,0)              ,"PEM routines"},
     142                 :            : {ERR_PACK(ERR_LIB_DSA,0,0)              ,"dsa routines"},
     143                 :            : {ERR_PACK(ERR_LIB_X509,0,0)             ,"x509 certificate routines"},
     144                 :            : {ERR_PACK(ERR_LIB_ASN1,0,0)             ,"asn1 encoding routines"},
     145                 :            : {ERR_PACK(ERR_LIB_CONF,0,0)             ,"configuration file routines"},
     146                 :            : {ERR_PACK(ERR_LIB_CRYPTO,0,0)           ,"common libcrypto routines"},
     147                 :            : {ERR_PACK(ERR_LIB_EC,0,0)               ,"elliptic curve routines"},
     148                 :            : {ERR_PACK(ERR_LIB_ECDSA,0,0)            ,"ECDSA routines"},
     149                 :            : {ERR_PACK(ERR_LIB_ECDH,0,0)             ,"ECDH routines"},
     150                 :            : {ERR_PACK(ERR_LIB_SSL,0,0)              ,"SSL routines"},
     151                 :            : {ERR_PACK(ERR_LIB_BIO,0,0)              ,"BIO routines"},
     152                 :            : {ERR_PACK(ERR_LIB_PKCS7,0,0)            ,"PKCS7 routines"},
     153                 :            : {ERR_PACK(ERR_LIB_X509V3,0,0)           ,"X509 V3 routines"},
     154                 :            : {ERR_PACK(ERR_LIB_PKCS12,0,0)           ,"PKCS12 routines"},
     155                 :            : {ERR_PACK(ERR_LIB_RAND,0,0)             ,"random number generator"},
     156                 :            : {ERR_PACK(ERR_LIB_DSO,0,0)              ,"DSO support routines"},
     157                 :            : {ERR_PACK(ERR_LIB_TS,0,0)               ,"time stamp routines"},
     158                 :            : {ERR_PACK(ERR_LIB_ENGINE,0,0)           ,"engine routines"},
     159                 :            : {ERR_PACK(ERR_LIB_OCSP,0,0)             ,"OCSP routines"},
     160                 :            : {ERR_PACK(ERR_LIB_FIPS,0,0)             ,"FIPS routines"},
     161                 :            : {ERR_PACK(ERR_LIB_CMS,0,0)              ,"CMS routines"},
     162                 :            : {ERR_PACK(ERR_LIB_HMAC,0,0)             ,"HMAC routines"},
     163                 :            : {0,NULL},
     164                 :            :         };
     165                 :            : 
     166                 :            : static ERR_STRING_DATA ERR_str_functs[]=
     167                 :            :         {
     168                 :            :         {ERR_PACK(0,SYS_F_FOPEN,0),             "fopen"},
     169                 :            :         {ERR_PACK(0,SYS_F_CONNECT,0),           "connect"},
     170                 :            :         {ERR_PACK(0,SYS_F_GETSERVBYNAME,0),     "getservbyname"},
     171                 :            :         {ERR_PACK(0,SYS_F_SOCKET,0),            "socket"}, 
     172                 :            :         {ERR_PACK(0,SYS_F_IOCTLSOCKET,0),       "ioctlsocket"},
     173                 :            :         {ERR_PACK(0,SYS_F_BIND,0),              "bind"},
     174                 :            :         {ERR_PACK(0,SYS_F_LISTEN,0),            "listen"},
     175                 :            :         {ERR_PACK(0,SYS_F_ACCEPT,0),            "accept"},
     176                 :            : #ifdef OPENSSL_SYS_WINDOWS
     177                 :            :         {ERR_PACK(0,SYS_F_WSASTARTUP,0),        "WSAstartup"},
     178                 :            : #endif
     179                 :            :         {ERR_PACK(0,SYS_F_OPENDIR,0),           "opendir"},
     180                 :            :         {ERR_PACK(0,SYS_F_FREAD,0),             "fread"},
     181                 :            :         {0,NULL},
     182                 :            :         };
     183                 :            : 
     184                 :            : static ERR_STRING_DATA ERR_str_reasons[]=
     185                 :            :         {
     186                 :            : {ERR_R_SYS_LIB                          ,"system lib"},
     187                 :            : {ERR_R_BN_LIB                           ,"BN lib"},
     188                 :            : {ERR_R_RSA_LIB                          ,"RSA lib"},
     189                 :            : {ERR_R_DH_LIB                           ,"DH lib"},
     190                 :            : {ERR_R_EVP_LIB                          ,"EVP lib"},
     191                 :            : {ERR_R_BUF_LIB                          ,"BUF lib"},
     192                 :            : {ERR_R_OBJ_LIB                          ,"OBJ lib"},
     193                 :            : {ERR_R_PEM_LIB                          ,"PEM lib"},
     194                 :            : {ERR_R_DSA_LIB                          ,"DSA lib"},
     195                 :            : {ERR_R_X509_LIB                         ,"X509 lib"},
     196                 :            : {ERR_R_ASN1_LIB                         ,"ASN1 lib"},
     197                 :            : {ERR_R_CONF_LIB                         ,"CONF lib"},
     198                 :            : {ERR_R_CRYPTO_LIB                       ,"CRYPTO lib"},
     199                 :            : {ERR_R_EC_LIB                           ,"EC lib"},
     200                 :            : {ERR_R_SSL_LIB                          ,"SSL lib"},
     201                 :            : {ERR_R_BIO_LIB                          ,"BIO lib"},
     202                 :            : {ERR_R_PKCS7_LIB                        ,"PKCS7 lib"},
     203                 :            : {ERR_R_X509V3_LIB                       ,"X509V3 lib"},
     204                 :            : {ERR_R_PKCS12_LIB                       ,"PKCS12 lib"},
     205                 :            : {ERR_R_RAND_LIB                         ,"RAND lib"},
     206                 :            : {ERR_R_DSO_LIB                          ,"DSO lib"},
     207                 :            : {ERR_R_ENGINE_LIB                       ,"ENGINE lib"},
     208                 :            : {ERR_R_OCSP_LIB                         ,"OCSP lib"},
     209                 :            : {ERR_R_TS_LIB                           ,"TS lib"},
     210                 :            : {ERR_R_ECDSA_LIB                        ,"ECDSA lib"},
     211                 :            : 
     212                 :            : {ERR_R_NESTED_ASN1_ERROR                ,"nested asn1 error"},
     213                 :            : {ERR_R_BAD_ASN1_OBJECT_HEADER           ,"bad asn1 object header"},
     214                 :            : {ERR_R_BAD_GET_ASN1_OBJECT_CALL         ,"bad get asn1 object call"},
     215                 :            : {ERR_R_EXPECTING_AN_ASN1_SEQUENCE       ,"expecting an asn1 sequence"},
     216                 :            : {ERR_R_ASN1_LENGTH_MISMATCH             ,"asn1 length mismatch"},
     217                 :            : {ERR_R_MISSING_ASN1_EOS                 ,"missing asn1 eos"},
     218                 :            : 
     219                 :            : {ERR_R_FATAL                            ,"fatal"},
     220                 :            : {ERR_R_MALLOC_FAILURE                   ,"malloc failure"},
     221                 :            : {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED      ,"called a function you should not call"},
     222                 :            : {ERR_R_PASSED_NULL_PARAMETER            ,"passed a null parameter"},
     223                 :            : {ERR_R_INTERNAL_ERROR                   ,"internal error"},
     224                 :            : {ERR_R_DISABLED                         ,"called a function that was disabled at compile-time"},
     225                 :            : 
     226                 :            : {0,NULL},
     227                 :            :         };
     228                 :            : #endif
     229                 :            : 
     230                 :            : 
     231                 :            : /* Define the predeclared (but externally opaque) "ERR_FNS" type */
     232                 :            : struct st_ERR_FNS
     233                 :            :         {
     234                 :            :         /* Works on the "error_hash" string table */
     235                 :            :         LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
     236                 :            :         void (*cb_err_del)(void);
     237                 :            :         ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
     238                 :            :         ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
     239                 :            :         ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
     240                 :            :         /* Works on the "thread_hash" error-state table */
     241                 :            :         LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
     242                 :            :         void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
     243                 :            :         ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
     244                 :            :         ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
     245                 :            :         void (*cb_thread_del_item)(const ERR_STATE *);
     246                 :            :         /* Returns the next available error "library" numbers */
     247                 :            :         int (*cb_get_next_lib)(void);
     248                 :            :         };
     249                 :            : 
     250                 :            : /* Predeclarations of the "err_defaults" functions */
     251                 :            : static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
     252                 :            : static void int_err_del(void);
     253                 :            : static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
     254                 :            : static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
     255                 :            : static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
     256                 :            : static LHASH_OF(ERR_STATE) *int_thread_get(int create);
     257                 :            : static void int_thread_release(LHASH_OF(ERR_STATE) **hash);
     258                 :            : static ERR_STATE *int_thread_get_item(const ERR_STATE *);
     259                 :            : static ERR_STATE *int_thread_set_item(ERR_STATE *);
     260                 :            : static void int_thread_del_item(const ERR_STATE *);
     261                 :            : static int int_err_get_next_lib(void);
     262                 :            : /* The static ERR_FNS table using these defaults functions */
     263                 :            : static const ERR_FNS err_defaults =
     264                 :            :         {
     265                 :            :         int_err_get,
     266                 :            :         int_err_del,
     267                 :            :         int_err_get_item,
     268                 :            :         int_err_set_item,
     269                 :            :         int_err_del_item,
     270                 :            :         int_thread_get,
     271                 :            :         int_thread_release,
     272                 :            :         int_thread_get_item,
     273                 :            :         int_thread_set_item,
     274                 :            :         int_thread_del_item,
     275                 :            :         int_err_get_next_lib
     276                 :            :         };
     277                 :            : 
     278                 :            : /* The replacable table of ERR_FNS functions we use at run-time */
     279                 :            : static const ERR_FNS *err_fns = NULL;
     280                 :            : 
     281                 :            : /* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
     282                 :            : #define ERRFN(a) err_fns->cb_##a
     283                 :            : 
     284                 :            : /* The internal state used by "err_defaults" - as such, the setting, reading,
     285                 :            :  * creating, and deleting of this data should only be permitted via the
     286                 :            :  * "err_defaults" functions. This way, a linked module can completely defer all
     287                 :            :  * ERR state operation (together with requisite locking) to the implementations
     288                 :            :  * and state in the loading application. */
     289                 :            : static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
     290                 :            : static LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
     291                 :            : static int int_thread_hash_references = 0;
     292                 :            : static int int_err_library_number= ERR_LIB_USER;
     293                 :            : 
     294                 :            : /* Internal function that checks whether "err_fns" is set and if not, sets it to
     295                 :            :  * the defaults. */
     296                 :   27189092 : static void err_fns_check(void)
     297                 :            :         {
     298         [ +  + ]:   27189092 :         if (err_fns) return;
     299                 :            :         
     300                 :       1633 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     301         [ +  - ]:       1633 :         if (!err_fns)
     302                 :       1633 :                 err_fns = &err_defaults;
     303                 :       1633 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     304                 :            :         }
     305                 :            : 
     306                 :            : /* API functions to get or set the underlying ERR functions. */
     307                 :            : 
     308                 :          0 : const ERR_FNS *ERR_get_implementation(void)
     309                 :            :         {
     310                 :          0 :         err_fns_check();
     311                 :          0 :         return err_fns;
     312                 :            :         }
     313                 :            : 
     314                 :          0 : int ERR_set_implementation(const ERR_FNS *fns)
     315                 :            :         {
     316                 :          0 :         int ret = 0;
     317                 :            : 
     318                 :          0 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     319                 :            :         /* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
     320                 :            :          * an error is there?! */
     321         [ #  # ]:          0 :         if (!err_fns)
     322                 :            :                 {
     323                 :          0 :                 err_fns = fns;
     324                 :          0 :                 ret = 1;
     325                 :            :                 }
     326                 :          0 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     327                 :          0 :         return ret;
     328                 :            :         }
     329                 :            : 
     330                 :            : /* These are the callbacks provided to "lh_new()" when creating the LHASH tables
     331                 :            :  * internal to the "err_defaults" implementation. */
     332                 :            : 
     333                 :            : static unsigned long get_error_values(int inc,int top,const char **file,int *line,
     334                 :            :                                       const char **data,int *flags);
     335                 :            : 
     336                 :            : /* The internal functions used in the "err_defaults" implementation */
     337                 :            : 
     338                 :   52365328 : static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
     339                 :            :         {
     340                 :            :         unsigned long ret,l;
     341                 :            : 
     342                 :   26182664 :         l=a->error;
     343                 :   26182664 :         ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
     344                 :   26182664 :         return(ret^ret%19*13);
     345                 :            :         }
     346                 :   52365328 : static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
     347                 :            : 
     348                 :   46910488 : static int err_string_data_cmp(const ERR_STRING_DATA *a,
     349                 :            :                                const ERR_STRING_DATA *b)
     350                 :            :         {
     351                 :   23455244 :         return (int)(a->error - b->error);
     352                 :            :         }
     353                 :   46910488 : static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
     354                 :            : 
     355                 :   26182665 : static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
     356                 :            :         {
     357                 :   26182665 :         LHASH_OF(ERR_STRING_DATA) *ret = NULL;
     358                 :            : 
     359                 :   26182665 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     360 [ +  + ][ +  + ]:   26182665 :         if (!int_error_hash && create)
     361                 :            :                 {
     362                 :       1628 :                 CRYPTO_push_info("int_err_get (err.c)");
     363                 :       1628 :                 int_error_hash = lh_ERR_STRING_DATA_new();
     364                 :       1628 :                 CRYPTO_pop_info();
     365                 :            :                 }
     366         [ +  + ]:   26182665 :         if (int_error_hash)
     367                 :   26182664 :                 ret = int_error_hash;
     368                 :   26182665 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     369                 :            : 
     370                 :   26182665 :         return ret;
     371                 :            :         }
     372                 :            : 
     373                 :       1627 : static void int_err_del(void)
     374                 :            :         {
     375                 :       1627 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     376         [ +  + ]:       1627 :         if (int_error_hash)
     377                 :            :                 {
     378                 :       1626 :                 lh_ERR_STRING_DATA_free(int_error_hash);
     379                 :       1626 :                 int_error_hash = NULL;
     380                 :            :                 }
     381                 :       1627 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     382                 :       1627 :         }
     383                 :            : 
     384                 :      51394 : static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
     385                 :            :         {
     386                 :            :         ERR_STRING_DATA *p;
     387                 :            :         LHASH_OF(ERR_STRING_DATA) *hash;
     388                 :            : 
     389                 :      51394 :         err_fns_check();
     390                 :      51394 :         hash = ERRFN(err_get)(0);
     391         [ +  + ]:      51394 :         if (!hash)
     392                 :            :                 return NULL;
     393                 :            : 
     394                 :      51393 :         CRYPTO_r_lock(CRYPTO_LOCK_ERR);
     395                 :      51393 :         p = lh_ERR_STRING_DATA_retrieve(hash, d);
     396                 :      51393 :         CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
     397                 :            : 
     398                 :      51393 :         return p;
     399                 :            :         }
     400                 :            : 
     401                 :   26017859 : static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
     402                 :            :         {
     403                 :            :         ERR_STRING_DATA *p;
     404                 :            :         LHASH_OF(ERR_STRING_DATA) *hash;
     405                 :            : 
     406                 :   26017859 :         err_fns_check();
     407                 :   26017859 :         hash = ERRFN(err_get)(1);
     408         [ +  - ]:   26017859 :         if (!hash)
     409                 :            :                 return NULL;
     410                 :            : 
     411                 :   26017859 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     412                 :   26017859 :         p = lh_ERR_STRING_DATA_insert(hash, d);
     413                 :   26017859 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     414                 :            : 
     415                 :   26017859 :         return p;
     416                 :            :         }
     417                 :            : 
     418                 :     113412 : static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
     419                 :            :         {
     420                 :            :         ERR_STRING_DATA *p;
     421                 :            :         LHASH_OF(ERR_STRING_DATA) *hash;
     422                 :            : 
     423                 :     113412 :         err_fns_check();
     424                 :     113412 :         hash = ERRFN(err_get)(0);
     425         [ +  - ]:     113412 :         if (!hash)
     426                 :            :                 return NULL;
     427                 :            : 
     428                 :     113412 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     429                 :     113412 :         p = lh_ERR_STRING_DATA_delete(hash, d);
     430                 :     113412 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     431                 :            : 
     432                 :     113412 :         return p;
     433                 :            :         }
     434                 :            : 
     435                 :     418922 : static unsigned long err_state_hash(const ERR_STATE *a)
     436                 :            :         {
     437                 :     418922 :         return CRYPTO_THREADID_hash(&a->tid) * 13;
     438                 :            :         }
     439                 :     837844 : static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
     440                 :            : 
     441                 :     417294 : static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
     442                 :            :         {
     443                 :     417294 :         return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
     444                 :            :         }
     445                 :     834588 : static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
     446                 :            : 
     447                 :     420555 : static LHASH_OF(ERR_STATE) *int_thread_get(int create)
     448                 :            :         {
     449                 :     420555 :         LHASH_OF(ERR_STATE) *ret = NULL;
     450                 :            : 
     451                 :     420555 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     452 [ +  + ][ +  + ]:     420555 :         if (!int_thread_hash && create)
     453                 :            :                 {
     454                 :       1628 :                 CRYPTO_push_info("int_thread_get (err.c)");
     455                 :       1628 :                 int_thread_hash = lh_ERR_STATE_new();
     456                 :       1628 :                 CRYPTO_pop_info();
     457                 :            :                 }
     458         [ +  + ]:     420555 :         if (int_thread_hash)
     459                 :            :                 {
     460                 :     418922 :                 int_thread_hash_references++;
     461                 :     418922 :                 ret = int_thread_hash;
     462                 :            :                 }
     463                 :     420555 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     464                 :     420555 :         return ret;
     465                 :            :         }
     466                 :            : 
     467                 :     418922 : static void int_thread_release(LHASH_OF(ERR_STATE) **hash)
     468                 :            :         {
     469                 :            :         int i;
     470                 :            : 
     471 [ +  - ][ +  - ]:     418922 :         if (hash == NULL || *hash == NULL)
     472                 :            :                 return;
     473                 :            : 
     474                 :     418922 :         i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
     475                 :            : 
     476                 :            : #ifdef REF_PRINT
     477                 :            :         fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
     478                 :            : #endif
     479         [ +  - ]:     418922 :         if (i > 0) return;
     480                 :            : #ifdef REF_CHECK
     481                 :            :         if (i < 0)
     482                 :            :                 {
     483                 :            :                 fprintf(stderr,"int_thread_release, bad reference count\n");
     484                 :            :                 abort(); /* ok */
     485                 :            :                 }
     486                 :            : #endif
     487                 :     418922 :         *hash = NULL;
     488                 :            :         }
     489                 :            : 
     490                 :     417297 : static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
     491                 :            :         {
     492                 :            :         ERR_STATE *p;
     493                 :            :         LHASH_OF(ERR_STATE) *hash;
     494                 :            : 
     495                 :     417297 :         err_fns_check();
     496                 :     417297 :         hash = ERRFN(thread_get)(0);
     497         [ +  + ]:     417297 :         if (!hash)
     498                 :            :                 return NULL;
     499                 :            : 
     500                 :     415669 :         CRYPTO_r_lock(CRYPTO_LOCK_ERR);
     501                 :     415669 :         p = lh_ERR_STATE_retrieve(hash, d);
     502                 :     415669 :         CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
     503                 :            : 
     504                 :     415669 :         ERRFN(thread_release)(&hash);
     505                 :     415669 :         return p;
     506                 :            :         }
     507                 :            : 
     508                 :       1628 : static ERR_STATE *int_thread_set_item(ERR_STATE *d)
     509                 :            :         {
     510                 :            :         ERR_STATE *p;
     511                 :            :         LHASH_OF(ERR_STATE) *hash;
     512                 :            : 
     513                 :       1628 :         err_fns_check();
     514                 :       1628 :         hash = ERRFN(thread_get)(1);
     515         [ +  - ]:       1628 :         if (!hash)
     516                 :            :                 return NULL;
     517                 :            : 
     518                 :       1628 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     519                 :       1628 :         p = lh_ERR_STATE_insert(hash, d);
     520                 :       1628 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     521                 :            : 
     522                 :       1628 :         ERRFN(thread_release)(&hash);
     523                 :       1628 :         return p;
     524                 :            :         }
     525                 :            : 
     526                 :       1630 : static void int_thread_del_item(const ERR_STATE *d)
     527                 :            :         {
     528                 :            :         ERR_STATE *p;
     529                 :            :         LHASH_OF(ERR_STATE) *hash;
     530                 :            : 
     531                 :       1630 :         err_fns_check();
     532                 :       1630 :         hash = ERRFN(thread_get)(0);
     533         [ +  + ]:       1630 :         if (!hash)
     534                 :          5 :                 return;
     535                 :            : 
     536                 :       1625 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     537                 :       1625 :         p = lh_ERR_STATE_delete(hash, d);
     538                 :            :         /* make sure we don't leak memory */
     539         [ +  - ]:       1625 :         if (int_thread_hash_references == 1
     540 [ +  - ][ +  - ]:       1625 :             && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0)
     541                 :            :                 {
     542                 :       1625 :                 lh_ERR_STATE_free(int_thread_hash);
     543                 :       1625 :                 int_thread_hash = NULL;
     544                 :            :                 }
     545                 :       1625 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     546                 :            : 
     547                 :       1625 :         ERRFN(thread_release)(&hash);
     548         [ +  - ]:       1625 :         if (p)
     549                 :       1625 :                 ERR_STATE_free(p);
     550                 :            :         }
     551                 :            : 
     552                 :       6552 : static int int_err_get_next_lib(void)
     553                 :            :         {
     554                 :            :         int ret;
     555                 :            : 
     556                 :       6552 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     557                 :       6552 :         ret = int_err_library_number++;
     558                 :       6552 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     559                 :            : 
     560                 :       6552 :         return ret;
     561                 :            :         }
     562                 :            : 
     563                 :            : 
     564                 :            : #ifndef OPENSSL_NO_ERR
     565                 :            : #define NUM_SYS_STR_REASONS 127
     566                 :            : #define LEN_SYS_STR_REASON 32
     567                 :            : 
     568                 :            : static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
     569                 :            : /* SYS_str_reasons is filled with copies of strerror() results at
     570                 :            :  * initialization.
     571                 :            :  * 'errno' values up to 127 should cover all usual errors,
     572                 :            :  * others will be displayed numerically by ERR_error_string.
     573                 :            :  * It is crucial that we have something for each reason code
     574                 :            :  * that occurs in ERR_str_reasons, or bogus reason strings
     575                 :            :  * will be returned for SYSerr(), which always gets an errno
     576                 :            :  * value and never one of those 'standard' reason codes. */
     577                 :            : 
     578                 :     109025 : static void build_SYS_str_reasons(void)
     579                 :            :         {
     580                 :            :         /* OPENSSL_malloc cannot be used here, use static storage instead */
     581                 :            :         static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
     582                 :            :         int i;
     583                 :            :         static int init = 1;
     584                 :            : 
     585                 :     109025 :         CRYPTO_r_lock(CRYPTO_LOCK_ERR);
     586         [ +  + ]:     109025 :         if (!init)
     587                 :            :                 {
     588                 :     107397 :                 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
     589                 :     107397 :                 return;
     590                 :            :                 }
     591                 :            :         
     592                 :       1628 :         CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
     593                 :       1628 :         CRYPTO_w_lock(CRYPTO_LOCK_ERR);
     594         [ +  - ]:       1628 :         if (!init)
     595                 :            :                 {
     596                 :          0 :                 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     597                 :          0 :                 return;
     598                 :            :                 }
     599                 :            : 
     600         [ +  + ]:     208384 :         for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
     601                 :            :                 {
     602                 :     206756 :                 ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
     603                 :            : 
     604                 :     206756 :                 str->error = (unsigned long)i;
     605         [ +  - ]:     206756 :                 if (str->string == NULL)
     606                 :            :                         {
     607                 :     206756 :                         char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
     608                 :     206756 :                         char *src = strerror(i);
     609         [ +  - ]:     206756 :                         if (src != NULL)
     610                 :            :                                 {
     611                 :            :                                 strncpy(*dest, src, sizeof *dest);
     612                 :     206756 :                                 (*dest)[sizeof *dest - 1] = '\0';
     613                 :     206756 :                                 str->string = *dest;
     614                 :            :                                 }
     615                 :            :                         }
     616         [ -  + ]:     206756 :                 if (str->string == NULL)
     617                 :          0 :                         str->string = "unknown";
     618                 :            :                 }
     619                 :            : 
     620                 :            :         /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
     621                 :            :          * as required by ERR_load_strings. */
     622                 :            : 
     623                 :       1628 :         init = 0;
     624                 :            :         
     625                 :       1628 :         CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
     626                 :            :         }
     627                 :            : #endif
     628                 :            : 
     629                 :            : #define err_clear_data(p,i) \
     630                 :            :         do { \
     631                 :            :         if (((p)->err_data[i] != NULL) && \
     632                 :            :                 (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
     633                 :            :                 {  \
     634                 :            :                 OPENSSL_free((p)->err_data[i]); \
     635                 :            :                 (p)->err_data[i]=NULL; \
     636                 :            :                 } \
     637                 :            :         (p)->err_data_flags[i]=0; \
     638                 :            :         } while(0)
     639                 :            : 
     640                 :            : #define err_clear(p,i) \
     641                 :            :         do { \
     642                 :            :         (p)->err_flags[i]=0; \
     643                 :            :         (p)->err_buffer[i]=0; \
     644                 :            :         err_clear_data(p,i); \
     645                 :            :         (p)->err_file[i]=NULL; \
     646                 :            :         (p)->err_line[i]= -1; \
     647                 :            :         } while(0)
     648                 :            : 
     649                 :       1625 : static void ERR_STATE_free(ERR_STATE *s)
     650                 :            :         {
     651                 :            :         int i;
     652                 :            : 
     653         [ +  - ]:       1625 :         if (s == NULL)
     654                 :       1625 :             return;
     655                 :            : 
     656         [ +  + ]:      27625 :         for (i=0; i<ERR_NUM_ERRORS; i++)
     657                 :            :                 {
     658 [ +  + ][ +  - ]:      26000 :                 err_clear_data(s,i);
     659                 :            :                 }
     660                 :       1625 :         OPENSSL_free(s);
     661                 :            :         }
     662                 :            : 
     663                 :     109025 : void ERR_load_ERR_strings(void)
     664                 :            :         {
     665                 :     109025 :         err_fns_check();
     666                 :            : #ifndef OPENSSL_NO_ERR
     667                 :     109025 :         err_load_strings(0,ERR_str_libraries);
     668                 :     109025 :         err_load_strings(0,ERR_str_reasons);
     669                 :     109025 :         err_load_strings(ERR_LIB_SYS,ERR_str_functs);
     670                 :     109025 :         build_SYS_str_reasons();
     671                 :     109025 :         err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
     672                 :            : #endif
     673                 :     109025 :         }
     674                 :            : 
     675                 :     543272 : static void err_load_strings(int lib, ERR_STRING_DATA *str)
     676                 :            :         {
     677         [ +  + ]:   26561131 :         while (str->error)
     678                 :            :                 {
     679         [ +  + ]:   26017859 :                 if (lib)
     680                 :   15100953 :                         str->error|=ERR_PACK(lib,0,0);
     681                 :   26017859 :                 ERRFN(err_set_item)(str);
     682                 :   26017859 :                 str++;
     683                 :            :                 }
     684                 :     543272 :         }
     685                 :            : 
     686                 :     107172 : void ERR_load_strings(int lib, ERR_STRING_DATA *str)
     687                 :            :         {
     688                 :     107172 :         ERR_load_ERR_strings();
     689                 :     107172 :         err_load_strings(lib, str);
     690                 :     107172 :         }
     691                 :            : 
     692                 :      15994 : void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
     693                 :            :         {
     694         [ +  + ]:     129406 :         while (str->error)
     695                 :            :                 {
     696         [ +  + ]:     113412 :                 if (lib)
     697                 :     109050 :                         str->error|=ERR_PACK(lib,0,0);
     698                 :     113412 :                 ERRFN(err_del_item)(str);
     699                 :     113412 :                 str++;
     700                 :            :                 }
     701                 :      15994 :         }
     702                 :            : 
     703                 :       1627 : void ERR_free_strings(void)
     704                 :            :         {
     705                 :       1627 :         err_fns_check();
     706                 :       1627 :         ERRFN(err_del)();
     707                 :       1627 :         }
     708                 :            : 
     709                 :            : /********************************************************/
     710                 :            : 
     711                 :     140418 : void ERR_put_error(int lib, int func, int reason, const char *file,
     712                 :            :              int line)
     713                 :            :         {
     714                 :            :         ERR_STATE *es;
     715                 :            : 
     716                 :            : #ifdef _OSD_POSIX
     717                 :            :         /* In the BS2000-OSD POSIX subsystem, the compiler generates
     718                 :            :          * path names in the form "*POSIX(/etc/passwd)".
     719                 :            :          * This dirty hack strips them to something sensible.
     720                 :            :          * @@@ We shouldn't modify a const string, though.
     721                 :            :          */
     722                 :            :         if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
     723                 :            :                 char *end;
     724                 :            : 
     725                 :            :                 /* Skip the "*POSIX(" prefix */
     726                 :            :                 file += sizeof("*POSIX(")-1;
     727                 :            :                 end = &file[strlen(file)-1];
     728                 :            :                 if (*end == ')')
     729                 :            :                         *end = '\0';
     730                 :            :                 /* Optional: use the basename of the path only. */
     731                 :            :                 if ((end = strrchr(file, '/')) != NULL)
     732                 :            :                         file = &end[1];
     733                 :            :         }
     734                 :            : #endif
     735                 :     140418 :         es=ERR_get_state();
     736                 :            : 
     737                 :     140418 :         es->top=(es->top+1)%ERR_NUM_ERRORS;
     738         [ +  + ]:     140418 :         if (es->top == es->bottom)
     739                 :     125641 :                 es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
     740                 :     140418 :         es->err_flags[es->top]=0;
     741                 :     140418 :         es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
     742                 :     140418 :         es->err_file[es->top]=file;
     743                 :     140418 :         es->err_line[es->top]=line;
     744 [ +  + ][ +  - ]:     140418 :         err_clear_data(es,es->top);
     745                 :     140418 :         }
     746                 :            : 
     747                 :      89408 : void ERR_clear_error(void)
     748                 :            :         {
     749                 :            :         int i;
     750                 :            :         ERR_STATE *es;
     751                 :            : 
     752                 :      89408 :         es=ERR_get_state();
     753                 :            : 
     754         [ +  + ]:    1519936 :         for (i=0; i<ERR_NUM_ERRORS; i++)
     755                 :            :                 {
     756 [ +  + ][ +  - ]:    1430528 :                 err_clear(es,i);
     757                 :            :                 }
     758                 :      89408 :         es->top=es->bottom=0;
     759                 :      89408 :         }
     760                 :            : 
     761                 :            : 
     762                 :          0 : unsigned long ERR_get_error(void)
     763                 :          0 :         { return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }
     764                 :            : 
     765                 :          0 : unsigned long ERR_get_error_line(const char **file,
     766                 :            :              int *line)
     767                 :          0 :         { return(get_error_values(1,0,file,line,NULL,NULL)); }
     768                 :            : 
     769                 :       1997 : unsigned long ERR_get_error_line_data(const char **file, int *line,
     770                 :            :              const char **data, int *flags)
     771                 :       1997 :         { return(get_error_values(1,0,file,line,data,flags)); }
     772                 :            : 
     773                 :            : 
     774                 :      87234 : unsigned long ERR_peek_error(void)
     775                 :      87234 :         { return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }
     776                 :            : 
     777                 :          0 : unsigned long ERR_peek_error_line(const char **file, int *line)
     778                 :          0 :         { return(get_error_values(0,0,file,line,NULL,NULL)); }
     779                 :            : 
     780                 :          0 : unsigned long ERR_peek_error_line_data(const char **file, int *line,
     781                 :            :              const char **data, int *flags)
     782                 :          0 :         { return(get_error_values(0,0,file,line,data,flags)); }
     783                 :            : 
     784                 :            : 
     785                 :        652 : unsigned long ERR_peek_last_error(void)
     786                 :        652 :         { return(get_error_values(0,1,NULL,NULL,NULL,NULL)); }
     787                 :            : 
     788                 :          0 : unsigned long ERR_peek_last_error_line(const char **file, int *line)
     789                 :          0 :         { return(get_error_values(0,1,file,line,NULL,NULL)); }
     790                 :            : 
     791                 :          0 : unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
     792                 :            :              const char **data, int *flags)
     793                 :          0 :         { return(get_error_values(0,1,file,line,data,flags)); }
     794                 :            : 
     795                 :            : 
     796                 :      89883 : static unsigned long get_error_values(int inc, int top, const char **file, int *line,
     797                 :            :              const char **data, int *flags)
     798                 :            :         {       
     799                 :      89883 :         int i=0;
     800                 :            :         ERR_STATE *es;
     801                 :            :         unsigned long ret;
     802                 :            : 
     803                 :      89883 :         es=ERR_get_state();
     804                 :            : 
     805         [ -  + ]:      89883 :         if (inc && top)
     806                 :            :                 {
     807         [ #  # ]:          0 :                 if (file) *file = "";
     808         [ #  # ]:          0 :                 if (line) *line = 0;
     809         [ #  # ]:          0 :                 if (data) *data = "";
     810         [ #  # ]:          0 :                 if (flags) *flags = 0;
     811                 :            :                         
     812                 :            :                 return ERR_R_INTERNAL_ERROR;
     813                 :            :                 }
     814                 :            : 
     815         [ +  + ]:      89883 :         if (es->bottom == es->top) return 0;
     816         [ +  + ]:       1155 :         if (top)
     817                 :            :                 i=es->top;                    /* last error */
     818                 :            :         else
     819                 :        503 :                 i=(es->bottom+1)%ERR_NUM_ERRORS; /* first error */
     820                 :            : 
     821                 :       1155 :         ret=es->err_buffer[i];
     822         [ +  + ]:       1155 :         if (inc)
     823                 :            :                 {
     824                 :        130 :                 es->bottom=i;
     825                 :        130 :                 es->err_buffer[i]=0;
     826                 :            :                 }
     827                 :            : 
     828         [ +  + ]:       1155 :         if ((file != NULL) && (line != NULL))
     829                 :            :                 {
     830         [ -  + ]:        130 :                 if (es->err_file[i] == NULL)
     831                 :            :                         {
     832                 :          0 :                         *file="NA";
     833         [ #  # ]:          0 :                         if (line != NULL) *line=0;
     834                 :            :                         }
     835                 :            :                 else
     836                 :            :                         {
     837                 :        130 :                         *file=es->err_file[i];
     838         [ +  - ]:        130 :                         if (line != NULL) *line=es->err_line[i];
     839                 :            :                         }
     840                 :            :                 }
     841                 :            : 
     842         [ +  + ]:       1155 :         if (data == NULL)
     843                 :            :                 {
     844         [ -  + ]:       1025 :                 if (inc)
     845                 :            :                         {
     846 [ #  # ][ #  # ]:          0 :                         err_clear_data(es, i);
     847                 :            :                         }
     848                 :            :                 }
     849                 :            :         else
     850                 :            :                 {
     851         [ +  + ]:        130 :                 if (es->err_data[i] == NULL)
     852                 :            :                         {
     853                 :        121 :                         *data="";
     854         [ +  - ]:        121 :                         if (flags != NULL) *flags=0;
     855                 :            :                         }
     856                 :            :                 else
     857                 :            :                         {
     858                 :          9 :                         *data=es->err_data[i];
     859         [ +  - ]:          9 :                         if (flags != NULL) *flags=es->err_data_flags[i];
     860                 :            :                         }
     861                 :            :                 }
     862                 :       1155 :         return ret;
     863                 :            :         }
     864                 :            : 
     865                 :        130 : void ERR_error_string_n(unsigned long e, char *buf, size_t len)
     866                 :            :         {
     867                 :            :         char lsbuf[64], fsbuf[64], rsbuf[64];
     868                 :            :         const char *ls,*fs,*rs;
     869                 :            :         unsigned long l,f,r;
     870                 :            : 
     871                 :        130 :         l=ERR_GET_LIB(e);
     872                 :        130 :         f=ERR_GET_FUNC(e);
     873                 :        130 :         r=ERR_GET_REASON(e);
     874                 :            : 
     875                 :        130 :         ls=ERR_lib_error_string(e);
     876                 :        130 :         fs=ERR_func_error_string(e);
     877                 :        130 :         rs=ERR_reason_error_string(e);
     878                 :            : 
     879         [ -  + ]:        130 :         if (ls == NULL) 
     880                 :          0 :                 BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
     881         [ -  + ]:        130 :         if (fs == NULL)
     882                 :          0 :                 BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
     883         [ -  + ]:        130 :         if (rs == NULL)
     884                 :          0 :                 BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
     885                 :            : 
     886 [ +  - ][ +  - ]:        130 :         BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, 
                 [ +  - ]
     887                 :            :                 fs?fs:fsbuf, rs?rs:rsbuf);
     888         [ -  + ]:        130 :         if (strlen(buf) == len-1)
     889                 :            :                 {
     890                 :            :                 /* output may be truncated; make sure we always have 5 
     891                 :            :                  * colon-separated fields, i.e. 4 colons ... */
     892                 :            : #define NUM_COLONS 4
     893         [ #  # ]:          0 :                 if (len > NUM_COLONS) /* ... if possible */
     894                 :            :                         {
     895                 :            :                         int i;
     896                 :            :                         char *s = buf;
     897                 :            :                         
     898         [ #  # ]:          0 :                         for (i = 0; i < NUM_COLONS; i++)
     899                 :            :                                 {
     900                 :          0 :                                 char *colon = strchr(s, ':');
     901 [ #  # ][ #  # ]:          0 :                                 if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
     902                 :            :                                         {
     903                 :            :                                         /* set colon no. i at last possible position
     904                 :            :                                          * (buf[len-1] is the terminating 0)*/
     905                 :          0 :                                         colon = &buf[len-1] - NUM_COLONS + i;
     906                 :          0 :                                         *colon = ':';
     907                 :            :                                         }
     908                 :          0 :                                 s = colon + 1;
     909                 :            :                                 }
     910                 :            :                         }
     911                 :            :                 }
     912                 :        130 :         }
     913                 :            : 
     914                 :            : /* BAD for multi-threading: uses a local buffer if ret == NULL */
     915                 :            : /* ERR_error_string_n should be used instead for ret != NULL
     916                 :            :  * as ERR_error_string cannot know how large the buffer is */
     917                 :          0 : char *ERR_error_string(unsigned long e, char *ret)
     918                 :            :         {
     919                 :            :         static char buf[256];
     920                 :            : 
     921         [ #  # ]:          0 :         if (ret == NULL) ret=buf;
     922                 :          0 :         ERR_error_string_n(e, ret, 256);
     923                 :            : 
     924                 :          0 :         return ret;
     925                 :            :         }
     926                 :            : 
     927                 :          0 : LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
     928                 :            :         {
     929                 :          0 :         err_fns_check();
     930                 :          0 :         return ERRFN(err_get)(0);
     931                 :            :         }
     932                 :            : 
     933                 :          0 : LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
     934                 :            :         {
     935                 :          0 :         err_fns_check();
     936                 :          0 :         return ERRFN(thread_get)(0);
     937                 :            :         }
     938                 :            : 
     939                 :          0 : void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
     940                 :            :         {
     941                 :          0 :         err_fns_check();
     942                 :          0 :         ERRFN(thread_release)(hash);
     943                 :          0 :         }
     944                 :            : 
     945                 :        130 : const char *ERR_lib_error_string(unsigned long e)
     946                 :            :         {
     947                 :            :         ERR_STRING_DATA d,*p;
     948                 :            :         unsigned long l;
     949                 :            : 
     950                 :        130 :         err_fns_check();
     951                 :        130 :         l=ERR_GET_LIB(e);
     952                 :        130 :         d.error=ERR_PACK(l,0,0);
     953                 :        130 :         p=ERRFN(err_get_item)(&d);
     954         [ +  - ]:        130 :         return((p == NULL)?NULL:p->string);
     955                 :            :         }
     956                 :            : 
     957                 :      51109 : const char *ERR_func_error_string(unsigned long e)
     958                 :            :         {
     959                 :            :         ERR_STRING_DATA d,*p;
     960                 :            :         unsigned long l,f;
     961                 :            : 
     962                 :      51109 :         err_fns_check();
     963                 :      51109 :         l=ERR_GET_LIB(e);
     964                 :      51109 :         f=ERR_GET_FUNC(e);
     965                 :      51109 :         d.error=ERR_PACK(l,f,0);
     966                 :      51109 :         p=ERRFN(err_get_item)(&d);
     967         [ +  + ]:      51109 :         return((p == NULL)?NULL:p->string);
     968                 :            :         }
     969                 :            : 
     970                 :        130 : const char *ERR_reason_error_string(unsigned long e)
     971                 :            :         {
     972                 :        130 :         ERR_STRING_DATA d,*p=NULL;
     973                 :            :         unsigned long l,r;
     974                 :            : 
     975                 :        130 :         err_fns_check();
     976                 :        130 :         l=ERR_GET_LIB(e);
     977                 :        130 :         r=ERR_GET_REASON(e);
     978                 :        130 :         d.error=ERR_PACK(l,0,r);
     979                 :        130 :         p=ERRFN(err_get_item)(&d);
     980         [ +  + ]:        130 :         if (!p)
     981                 :            :                 {
     982                 :         25 :                 d.error=ERR_PACK(0,0,r);
     983                 :         25 :                 p=ERRFN(err_get_item)(&d);
     984                 :            :                 }
     985         [ +  - ]:        130 :         return((p == NULL)?NULL:p->string);
     986                 :            :         }
     987                 :            : 
     988                 :       1630 : void ERR_remove_thread_state(const CRYPTO_THREADID *id)
     989                 :            :         {
     990                 :            :         ERR_STATE tmp;
     991                 :            : 
     992         [ -  + ]:       1630 :         if (id)
     993                 :          0 :                 CRYPTO_THREADID_cpy(&tmp.tid, id);
     994                 :            :         else
     995                 :       1630 :                 CRYPTO_THREADID_current(&tmp.tid);
     996                 :       1630 :         err_fns_check();
     997                 :            :         /* thread_del_item automatically destroys the LHASH if the number of
     998                 :            :          * items reaches zero. */
     999                 :       1630 :         ERRFN(thread_del_item)(&tmp);
    1000                 :       1630 :         }
    1001                 :            : 
    1002                 :            : #ifndef OPENSSL_NO_DEPRECATED
    1003                 :          0 : void ERR_remove_state(unsigned long pid)
    1004                 :            :         {
    1005                 :          0 :         ERR_remove_thread_state(NULL);
    1006                 :          0 :         }
    1007                 :            : #endif
    1008                 :            : 
    1009                 :     415669 : ERR_STATE *ERR_get_state(void)
    1010                 :            :         {
    1011                 :            :         static ERR_STATE fallback;
    1012                 :     415669 :         ERR_STATE *ret,tmp,*tmpp=NULL;
    1013                 :            :         int i;
    1014                 :            :         CRYPTO_THREADID tid;
    1015                 :            : 
    1016                 :     415669 :         err_fns_check();
    1017                 :     415669 :         CRYPTO_THREADID_current(&tid);
    1018                 :     415669 :         CRYPTO_THREADID_cpy(&tmp.tid, &tid);
    1019                 :     415669 :         ret=ERRFN(thread_get_item)(&tmp);
    1020                 :            : 
    1021                 :            :         /* ret == the error state, if NULL, make a new one */
    1022         [ +  + ]:     415669 :         if (ret == NULL)
    1023                 :            :                 {
    1024                 :       1628 :                 ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
    1025         [ +  - ]:       1628 :                 if (ret == NULL) return(&fallback);
    1026                 :       1628 :                 CRYPTO_THREADID_cpy(&ret->tid, &tid);
    1027                 :       1628 :                 ret->top=0;
    1028                 :       1628 :                 ret->bottom=0;
    1029         [ +  + ]:      27676 :                 for (i=0; i<ERR_NUM_ERRORS; i++)
    1030                 :            :                         {
    1031                 :      26048 :                         ret->err_data[i]=NULL;
    1032                 :      26048 :                         ret->err_data_flags[i]=0;
    1033                 :            :                         }
    1034                 :       1628 :                 tmpp = ERRFN(thread_set_item)(ret);
    1035                 :            :                 /* To check if insertion failed, do a get. */
    1036         [ -  + ]:       1628 :                 if (ERRFN(thread_get_item)(ret) != ret)
    1037                 :            :                         {
    1038                 :          0 :                         ERR_STATE_free(ret); /* could not insert it */
    1039                 :          0 :                         return(&fallback);
    1040                 :            :                         }
    1041                 :            :                 /* If a race occurred in this function and we came second, tmpp
    1042                 :            :                  * is the first one that we just replaced. */
    1043         [ -  + ]:       1628 :                 if (tmpp)
    1044                 :          0 :                         ERR_STATE_free(tmpp);
    1045                 :            :                 }
    1046                 :     415669 :         return ret;
    1047                 :            :         }
    1048                 :            : 
    1049                 :       6552 : int ERR_get_next_error_library(void)
    1050                 :            :         {
    1051                 :       6552 :         err_fns_check();
    1052                 :       6552 :         return ERRFN(get_next_lib)();
    1053                 :            :         }
    1054                 :            : 
    1055                 :       4774 : void ERR_set_error_data(char *data, int flags)
    1056                 :            :         {
    1057                 :            :         ERR_STATE *es;
    1058                 :            :         int i;
    1059                 :            : 
    1060                 :       4774 :         es=ERR_get_state();
    1061                 :            : 
    1062                 :       4774 :         i=es->top;
    1063         [ +  + ]:       4774 :         if (i == 0)
    1064                 :        281 :                 i=ERR_NUM_ERRORS-1;
    1065                 :            : 
    1066 [ -  + ][ #  # ]:       4774 :         err_clear_data(es,i);
    1067                 :       4774 :         es->err_data[i]=data;
    1068                 :       4774 :         es->err_data_flags[i]=flags;
    1069                 :       4774 :         }
    1070                 :            : 
    1071                 :       4774 : void ERR_add_error_data(int num, ...)
    1072                 :            :         {
    1073                 :            :         va_list args;
    1074                 :       4774 :         va_start(args, num);
    1075                 :       4774 :         ERR_add_error_vdata(num, args);
    1076                 :       4774 :         va_end(args);
    1077                 :       4774 :         }
    1078                 :            : 
    1079                 :       4774 : void ERR_add_error_vdata(int num, va_list args)
    1080                 :            :         {
    1081                 :            :         int i,n,s;
    1082                 :            :         char *str,*p,*a;
    1083                 :            : 
    1084                 :       4774 :         s=80;
    1085                 :       4774 :         str=OPENSSL_malloc(s+1);
    1086         [ +  - ]:       4774 :         if (str == NULL) return;
    1087                 :       4774 :         str[0]='\0';
    1088                 :            : 
    1089                 :       4774 :         n=0;
    1090         [ +  + ]:      24271 :         for (i=0; i<num; i++)
    1091                 :            :                 {
    1092         [ +  - ]:      19497 :                 a=va_arg(args, char*);
    1093                 :            :                 /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
    1094         [ +  + ]:      19497 :                 if (a != NULL)
    1095                 :            :                         {
    1096                 :      18781 :                         n+=strlen(a);
    1097         [ +  + ]:      18781 :                         if (n > s)
    1098                 :            :                                 {
    1099                 :       3154 :                                 s=n+20;
    1100                 :       3154 :                                 p=OPENSSL_realloc(str,s+1);
    1101         [ -  + ]:       3154 :                                 if (p == NULL)
    1102                 :            :                                         {
    1103                 :          0 :                                         OPENSSL_free(str);
    1104                 :          0 :                                         return;
    1105                 :            :                                         }
    1106                 :            :                                 else
    1107                 :            :                                         str=p;
    1108                 :            :                                 }
    1109                 :      18781 :                         BUF_strlcat(str,a,(size_t)s+1);
    1110                 :            :                         }
    1111                 :            :                 }
    1112                 :       4774 :         ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
    1113                 :            :         }
    1114                 :            : 
    1115                 :      45593 : int ERR_set_mark(void)
    1116                 :            :         {
    1117                 :            :         ERR_STATE *es;
    1118                 :            : 
    1119                 :      45593 :         es=ERR_get_state();
    1120                 :            : 
    1121         [ +  + ]:      45593 :         if (es->bottom == es->top) return 0;
    1122                 :        779 :         es->err_flags[es->top]|=ERR_FLAG_MARK;
    1123                 :        779 :         return 1;
    1124                 :            :         }
    1125                 :            : 
    1126                 :      45593 : int ERR_pop_to_mark(void)
    1127                 :            :         {
    1128                 :            :         ERR_STATE *es;
    1129                 :            : 
    1130                 :      45593 :         es=ERR_get_state();
    1131                 :            : 
    1132         [ +  + ]:      98425 :         while(es->bottom != es->top
    1133         [ +  + ]:       8018 :                 && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
    1134                 :            :                 {
    1135 [ +  + ][ +  - ]:       7239 :                 err_clear(es,es->top);
    1136                 :       7239 :                 es->top-=1;
    1137         [ +  + ]:      52832 :                 if (es->top == -1) es->top=ERR_NUM_ERRORS-1;
    1138                 :            :                 }
    1139                 :            :                 
    1140         [ +  + ]:      45593 :         if (es->bottom == es->top) return 0;
    1141                 :        779 :         es->err_flags[es->top]&=~ERR_FLAG_MARK;
    1142                 :        779 :         return 1;
    1143                 :            :         }

Generated by: LCOV version 1.9