bakalarska_praca/rs232_kanal/server.c
2020-04-10 19:04:14 +02:00

310 lines
9.7 KiB
C

//////////////////////////////////////////////////
// Bakalarska praca //
// Meno studenta: Tomas Lukac //
// Veduci BP: prof. Ing. Milos Drutarovsky CSc. //
// Skola: KEMT FEI TUKE //
// Datum poslednej upravy: 6.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/server/server_rsa.key"
#define RSA_CERTIFIKAT "../certifikaty/server/server_rsa.pem"
#define ECC_KLUC "../certifikaty/server/server_ecc.key"
#define ECC_CERTIFIKAT "../certifikaty/server/server_ecc.pem"
#define VYGENEROVANY_KLUC "../certifikaty/server/vygenerovany_kluc.key"
#define VYGENEROVANY_CERTIFIKAT "../certifikaty/server/vygenerovany_certifikat.pem"
#define KOMUNIKACNY_SUBOR "server.txt"
int rs232_prijat;
int cislo_rozhrania = 0;
int prebieha_nacitanie = 0;
int aktualne_data = 0;
int rs232_citanie(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
int uspech = 0;
//ziskanie dat zo serioveho rozhrania
if(aktualne_data == 0)
{
FILE* f = fopen(KOMUNIKACNY_SUBOR, "ab");
int nacitane_data = 0;
unsigned char znak;
//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
while(1)
{
uspech = RS232_PollComport(cislo_rozhrania, &znak, 1);
if(uspech > 0)
{
if(!prebieha_nacitanie && (znak == zaciatok_spravy[zaciatok_spravy_pozicia]) && (zaciatok_spravy_pozicia <= 2))
{
zaciatok_spravy_pozicia++;
}
else if(!prebieha_nacitanie && (znak == zaciatok_spravy[zaciatok_spravy_pozicia]) && (zaciatok_spravy_pozicia == 3))
{
//ak bol najdeny koniec kontrolneho vzoru, tak je zapnuta znacka,
//ktora urcuje ze prebieha nacitavanie spravy
prebieha_nacitanie = 1;
zaciatok_spravy_pozicia = 0;
//zaciatok_spravy_pozicia = 0;
}
else if((prebieha_nacitanie && (znak == koniec_spravy[0]) && (koniec_spravy_pozicia == 0)) || (!prebieha_nacitanie && (znak == koniec_spravy[0]) && (koniec_spravy_pozicia <= 2)))
{
koniec_spravy_pozicia++;
prebieha_nacitanie = 0;
}
else if(!prebieha_nacitanie && znak != koniec_spravy[0])
{
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;
}
else if(!prebieha_nacitanie && (znak == koniec_spravy[0]) && (koniec_spravy_pozicia == 3))
{
//ak bol najdeny koniec kontrolneho vzoru, tak je vypnuta znacka,
//ktora urcuje ze prebieha nacitanie spravy
prebieha_nacitanie = 0;
koniec_spravy_pozicia = 0;
//koniec_spravy_pozicia = 0;
break;
}
else
{
if(prebieha_nacitanie)
{
fwrite((char*)&znak, 1, uspech, f);
nacitane_data += uspech;
}
}
}
}
aktualne_data = nacitane_data;
nacitane_data = 0;
fclose(f);
}
//nacitanie dat zo suboru do buffera
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};
RS232_SendBuf(cislo_rozhrania, (unsigned char*)zaciatok_spravy, 4);
uspech = RS232_SendBuf(cislo_rozhrania, (unsigned char*)buf, sz);
RS232_SendBuf(cislo_rozhrania, (unsigned char*)koniec_spravy, 4);
RS232_flushTX(cislo_rozhrania);
return uspech;
}
int main(int argc, char const *argv[])
{
WOLFSSL *ssl;
WOLFSSL_CTX *ctx = NULL;
int rychlost = 9600;
char rezim[]={'8','N','1', 0};
int zadane_rozhranie = 0;
int generovanie_certifikatu = 0;
int nacitanie_zo_suboru = 0;
nastavenia_aplikacie nastavenia;
rs232_prijat = open(KOMUNIKACNY_SUBOR, O_RDWR | O_NOCTTY | O_NDELAY);
int uspech;
if((ctx = nastavit_ctx_server()) == NULL)
{
return -1;
}
else
{
for(int i = 0; i < argc; i++)
{
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"))
{
printf("jo\n");
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;
}
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;
}
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;
}
//nastav_sifry(ctx, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
//wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
wolfSSL_SetIOSend(ctx, rs232_zapis);
wolfSSL_SetIORecv(ctx, rs232_citanie);
while(1)
{
printf("------------\n");
if ((ssl = wolfSSL_new(ctx)) == NULL)
{
printf("Nepodarilo sa vytvorit ssl relaciu\n");
wolfSSL_CTX_free(ctx);
return -1;
}
wolfSSL_set_fd(ssl, rs232_prijat);
wolfSSL_set_using_nonblock(ssl, rs232_prijat);
uspech = wolfSSL_accept(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");
return -1;
}
zobraz_sifru(ssl);
zobraz_certifikat(ssl);
nastav_funkciu(&nastavenia, funkcia_BLAKE2B);
prijat_subor(ssl, ctx, &nastavenia);
}
RS232_CloseComport(cislo_rozhrania);
close(rs232_prijat);
close(open(KOMUNIKACNY_SUBOR, O_RDWR | O_NOCTTY | O_NDELAY));
return 0;
}