196 lines
4.7 KiB
C
196 lines
4.7 KiB
C
//
|
|
// Készítette: Toldi Balázs Ádám
|
|
// Dátum: 2019. 10. 20.
|
|
//
|
|
#include "crypto.h"
|
|
|
|
#undef APPMACROS_ONLY
|
|
#include <openssl/applink.c>
|
|
|
|
|
|
RSA * createRSA(unsigned char * key,int public)
|
|
{
|
|
RSA *rsa= NULL;
|
|
BIO *keybio ;
|
|
keybio = BIO_new_mem_buf(key, -1);
|
|
if (keybio==NULL)
|
|
{
|
|
printf( "Failed to create key BIO");
|
|
return 0;
|
|
}
|
|
if(public)
|
|
{
|
|
rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
|
|
}
|
|
else
|
|
{
|
|
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
|
|
}
|
|
if(rsa == NULL)
|
|
{
|
|
printf( "Failed to create RSA");
|
|
}
|
|
|
|
return rsa;
|
|
}
|
|
|
|
RSA *createRSAfromFile(char *file, int pub) {
|
|
FILE * fp = fopen(file,"rb");
|
|
|
|
if(fp == NULL)
|
|
{
|
|
printf("Unable to open file %s \n",file);
|
|
return NULL;
|
|
}
|
|
RSA *rsa= RSA_new() ;
|
|
if(pub)
|
|
{
|
|
rsa = PEM_read_RSA_PUBKEY(fp, &rsa,NULL, NULL);
|
|
}
|
|
else
|
|
{
|
|
rsa = PEM_read_RSAPrivateKey(fp, &rsa,NULL, NULL);
|
|
}
|
|
return rsa;
|
|
}
|
|
|
|
|
|
|
|
RSA *generate_key() {
|
|
int ret = 0;
|
|
RSA *r = NULL;
|
|
BIGNUM *bne = NULL;
|
|
BIO *bp_public = NULL, *bp_private = NULL;
|
|
|
|
int bits = 2048;
|
|
unsigned long e = RSA_F4;
|
|
|
|
// 1. generate rsa key
|
|
bne = BN_new();
|
|
ret = BN_set_word(bne,e);
|
|
if(ret != 1){
|
|
BIO_free_all(bp_public);
|
|
BIO_free_all(bp_private);
|
|
RSA_free(r);
|
|
BN_free(bne);
|
|
}
|
|
|
|
r = RSA_new();
|
|
ret = RSA_generate_key_ex(r, bits, bne, NULL);
|
|
if(ret != 1){
|
|
BIO_free_all(bp_public);
|
|
BIO_free_all(bp_private);
|
|
RSA_free(r);
|
|
BN_free(bne);
|
|
}
|
|
|
|
// 2. save public key
|
|
bp_public = BIO_new_file("public.pem", "w+");
|
|
ret = PEM_write_bio_RSAPublicKey(bp_public, r);
|
|
if(ret != 1){
|
|
BIO_free_all(bp_public);
|
|
BIO_free_all(bp_private);
|
|
RSA_free(r);
|
|
BN_free(bne);
|
|
}
|
|
|
|
// 3. save private key
|
|
bp_private = BIO_new_file("private.pem", "w+");
|
|
ret = PEM_write_bio_RSAPrivateKey(bp_private, r, NULL, NULL, 0, NULL, NULL);
|
|
BIO_free_all(bp_public);
|
|
BIO_free_all(bp_private);
|
|
RSA_free(r);
|
|
BN_free(bne);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
void RSA_getPublicKey(RSA*r,char* pubkey){
|
|
int keylen;
|
|
|
|
BIO *bio = BIO_new(BIO_s_mem());
|
|
int res = PEM_write_bio_RSA_PUBKEY(bio,r);
|
|
keylen = BIO_pending(bio);
|
|
|
|
int re = BIO_read(bio, pubkey, keylen);
|
|
BIO_free_all(bio);
|
|
}
|
|
|
|
int public_encrypt(unsigned char *data, int data_len, unsigned char *key, unsigned char *encrypted) {
|
|
RSA * rsa = createRSA(key,1);
|
|
int result = RSA_public_encrypt(data_len,data,encrypted,rsa,RSA_PKCS1_PADDING);
|
|
return result;
|
|
}
|
|
|
|
int private_decrypt(unsigned char *enc_data, int data_len, unsigned char *key, unsigned char *decrypted) {
|
|
RSA * rsa = createRSA(key,0);
|
|
int result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,RSA_PKCS1_PADDING);
|
|
return result;
|
|
}
|
|
|
|
int base64Encode(const unsigned char* input ,size_t len, char** output) {
|
|
BIO *bio, *b64;
|
|
BUF_MEM *bufferPtr;
|
|
|
|
b64 = BIO_new(BIO_f_base64());
|
|
bio = BIO_new(BIO_s_mem());
|
|
bio = BIO_push(b64, bio);
|
|
|
|
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
|
|
BIO_write(bio, input, len);
|
|
BIO_flush(bio);
|
|
BIO_get_mem_ptr(bio, &bufferPtr);
|
|
BIO_set_close(bio, BIO_NOCLOSE);
|
|
BIO_free_all(bio);
|
|
|
|
*output=bufferPtr->data;
|
|
|
|
|
|
return 0;
|
|
}
|
|
size_t calcDecodeLength(const char* b64input) { //Calculates the length of a decoded string
|
|
size_t len = strlen(b64input),
|
|
padding = 0;
|
|
|
|
if (b64input[len-1] == '=' && b64input[len-2] == '=') //last two chars are =
|
|
padding = 2;
|
|
else if (b64input[len-1] == '=') //last char is =
|
|
padding = 1;
|
|
|
|
return (len*3)/4 - padding;
|
|
}
|
|
|
|
int base64Decode(const char* input, unsigned char**buffer,size_t* len) { //Decodes a base64 encoded string
|
|
BIO *bio, *b64;
|
|
|
|
int decodeLen = calcDecodeLength(input);
|
|
*buffer = (unsigned char*)malloc(decodeLen + 1);
|
|
(*buffer)[decodeLen] = '\0';
|
|
|
|
bio = BIO_new_mem_buf(input, -1);
|
|
b64 = BIO_new(BIO_f_base64());
|
|
bio = BIO_push(b64, bio);
|
|
|
|
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer
|
|
*len = BIO_read(bio, *buffer, strlen(input));
|
|
assert(*len == decodeLen); //length should equal decodeLen, else something went horribly wrong
|
|
BIO_free_all(bio);
|
|
|
|
return (0); //success
|
|
}
|
|
|
|
void hexEncode(char*input,char* output){
|
|
size_t len = strlen(input);
|
|
for(int i = 0; i<len; i++){
|
|
sprintf(output+i*2, "%02X", input[i]);
|
|
}
|
|
|
|
}
|
|
|
|
void hexDecode(char *input, char *out) {
|
|
size_t len = strlen(input);
|
|
for(int i = 0; i<len; i++){
|
|
sprintf(out+i, "%x", input[i]);
|
|
}
|
|
}
|