ERR: Implement the macros ERR_raise() and ERR_raise_data() and use them
authorRichard Levitte <levitte@openssl.org>
Wed, 24 Jul 2019 11:13:52 +0000 (13:13 +0200)
committerRichard Levitte <levitte@openssl.org>
Wed, 31 Jul 2019 04:43:21 +0000 (06:43 +0200)
The ERR_raise() macro uses a trick in C.  The following is permitted:

    #include <stdio.h>

    void first(void)
    {
        printf("Hello! ");
    }

    void foo(const char *bar)
    {
        printf("%s", bar);
    }

    int main()
    {
        /* This */
        (first(),foo)("cookie");
    }

ERR_raise_data() can be used to implement FUNCerr() as well, which
takes away the need for the special function ERR_put_func_error().

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9452)

doc/man3/ERR_put_error.pod
include/openssl/err.h
util/private.num

index c2913d5..d9bbba9 100644 (file)
@@ -2,6 +2,7 @@
 
 =head1 NAME
 
+ERR_raise, ERR_raise_data,
 ERR_put_error, ERR_put_func_error,
 ERR_add_error_data, ERR_add_error_vdata - record an error
 
@@ -9,6 +10,9 @@ ERR_add_error_data, ERR_add_error_vdata - record an error
 
  #include <openssl/err.h>
 
+ void ERR_raise(int lib, int reason);
+ void ERR_raise_data(int lib, int reason, const char *fmt, ...);
+
  void ERR_put_error(int lib, int func, int reason, const char *file, int line);
  void ERR_put_func_error(int lib, const char *func, int reason,
                          const char *file, int line);
@@ -18,6 +22,16 @@ ERR_add_error_data, ERR_add_error_vdata - record an error
 
 =head1 DESCRIPTION
 
+ERR_raise() adds a new error to the thread's error queue.  The
+error occured in the library B<lib> for the reason given by the
+B<reason> code.  Furthermore, the name of the file, the line, and name
+of the function where the error occured is saved with the error
+record.
+
+ERR_raise_data() does the same thing as ERR_raise(), but also lets the
+caller specify additional information as a format string B<fmt> and an
+arbitrary number of values, which are processed with L<BIO_snprintf(3)>.  
+
 ERR_put_error() adds an error code to the thread's error queue. It
 signals that the error of reason code B<reason> occurred in function
 B<func> of library B<lib>, in line number B<line> of B<file>.
@@ -64,8 +78,12 @@ the ASN1err() macro.
 
 =head1 RETURN VALUES
 
-ERR_put_error() and ERR_add_error_data() return
-no values.
+ERR_raise(), ERR_put_error() and ERR_add_error_data()
+return no values.
+
+=head1 NOTES
+
+ERR_raise() is implemented as a macro.
 
 =head1 SEE ALSO
 
@@ -73,7 +91,7 @@ L<ERR_load_strings(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
index 90e1467..7aac9b8 100644 (file)
@@ -108,49 +108,49 @@ typedef struct err_state_st {
 # define ERR_LIB_USER            128
 
 # if ! OPENSSL_API_3
-#  define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-#endif
-# define FUNCerr(f,r)  ERR_PUT_func_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
-# define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define OSSL_STOREerr(f,r) ERR_PUT_error(ERR_LIB_OSSL_STORE,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CRMFerr(f,r) ERR_PUT_error(ERR_LIB_CRMF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CMPerr(f,r) ERR_PUT_error(ERR_LIB_CMP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CTerr(f,r) ERR_PUT_error(ERR_LIB_CT,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ESSerr(f,r) ERR_PUT_error(ERR_LIB_ESS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PROPerr(f,r) ERR_PUT_error(ERR_LIB_PROP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PROVerr(f,r) ERR_PUT_error(ERR_LIB_PROV,0,(r),OPENSSL_FILE,OPENSSL_LINE)
+#  define SYSerr(f,r)  ERR_raise(ERR_LIB_SYS,(r))
+# endif
+# define FUNCerr(f,r)  ERR_raise_data(ERR_LIB_SYS,(r),"calling function %s",(f))
+# define BNerr(f,r)   ERR_raise(ERR_LIB_RSA,(r))
+# define RSAerr(f,r)  ERR_raise(ERR_LIB_RSA,(r))
+# define DHerr(f,r)   ERR_raise(ERR_LIB_DH,(r))
+# define EVPerr(f,r)  ERR_raise(ERR_LIB_EVP,(r))
+# define BUFerr(f,r)  ERR_raise(ERR_LIB_BUF,(r))
+# define OBJerr(f,r)  ERR_raise(ERR_LIB_OBJ,(r))
+# define PEMerr(f,r)  ERR_raise(ERR_LIB_PEM,(r))
+# define DSAerr(f,r)  ERR_raise(ERR_LIB_DSA,(r))
+# define X509err(f,r) ERR_raise(ERR_LIB_X509,(r))
+# define ASN1err(f,r) ERR_raise(ERR_LIB_ASN1,(r))
+# define CONFerr(f,r) ERR_raise(ERR_LIB_CONF,(r))
+# define CRYPTOerr(f,r) ERR_raise(ERR_LIB_CRYPTO,(r))
+# define ECerr(f,r)   ERR_raise(ERR_LIB_EC,(r))
+# define SSLerr(f,r)  ERR_raise(ERR_LIB_SSL,(r))
+# define BIOerr(f,r)  ERR_raise(ERR_LIB_BIO,(r))
+# define PKCS7err(f,r) ERR_raise(ERR_LIB_PKCS7,(r))
+# define X509V3err(f,r) ERR_raise(ERR_LIB_X509V3,(r))
+# define PKCS12err(f,r) ERR_raise(ERR_LIB_PKCS12,(r))
+# define RANDerr(f,r) ERR_raise(ERR_LIB_RAND,(r))
+# define DSOerr(f,r) ERR_raise(ERR_LIB_DSO,(r))
+# define ENGINEerr(f,r) ERR_raise(ERR_LIB_ENGINE,(r))
+# define OCSPerr(f,r) ERR_raise(ERR_LIB_OCSP,(r))
+# define UIerr(f,r) ERR_raise(ERR_LIB_UI,(r))
+# define COMPerr(f,r) ERR_raise(ERR_LIB_COMP,(r))
+# define ECDSAerr(f,r)  ERR_raise(ERR_LIB_ECDSA,(r))
+# define ECDHerr(f,r)  ERR_raise(ERR_LIB_ECDH,(r))
+# define OSSL_STOREerr(f,r) ERR_raise(ERR_LIB_OSSL_STORE,(r))
+# define FIPSerr(f,r) ERR_raise(ERR_LIB_FIPS,(r))
+# define CMSerr(f,r) ERR_raise(ERR_LIB_CMS,(r))
+# define CRMFerr(f,r) ERR_raise(ERR_LIB_CRMF,(r))
+# define CMPerr(f,r) ERR_raise(ERR_LIB_CMP,(r))
+# define TSerr(f,r) ERR_raise(ERR_LIB_TS,(r))
+# define HMACerr(f,r) ERR_raise(ERR_LIB_HMAC,(r))
+# define CTerr(f,r) ERR_raise(ERR_LIB_CT,(r))
+# define ASYNCerr(f,r) ERR_raise(ERR_LIB_ASYNC,(r))
+# define KDFerr(f,r) ERR_raise(ERR_LIB_KDF,(r))
+# define SM2err(f,r) ERR_raise(ERR_LIB_SM2,(r))
+# define ESSerr(f,r) ERR_raise(ERR_LIB_ESS,(r))
+# define PROPerr(f,r) ERR_raise(ERR_LIB_PROP,(r))
+# define PROVerr(f,r) ERR_raise(ERR_LIB_PROV,(r))
 
 # define ERR_PACK(l,f,r) ( \
         (((unsigned int)(l) & 0x0FF) << 24L) | \
@@ -245,6 +245,13 @@ void ERR_set_debug(const char *file, int line, const char *func);
 void ERR_set_error(int lib, int reason, const char *fmt, ...);
 void ERR_vset_error(int lib, int reason, const char *fmt, va_list args);
 
+/* Main error raising functions */
+#define ERR_raise(lib, reason) ERR_raise_data((lib),(reason),NULL)
+#define ERR_raise_data                                          \
+    (ERR_new(),                                                 \
+     ERR_set_debug(OPENSSL_FILE,OPENSSL_LINE,OPENSSL_FUNC),     \
+     ERR_set_error)
+
 void ERR_put_error(int lib, int func, int reason, const char *file, int line);
 void ERR_put_func_error(int lib, const char *func, int reason,
                         const char *file, int line);
index 1e76dfb..3c00589 100644 (file)
@@ -196,6 +196,8 @@ ERR_GET_REASON                          define
 ERR_PACK                                define
 ERR_free_strings                        define deprecated 1.1.0
 ERR_load_crypto_strings                 define deprecated 1.1.0
+ERR_raise                               define
+ERR_raise_data                          define
 EVP_DigestSignUpdate                    define
 EVP_DigestVerifyUpdate                  define
 EVP_KDF_name                            define