Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pc:laboratoare:13 [2020/04/23 11:04]
radu.ciobanu created
pc:laboratoare:13 [2022/06/02 13:09] (current)
dorinel.filip
Line 1: Line 1:
-===== Laboratorul 13 =====+===== Laboratorul 13 - Protocoale de securitate. utilizarea programatica ​===== 
 + 
 +==== Utilizare programatica ==== 
 + 
 +Protocolul SSL (Secure Socket Layer - https://​www.ssl.com/​faqs/​faq-what-is-ssl/​) a aparut ca urmare 
 +a necesitatii de a asigura conexiuni sigure in Internet, in stiva de protocoale fiind situat intre nivelul TCP 
 +si nivelul aplicatie. Protocolul asigura autentificarea mutuala a celor doua entitati care comunica, confidentialitatea 
 +comunicarii si protectia integritatii datelor. Una dintre cele mai des intalnite aplicatii ale SSL-ului este 
 +HTTPS (HTTP securizat), care consta din protocolul HTTP utilizat peste SSL. 
 + 
 +SSL si conexiunile securizate pot fi folosite pentru orice tip de protocol pe Internet, HTTP, POP3 sau FTP. 
 +SSL poate fi folosit si pentru a securiza sesiuni de Telnet. Orice tip de conexiune poate fi securizat in teorie 
 +folosind SSL, dar ar trebui sa fie folosit numai pentru conexiuni care vor folosi date ce trebuie protejate. 
 + 
 +OpenSSL ofera mai mult decat SSL, fiind o biblioteca vasta de functii ce permite lucrul cu message digests, 
 +encriptari si decriptari de fisiere, certificate digitale, semnaturi digitale. Deasemenea OpenSSL este nu numai 
 +un API, ci si un utilitar ce poate fi folosit din linia de comanda care prezinta aceleasi functionalitati expuse 
 +de API permitind in plus si testarea serverelor si a clientilor SSL. 
 + 
 +Pentru a instala si uneltele de dezvoltare (inclusiv bibliotecile openssl). 
 + 
 +<​code>​ 
 +sudo apt-get install libssl-dev 
 +</​code>​ 
 + 
 +Urmatoarele fisere header bio.h, ssl.h, err.h vor fi folosite pe parcurs. Daca libssl-dev nu e instalat, importul 
 +fisierelor header de mai jos va da erori la compilare. 
 + 
 +<​code>​ 
 +/* OpenSSL headers */ 
 +#include "​openssl/​bio.h"​ 
 +#include "​openssl/​ssl.h"​ 
 +#include "​openssl/​err.h"​ 
 +</​code>​ 
 + 
 +De asemenea sunt necesare urmatoarele linii de cod pentru a initializa libraria OpenSSL: 
 + 
 +<​code>​ 
 +/* Initializare OpenSSL */ 
 +SSL_library_init (); 
 +SSL_load_error_strings();​ 
 +ERR_load_BIO_strings();​ 
 +OpenSSL_add_all_algorithms();​ 
 +</​code>​ 
 + 
 +OpenSSL foloseste o biblioteca numita BIO pentru a asigura comunicarea atit securizata cat si nesecurizata. 
 +Pentru a crea o conexiune fie ea securizata sau nu, un pointer pentru un obiect de tip BIO trebuie creat 
 +similar cu crearea unui pointer la FILE (in C). Crearea unei noi conexiuni se face cu //​BIO_new_connect()//,​ 
 +specificand hostname si portul. Daca a aparut vreo eroare la crearea obiectului BIO, functia va intoarce 
 +NULL. Totodata se va incerca sa se deschida conexiunea. Pentru a verifica daca acest lucru s-a realizat cu 
 +succes se apeleaza //​BIO_do_connect()//​ care returneaza 0 (OK) sau -1 (eroare). 
 + 
 +<​code>​ 
 +BIO * bio; 
 +bio = BIO_new_connect("​hostname:​port"​);​ 
 + 
 +if(bio == NULL) 
 +
 +   /* trateaza eroarea */ 
 +
 +if(BIO_do_connect(bio) <= 0) 
 +
 +   /* trateaza conexiune esuata*/ 
 +
 +</​code>​ 
 + 
 +Citirea/​scrierea de la/la un obiect BIO se face cu functiile //​BIO_read()//​ si respectiv //​BIO_write()//​. 
 + 
 +<​code>​ 
 +int BIO_read(BIO *b, void *buf, int len); 
 +int BIO_write(BIO *b, const void *buf, int len); 
 +</​code>​ 
 + 
 +Functia //​BIO_read()//​ incearca sa citeasca len octeti din b si sa plaseze rezultatul in bufferul buf. Pentru o conexiune blocanta 
 +0 inseamna ca conexiunea a fost inchisa in timp ce -1 indica ca a aparut o eroare. Pentru o conexiune 
 +neblocanta o valoare 0 inseamna ca nu s-a citit nimic iar -1 ca a aparut o eroare. In acest caz se poate 
 +reincerca operatia care a dat eroare, cu //​BIO_should_retry()//​. 
 + 
 +<​code>​ 
 +int x = BIO_read(bio,​ buf, len); 
 +if(x == 0) 
 +
 +   /* trateaza conexiune inchisa*/ 
 +
 +else if(x < 0) 
 +
 +   if(! BIO_should_retry(bio)) 
 +   { 
 +      /* trateaza esec operatie read */ 
 +   } 
 +   /* trateaza operatie reusita de retry */ 
 +
 +</​code>​ 
 + 
 +Functia //​BIO_write()//​ incearca sa scrie len octeti din buf la b.In ambele variante o valoare returnata de -2 inseamna ca functia nu 
 +e implementata pentru tipul specific BIO folosit. 
 + 
 +<​code>​ 
 +if(BIO_write(bio,​ buf, len) <= 0) 
 +
 +if(! BIO_should_retry(bio)) 
 +
 +   /* trateaza esec operatie write */ 
 +
 +   /* trateaza retry reusit */ 
 +
 +</​code>​ 
 + 
 +Conexiunea poate fi inchisa in doua moduri, cu //​BIO_reset()//​ astfel incat poate fi reutilizata ulterior sau cu 
 +//​BIO_free_all()//​ caz in care se elibereaza memoria alocata si se inchide socketul asociat. 
 + 
 +<​code>​ 
 +/* reutilizare conexiune*/​ 
 +BIO_reset(bio);​ 
 +/* eliberare memorie */ 
 +BIO_free_all(bio);​ 
 +</​code>​ 
 + 
 +=== Stabilirea unei conexiuni securizate === 
 + 
 +Conexiunile securizate necesita un handshake dupa stabilirea conexiunii. In cursul handshake-ului,​ serverul 
 +trimite clientului un certificat, pe care apoi clientul il verifica folosind un set de certificate (certificate store) 
 +pe care le considera de incredere (trusted). Deasemenea verifica daca certificatul nu a expirat. Clientul 
 +trimite un certificat catre server numai daca acesta din urma cere unul (autentificarea clientului). Folosind 
 +transferul de certificate se face setup-ul conexiunii securizate. Clientul sau serverul pot solicita un nou 
 +handshake la orice moment. RFC 2246 detaliaza aspectele referitoare la protocolul de handshake. 
 + 
 +Pentru a stabili o conexiune securizata mai sunt necesari doi pointeri unul de tip //SSL_CTX// (context object) 
 +si unul de tip SSL. 
 + 
 +<​code>​ 
 +SSL_CTX * ctx = SSL_CTX_new(SSLv23_client_method());​ 
 +SSL * ssl; 
 +</​code>​ 
 + 
 +Urmatorul pas este includerea certificate store mentionat anterior. OpenSSL furnizeaza un set de certificate 
 +trusted. In arhiva cu codul sursa din distributia OpenSSL se afla un fisier ”TrustStore.pem.” care include 
 +toate certificatele trusted. 
 + 
 +Functia //​SSL_CTX_load_verify_ locations()//​ e folosita pentru a incarca acest fisier. Aceasta functie are trei 
 +parametri: pointerul la context calea catre fisierul *.pem si calea catre un director ce contine certificate. 
 +Unul din ultimii doi parametri trebuie specificat (ori fisierul *.pem sau, alternativ, directorul ce contine 
 +certificatele trusted). Returneaza 1 in caz de succes si 0 daca a aparut o problema. 
 + 
 +<​code>​ 
 +if(! SSL_CTX_load_verify_locations(ctx,​ "​TrustStore.pem",​ NULL)) 
 +
 +   /* trateaza esec incarcare trust store */ 
 +
 +</​code>​ 
 + 
 +Crearea unei noi conexiuni securizate se face cu: 
 + 
 +<​code>​ 
 +bio = BIO_new_ssl_connect(ctx);​ 
 +BIO_get_ssl(bio,​ & ssl); 
 +SSL_set_mode(ssl,​ SSL_MODE_AUTO_RETRY);​  
 +// cu aceasta optiune daca serverul 
 +// doreste sa initieze din nou un handshake la un moment oarecare de timp, 
 +// OpenSSL se va ocupa in background de acest task 
 +</​code>​ 
 + 
 +Dupa ce acest set-up a fost realizat se poate trece la deschiderea propriu-zisa a conexiunii 
 + 
 +<​code>​ 
 +/* incearca sa se conecteze */ 
 +BIO_set_conn_hostname(bio,​ "​hostname:​port"​);​ 
 + 
 +/* verifica conexiunea deschisa si efectueaza handshake */ 
 +if(BIO_do_connect(bio) <= 0) 
 +
 +   /* trateaza esec conexiune */ 
 +
 +</​code>​ 
 + 
 +Pentru a verifica daca validarea certificatului s-a facut cu succes se apeleaza //​SSL_get_verify_result()//​ cu unic 
 +parametru structura SSL. Daca validarea s-a efectuat cu succes returneaza X509 V OK, altfel intoarce un 
 +cod de eroare care poate fi documentat daca se foloseste optiunea verify in linia de comanda a utilitarului. 
 + 
 +<​code>​ 
 +if(SSL_get_verify_result(ssl) != X509_V_OK) 
 +
 +   /* trateaza esec verificare */ 
 +
 +</​code>​ 
 + 
 +Stiva de erori poate fi scrisa intr-un fisier cu //​ERR_print_errors_fp(FILE *);// 
 +Erorile au urmatorul format: 
 + 
 +<​code>​ 
 +[pid]:​error:​[error code]:​[library name]:​[function name]:​[reason string]:​[file name]:[ 
 +line]:​[optional text message] 
 +</​code>​ 
 + 
 +==== Cerinte laborator ==== 
 + 
 +Completati [[https://​ocw.cs.pub.ro/​courses/​_media/​pc/​laboratoare/​lab13-skel.zip|scheletul de cod]] astfel incat sa se efectueze o conexiune prin HTTPS la verisign.com si sa se 
 +salveze local, intr-un fisier pe disc, pagina home, printr-un apel de tip GET. 
 + 
 +Portul HTTPS implicit este 443. 
 + 
 +Pentru compilare se poate folosi: 
 + 
 +<​code>​ 
 +gcc http_client.c -lssl -lcrypto 
 +</​code>​ 
 + 
 +==== Referinte ==== 
 + 
 +  - http://​www.openssl.org/​ 
 +  - http://​www.linuxjournal.com/​article/​4822 
 +  - http://​www.rfc-editor.org/​rfc/​rfc2246.txt 
pc/laboratoare/13.1587629060.txt.gz · Last modified: 2020/04/23 11:04 by radu.ciobanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0