From ddb941f1c3b72152008f4061b1bfd17d293af938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Fri, 15 Sep 2023 16:46:33 +0200 Subject: [PATCH] Fix some incorrect use of Gambas strings. Better error messages. [GB.OPENSSL] * BUG: Fix some incorrect use of Gambas strings. * NEW: Better error messages. --- gb.openssl/src/c_cipher.c | 37 +++++++++++++++++++++++++----------- gb.openssl/src/c_digest.c | 2 +- gb.openssl/src/c_openssl.c | 39 +++++++++++++++++++------------------- gb.openssl/src/main.c | 8 +++++++- gb.openssl/src/main.h | 3 ++- 5 files changed, 55 insertions(+), 34 deletions(-) diff --git a/gb.openssl/src/c_cipher.c b/gb.openssl/src/c_cipher.c index 647847bd4..ab3a571e3 100644 --- a/gb.openssl/src/c_cipher.c +++ b/gb.openssl/src/c_cipher.c @@ -35,7 +35,7 @@ #define __C_CIPHER_C #include - +#include #include #include #include @@ -66,7 +66,7 @@ static void get_clist(void) /* XXX: There is EVP_CIPHER_do_all_sorted() but that still returns * entries twice (NOT next to each other), so we sort manually */ EVP_CIPHER_do_all(clist_func, NULL); - sort_and_dedupe(_clist); + MAIN_sort_and_dedupe(_clist); } /**G @@ -126,8 +126,7 @@ END_METHOD **/ BEGIN_METHOD(Cipher_IsSupported, GB_STRING method) - _method = EVP_get_cipherbyname(STRING(method)); - GB.ReturnBoolean(!!_method); + GB.ReturnBoolean(EVP_get_cipherbyname(GB.ToZeroString(ARG(method))) != NULL); END_METHOD @@ -260,7 +259,7 @@ BEGIN_METHOD(CipherMethod_Encrypt, GB_STRING plain; GB_STRING key; assert(RAND_bytes(iv, sizeof(iv))); } else { if (LENGTH(iv) != sizeof(iv)) { - GB.Error("InitVector length does not match method"); + GB.Error("Init vector length does not match method"); return; } memcpy(iv, STRING(iv), sizeof(iv)); @@ -269,7 +268,10 @@ BEGIN_METHOD(CipherMethod_Encrypt, GB_STRING plain; GB_STRING key; cipher = do_cipher((uchar *) STRING(plain), LENGTH(plain), key, iv, &length, 1, &errmsg); if (!cipher) { - GB.Error(errmsg ? errmsg : "Encryption failed"); + if (errmsg) + GB.Error(errmsg); + else + MAIN_error("Encryption failed: &1"); return; } @@ -296,7 +298,10 @@ BEGIN_METHOD(CipherMethod_Decrypt, GB_OBJECT ciph) (uchar *) ciph->key, (uchar *) ciph->iv, &length, 0, &errmsg); if (!plain) { - GB.Error(errmsg ? errmsg : "Decryption failed"); + if (errmsg) + GB.Error(errmsg); + else + MAIN_error("Decryption failed: &1"); return; } GB.ReturnNewString(plain, length); @@ -348,7 +353,10 @@ BEGIN_METHOD(CipherMethod_EncryptSalted, GB_STRING plain; GB_STRING passwd; cipher = do_cipher((uchar *) STRING(plain), LENGTH(plain), key, iv, &length, 1, &errmsg); if (!cipher) { - GB.Error(errmsg ? errmsg : "Encryption failed"); + if (errmsg) + GB.Error(errmsg); + else + MAIN_error("Encryption failed: &1"); return; } res = GB.NewZeroString("Salted__"); @@ -373,12 +381,16 @@ BEGIN_METHOD(CipherMethod_DecryptSalted, GB_STRING cipher; GB_STRING passwd) unsigned int clen, length; char *plain, *errmsg; - if (!strstr(STRING(cipher), "Salted__")) { + if (LENGTH(cipher) <= 8 || strncmp(STRING(cipher), "Salted__", 8)) { GB.Error("Unrecognised cipher string format"); return; } /* salt begins at STRING(cipher) + strlen("Salted__") */ - memcpy(salt, STRING(cipher) + 8, sizeof(salt)); + + clen = LENGTH(cipher) - 8; + if (clen > sizeof(salt)) + clen = sizeof(salt); + memcpy(salt, STRING(cipher) + 8, clen); // "openssl enc" >= 1.1.0 uses SHA256 by default instead of MD5 // EVP_BytesToKey(_method, EVP_sha256(), salt, (uchar *) STRING(passwd), @@ -389,7 +401,10 @@ BEGIN_METHOD(CipherMethod_DecryptSalted, GB_STRING cipher; GB_STRING passwd) clen = LENGTH(cipher) - (uint) (cipher - (uchar *) STRING(cipher)); plain = do_cipher((uchar *) cipher, clen, key, iv, &length, 0, &errmsg); if (!plain) { - GB.Error(errmsg ? errmsg : "Decryption failed"); + if (errmsg) + GB.Error(errmsg); + else + MAIN_error("Decryption failed: &1"); return; } GB.ReturnNewString(plain, length); diff --git a/gb.openssl/src/c_digest.c b/gb.openssl/src/c_digest.c index 53db9e1cf..294ef9c95 100644 --- a/gb.openssl/src/c_digest.c +++ b/gb.openssl/src/c_digest.c @@ -62,7 +62,7 @@ static void get_dlist(void) { GB.Array.New(&_dlist, GB_T_STRING, 0); EVP_MD_do_all(dlist_func, NULL); - sort_and_dedupe(_dlist); + MAIN_sort_and_dedupe(_dlist); } /**G diff --git a/gb.openssl/src/c_openssl.c b/gb.openssl/src/c_openssl.c index 19c261d85..32285d780 100644 --- a/gb.openssl/src/c_openssl.c +++ b/gb.openssl/src/c_openssl.c @@ -37,7 +37,6 @@ #include #include #include -#include #include "main.h" #include "c_openssl.h" @@ -56,11 +55,11 @@ BEGIN_METHOD(OpenSSL_RandomBytes, GB_INTEGER length) int res; if (VARG(length) < 1) { - GB.Error("Invalid Parameter: length must be greater than 0"); + GB.Error("Invalid argument: Length must be greater than 0"); return; } if (VARG(length) > 0x7FFFEFF7) { - GB.Error("Invalid Parameter: length must be less than 2,147,479,544"); + GB.Error("Invalid argument: Length must be less than 2,147,479,544"); return; } ret = GB.TempString(NULL, VARG(length)); @@ -73,7 +72,7 @@ BEGIN_METHOD(OpenSSL_RandomBytes, GB_INTEGER length) GB.Error("Random number generator not supported"); return; } else if (res == 0) { - GB.Error(ERR_error_string(ERR_get_error(), NULL)); + MAIN_error("Unable to get random number: &1"); return; } @@ -93,30 +92,30 @@ BEGIN_METHOD(OpenSSL_Pbkdf2, GB_STRING password; GB_STRING salt; GB_LONG iterati const EVP_MD *emethod; if (VARG(iterations) < 1) { - GB.Error("Invalid Parameter: iterations must be greater than 0"); + GB.Error("Invalid argument: Iterations must be greater than 0"); return; } lKey = VARG(keylength); if (lKey < 1) { - GB.Error("Invalid Parameter: keylength must be greater than 0"); + GB.Error("Invalid argument: KeyLength must be greater than 0"); return; } if (lKey > 0x7FFFEFF7) { - GB.Error("Invalid Parameter: keylength must be less than 2,147,479,544"); + GB.Error("Invalid argument: KeyLength must be less than 2,147,479,544"); return; } hash = GB.TempString(NULL, lKey); emethod = EVP_get_digestbyname(STRING(method)); if (!emethod) { - GB.Error("Invalid Parameter: method not a supported digest"); + GB.Error("Invalid argument: Method not a supported digest"); return; } memset(hash, 0, lKey); ret = PKCS5_PBKDF2_HMAC((const char *) STRING(password), LENGTH(password), (const unsigned char *) STRING(salt), LENGTH(salt), (int) VARG(iterations), emethod, lKey, (unsigned char *) hash); if (ret == 0) { - GB.Error("OpenSSL Error: Pbkdf2 call failed"); - return; + MAIN_error("Pbkdf2 call failed: &1"); + return; } GB.ReturnString(hash); #endif @@ -136,51 +135,51 @@ BEGIN_METHOD(OpenSSL_Scrypt, GB_STRING password; GB_STRING salt; GB_LONG N; GB_L lKey = VARG(keylength); if (lKey < 1) { - GB.Error("Invalid Parameter: keylength must be greater than 0"); + GB.Error("Invalid argument: KeyLength must be greater than 0"); return; } if (lKey > 0x7FFFEFF7L) { - GB.Error("Invalid Parameter: keylength must be less than 2,147,479,544"); + GB.Error("Invalid argument: KeyLength must be less than 2,147,479,544"); return; } hash = GB.TempString(NULL, lKey); lN = VARG(N); if (lN < 2) { - GB.Error("Invalid Parameter: N must be greater than 1"); + GB.Error("Invalid argument: N must be greater than 1"); return; } /* Bitwise power of 2 test */ if (lN == 0 || (lN & (lN - 1)) != 0) { - GB.Error("Invalid Parameter: N must be a power of 2"); + GB.Error("Invalid argument: N must be a power of 2"); return; } lR = VARG(r); if (lR < 1) { - GB.Error("Invalid Parameter: r must be greater than 0"); + GB.Error("Invalid argument: R must be greater than 0"); return; } if (lR > 0xFFFFFFFFL) { - GB.Error("Invalid Parameter: r must be a 32-bit number"); + GB.Error("Invalid argument: R must be a 32-bit number"); return; } lP = VARG(p); if (lP < 1) { - GB.Error("Invalid Parameter: p must be greater than 0"); + GB.Error("Invalid argument: P must be greater than 0"); return; } if (lP > 0xFFFFFFFFL) { - GB.Error("Invalid Parameter: p must be a 32-bit number"); + GB.Error("Invalid argument: P must be a 32-bit number"); return; } if (EVP_PBE_scrypt(NULL, 0, NULL, 0, lN, lR, lP, 0, NULL, 0) == 0) { - GB.Error("Invalid Parameter: The combination of N, r, and p was rejected by OpenSSL"); + GB.Error("Invalid argument: The combination of N, R, and P was rejected by OpenSSL"); return; } memset(hash, 0, lKey); ret = EVP_PBE_scrypt((const char *) STRING(password), LENGTH(password), (const unsigned char *) STRING(salt), LENGTH(salt), lN, lR, lP, 0, (unsigned char *) hash, lKey); if (ret == 0) { - GB.Error("OpenSSL Error: Scrypt call failed"); + MAIN_error("Scrypt call failed: &1"); return; } GB.ReturnString(hash); diff --git a/gb.openssl/src/main.c b/gb.openssl/src/main.c index 475f45192..c5b9dfd89 100644 --- a/gb.openssl/src/main.c +++ b/gb.openssl/src/main.c @@ -35,6 +35,7 @@ #define __MAIN_C #include +#include #include "main.h" #include "c_openssl.h" @@ -62,7 +63,7 @@ GB_DESC *GB_CLASSES[] EXPORT = { NULL }; -void sort_and_dedupe(GB_ARRAY list) +void MAIN_sort_and_dedupe(GB_ARRAY list) { GB_FUNCTION sortfn, removefn; int i; @@ -103,6 +104,11 @@ void sort_and_dedupe(GB_ARRAY list) } } +void MAIN_error(const char *msg) +{ + GB.Error(msg, ERR_error_string(ERR_get_error(), NULL)); +} + int EXPORT GB_INIT() { return 0; diff --git a/gb.openssl/src/main.h b/gb.openssl/src/main.h index 7b22a754c..0f3a11134 100644 --- a/gb.openssl/src/main.h +++ b/gb.openssl/src/main.h @@ -42,6 +42,7 @@ extern GB_INTERFACE GB; #endif -void sort_and_dedupe(GB_ARRAY list); +void MAIN_sort_and_dedupe(GB_ARRAY list); +void MAIN_error(const char *msg); #endif /* __MAIN_H */