379 lines
13 KiB
C
379 lines
13 KiB
C
//////////////////////////////////////////////////
|
|
// Bakalarska praca //
|
|
// Meno studenta: Tomas Lukac //
|
|
// Veduci BP: prof. Ing. Milos Drutarovsky CSc. //
|
|
// Skola: KEMT FEI TUKE //
|
|
// Datum poslednej upravy: 15.4.2020 //
|
|
//////////////////////////////////////////////////
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <wolfssl/ssl.h>
|
|
#include <wolfssl/certs_test.h>
|
|
#include <wolfssl/wolfcrypt/types.h>
|
|
|
|
#ifdef _WIN32
|
|
#include <Windows.h>
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#define O_NOCTTY 0x8000
|
|
#define O_NDELAY 0x4000
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include "../../kniznica/kryptografia.h"
|
|
#include "../../kniznica/komunikacia.h"
|
|
#include "../../kniznica/rs232.h"
|
|
|
|
#define RSA_VELKOST 2048
|
|
#define ECC_VELKOST 32
|
|
#define RSA_EXPONENT 65537
|
|
|
|
//cesty ku suborom
|
|
#define RSA_KLUC "../../certifikaty/klient/klient_rsa.key"
|
|
#define RSA_CERTIFIKAT "../../certifikaty/klient/klient_rsa.pem"
|
|
#define ECC_KLUC "../../certifikaty/klient/klient_ecc.key"
|
|
#define ECC_CERTIFIKAT "../../certifikaty/klient/klient_ecc.pem"
|
|
#define VYGENEROVANY_KLUC "../../certifikaty/klient/vygenerovany_kluc.key"
|
|
#define VYGENEROVANY_CERTIFIKAT "../../certifikaty/klient/vygenerovany_certifikat.pem"
|
|
#define KOMUNIKACNY_SUBOR "klient.txt"
|
|
|
|
int rs232_prijat;
|
|
int cislo_rozhrania = 0;
|
|
int aktualne_data = 0;
|
|
|
|
int rs232_citanie(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|
{
|
|
int uspech = 0;
|
|
int prebieha_nacitanie = 0;
|
|
int prebieha_nacitanie_velkosti_spravy = 0;
|
|
unsigned char znak;
|
|
|
|
|
|
//ziskanie dat zo serioveho rozhrania
|
|
if(aktualne_data == 0)
|
|
{
|
|
//otvorenie suboru do ktoreho sa zapisuju prijate binarne data
|
|
//ktore sa nasledne nacitaju do buffera (buf) pre desifrovanie
|
|
FILE* f = fopen(KOMUNIKACNY_SUBOR, "ab+");
|
|
|
|
//mnozstvo nacitanych dat
|
|
int nacitane_data = 0;
|
|
//velkost spravy, ktora sa bude prijmat
|
|
int velkost_spravy = 0;
|
|
//urcuje kolko bajtov z informacie o velkosti spravy
|
|
//uz bolo prijatych z celkoveho poctu (4)
|
|
int velkost_spravy_bajt = 0;
|
|
int velkost_spravy_pocet_bajtov = 4;
|
|
|
|
//kontrolne vzory, ktore jednoznacne identifikuju zaciatok a koniec spravy
|
|
unsigned char zaciatok_spravy[] = {0xAA, 0xAA, 0xAA, 0xAA};
|
|
int zaciatok_spravy_pozicia = 0; //aktualna pozicia v kontrolnom vzore
|
|
unsigned char koniec_spravy[] = {0xBB, 0xBB, 0xBB, 0xBB};
|
|
int koniec_spravy_pozicia = 0; //aktualna pozicia v kontrolnom vzore
|
|
int velkost_kontrolneho_vzoru = sizeof(zaciatok_spravy)/sizeof(zaciatok_spravy[0]);
|
|
|
|
while(1)
|
|
{
|
|
uspech = RS232_PollComport(cislo_rozhrania, &znak, 1);
|
|
if(uspech > 0)
|
|
{
|
|
//ak nacitanie spravy este nezacalo, ale bol najdeny bajt, ktory je sucastou kontrolneho vzoru,
|
|
//ktory urcuje zaciatok spravy, posun sa v kontrolnom vzore o jednu poziciu a cakaj ci nebudu
|
|
//prichadzat dalsie bajty z tohto kontrolneho vzoru
|
|
if(!prebieha_nacitanie && (znak == zaciatok_spravy[zaciatok_spravy_pozicia]) &&
|
|
(zaciatok_spravy_pozicia < velkost_kontrolneho_vzoru - 1))
|
|
{
|
|
zaciatok_spravy_pozicia++;
|
|
}
|
|
//ak prebehlo nacitanie vsetkych bajtov, ktore su sucastou kontrolneho vzoru urcujuceho zaciatok spravy
|
|
//ocakavaj prichod bajtov, ktore budu niest informaciu o velkosti spravy
|
|
else if(!prebieha_nacitanie && (znak == zaciatok_spravy[zaciatok_spravy_pozicia]) &&
|
|
(zaciatok_spravy_pozicia == velkost_kontrolneho_vzoru - 1))
|
|
{
|
|
prebieha_nacitanie_velkosti_spravy = 1;
|
|
zaciatok_spravy_pozicia = 0;
|
|
}
|
|
//pokracuj v nacitavani bajtov urcujucich velkost spravy, dokym nie su vsetky nacitane
|
|
//a po nacitani vsetkych bajtov moze zacat nacitanie spravy
|
|
else if(!prebieha_nacitanie && prebieha_nacitanie_velkosti_spravy)
|
|
{
|
|
velkost_spravy_bajt++;
|
|
if(velkost_spravy_bajt == velkost_spravy_pocet_bajtov)
|
|
{
|
|
prebieha_nacitanie = 1;
|
|
prebieha_nacitanie_velkosti_spravy = 0;
|
|
}
|
|
}
|
|
//ak prebieha nacitanie a bol najdeny bajt, ktory je sucastou kontrolneho vzoru, ktory urcuje koniec spravy,
|
|
//posun sa v kontrolnom vzore o jednu poziciu a cakaj ci nebudu prichadzat dalsie bajty z tohto kontrolneho vzoru
|
|
else if((prebieha_nacitanie && (znak == koniec_spravy[koniec_spravy_pozicia]) &&
|
|
(koniec_spravy_pozicia == 0)) || (!prebieha_nacitanie && (znak == koniec_spravy[koniec_spravy_pozicia]) &&
|
|
(koniec_spravy_pozicia < velkost_kontrolneho_vzoru - 1)))
|
|
{
|
|
koniec_spravy_pozicia++;
|
|
prebieha_nacitanie = 0;
|
|
}
|
|
//v pripade ak zacalo nacitanie kontrolneho vzoru, ktory urcuje koniec spravy, ale nebol najdeny posledny znak z tohto vzoru
|
|
//nacitaj do suboru docasne nezapisane znaky, ktore su sucastou kontrolneho vzoru a zaroven nacitaj aktualny znak
|
|
else if(!prebieha_nacitanie_velkosti_spravy && !prebieha_nacitanie && znak != koniec_spravy[koniec_spravy_pozicia])
|
|
{
|
|
for(int i = 0; i < koniec_spravy_pozicia; i++)
|
|
{
|
|
fwrite((char*)&koniec_spravy[i], 1, uspech, f);
|
|
nacitane_data += uspech;
|
|
}
|
|
fwrite((char*)&znak, 1, uspech, f);
|
|
nacitane_data += uspech;
|
|
|
|
koniec_spravy_pozicia = 0;
|
|
prebieha_nacitanie = 1;
|
|
}
|
|
//ak prebehlo nacitanie vsetkych bajtov, ktore su sucastou kontrolneho vzoru urcujuceho koniec spravy
|
|
//ukonci nacitanie spravy
|
|
else if(!prebieha_nacitanie_velkosti_spravy && !prebieha_nacitanie && (znak == koniec_spravy[0]) &&
|
|
(koniec_spravy_pozicia == 3))
|
|
{
|
|
prebieha_nacitanie = 0;
|
|
koniec_spravy_pozicia = 0;
|
|
break;
|
|
}
|
|
//inak prebieha nacitanie, cize zapis aktualny znak (bajt) do suboru
|
|
else
|
|
{
|
|
if(prebieha_nacitanie && !prebieha_nacitanie_velkosti_spravy)
|
|
{
|
|
fwrite((char*)&znak, 1, uspech, f);
|
|
nacitane_data += uspech;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
aktualne_data = nacitane_data;
|
|
nacitane_data = 0;
|
|
fclose(f);
|
|
}
|
|
//nacitanie dat zo suboru do buffera pre desifrovanie
|
|
uspech = 0;
|
|
while(uspech <= 0)
|
|
uspech = read(rs232_prijat, buf, sz);
|
|
aktualne_data -= uspech;
|
|
|
|
return uspech;
|
|
}
|
|
|
|
int rs232_zapis(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|
{
|
|
int uspech = 0;
|
|
|
|
//kontrolne vzory, ktore jednoznacne identifikuju zaciatok a koniec spravy
|
|
unsigned char zaciatok_spravy[] = {0xAA, 0xAA, 0xAA, 0xAA};
|
|
unsigned char koniec_spravy[] = {0xBB, 0xBB, 0xBB, 0xBB};
|
|
|
|
//vytvorenie bajtov ktore budu niest informaciu o velkosti posielanej spravy
|
|
unsigned char* velkost_spravy = calloc(4, sizeof(unsigned char));
|
|
velkost_spravy[0] = (sz >> 24) & 0xFF;
|
|
velkost_spravy[1] = (sz >> 16) & 0xFF;
|
|
velkost_spravy[2] = (sz >> 8) & 0xFF;
|
|
velkost_spravy[3] = sz & 0xFF;
|
|
|
|
//odoslanie kontrolnych vzorov, bajtov s velkostou spravy a samotnych dat na seriove rozhranie
|
|
RS232_SendBuf(cislo_rozhrania, (unsigned char*)zaciatok_spravy, sizeof(zaciatok_spravy));
|
|
RS232_SendBuf(cislo_rozhrania, (unsigned char*)velkost_spravy, 4);
|
|
uspech = (int)RS232_SendBuf(cislo_rozhrania, (unsigned char*)buf, sz);
|
|
RS232_SendBuf(cislo_rozhrania, (unsigned char*)koniec_spravy, sizeof(koniec_spravy));
|
|
free(velkost_spravy);
|
|
|
|
return uspech;
|
|
}
|
|
|
|
int main(int argc, char const *argv[])
|
|
{
|
|
char rezim[]={'8','N','1', 0};
|
|
int rychlost = 9600;
|
|
WOLFSSL *ssl;
|
|
WOLFSSL_CTX *ctx = NULL;
|
|
const char* subor = NULL;
|
|
int zadane_rozhranie = 0;
|
|
int uvedeny_subor = 0;
|
|
int nacitanie_zo_suboru = 0;
|
|
int generovanie_certifikatu = 0;
|
|
nastavenia_aplikacie nastavenia;
|
|
RS232_flushRXTX(cislo_rozhrania);
|
|
|
|
rs232_prijat = open(KOMUNIKACNY_SUBOR, O_RDWR | O_NOCTTY | O_NDELAY);
|
|
|
|
int uspech;
|
|
if((ctx = nastavit_ctx_klient()) == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
for(int i = 0; i < argc; i++)
|
|
{
|
|
if( (!strcmp(argv[i], "-s")) )
|
|
{
|
|
uvedeny_subor = 1;
|
|
if((argv[i+1] == NULL) )
|
|
{
|
|
printf("Nezadali ste cestu ku suboru\n");
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
subor = argv[i+1];
|
|
}
|
|
}
|
|
if( (!strcmp(argv[i], "-port")) )
|
|
{
|
|
zadane_rozhranie = 1;
|
|
if((argv[i+1] == NULL))
|
|
{
|
|
printf("Nezadali ste cislo serioveho rozhrania\n");
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
cislo_rozhrania = atoi(argv[i+1]);
|
|
if(RS232_OpenComport(cislo_rozhrania, rychlost, rezim, 1))
|
|
{
|
|
fprintf(stderr, "Nebolo mozne otvorit seriove rozhranie\n");
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
else if( (!strcmp(argv[i], "-n")) )
|
|
{
|
|
nacitanie_zo_suboru = 1;
|
|
if(generovanie_certifikatu)
|
|
{
|
|
fprintf(stderr, "Nie je mozne zvolit obidve metody nacitania certifikatov naraz\n");
|
|
return -1;
|
|
}
|
|
if((argv[i+1] == NULL) || (i == argc-1))
|
|
{
|
|
printf("Nezadali ste typ certifikatu ktory chcete nacitat zo suboru\n");
|
|
return -1;
|
|
}
|
|
else if(!strcmp(argv[i+1], "rsa"))
|
|
{
|
|
wolfSSL_CTX_load_verify_locations(ctx, "../../certifikaty/autorita/autorita_rsa.pem", NULL);
|
|
if(nacitat_certifikaty(ctx, RSA_CERTIFIKAT, RSA_KLUC) == -1) return -1;
|
|
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
|
|
|
|
}
|
|
else if(!strcmp(argv[i+1], "ecc"))
|
|
{
|
|
wolfSSL_CTX_load_verify_locations(ctx, "../../certifikaty/autorita/autorita_ecc.pem", NULL);
|
|
if(nacitat_certifikaty(ctx, ECC_CERTIFIKAT, ECC_KLUC) == -1) return -1;
|
|
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
|
|
|
|
}
|
|
else
|
|
{
|
|
printf("Zadali ste nespravny typ certifikatu\n");
|
|
return -1;
|
|
}
|
|
}
|
|
else if( (!strcmp(argv[i], "-g")) )
|
|
{
|
|
generovanie_certifikatu = 1;
|
|
if(nacitanie_zo_suboru)
|
|
{
|
|
fprintf(stderr, "Nie je mozne zvolit obidve metody nacitania certifikatov naraz\n");
|
|
return -1;
|
|
}
|
|
if((argv[i+1] == NULL) || (i == argc-1))
|
|
{
|
|
printf("Nezadali ste typ certifikatu ktory chcete vygenerovat\n");
|
|
return -1;
|
|
}
|
|
else if(!strcmp(argv[i+1], "rsa"))
|
|
{
|
|
wolfSSL_CTX_load_verify_locations(ctx, "../../certifikaty/autorita/autorita_rsa.pem", NULL);
|
|
if(generovat_rsa_certifikat(RSA_VELKOST, RSA_EXPONENT, CTC_SHA256wRSA, "SR", "Kosice", "local.dev", "server@server.sk") == -1) return -1;
|
|
if(nacitat_certifikaty(ctx, VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC) == -1) return -1;
|
|
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
|
|
|
|
}
|
|
else if(!strcmp(argv[i+1], "ecc"))
|
|
{
|
|
wolfSSL_CTX_load_verify_locations(ctx, "../../certifikaty/autorita/autorita_ecc.pem", NULL);
|
|
if(generovat_ecc_certifikat(ECC_VELKOST, ECC_SECP256R1, CTC_SHAwECDSA, "SR", "Kosice", "local.dev", "server@server.sk") == -1) return -1;
|
|
if(nacitat_certifikaty(ctx, VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC) == -1) return -1;
|
|
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
|
|
}
|
|
else
|
|
{
|
|
printf("Zadali ste nespravny typ certifikatu\n");
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!zadane_rozhranie)
|
|
{
|
|
fprintf(stderr, "Nebol urcene seriove rozhranie\n");
|
|
return -1;
|
|
}
|
|
else if(!generovanie_certifikatu && !nacitanie_zo_suboru)
|
|
{
|
|
fprintf(stderr, "Nebola zvolena metoda nacitania certifikatov\n");
|
|
printf("Zadajde prepinac -g (generovanie), alebo -n (nacitanie_zo_suboru) s parametrom rsa alebo ecc\n");
|
|
return -1;
|
|
}
|
|
else if(!uvedeny_subor)
|
|
{
|
|
fprintf(stderr, "Nebola uvedena cesta ku suboru na odoslanie\n");
|
|
return -1;
|
|
}
|
|
|
|
//nastav_sifry(ctx, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
|
|
|
|
//nastavenie vlastnych I/O funkcii
|
|
wolfSSL_SetIOSend(ctx, rs232_zapis);
|
|
wolfSSL_SetIORecv(ctx, rs232_citanie);
|
|
|
|
//pokus o vytvorenie novej wolfSSL relacie
|
|
if ((ssl = wolfSSL_new(ctx)) == NULL)
|
|
{
|
|
printf("Nepodarilo sa vytvorit ssl relaciu\n");
|
|
wolfSSL_CTX_free(ctx);
|
|
return -1;
|
|
}
|
|
|
|
//priradenie file descriptora suboru ako I/O pre TLS spojenie
|
|
wolfSSL_set_fd(ssl, rs232_prijat);
|
|
wolfSSL_set_using_nonblock(ssl, rs232_prijat);
|
|
|
|
//pokus o inizicalizaciu TLS handshaku so serverom
|
|
uspech = wolfSSL_connect(ssl);
|
|
if(uspech != SSL_SUCCESS)
|
|
{
|
|
char* popis_chyby = calloc(100, sizeof(char));
|
|
int chyba = wolfSSL_get_error(ssl, 0);
|
|
wolfSSL_ERR_error_string(chyba, popis_chyby);
|
|
fprintf(stderr, "Nastala chyba v spojeni.\nCislo chyby: %d\nDovod chyby: %s\n", chyba, popis_chyby);
|
|
printf("Skontrolujte certifikaty.\n");
|
|
free(popis_chyby);
|
|
return -1;
|
|
}
|
|
|
|
zobraz_sifru(ssl);
|
|
zobraz_certifikat(ssl);
|
|
nastav_funkciu(&nastavenia, "crc", ziadna);
|
|
poslat_subor(ssl, ctx, subor, &nastavenia);
|
|
|
|
//ukoncenie spojenia, vymazanie komunikacneho suboru
|
|
//a vycistenie serioveho buffera
|
|
ukoncit_spojenie(ssl, ctx);
|
|
RS232_flushRXTX(cislo_rozhrania);
|
|
RS232_CloseComport(cislo_rozhrania);
|
|
close(rs232_prijat);
|
|
fclose(fopen(KOMUNIKACNY_SUBOR, "wb"));
|
|
return 0;
|
|
} |