Add common error handling function 87/72587/3
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 1 Jun 2016 15:02:22 +0000 (17:02 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Mon, 6 Jun 2016 09:00:35 +0000 (02:00 -0700)
The function tries to convert openssl errors to yaca ones. If it succeeds it
removes the remaining errors from the queue. Otherwise it dumps them. It should
be called after each openssl failure.

Change-Id: I88c557e8d42f9ea70d5a8b25f2bd3181534e4ff8

src/debug.c
src/internal.h

index 13c0a9b58c1ed9416abbc89b1577cfc236045f30..595626c2c49483dc35777c0392b7ac1ff860d32f 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #include <openssl/err.h>
+#include <openssl/pem.h>
 
 #include <yaca_error.h>
 
@@ -60,9 +61,6 @@ char *error_translate(yaca_error_e err)
        }
 }
 
-// TODO use peeking function to intercept common errors
-//unsigned long ERR_peek_error();
-
 void error_dump(const char *file, int line, const char *function, int code)
 {
        if (error_cb == NULL) {
@@ -114,3 +112,40 @@ void error_dump(const char *file, int line, const char *function, int code)
        (*error_cb)(buf);
 }
 
+int error_handle(const char *file, int line, const char *function)
+{
+       int ret;
+       unsigned long err = ERR_peek_error();
+
+       /* fatal errors */
+       if (ERR_FATAL_ERROR(err) > 0) {
+               switch (ERR_GET_REASON(err)) {
+               case ERR_R_MALLOC_FAILURE:
+                       ret = YACA_ERROR_OUT_OF_MEMORY;
+                       break;
+               case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
+               case ERR_R_PASSED_NULL_PARAMETER:
+                       ret = YACA_ERROR_INVALID_ARGUMENT;
+                       break;
+               case ERR_R_INTERNAL_ERROR:
+               case ERR_R_DISABLED:
+               default:
+                       ret = YACA_ERROR_INTERNAL;
+               }
+       /* known errors */
+       } else {
+               switch (err) {
+               case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT):
+               case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT):
+                       ret = YACA_ERROR_PASSWORD_INVALID;
+                       break;
+               default:
+                       error_dump(file, line, function, YACA_ERROR_INTERNAL);
+                       ret = YACA_ERROR_INTERNAL;
+               }
+       }
+
+       /* remove all errors from queue */
+       ERR_clear_error();
+       return ret;
+}
index 2b437cf68da55d66e9d2482ff880f5e15e831a10..c22c2ef92ca160ba31b2b4f259a2c25fd16ad366 100644 (file)
@@ -100,4 +100,18 @@ void error_dump(const char *file, int line, const char *function, int code);
 #define ERROR_DUMP(code) error_dump(__FILE__, __LINE__, __func__, (code))
 #define ERROR_CLEAR() ERR_clear_error()
 
+/**
+ * Function responsible for translating the openssl error to yaca error and
+ * clearing/dumping the openssl error queue. Use only after openssl function
+ * failure.
+ *
+ * The function checks only first error in the queue. If the function doesn't
+ * find any error in openssl queue or is not able to translate it, it will
+ * return YACA_ERROR_INTERNAL and dump openssl errors if any. If the
+ * translation succeeds the function will clear the error queue and return the
+ * result of translation.
+ */
+int error_handle(const char *file, int line, const char *function);
+#define ERROR_HANDLE() error_handle(__FILE__, __LINE__, __func__)
+
 #endif /* YACA_INTERNAL_H */