////////////////////////////////////////////////// // Bakalarska praca // // Meno studenta: Tomas Lukac // // Veduci BP: prof. Ing. Milos Drutarovsky CSc. // // Skola: KEMT FEI TUKE // // Datum poslednej upravy: 12.3.2020 // ////////////////////////////////////////////////// #include "kryptografia.h" WOLFSSL_CTX* nastavit_ctx_klient() { WOLFSSL_METHOD* method; wolfSSL_Init(); method = wolfTLSv1_2_client_method(); WOLFSSL_CTX *ctx = wolfSSL_CTX_new(method); if (ctx == NULL) { printf("Nepodarilo sa inicializovat WOLFSSL_CTX\n"); return NULL; } return ctx; } WOLFSSL_CTX* nastavit_ctx_server() { WOLFSSL_METHOD* method; wolfSSL_Init(); method = wolfTLSv1_2_server_method(); WOLFSSL_CTX *ctx = wolfSSL_CTX_new(method); if (ctx == NULL) { printf("Nepodarilo sa inicializovat WOLFSSL_CTX\n"); return NULL; } return ctx; } void nastav_sifry(WOLFSSL_CTX* ctx, const char* sifry) { wolfSSL_CTX_set_cipher_list(ctx, sifry); } void zobraz_sifru(WOLFSSL* ssl) { printf ("Pouzita sifra: %s\n", wolfSSL_get_cipher(ssl)); } int generovat_rsa_certifikat(int pocet_bitov, int exponent, int algoritmus, char* krajina, char* mesto, char* domena, char* email) { int uspech; //premenne pre ukladanie dat autority RsaKey kluc_autorita; byte pem_autorita[VELKOST_BUFFERA]; word32 pem_autorita_velkost; byte der_autorita[VELKOST_BUFFERA]; word32 der_autorita_velkost; //vytvorenie struktury RsaKey autority zo sukromneho kluca vo formate PEM ulozeneho v subore certifikaty/autorita.key memset(pem_autorita, 0, sizeof(pem_autorita)); FILE* subor = fopen("../certifikaty/autorita_rsa.key", "rb"); pem_autorita_velkost = fread(pem_autorita, 1, VELKOST_BUFFERA, subor); if(pem_autorita_velkost < 0) { fprintf(stderr, "Nepodarilo sa nacitat obsah suboru\n"); } word32 index = 0; //nastavi odkial zacat citat buffer memset(der_autorita, 0, sizeof(der_autorita)); der_autorita_velkost = wolfSSL_KeyPemToDer(pem_autorita, sizeof(pem_autorita), der_autorita, sizeof(der_autorita), ""); wc_InitRsaKey(&kluc_autorita, 0); uspech = wc_RsaPrivateKeyDecode(der_autorita, &index, &kluc_autorita, der_autorita_velkost); if(uspech != 0) { fprintf(stderr, "Nepodarilo sa vytvorit RsaKey strukturu z kluca autority\n"); return -1; } RsaKey* k = &kluc_autorita; if (k == NULL) { fprintf(stderr, "Nepodarilo sa vytvorit RsaKey strukturu z kluca autority\n"); return -1; } //generator nahodnych cisel WC_RNG generator; wc_InitRng(&generator); //premenne pre ukladanie dat vygenerovaneho kluca RsaKey kluc; byte der_kluc[VELKOST_BUFFERA]; word32 der_kluc_velkost; byte pem_kluc[VELKOST_BUFFERA]; word32 pem_kluc_velkost; //vygenerovanie kluca wc_InitRsaKey(&kluc, 0); uspech = wc_MakeRsaKey(&kluc, pocet_bitov, exponent, &generator); if(uspech != 0) { fprintf(stderr, "Chyba pri generovani kluca.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); return -1; } der_kluc_velkost = wc_RsaKeyToDer(&kluc, der_kluc, sizeof(der_kluc)); if(der_kluc_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru DER so sukromnym klucom.\n"); return -1; } memset(pem_kluc, 0, sizeof(pem_kluc)); pem_kluc_velkost = wc_DerToPem(der_kluc, der_kluc_velkost, pem_kluc, sizeof(pem_kluc), PRIVATEKEY_TYPE); if(pem_kluc_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru PEM so sukromnym klucom\n"); return -1; } //zapis vygenerovaneho klucu do suboru subor = fopen("../certifikaty/vygenerovany_kluc.key", "wb"); fwrite(pem_kluc, 1, pem_kluc_velkost, subor); fclose(subor); printf("RSA kluc bol uspesne vygenerovany.\n"); //premenne pre ukladanie dat certifikatu Cert certifikat; byte der_certifikat[VELKOST_BUFFERA]; word32 der_certifikat_velkost; byte pem_certifikat[VELKOST_BUFFERA]; word32 pem_certifikat_velkost; //vygenerovanie a podpis certifikatu wc_InitCert(&certifikat); strncpy(certifikat.subject.country, krajina, CTC_NAME_SIZE); strncpy(certifikat.subject.state, "-", CTC_NAME_SIZE); strncpy(certifikat.subject.locality, mesto, CTC_NAME_SIZE); strncpy(certifikat.subject.org, "-", CTC_NAME_SIZE); strncpy(certifikat.subject.unit, "-", CTC_NAME_SIZE); strncpy(certifikat.subject.commonName, domena, CTC_NAME_SIZE); strncpy(certifikat.subject.email, email, CTC_NAME_SIZE); certifikat.isCA = 0; certifikat.sigType = algoritmus; certifikat.daysValid = 1825; uspech = wc_SetIssuer(&certifikat, "../certifikaty/autorita_rsa.pem"); if(uspech < 0) { fprintf(stderr, "Nastala chyba pri nastaveni autority.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); return -1; } der_certifikat_velkost = wc_MakeCert(&certifikat, der_certifikat, sizeof(der_certifikat), &kluc, NULL, &generator); if(der_certifikat_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru DER s certifikatom.\n"); return -1; } der_certifikat_velkost = wc_SignCert(certifikat.bodySz, certifikat.sigType, der_certifikat, sizeof(der_certifikat), &kluc_autorita, NULL, &generator); if(der_certifikat_velkost < 0) { fprintf(stderr, "Nastala chyba pri podpisovani certifikatu.\n"); return -1; } memset(pem_certifikat, 0, sizeof(pem_certifikat)); pem_certifikat_velkost = wc_DerToPem(der_certifikat, der_certifikat_velkost, pem_certifikat, sizeof(pem_certifikat), CERT_TYPE); if(pem_certifikat_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru PEM s certifikatom.\n"); return -1; } //zapis vygenerovaneho klucu do suboru subor = fopen("../certifikaty/vygenerovany_certifikat.pem", "wb"); fwrite(pem_certifikat, 1, pem_certifikat_velkost, subor); fclose(subor); printf("Certifikat bol uspesne vygenerovany\n"); return 0; } int generovat_ecc_certifikat(int pocet_bitov, ecc_curve_id kluc_krivka, int algoritmus, char* krajina, char* mesto, char* domena, char* email) { int uspech = 0 ; //premenne pre ukladanie dat autority ecc_key kluc_autorita; byte pem_autorita[VELKOST_BUFFERA]; word32 pem_autorita_velkost; byte der_autorita[VELKOST_BUFFERA]; word32 der_autorita_velkost; //vytvorenie struktury ecc_key autority zo sukromneho kluca vo formate PEM ulozeneho v subore certifikaty/autorita_ecc.key memset(pem_autorita, 0, sizeof(pem_autorita)); FILE* subor = fopen("../certifikaty/autorita_ecc.key", "rb"); pem_autorita_velkost = fread(pem_autorita, 1, VELKOST_BUFFERA , subor); if(pem_autorita_velkost < 0) { fprintf(stderr, "Nepodarilo sa nacitat obsah suboru\n"); } fclose(subor); word32 index = 0; //nastavi odkial zacat citat buffer der_autorita_velkost = wolfSSL_KeyPemToDer(pem_autorita, sizeof(pem_autorita), der_autorita, sizeof(der_autorita), ""); wc_EccPrivateKeyDecode(der_autorita, &index, &kluc_autorita, der_autorita_velkost); ecc_key* k = &kluc_autorita; if (k == NULL) { fprintf(stderr, "Nepodarilo sa vytvorit ecc_key strukturu z kluca autority\n"); return -1; } //generator nahodnych cisel WC_RNG generator; wc_InitRng(&generator); //premenne pre ukladanie dat vygenerovaneho kluca ecc_key kluc; byte der_kluc[VELKOST_BUFFERA]; word32 der_kluc_velkost; byte pem_kluc[VELKOST_BUFFERA]; word32 pem_kluc_velkost; //vygenerovanie kluca wc_ecc_init(&kluc); uspech = wc_ecc_make_key_ex(&generator, pocet_bitov, &kluc, kluc_krivka); if(uspech != 0) { fprintf(stderr, "Chyba pri generovani kluca.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); return -1; } der_kluc_velkost = wc_EccKeyToDer(&kluc, der_kluc, sizeof(der_kluc)); if(der_kluc_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru DER so sukromnym klucom.\n"); return -1; } pem_kluc_velkost = wc_DerToPem(der_kluc, der_kluc_velkost, pem_kluc, sizeof(pem_kluc), ECC_PRIVATEKEY_TYPE); if(pem_kluc_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru PEM so sukromnym klucom\n"); return -1; } //zapis vygenerovaneho kluca do suboru subor = fopen("../certifikaty/vygenerovany_kluc.key", "wb"); fwrite(pem_kluc, 1, pem_kluc_velkost, subor); fclose(subor); printf("ECC kluc bol uspesne vygenerovany a nacitany.\n"); //premenne pre ukladanie dat certifikatu Cert certifikat; byte der_certifikat[VELKOST_BUFFERA]; word32 der_certifikat_velkost; byte pem_certifikat[VELKOST_BUFFERA]; word32 pem_certifikat_velkost; //vygenerovanie a podpis certifikatu wc_InitCert(&certifikat); strncpy(certifikat.subject.country, krajina, CTC_NAME_SIZE); strncpy(certifikat.subject.state, "-", CTC_NAME_SIZE); strncpy(certifikat.subject.locality, mesto, CTC_NAME_SIZE); strncpy(certifikat.subject.org, "-", CTC_NAME_SIZE); strncpy(certifikat.subject.unit, "-", CTC_NAME_SIZE); strncpy(certifikat.subject.commonName, domena, CTC_NAME_SIZE); strncpy(certifikat.subject.email, email, CTC_NAME_SIZE); certifikat.isCA = 0; certifikat.sigType = algoritmus; certifikat.daysValid = 1825; uspech = wc_SetIssuer(&certifikat, "../certifikaty/autorita_ecc.pem"); if(uspech != 0) { fprintf(stderr, "Nastala chyba pri nastaveni autority.\nCislo chyby: %d\nDovod chyby: %s\n", uspech, wc_GetErrorString(uspech)); return -1; } der_certifikat_velkost = wc_MakeCert(&certifikat, der_certifikat, sizeof(der_certifikat), NULL, &kluc, &generator); if(der_certifikat_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru DER s certifikatom.\n"); return -1; } der_certifikat_velkost = wc_SignCert(certifikat.bodySz, certifikat.sigType, der_certifikat, sizeof(der_certifikat), NULL, &kluc_autorita, &generator); if(der_certifikat_velkost < 0) { fprintf(stderr, "Nastala chyba pri podpisovani certifikatu.\n"); return -1; } memset(pem_certifikat, 0, sizeof(pem_certifikat)); pem_certifikat_velkost = wc_DerToPem(der_certifikat, der_certifikat_velkost, pem_certifikat, sizeof(pem_certifikat), CERT_TYPE); if(pem_certifikat_velkost < 0) { fprintf(stderr, "Nastala chyba pri vytvoreni suboru PEM s certifikatom.\n"); return -1; } //zapis vygenerovaneho klucu do suboru subor = fopen("../certifikaty/vygenerovany_certifikat.pem", "wb"); fwrite(pem_certifikat, 1, pem_certifikat_velkost, subor); fclose(subor); return 0; } int nacitat_certifikaty(WOLFSSL_CTX* ctx, const char* subor_certifikat, const char* subor_kluc) { int uspech = 0; //nacitanie certifikatu do WOLFSSL_CTX struktury, cesta ku suboru sa predava z argumentu funkcie uspech = wolfSSL_CTX_use_certificate_file(ctx, subor_certifikat, SSL_FILETYPE_PEM); if(uspech != SSL_SUCCESS) { printf("Chyba pri nacitani certifikatu\n"); return -1; } //nacitanie sukromneho kluca do WOLFSSL_CTX struktury, cesta ku suboru sa predava z argumentu funkcie uspech = wolfSSL_CTX_use_PrivateKey_file(ctx, subor_kluc, SSL_FILETYPE_PEM); if(uspech != SSL_SUCCESS) { printf("Chyba pri nacitani kluca\n"); return -1; } printf("Certifikat a kluc boli uspesne nacitane\n"); //kontrola sukromneho kluca if(!wolfSSL_CTX_check_private_key(ctx)) { fprintf(stderr, "Sukromny kluc sa nezhoduje s certifikatom\n"); return -1; } return 0; } void zobraz_certifikat(WOLFSSL* ssl) { printf("Informacie o certifikate:\n"); WOLFSSL_X509 *certifikat = wolfSSL_get_peer_certificate(ssl); char* pole; if (!certifikat) { printf("Nebolo mozne ziskat ziadny certifikat\n"); } if ((pole = wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(certifikat), 0, 0))) { printf("Nazov domeny: %s\n", pole); //wolfSSL_free(line); } if ((pole = wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_issuer_name(certifikat), 0, 0))) { printf("Certifikacna autorita: %s\n", pole); //wolfSSL_free(line); } X509_free(certifikat); } byte* generovat_hash(char* cesta) { int pocet_bajtov; FILE* subor = fopen(cesta, "rb"); unsigned char data[1024]; byte* vysledok = calloc(SHA_DIGEST_SIZE, sizeof(byte)); Sha sha; wc_InitSha(&sha); while ((pocet_bajtov = fread (data, 1, 1024, subor)) != 0) wc_ShaUpdate(&sha, data, pocet_bajtov); wc_ShaFinal(&sha, vysledok); return vysledok; } void ukoncit_spojenie(WOLFSSL *ssl, WOLFSSL_CTX *ctx) { printf("Ukoncujem program.\n"); wolfSSL_shutdown(ssl); wolfSSL_free(ssl); printf("Spojenie ukoncene.\n"); wolfSSL_CTX_free(ctx); wolfSSL_Cleanup(); printf("Program bol ukonceny.\n"); }