bakalarska_praca/rs232_kanal/klient/klient.c

318 lines
9.5 KiB
C
Raw Permalink Normal View History

2020-03-11 21:01:54 +00:00
//////////////////////////////////////////////////
// Bakalarska praca //
// Meno studenta: Tomas Lukac //
// Veduci BP: prof. Ing. Milos Drutarovsky CSc. //
// Skola: KEMT FEI TUKE //
2020-05-06 10:53:08 +00:00
// Datum poslednej upravy: 6.5.2020 //
2020-03-11 21:01:54 +00:00
//////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wolfssl/ssl.h>
#include <wolfssl/certs_test.h>
#include <wolfssl/wolfcrypt/types.h>
#include <time.h>
2020-03-11 21:01:54 +00:00
#ifdef _WIN32
#include <Windows.h>
2020-03-30 01:32:44 +00:00
#include <io.h>
#include <fcntl.h>
2020-04-07 20:11:21 +00:00
#define O_NOCTTY 0x8000
#define O_NDELAY 0x4000
2020-03-11 21:01:54 +00:00
#else
#include <unistd.h>
#endif
2020-04-16 09:25:05 +00:00
#include "../../kniznica/kryptografia.h"
#include "../../kniznica/komunikacia.h"
2020-03-11 21:01:54 +00:00
2020-04-07 20:11:21 +00:00
#define RSA_VELKOST 2048
#define ECC_VELKOST 32
#define RSA_EXPONENT 65537
//cesty ku suborom
2020-04-16 09:25:05 +00:00
#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"
2020-04-07 20:11:21 +00:00
#define KOMUNIKACNY_SUBOR "klient.txt"
//subor do ktoreho sa zapisuje komunikacia
int k_subor;
2020-04-10 17:04:14 +00:00
int cislo_rozhrania = 0;
//velkost dat ktore sa prave nachadzaju v seriovom bufferi
//a cakaju na nacitanie do buffera pre desifrovanie
2020-04-07 20:11:21 +00:00
int aktualne_data = 0;
2020-03-30 01:32:44 +00:00
//mnozstvo dat ktore boli nacitane do buffera pre desifrovanie
//pri zavolani funkcie rs232_citanie()
int nacitane_data = 0;
2020-04-16 09:25:05 +00:00
int rs232_citanie(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
2020-04-07 20:11:21 +00:00
//ziskanie dat zo serioveho rozhrania
if(aktualne_data == 0)
{
aktualne_data = rs232_prijat_spravu(cislo_rozhrania, KOMUNIKACNY_SUBOR);
if(aktualne_data <= 0)
2020-04-07 20:11:21 +00:00
{
fprintf(stderr, "Nastala chyba pri prijati spravy\n");
return -1;
2020-04-07 20:11:21 +00:00
}
2020-03-30 01:32:44 +00:00
}
2020-04-16 09:25:05 +00:00
//nacitanie dat zo suboru do buffera pre desifrovanie
nacitane_data = 0;
while(nacitane_data <= 0)
nacitane_data = read(k_subor, buf, sz);
aktualne_data -= nacitane_data;
return nacitane_data;
2020-03-30 01:32:44 +00:00
}
int rs232_zapis(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
int uspech = 0;
int odoslane_data = 0;
//poslanie dat na seriove rozhranie
odoslane_data = rs232_odoslat_spravu(cislo_rozhrania, buf, sz);
if(odoslane_data <= 0)
{
fprintf(stderr, "Nastala chyba pri posielani dat\n");
return -1;
}
2020-04-07 20:11:21 +00:00
return odoslane_data;
2020-03-30 01:32:44 +00:00
}
2020-03-11 21:01:54 +00:00
int main(int argc, char const *argv[])
{
//nastavenie rezimu rezhrania
//8 -> pocet bitov, N -> no parity, 1 -> jeden stopbit
2020-03-30 01:32:44 +00:00
char rezim[]={'8','N','1', 0};
//nastavenie rychlosti rozhrania v baudoch
int rychlost = 128000;
2020-03-11 21:01:54 +00:00
WOLFSSL *ssl;
WOLFSSL_CTX *ctx = NULL;
2020-04-10 17:04:14 +00:00
const char* subor = NULL;
2020-05-17 13:12:06 +00:00
int autentizacia = 0;
2020-04-07 20:11:21 +00:00
int zadane_rozhranie = 0;
int uvedeny_subor = 0;
int nacitanie_zo_suboru = 0;
int generovanie_certifikatu = 0;
nastavenia_aplikacie nastavenia;
2020-03-11 21:01:54 +00:00
k_subor = open(KOMUNIKACNY_SUBOR, O_RDWR | O_NOCTTY | O_NDELAY);
2020-03-30 01:32:44 +00:00
int uspech;
2020-03-11 21:01:54 +00:00
if((ctx = nastavit_ctx_klient()) == NULL)
{
return -1;
}
2020-04-07 20:11:21 +00:00
else
{
2020-05-17 13:12:06 +00:00
printf("---------------\n| Certifikaty |\n---------------\n");
2020-04-07 20:11:21 +00:00
for(int i = 0; i < argc; i++)
{
2020-05-17 13:12:06 +00:00
if( (!strcmp(argv[i], "-subor")) )
2020-04-07 20:11:21 +00:00
{
uvedeny_subor = 1;
if((argv[i+1] == NULL) )
{
printf("Nezadali ste cestu ku suboru\n");
return -1;
}
else
{
subor = argv[i+1];
}
}
2020-05-17 13:12:06 +00:00
else if( (!strcmp(argv[i], "-port")) )
2020-04-07 20:11:21 +00:00
{
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_otvorit_rozhranie(cislo_rozhrania, rychlost, rezim, 1))
2020-04-07 20:11:21 +00:00
{
return -1;
}
}
}
2020-05-17 13:12:06 +00:00
else if( (!strcmp(argv[i], "-cert-aut")) )
{
if((argv[i+1] == NULL) || (i == argc-1))
{
printf("Nezadali ste typ certifikatu autority ktory chcete nacitat\n");
return -1;
}
else if(!strcmp(argv[i+1], "rsa"))
{
wolfSSL_CTX_load_verify_locations(ctx, "../../certifikaty/autorita/autorita_rsa.pem", NULL);
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
autentizacia = 1;
}
else if(!strcmp(argv[i+1], "ecc"))
{
wolfSSL_CTX_load_verify_locations(ctx, "../../certifikaty/autorita/autorita_ecc.pem", NULL);
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
autentizacia = 1;
}
else
{
printf("Zadali ste nespravny typ certifikatu\n");
return -1;
}
}
else if( (!strcmp(argv[i], "-cert")) )
2020-04-07 20:11:21 +00:00
{
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"))
{
if(nacitat_certifikaty(ctx, RSA_CERTIFIKAT, RSA_KLUC) == -1) return -1;
}
else if(!strcmp(argv[i+1], "ecc"))
{
if(nacitat_certifikaty(ctx, ECC_CERTIFIKAT, ECC_KLUC) == -1) return -1;
}
else
{
printf("Zadali ste nespravny typ certifikatu\n");
return -1;
}
}
2020-05-17 13:12:06 +00:00
else if( (!strcmp(argv[i], "-cert-gen")) )
2020-04-07 20:11:21 +00:00
{
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"))
{
2020-05-17 13:12:06 +00:00
if(generovat_rsa_certifikat(VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC, RSA_VELKOST, RSA_EXPONENT, CTC_SHA256wRSA, "SR", "Kosice", "local.dev", "server@server.sk") == -1) return -1;
2020-04-07 20:11:21 +00:00
if(nacitat_certifikaty(ctx, VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC) == -1) return -1;
}
else if(!strcmp(argv[i+1], "ecc"))
{
2020-05-17 13:12:06 +00:00
if(generovat_ecc_certifikat(VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC, ECC_VELKOST, ECC_SECP256R1, CTC_SHAwECDSA, "SR", "Kosice", "local.dev", "server@server.sk") == -1) return -1;
2020-04-07 20:11:21 +00:00
if(nacitat_certifikaty(ctx, VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC) == -1) return -1;
}
else
{
printf("Zadali ste nespravny typ certifikatu\n");
return -1;
}
}
}
}
2020-05-17 13:12:06 +00:00
//vypis upozornenia o autentizacii
if(!autentizacia)
{
printf("Nebol nacitany certifikat autority, takze nebude vykonana autentizacia druhej strany\n");
}
2020-04-07 20:11:21 +00:00
if(!zadane_rozhranie)
2020-05-17 13:12:06 +00:00
{
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 -gen-cert (generovanie), alebo -cert (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;
}
2020-04-07 20:11:21 +00:00
//nastav_sifry(ctx, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
2020-03-11 21:01:54 +00:00
2020-04-16 09:25:05 +00:00
//nastavenie vlastnych I/O funkcii
2020-03-11 21:01:54 +00:00
wolfSSL_SetIOSend(ctx, rs232_zapis);
wolfSSL_SetIORecv(ctx, rs232_citanie);
2020-04-16 09:25:05 +00:00
//pokus o vytvorenie novej wolfSSL relacie
2020-03-11 21:01:54 +00:00
if ((ssl = wolfSSL_new(ctx)) == NULL)
{
printf("Nepodarilo sa vytvorit ssl relaciu\n");
wolfSSL_CTX_free(ctx);
return -1;
}
2020-04-16 09:25:05 +00:00
//priradenie file descriptora suboru ako I/O pre TLS spojenie
wolfSSL_set_fd(ssl, k_subor);
wolfSSL_set_using_nonblock(ssl, k_subor);
2020-04-16 09:25:05 +00:00
//pokus o inizicalizaciu TLS handshaku so serverom
2020-05-17 13:12:06 +00:00
printf("-----------------\n| TLS Handshake |\n-----------------\n");
printf("Inicializacia TLS spojenia\n");
2020-04-07 20:11:21 +00:00
uspech = wolfSSL_connect(ssl);
if(uspech != SSL_SUCCESS)
2020-03-11 21:01:54 +00:00
{
2020-04-07 20:11:21 +00:00
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");
fclose(fopen(KOMUNIKACNY_SUBOR, "wb"));
2020-04-16 09:25:05 +00:00
free(popis_chyby);
2020-04-07 20:11:21 +00:00
return -1;
2020-03-11 21:01:54 +00:00
}
2020-05-17 13:12:06 +00:00
printf("Podarilo sa vytvorit TLS spojenie\n");
2020-04-07 20:11:21 +00:00
zobraz_sifru(ssl);
2020-05-17 13:12:06 +00:00
printf("----------------------------\n| Informacie o certifikate |\n----------------------------\n");
2020-04-07 20:11:21 +00:00
zobraz_certifikat(ssl);
//nastavenie funkcie pre vypocet kontrolneho suctu
//nastavime typ "crc" alebo "hash" a nazov funkcie, nazov druhej funkcie nastavime na NULL
nastav_funkciu(&nastavenia, "crc", (hashovacia_funkcia)NULL, funkcia_CRC32);
2020-05-17 13:12:06 +00:00
printf("-------------------\n| Poslanie suboru |\n-------------------\n");
if(poslat_subor(ssl, ctx, subor, &nastavenia, 4096) == -1) return -1;
printf("----------------------\n| Ukoncenie spojenia |\n----------------------\n");
2020-04-07 20:11:21 +00:00
2020-04-16 09:25:05 +00:00
//ukoncenie spojenia, vymazanie komunikacneho suboru
//a vycistenie serioveho buffera
ukoncit_spojenie(ssl, ctx);
rs232_zatvorit_rozhranie(cislo_rozhrania);
close(k_subor);
2020-04-16 09:25:05 +00:00
fclose(fopen(KOMUNIKACNY_SUBOR, "wb"));
2020-03-11 21:01:54 +00:00
return 0;
}