380 lines
12 KiB
C
380 lines
12 KiB
C
//////////////////////////////////////////////////
|
|
// 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");
|
|
}
|