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:
parent
3a515efc15
commit
ddb941f1c3
5 changed files with 55 additions and 34 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,29 +92,29 @@ 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");
|
||||
MAIN_error("Pbkdf2 call failed: &1");
|
||||
return;
|
||||
}
|
||||
GB.ReturnString(hash);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue