|
@@ -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
|