////////////////////////////////////////////////// // 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/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 VYGENEROVANA_ZIADOST "../../certifikaty/server/vygenerovana_ziadost.pem" int main(int argc, char **argv) { int autentizacia = 0; int uspech; int autentizacia_klienta = 0; int generovanie_certifikatu = 0; int nacitanie_zo_suboru = 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; int cislo_portu = 0; WOLFSSL_CTX* ctx; if((ctx = nastavit_ctx_server()) == 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], "-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(!port) { fprintf(stderr, "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; } //umoznuje vybrat sifry ktore sa budu nachadzat v sifrovacom subore //nastav_sifry(ctx, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); //pokus vytvorenie TCP/IP prenosoveho kanala printf("----------------\n| TCP/IP kanal |\n----------------\n"); printf("Pokus o inicializaciu TCP/IP prenosoveho kanala\n"); cislo_soketu = cakat_na_komunikaciu(cislo_portu); struct sockaddr_in adresa; WOLFSSL* ssl; int velkost = sizeof(adresa); int cislo_soketu_klienta = accept(cislo_soketu, (struct sockaddr*)&adresa, &velkost); printf("Spojenie [%s:%d]\n", inet_ntoa(adresa.sin_addr), ntohs(adresa.sin_port)); 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_klienta); wolfSSL_set_using_nonblock(ssl, 1); //cakanie na inicializaciu TLS handshaku klientom printf("-----------------\n| TLS Handshake |\n-----------------\n"); printf("Inicializacia TLS spojenia\n"); if(wolfSSL_accept(ssl) != 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); //vypocet casu prenosu suboru printf("-------------------\n| Prijatie suboru |\n-------------------\n"); clock_t cas; cas = clock(); if(prijat_subor(ssl, ctx, &nastavenia, 16384) == -1) return -1; cas = clock() - cas; printf("Cas prenosu suboru: %f sekund\n", (double)cas/CLOCKS_PER_SEC); printf("----------------------\n| Ukoncenie spojenia |\n----------------------\n"); ukoncit_spojenie(ssl, ctx); } ukoncit_soket(cislo_soketu); #if defined (_WIN32) WSACleanup(); #endif return 0; }