Fix some incorrect use of Gambas strings. Better error messages.

[GB.OPENSSL]
* BUG: Fix some incorrect use of Gambas strings.
* NEW: Better error messages.
This commit is contained in:
Benoît Minisini 2023-09-15 16:46:33 +02:00
parent 3a515efc15
commit ddb941f1c3
5 changed files with 55 additions and 34 deletions

View file

@ -35,7 +35,7 @@
#define __C_CIPHER_C
#include <assert.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
@ -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);

View file

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

View file

@ -37,7 +37,6 @@
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#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);

View file

@ -35,6 +35,7 @@
#define __MAIN_C
#include <openssl/evp.h>
#include <openssl/err.h>
#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;

View file

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