@ -39,6 +39,7 @@ extern "C" {
# endif
# endif
# include <limits.h>
# include <errno.h>
# define ERR_TXT_MALLOCED 0x01
@ -163,43 +164,95 @@ struct err_state_st {
# define X509err(f, r) ERR_raise_data(ERR_LIB_X509, (r), NULL)
# endif
/*
* The error code currently packs as follows ( viewed as hex nibbles ) :
/*-
* The error code packs differently depending on if it records a system
* error or an OpenSSL error .
*
* LL rRRRRR
* A system error packs like this ( we follow POSIX and only allow positive
* numbers that fit in an | int | ) :
*
* Where LL is the library code , r is the reason flags , and rRRRRR is the
* reason code .
* Do note that the reason flags is part of the reason code , and could as
* well be seen as a section of all possible reason codes . We do this for
* backward compatibility reasons , i . e . how ERR_R_FATAL was implemented .
* + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | 1 | system error number |
* + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*
* An OpenSSL error packs like this :
*
* System errors ( ERR_LIB_SYS ) are structured the same way , except they
* don ' t have any reason flag .
* < - - - - - - - - - - - - - - - - - - - - - - - - - - - - 32 bits - - - - - - - - - - - - - - - - - - - - - - - - - - >
* < - - - 8 bits - - - > < - - - - - - - - - - - - - - - - - - 23 bits - - - - - - - - - - - - - - - - - >
* + - + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | 0 | library | reason |
* + - + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*
* LL RRRRRR
* A few of the reason bits are reserved as flags with special meaning :
*
* < 4 bits > < - - - - - - - - - - - - - - 19 bits - - - - - - - - - - - - - >
* + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | rflags | reason |
* + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*
* We have the reason flags being part of the overall reason code for
* backward compatibility reasons , i . e . how ERR_R_FATAL was implemented .
*/
# define ERR_LIB_OFFSET 24L
# define ERR_LIB_MASK 0xFF
# define ERR_RFLAGS_OFFSET 20L
# define ERR_RFLAGS_MASK 0xF
# define ERR_REASON_MASK 0XFFFFFF
/* Macros to help decode recorded system errors */
# define ERR_SYSTEM_FLAG ((unsigned int)INT_MAX + 1)
# define ERR_SYSTEM_MASK ((unsigned int)INT_MAX)
/* Macros to help decode recorded OpenSSL errors */
# define ERR_LIB_OFFSET 23L
# define ERR_LIB_MASK 0xFF
# define ERR_RFLAGS_OFFSET 19L
# define ERR_RFLAGS_MASK 0xF
# define ERR_REASON_MASK 0X7FFFFF
/*
* Reason flags are defined pre - shifted to easily combine with the reason
* number .
*/
# define ERR_RFLAG_FATAL (0x1 << ERR_RFLAGS_OFFSET)
/* ERR_PACK takes reason flags and reason code combined in |r| */
# define ERR_PACK(l,f,r) \
( ( ( ( unsigned int ) ( l ) & ERR_LIB_MASK ) < < ERR_LIB_OFFSET ) | \
( ( ( unsigned int ) ( r ) & ERR_REASON_MASK ) ) )
# define ERR_GET_LIB(l) (int)(((l) >> ERR_LIB_OFFSET) & ERR_LIB_MASK)
# define ERR_GET_FUNC(l) 0
# define ERR_GET_RFLAGS(l) (int)((l) & (ERR_RFLAGS_MASK << ERR_RFLAGS_OFFSET))
# define ERR_GET_REASON(l) (int)((l) & ERR_REASON_MASK)
# define ERR_FATAL_ERROR(l) (int)((l) & ERR_RFLAG_FATAL)
# define ERR_RFLAG_FATAL (0x1 << ERR_RFLAGS_OFFSET)
# define ERR_SYSTEM_ERROR(errcode) (((errcode) & ERR_SYSTEM_FLAG) != 0)
static ossl_inline int ERR_GET_LIB ( unsigned long errcode )
{
if ( ERR_SYSTEM_ERROR ( errcode ) )
return ERR_LIB_SYS ;
return ( errcode > > ERR_LIB_OFFSET ) & ERR_LIB_MASK ;
}
static ossl_inline int ERR_GET_FUNC ( unsigned long errcode )
{
return 0 ;
}
static ossl_inline int ERR_GET_RFLAGS ( unsigned long errcode )
{
if ( ERR_SYSTEM_ERROR ( errcode ) )
return 0 ;
return errcode & ( ERR_RFLAGS_MASK < < ERR_RFLAGS_OFFSET ) ;
}
static ossl_inline int ERR_GET_REASON ( unsigned long errcode )
{
if ( ERR_SYSTEM_ERROR ( errcode ) )
return errcode & ERR_SYSTEM_MASK ;
return errcode & ERR_REASON_MASK ;
}
static ossl_inline int ERR_FATAL_ERROR ( unsigned long errcode )
{
return ( ERR_GET_RFLAGS ( errcode ) & ERR_RFLAG_FATAL ) ! = 0 ;
}
/*
* ERR_PACK is a helper macro to properly pack OpenSSL error codes and may
* only be used for that purpose . System errors are packed internally .
* ERR_PACK takes reason flags and reason code combined in | reason | .
* ERR_PACK ignores | func | , that parameter is just legacy from pre - 3.0 OpenSSL .
*/
# define ERR_PACK(lib,func,reason) \
( ( ( ( unsigned long ) ( lib ) & ERR_LIB_MASK ) < < ERR_LIB_OFFSET ) | \
( ( ( unsigned long ) ( reason ) & ERR_REASON_MASK ) ) )
# ifndef OPENSSL_NO_DEPRECATED_3_0
# define SYS_F_FOPEN 0