MAYBE THIS POST SHOULD BE MOVED TO THE GENERAL CATEGORY...
First things first. I suck at C code!! Thus I need help to use this function from openssl.pas:
function RSA_private_decrypt(flen: cint; from_buf, to_buf: PByte; arsa: PRSA; padding: cint): cint;
I'm using this
example in C as a guide:
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <string.h>
#define KEY_LENGTH 2048
#define PUB_EXP 3
#define PRINT_KEYS
#define WRITE_TO_FILE
int main(void) {
size_t pri_len; // Length of private key
size_t pub_len; // Length of public key
char *pri_key; // Private key
char *pub_key; // Public key
char msg[KEY_LENGTH/8]; // Message to encrypt
char *encrypt = NULL; // Encrypted message
char *decrypt = NULL; // Decrypted message
char *err; // Buffer for any error messages
// Generate key pair
printf("Generating RSA (%d bits) keypair...", KEY_LENGTH
); RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL);
// To get the C-string PEM form:
BIO *pri = BIO_new(BIO_s_mem());
BIO *pub = BIO_new(BIO_s_mem());
PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
PEM_write_bio_RSAPublicKey(pub, keypair);
pri_len = BIO_pending(pri);
pub_len = BIO_pending(pub);
pri_key
= malloc(pri_len
+ 1); pub_key
= malloc(pub_len
+ 1);
BIO_read(pri, pri_key, pri_len);
BIO_read(pub, pub_key, pub_len);
pri_key[pri_len] = '\0';
pub_key[pub_len] = '\0';
#ifdef PRINT_KEYS
printf("\n%s\n%s\n", pri_key
, pub_key
); #endif
// Get the message to encrypt
printf("Message to encrypt: "); fgets(msg
, KEY_LENGTH
-1, stdin
);
// Encrypt the message
encrypt
= malloc(RSA_size
(keypair
)); int encrypt_len;
if((encrypt_len
= RSA_public_encrypt
(strlen(msg
)+1, (unsigned char*)msg
, (unsigned char*)encrypt
, keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr
, "Error encrypting message: %s\n", err
); goto free_stuff;
}
#ifdef WRITE_TO_FILE
// Write the encrypted message to a file
FILE
*out
= fopen("out.bin", "w"); fwrite(encrypt
, sizeof(*encrypt
), RSA_size
(keypair
), out
); printf("Encrypted message written to file.\n"); encrypt = NULL;
// Read it back
printf("Reading back encrypted message and attempting decryption...\n"); encrypt
= malloc(RSA_size
(keypair
)); out
= fopen("out.bin", "r"); fread(encrypt
, sizeof(*encrypt
), RSA_size
(keypair
), out
); #endif
// Decrypt it
decrypt
= malloc(encrypt_len
); if(RSA_private_decrypt(encrypt_len, (unsigned char*)encrypt, (unsigned char*)decrypt,
keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), err);
fprintf(stderr
, "Error decrypting message: %s\n", err
); goto free_stuff;
}
printf("Decrypted message: %s\n", decrypt
);
free_stuff:
RSA_free(keypair);
BIO_free_all(pub);
BIO_free_all(pri);
return 0;
}
I'll appreciate any help on this subject.
Now the whining and wailing (you can skip this part):
Well, I have my eyes sore reading code from lNet, Synapse and code in JAVA as well, and I couldn't find much.
In lNet it seams like there is no RSA decryption or it is really hard for me to find the place where decryption is done.
In Synapse I can't see how it is done either.
The LockBox component has an implementation for RSA but it can't decrypt beyond 1024 bit, so for what we need is useless and didn't even try to use it.
Then after a long time of looking to the Lazarus forum and the wiki. Digging in JAVA Android Studio code. And also googling around I found the C code example (above mentioned) doing the decryption (I stumbled many times on it thanks to this old post
RSA Encryption ).
At first I didn't pay attention to it because I'm not comfortable with C code and there's a lot of things that I don't know well how to wrap it around with Pascal code.
But after reaching the end of the road I found that FPC has something done with OpenSSL and there is an example (located in
{Lazarusfolder}\fpc\3.2.0\source\packages\openssl\examples\genkeypair.lpr) to generate both keys (public and private) which is good but not good enough. So I looked through the whole FPC and Lazarus code and couldn't find a place where the (deprecated from OpenSSL library)
function RSA_private_decrypt(flen: cint; from_buf, to_buf: PByte; arsa: PRSA; padding: cint): cint; from
openssl.pas is used
Thank you very much if you went this far reading.