]> git.ozlabs.org Git - ppp.git/commitdiff
pppd: Add additional functions to handle debugging of crypto calls (#509)
authorEivind Næss <eivnaes@yahoo.com>
Mon, 2 Sep 2024 23:41:27 +0000 (16:41 -0700)
committerGitHub <noreply@github.com>
Mon, 2 Sep 2024 23:41:27 +0000 (09:41 +1000)
Signed-off-by: Eivind Næss <eivnaes@yahoo.com>
pppd/Makefile.am
pppd/crypto.c
pppd/crypto.h
pppd/main.c

index 65880ab186636e3474b6577f9e4518dbf577bf49..37eeabb764b7dc9357e541d9ef524d596a4038c3 100644 (file)
@@ -10,7 +10,7 @@ utest_peap_SOURCES = peap.c utils.c mppe.c
 utest_peap_CPPFLAGS = -DUNIT_TEST
 utest_peap_LDFLAGS =
 
-utest_crypto_SOURCES = crypto.c
+utest_crypto_SOURCES = crypto.c utils.c
 utest_crypto_CPPFLAGS = -DUNIT_TEST
 utest_crypto_LDFLAGS =
 
index 905f11d9bc16fbd68ddb6d7e686e14256b5ae5f2..05cdb788fcc9257ff70b2744e3a5625dea22c3c6 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#include "pppd.h"
 #include "crypto.h"
 #include "crypto-priv.h"
 
 #ifdef PPP_WITH_OPENSSL
 #include <openssl/opensslv.h>
+#include <openssl/err.h>
 #endif
 
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
@@ -68,29 +70,41 @@ void PPP_MD_CTX_free(PPP_MD_CTX* ctx)
 
 int PPP_DigestInit(PPP_MD_CTX *ctx, const PPP_MD *type)
 {
+    int ret = 0;
     if (ctx) {
         ctx->md = *type;
         if (ctx->md.init_fn) {
-            return ctx->md.init_fn(ctx);
+            ret = ctx->md.init_fn(ctx);
+            if (!ret) {
+                PPP_crypto_error("Could not initialize digest");
+            }
         }
     }
-    return 0;
+    return ret;
 }
 
 int PPP_DigestUpdate(PPP_MD_CTX *ctx, const void *data, size_t length)
 {
+    int ret = 0;
     if (ctx && ctx->md.update_fn) {
-        return ctx->md.update_fn(ctx, data, length);
+        ret = ctx->md.update_fn(ctx, data, length);
+        if (!ret) {
+            PPP_crypto_error("Could not update digest");
+        }
     }
-    return 0;
+    return ret;
 }
 
 int PPP_DigestFinal(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *outlen)
 {
+    int ret = 0;
     if (ctx && ctx->md.final_fn) {
-        return ctx->md.final_fn(ctx, out, outlen);
+        ret = ctx->md.final_fn(ctx, out, outlen);
+        if (!ret) {
+            PPP_crypto_error("Could not perform final digest");
+        }
     }
-    return 0;
+    return ret;
 }
 
 PPP_CIPHER_CTX *PPP_CIPHER_CTX_new(void)
@@ -112,33 +126,75 @@ void PPP_CIPHER_CTX_free(PPP_CIPHER_CTX *ctx)
 
 int PPP_CipherInit(PPP_CIPHER_CTX *ctx, const PPP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int encr)
 {
+    int ret = 0;
     if (ctx && cipher) {
+        ret = 1;
         ctx->is_encr = encr;
         ctx->cipher = *cipher;
         if (ctx->cipher.init_fn) {
-            ctx->cipher.init_fn(ctx, key, iv);
+            ret = ctx->cipher.init_fn(ctx, key, iv);
+            if (!ret) {
+                PPP_crypto_error("Could not initialize cipher");
+            }
         }
-        return 1;
     }
-    return 0;
+    return ret;
 }
 
 int PPP_CipherUpdate(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl)
 {
+    int ret = 0;
     if (ctx && ctx->cipher.update_fn) {
-        return ctx->cipher.update_fn(ctx, out, outl, in, inl);
+        ret = ctx->cipher.update_fn(ctx, out, outl, in, inl);
+        if (!ret) {
+            PPP_crypto_error("Could not perform crypto operation");
+        }
     }
-    return 0;
+    return ret;
 }
 
 int PPP_CipherFinal(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 {
+    int ret = 0;
     if (ctx && ctx->cipher.final_fn) {
-        return ctx->cipher.final_fn(ctx, out, outl);
+        ret = ctx->cipher.final_fn(ctx, out, outl);
+        if (!ret) {
+            PPP_crypto_error("Could not perform final crypto operation");
+        }
+    }
+    return ret;
+}
+
+void
+PPP_crypto_error(char *fmt, ...)
+{
+    va_list args;
+    char buf[1024];
+    int len = sizeof(buf);
+    int off = 0;
+    int err = 0;
+
+    va_start(args, fmt);
+    off = vsnprintf(buf, len, fmt, args);
+    va_end(args);
+
+#ifdef PPP_WITH_OPENSSL
+    err = ERR_peek_error();
+    if (err == 0 || (len-off) < 130) {
+        error("%s", buf);
+        return;
     }
-    return 0;
+
+#ifdef OPENSSL_VERSION_NUMBER < 0x10100000L
+    ERR_load_crypto_strings();
+#endif
+    error("%s, %s\n", buf, ERR_reason_error_string(err));
+#else
+    error("%s", buf);
+#endif
 }
 
+
 int PPP_crypto_init()
 {
     int retval = 0;
@@ -147,15 +203,18 @@ int PPP_crypto_init()
     g_crypto_ctx.legacy = OSSL_PROVIDER_load(NULL, "legacy");
     if (g_crypto_ctx.legacy == NULL)
     {
+        PPP_crypto_error("Could not load legacy provider");
         goto done;
     }
 
     g_crypto_ctx.provider = OSSL_PROVIDER_load(NULL, "default");
     if (g_crypto_ctx.provider == NULL)
     {
+        PPP_crypto_error("Could not load default provider");
         goto done;
     }
 #endif
+
     retval = 1;
 
 done:
@@ -176,12 +235,21 @@ int PPP_crypto_deinit()
         g_crypto_ctx.provider = NULL;
     }
 #endif
+
+#ifdef OPENSSL_VERSION_NUMBER < 0x10100000L
+    ERR_free_strings();
+#endif
     return 1;
 }
 
 #ifdef UNIT_TEST
 #include <stdio.h>
 
+int debug;
+int error_count;
+int unsuccess;
+
+
 int test_md4()
 {
     PPP_MD_CTX* ctx = NULL;
index c559d0c45993f3a6af351e1edad58104adee0fa2..013aefdbdf70369399424d54cbb095814d8db69f 100644 (file)
@@ -146,6 +146,11 @@ int PPP_CipherUpdate(PPP_CIPHER_CTX *ctx,
 int PPP_CipherFinal(PPP_CIPHER_CTX *ctx,
         unsigned char *out, int *outl);
 
+/*
+ * Log an error message to the log and append the crypto error
+ */
+void PPP_crypto_error(char *fmt, ...);
+
 /*
  * Global initialization, must be called once per process
  */
index 8310c9871e4bce3acd5acea6edc2c4bbc6d74ea4..d62e60301bcdc0a16f56f1ef118d85ea1417f9a6 100644 (file)
@@ -363,8 +363,6 @@ main(int argc, char *argv[])
     struct protent *protp;
     char numbuf[16];
 
-    PPP_crypto_init();
-
     strlcpy(path_ipup, PPP_PATH_IPUP, MAXPATHLEN);
     strlcpy(path_ipdown, PPP_PATH_IPDOWN, MAXPATHLEN);
 
@@ -381,6 +379,11 @@ main(int argc, char *argv[])
     /* Initialize syslog facilities */
     reopen_log();
 
+    /* Initialize crypto libraries */
+    if (!PPP_crypto_init()) {
+        exit(1);
+    }
+
     if (gethostname(hostname, sizeof(hostname)) < 0 ) {
        ppp_option_error("Couldn't get hostname: %m");
        exit(1);