diff --git a/gb.openssl/src/c_openssl.c b/gb.openssl/src/c_openssl.c index 1e14d7b95..4ebbaa999 100644 --- a/gb.openssl/src/c_openssl.c +++ b/gb.openssl/src/c_openssl.c @@ -52,9 +52,18 @@ **/ BEGIN_METHOD(OpenSSL_RandomBytes, GB_INTEGER length) - char *ret = GB.TempString(NULL, VARG(length)); + char *ret; int res; + if (VARG(length) < 1) { + GB.Error("Invalid Parameter: length must be greater than 0"); + return; + } + if (VARG(length) > 0x7FFFEFF7) { + GB.Error("Invalid Parameter: length must be less than 2,147,479,544"); + return; + } + ret = GB.TempString(NULL, VARG(length)); #if OPENSSL_VERSION_NUMBER < 0x10100000L res = RAND_pseudo_bytes((unsigned char *) ret, VARG(length)); #else @@ -76,25 +85,40 @@ END_METHOD BEGIN_METHOD(OpenSSL_Pbkdf2, GB_STRING password; GB_STRING salt; GB_LONG iterations; GB_INTEGER keylength; GB_STRING method) #if OPENSSL_VERSION_NUMBER < 0x10002000L - GB.Error("Pbkdf2 not supported"); - return; + GB.Error("Pbkdf2 not supported"); + return; #else - int ret; - char hash[VARG(keylength)]; - const EVP_MD *emethod; - emethod = EVP_get_digestbyname(STRING(method)); - if (!emethod) { - GB.Error("Digest method not supported"); - return; - } - memset(hash, 0, sizeof(hash)); - ret = PKCS5_PBKDF2_HMAC((const char *) STRING(password), LENGTH(password), (const unsigned char *) STRING(salt), - LENGTH(salt), (int) VARG(iterations), emethod, VARG(keylength), (unsigned char *) hash); - if (ret == 0) { - GB.Error("Pbkdf2 call failed"); - return; - } - GB.ReturnNewString(hash, VARG(keylength)); + int ret, lKey; + char *hash; + const EVP_MD *emethod; + + if (VARG(iterations) < 1) { + GB.Error("Invalid Parameter: iterations must be greater than 0"); + return; + } + lKey = VARG(keylength); + if (lKey < 1) { + GB.Error("Invalid Parameter: keylength must be greater than 0"); + return; + } + if (lKey > 0x7FFFEFF7) { + GB.Error("Invalid Parameter: 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"); + return; + } + memset(hash, 0, sizeof(hash)); + 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; + } + GB.ReturnString(hash); #endif END_METHOD @@ -102,46 +126,63 @@ END_METHOD BEGIN_METHOD(OpenSSL_Scrypt, GB_STRING password; GB_STRING salt; GB_LONG N; GB_LONG r; GB_LONG p; GB_LONG keylength) #if OPENSSL_VERSION_NUMBER < 0x10100000L - GB.Error("Scrypt not supported"); - return; + GB.Error("Scrypt not supported"); + return; #else - int ret; - uint64_t lN, lR, lP; - size_t lKey; - char hash[VARG(keylength)]; + int ret; + uint64_t lN, lR, lP; + size_t lKey; + char *hash; - lN = VARG(N); - if (lN < 2) { - GB.Error("N must be above 1"); - return; - } - lR = VARG(r); - if (lR == 0) { - GB.Error("R must be above 0"); - return; - } - lP = VARG(p); - if (lP == 0) { - GB.Error("P must be above 0"); - return; - } - lKey = VARG(keylength); - if (lKey == 0) { - GB.Error("Key must not be null"); - return; - } - if (EVP_PBE_scrypt(NULL, 0, NULL, 0, lN, lR, lP, 0, NULL, 0) == 0) { - GB.Error("Scrypt prep call failed"); - return; - } - memset(hash, 0, sizeof(hash)); - 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("Scrypt call failed"); - return; - } - GB.ReturnNewString(hash, lKey); + lKey = VARG(keylength); + if (lKey < 1) { + GB.Error("Invalid Parameter: keylength must be greater than 0"); + return; + } + if (lKey > 0x7FFFEFF7L) { + GB.Error("Invalid Parameter: 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"); + return; + } + if (ceil(log2(lN)) != floor(log2(lN))) { + GB.Error("Invalid Parameter: N must be a power of 2"); + return; + } + lR = VARG(r); + if (lR < 1) { + GB.Error("Invalid Parameter: r must be greater than 0"); + return; + } + if (lR > 0xFFFFFFFFL) { + GB.Error("Invalid Parameter: r must be a 32-bit number"); + return; + } + lP = VARG(p); + if (lP < 1) { + GB.Error("Invalid Parameter: p must be greater than 0"); + return; + } + if (lP > 0xFFFFFFFFL) { + GB.Error("Invalid Parameter: 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"); + return; + } + memset(hash, 0, sizeof(hash)); + 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"); + return; + } + GB.ReturnString(hash); #endif END_METHOD @@ -151,9 +192,9 @@ GB_DESC COpenSSL[] = { GB_STATIC_METHOD("RandomBytes", "s", OpenSSL_RandomBytes, "(Length)i"), - GB_STATIC_METHOD("Pbkdf2", "s", OpenSSL_Pbkdf2, "(Password)s(Salt)s(Iterations)i(KeyLength)i(Method)s"), + GB_STATIC_METHOD("Pbkdf2", "s", OpenSSL_Pbkdf2, "(Password)s(Salt)s(Iterations)l(KeyLength)i(Method)s"), - GB_STATIC_METHOD("Scrypt", "s", OpenSSL_Scrypt, "(Password)s(Salt)s(N)i(R)i(P)i(KeyLength)i"), + GB_STATIC_METHOD("Scrypt", "s", OpenSSL_Scrypt, "(Password)s(Salt)s(N)l(R)l(P)l(KeyLength)l"), GB_END_DECLARE };