I'm trying to write a service to decrypt a large number of openssl-encrypted content. It works great with a simple command line program, but when I use the same code in a Poco (multi-threaded) server, I get:
error:1C800064:Provider routines::bad decrypt
OpenSSL 3.0.8 7 Feb 2023 (Library: OpenSSL 3.0.8 7 Feb 2023)
I tried copying std::strings
into C arrays, to see if that would help -- no luck
I don't know what I'm doing wrong. Any ideas on how I can make this work? I see old references to using mutex callbacks but the docs say they're not needed anymore.
Here's the code that always works on a CLI program but never works in my Poco service:
int decodeAndDecrypt(const char * dataIn,
const unsigned char * key,
const unsigned char * iv,
char * dataOut,
int * outLen,
char * errorMsg)
{
while (ERR_get_error());
BIO * bio = BIO_new_mem_buf((void *)dataIn, -1);
BIO * b64 = BIO_new(BIO_f_base64());
BIO * cipher = BIO_new(BIO_f_cipher());
BIO_set_cipher(cipher, EVP_aes_256_cbc(), key, iv, 0);
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
BIO_push(cipher, b64);
BIO_push(b64, bio);
char * outPtr = dataOut;
int max = *outLen;
*outLen = 0;
errorMsg[0] = 0;
while (true)
{
char tmp[1024] = {0};
int bytesRead = BIO_read(cipher, tmp, sizeof(tmp));
if (bytesRead <= 0)
{
break;
}
if (bytesRead > max)
{
snprintf(errorMsg, ERR_SZ, "%s: result data exceeds maximum buffer size.", __func__);
return EXIT_FAILURE;
}
snprintf(outPtr, max, "%s", tmp);
outPtr += bytesRead;
*outLen += bytesRead;
max -= bytesRead;
}
if (*outLen == 0) // If no data was transferred, check for errors
{
unsigned long errNo(0);
bool errorsFound(false);
while ((errNo = ERR_get_error()))
{
errorsFound = true;
array< char, 256 > temp;
ERR_error_string_n(errNo, temp.data(), temp.size());
strcat(errorMsg, temp.data());
}
if (errorsFound)
{
return EXIT_FAILURE;
}
}
BIO_free_all(cipher);
return EXIT_SUCCESS;
}
I didn't realize that EVP_aes_256_cbc() must have a 256 bit key and a 128 bit IV. After making sure that both values were the correct length and zero padded for shorter values, this routine began to work properly.