I've finally found a solution.
The problem was strlen((char*)outputBuffer)
becuase it was always 0
since output from rsa_pkcs1_encrypt
starts with \0
.
The right solution is
bool AsymetricCipher::encrypt(const std::string &pathToPublicKey, std::istream &inputData, std::ostream &encryptedData) {
if(initServerPublicCtx(pathToPublicKey, 512)) {
std::cout << "Encryption error: Can't load public key from file: " << pathToPublicKey << std::endl;
return false;
}
entropy_context entropy;
ctr_drbg_context ctr_drbg;
char *pers = "rsa_encrypt";
entropy_init(&entropy);
if(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, (unsigned char*)pers, strlen(pers)) != 0) {
std::cout << "Encryption error: ctr_drbg_init failed" << std::endl;
return false;
}
size_t inputSize = ::getStreamSize(inputData);
unsigned char *buffer = new unsigned char[inputSize];
memset(buffer, 0, inputSize);
inputData.read((char *)buffer, inputSize);
size_t MAX_OUTPUT_LENGTH = ctx.len;
unsigned char *outputBuffer = new unsigned char[MAX_OUTPUT_LENGTH];
memset(outputBuffer, 0, MAX_OUTPUT_LENGTH);
bool retVal = true;
if(rsa_pkcs1_encrypt(&ctx, ctr_drbg_random, &ctr_drbg, RSA_PUBLIC, inputSize, buffer, outputBuffer) != 0) {
std::cout << "Encryption error: rsa_pkcs1_encrypt failed" << std::endl;
retVal = false;
}
if(retVal) {
std::string base64;
Base64Wrapper::encode(outputBuffer, MAX_OUTPUT_LENGTH, base64);
encryptedData << base64;
::cleanMemory(base64);
}
::cleanMemory(outputBuffer, MAX_OUTPUT_LENGTH);
::cleanMemory(buffer, ctx.len);
delete [] outputBuffer;
delete [] buffer;
return retVal;
}
And for decryption
bool AsymetricCipher::decrypt( const std::string &pathToPrivateKey, std::istream &encryptedData, std::ostream &decryptedData ) {
if(initServerPrivateCtx(pathToPrivateKey, 512)) {
std::cout << "Decrypt error: Can't load private key from file: " << pathToPrivateKey << std::endl;
return false;
}
size_t inputSize = ::getStreamSize(encryptedData);
size_t outputSize = 0;
unsigned char* buffer = NULL;
std::string base64;
size_t bufferSize = 0;
encryptedData >> base64;
Base64Wrapper::decode(base64, &buffer, &bufferSize);
::cleanMemory(base64);
size_t MAX_OUTPUT_LENGTH = ctx.len;
unsigned char *outputBuffer = new unsigned char[MAX_OUTPUT_LENGTH];
bool retVal = true;
if(rsa_pkcs1_decrypt(&ctx, RSA_PRIVATE, &outputSize, buffer, outputBuffer, MAX_OUTPUT_LENGTH) != 0) {
std::cout << "Decryption error: rsa_pkcs1_decrypt failed" << std::endl;
retVal = false;
}
if(retVal) {
outputBuffer[outputSize] = '\0';
decryptedData << outputBuffer;
}
::cleanMemory(buffer, bufferSize);
::cleanMemory(outputBuffer, outputSize);
delete [] outputBuffer;
delete [] buffer;
return retVal;
}