/*
http://ardoino.altervista.org/crypto-security/articles/openssl_all
*/
//-------------------rsa.c-----------------------------------------------
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#define READPUB 0
#define READSEC 1
void rsa_ed(int mode, char *fin, char *fout, char *pemfile)
{
int size=0,len=0,ks=0;
RSA *key=NULL;
FILE *fpin=NULL, *fpout=NULL;
unsigned char *cipher=NULL,*plain=NULL;
if (strcmp(fin, fout) == 0) {
fprintf(stderr,"Error: input and output files must not\
be the same file.\n");
exit(EXIT_FAILURE);
}
if (mode == 0) {
fpin = fopen(fin, "r");
key = (RSA *)readpemkeys(READPUB, pemfile);
fpout = fopen(fout, "w");
ks = RSA_size(key);
plain = (unsigned char *)malloc(ks * \
sizeof(unsigned char));
cipher = (unsigned char*)malloc(ks * \
sizeof(unsigned char));
printf("Encrypting '%s' file.\n", fin);
while(!feof(fpin)) {
memset(plain,'\0',ks + 1);
memset(cipher, '\0', ks + 1);
len = fread(plain, 1, ks - 11, fpin);
size = rsa_encrypt(key, plain, len, &cipher);
fwrite(cipher, 1, size, fpout);
}
fclose(fpout);
fclose(fpin);
free(cipher);
free(plain);
RSA_free(key);
printf("Done.\n");
} else if (mode == 1) {
fpin = fopen(fin, "r");
key = (RSA *)readpemkeys(READSEC, pemfile);
fpout = fopen(fout, "w");
ks = RSA_size(key);
cipher = (unsigned char*)malloc(ks * \
sizeof(unsigned char));
plain = (unsigned char*)malloc(ks * \
sizeof(unsigned char));
printf("Decrypting '%s' file.\n", fin);
while(!feof(fpin)) {
memset(cipher, '\0', ks);
memset(plain, '\0', ks);
if ((len = fread(cipher, 1, ks, fpin)) == 0)
break;
size = rsa_decrypt(key, cipher, len, &plain);
fwrite(plain, 1, size, fpout);
}
fclose(fpout);
fclose(fpin);
free(plain);
free(cipher);
RSA_free(key);
printf("Done.\n");
}
return;
}
void genkey(int size, char *secfile, char *pubfile)
{
RSA *key=NULL;
FILE *fp;
printf("Generating RSA keys[%d bits].\n", size);
if (size < 64) {
fprintf(stderr, "Error: RSA Key pair size too small.\n");
fprintf(stderr, "size >= 64\n");
exit(EXIT_FAILURE);
}
if((key = RSA_generate_key(size,3,NULL,NULL)) == NULL) {
fprintf(stderr,"%s\n",ERR_error_string(ERR_get_error(),NULL));
exit(EXIT_FAILURE);
}
if(RSA_check_key(key) < 1) {
fprintf(stderr,"Error: Problems while generating RSA Key.\n \
Retry.\n");
exit(EXIT_FAILURE);
}
fp=fopen(secfile,"w");
if(PEM_write_RSAPrivateKey(fp,key,NULL,NULL,0,0,NULL) == 0) {
fprintf(stderr,"Error: problems while writing RSA Private \
Key.\n");
exit(EXIT_FAILURE);
}
fclose(fp);
fp=fopen(pubfile,"w");
if(PEM_write_RSAPublicKey(fp,key) == 0) {
fprintf(stderr,"Error: problems while writing RSA Public Key.\n");
exit(EXIT_FAILURE);
}
fclose(fp);
RSA_free(key);
printf("Done.\n");
return;
}
void* readpemkeys(int type, char *pemfile)
{
FILE *fp;
RSA *key=NULL;
switch (type){
case READPUB:
if((fp = fopen(pemfile,"r")) == NULL) {
fprintf(stderr,"Error: Public Key file doesn't exists.\n");
exit(EXIT_FAILURE);
}
if((key = PEM_read_RSAPublicKey(fp,NULL,NULL,NULL)) == NULL) {
fprintf(stderr,"Error: problems while reading Public Key.\n");
exit(EXIT_FAILURE);
}
fclose(fp);
return key;
break;
case READSEC:
if((fp = fopen(pemfile,"r")) == NULL) {
fprintf(stderr,"Error: Private Key file doesn't exists.\n");
exit(EXIT_FAILURE);
}
if((key = PEM_read_RSAPrivateKey(fp,NULL,NULL,NULL)) == NULL) {
fprintf(stderr,"Error: problmes while reading Private Key. %d %s\n",type,pemfile);
exit(EXIT_FAILURE);
}
fclose(fp);
if(RSA_check_key(key) == -1) {
fprintf(stderr,"Error: Problems while reading RSA Private Key in \
'%s' file.\n",pemfile);
exit(EXIT_FAILURE);
} else if(RSA_check_key(key) == 0) {
fprintf(stderr,"Error: Bad RSA Private Key readed in '%s' \
file.\n",pemfile);
exit(EXIT_FAILURE);
}
else
return key;
break;
}
return key;
}
int rsa_encrypt(void *key, unsigned char *plain, int len, \
unsigned char **cipher)
{
int clen=0;
srand(time(NULL));
if((clen = RSA_public_encrypt(len, plain, *cipher, (RSA*)key, \
RSA_PKCS1_PADDING)) == -1) {
fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
exit(EXIT_FAILURE);
} else
return clen;
}
int rsa_decrypt(void *key, unsigned char *cipher, int len, \
unsigned char **plain)
{
int plen=0;
if((plen = RSA_private_decrypt(len, cipher, *plain, (RSA*)key,RSA_PKCS1_PADDING)) == -1) {
fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
exit(EXIT_FAILURE);
} else
return plen;
}
//-------------------end rsa.c-------------------------------------------