////////////////////////////////////////////////// // Bakalarska praca // // Meno studenta: Tomas Lukac // // Veduci BP: prof. Ing. Milos Drutarovsky CSc. // // Skola: KEMT FEI TUKE // // Datum poslednej upravy: 6.5.2020 // ////////////////////////////////////////////////// #include "../../kniznica/kryptografia.h" #include "../../kniznica/komunikacia.h" #include #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 VYGENEROVANA_ZIADOST "../../certifikaty/klient/vygenerovana_ziadost.pem" int main(int argc, char** argv) { int autentizacia = 0; clock_t cas; int uspech; int generovanie_certifikatu = 0; int nacitanie_zo_suboru = 0; int uvedeny_subor = 0; int ip = 0; int port = 0; nastavenia_aplikacie nastavenia; #if defined (_WIN32) WSADATA d; if(WSAStartup(MAKEWORD(2,2), &d)) { printf("Nastala chyba pri inicializacii winsocketu\n"); return -1; } #endif int cislo_soketu = 0; int cislo_portu = 0; char* ip_adresa = NULL; char* subor = NULL; WOLFSSL *ssl; WOLFSSL_CTX *ctx; if((ctx = nastavit_ctx_klient()) == NULL) { return -1; } else { //skontroluje ci nebol zadany prepinac "-g" pre moznost generovanie certifikatu, //ak ano pozrie aky typ certifikatu (v CLI argument hned za nim) bol zvoleny printf("---------------\n| Certifikaty |\n---------------\n"); for(int i = 0; i < argc; i++) { if( (!strcmp(argv[i], "-subor")) ) { 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], "-ip-adr")) ) { ip = 1; if((argv[i+1] == NULL) ) { printf("Nezadali ste ip adresu\n"); return -1; } else { ip_adresa = argv[i+1]; } } else if( (!strcmp(argv[i], "-port")) ) { port = 1; if((argv[i+1] == NULL) ) { printf("Nezadali ste cislo portu\n"); return -1; } else { cislo_portu = atoi(argv[i+1]); } } 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")) ) { 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; } } else if( (!strcmp(argv[i], "-cert-gen")) ) { 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")) { if(generovat_rsa_certifikat(VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC, 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")) { if(generovat_ecc_certifikat(VYGENEROVANY_CERTIFIKAT, VYGENEROVANY_KLUC, 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; } } } //vypis upozornenia o autentizacii if(!autentizacia) { printf("Nebol nacitany certifikat autority, takze nebude vykonana autentizacia druhej strany\n"); } if(!ip) { printf("Nebola zadana ip adresa servera\n"); return -1; } else if(!port) { printf("Nebol urceny port\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; } //umoznuje vybrat sifry ktore sa budu nachadzat v sifrovacom subore //nastav_sifry(ctx, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); //pokus o inicializaciu TCP/IP prenosoveho kanala printf("----------------\n| TCP/IP kanal |\n----------------\n"); printf("Pokus o inicializaciu TCP/IP prenosoveho kanala\n"); cislo_soketu = pripojit_na_server(ip_adresa, cislo_portu, 5); if(!cislo_soketu) return -1; printf("TCP/IP kanal bol uspesne vytvoreny\n"); //pokus o vytvorenie novej wolfSSL relacie ssl = wolfSSL_new(ctx); //priradenie file descriptora soketu ako I/O pre TLS spojenie wolfSSL_set_fd(ssl, cislo_soketu); wolfSSL_set_using_nonblock(ssl, 1); //pokus o inizicalizaciu TLS handshaku so serverom uspech = wolfSSL_connect(ssl); printf("-----------------\n| TLS Handshake |\n-----------------\n"); printf("Inicializacia TLS spojenia\n"); 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; } printf("Podarilo sa vytvorit TLS spojenie\n"); zobraz_sifru(ssl); printf("----------------------------\n| Informacie o certifikate |\n----------------------------\n"); 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); printf("-------------------\n| Poslanie suboru |\n-------------------\n"); if(poslat_subor(ssl, ctx, subor, &nastavenia, 16384) == -1) return -1; printf("----------------------\n| Ukoncenie spojenia |\n----------------------\n"); ukoncit_spojenie(ssl, ctx); } ukoncit_soket(cislo_soketu); #if defined (_WIN32) WSACleanup(); #endif return 0; }