Tekn.dr. Göran Pulkkis Överlärare i Datateknik Avancerad SSL-programmering I 25.1.2012 1 Innehåll SSL-sessioner Förnyad SSL-handskakning Blockerad/oblockerad in/uthantering 25.1.2012 2
SSL-sessioner Session skapas vid en SSL-handskakning såsom parametrar och krypteringnycklar i en SSL_SESSION post Identifieras med session ID context, som kan skapas av en SSL-server med SSL_CTX_set_session_id_context() En session ID context behövs för att en session skall kunna sparas ( session caching ) Grundinställningar för SSL-server: en session sparas i minnet en sessions maximala livslängd är 300 s föråldrade sessioner avlägsnas automatiskt Förbindelse en kommunikationprocess baserad på en session 25.1.2012 3 SSL-sessioner / Server-sidan En sessions maximala livslängd kan ställas in med SSL_CTX_set_timeout() Sättet att spara sessioner kan ställas in med flaggor med SSL_CTX_set_session_cache_mode() SSL_SESS_CACHE_NO_AUTO_CLEAR Föråldrade SSL_SESSION-poster måste avlägsnas manuellt med SSL_CTX_flush_sessions() SSL_SESS_CACHE_NO_INTERNAL_LOOKUP En sparad SSL_SESSION-post hämtas inte från minnet utan från en fil flagg -värden kombineras med bitwise OR 25.1.2012 4
SSL-sessioner / Server-sidan För att spara SSL_SESSION-poster i filer kan 3 självprogrammerade callback -funktioner utnyttjas int new_session_cb(ssl *ctx, SSL_SESSION *session); ställs in för anrop med SSL_CTX_sess_set_new_cb() blir efter inställning automatiskt anropad varje gång en ny SSL_SESSIONpost skapas vid en SSL-handskakning void remove_session_cb(ssl *ctx, SSL_SESSION *session); ställs in för anrop med SSL_CTX_sess_set_remove_cb() blir efter inställning automatiskt anropad vid radering en ogiltig eller föråldrad SSL_SESSION-post SSL_SESSION *get_session_cb(ssl *ctx, unsigned char *id, int len, int ref); ställs in för användning med SSL_CTX_sess_set_get_cb() blir efter inställning automatiskt anropad för att använda en fil då ingen sparad SSL_SESSION-post hittas i minnet 25.1.2012 5 SSL-sessioner / Server-sidan new_session_cb( ) { } acquire a lock for the file named according to the session id open file named according to session id encrypt and write the SSL_SESSION object to the file release the lock 25.1.2012 6
SSL-sessioner / Server-sidan remove_session_cb( ) { } acquire a lock for the file named according to the session id remove the file named according to the session id release the lock 25.1.2012 7 SSL-sessioner / Server-sidan get_session_cb( ) { } acquire a lock for the file named according to the session id in the 2nd arg read and decrypt contents of file and create a new SSL_SESSION object release the lock set the integer referenced by the fourth parameter to 0 return the new session object 25.1.2012 8
SSL-sessioner / Klientsidan En SSL_SESSION-post för en SSL_förbindelse returneras med SSL_get_session() eller SSL_get0_session() eller SSL_get1_session() (referensräknaren uppdateras) En SSL_SESSION-post kan sparas i minnet sparas en fil med makron PEM_write_bio_SSL_SESSION() eller makron PEM_write_SSL_SESSION() hämtas från en fil med makron PEM_read_bio_SSL_SESSION() eller Makron PEM_read_SSL_SESSION() 25.1.2012 9 SSL-sessioner / Klientsidan ssl = SSL_new(ctx)... setup underlying communications layer for ssl...... connect to host:port... if (saved_session for host:port in cache) { SSL_set_session(ssl, saved_session) SSL_SESSION_free(saved_session) } SSL_connect(ssl) call post_connection_check(ssl, host) and check return value... normal application code here... Saved_session = SSL_get1_session(ssl) if (saved_session!= NULL) enter saved_session into cache under host:port SSL_shutdown(ssl) SSL_free(ssl) 25.1.2012 10
Förnyad SSL-handskakning Begäran om SSL-handskakning med SSL_renegotiate(); En flagga hissas för att begäran om SSL-handskakning skall skickas till SSL-kommunikationpartnern i samband med nästa in/ut-operation Partnern kan ignorera denna begäran 25.1.2012 11 OpenSSL version 0.9.6 SSL-server kräver förnyad handskakning /* assume ssl is connected and error free up to here */ set_blocking(ssl); /* this is unnecessary if it is already blocking */ SSL_renegotiate(ssl); SSL_do_handshake(ssl); if (ssl->state!= SSL_ST_OK) int_error("failed to send renegotiation request"); ssl->state = SSL_ST_ACCEPT; SSL_do_handshake(ssl); if (ssl->state!= SSL_ST_OK) int_error("failed to complete renegotiation"); /* our renegotiation is complete */ 25.1.2012 12
OpenSSL version 0.9.6 Starkare autentisering krävs av SSL-klient /* assume ctx is an SSL_CTX object that is setup to not have any verify options. */ int normal_user = 1, admin_user = 2; SSL_CTX_set_session_id_context(ctx, &normal_user, sizeof(int)); /* perform rest of ctx setup, create an ssl object, and connect it */ /* normal SSL I/O operations and application code go here */ /* if we want to upgrade client privilege, we enter the following code block */ SSL_set_verify(ssl, SSL_VERIFY_PEER SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); SSL_set_session_id_context(ssl, &admin_user, sizeof(int)); /* renegotiation code fragment from previous example goes here. the new session is made */ post_connection_check(ssl, host); /* if everything is error-free, we have properly authenticated the client */ 25.1.2012 13 Förnyad SSL-handskakning i OpenSSL version 0.9.7 Ny funktion: SSL_renegotiate_pending() Returvärde!= 0 efter begäran om SSL-handskakning så länge handskakning ej skett Returvärde == 0 efter begäran om SSL-handskakning och handskakning har lyckats Ny flagga : SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, som kan hissas med SSL_CTX_set_options(); Hindrar SSL-klient att återanvända en giltig session efter begäran om SSL-handskakning 25.1.2012 14
IN/UT-hantering för SSL-förbindelse En SSL-förbindelse har två nivåer SSL-nivån (pekare på SSL-post) med kryptering/avkryptering Datakanalnivån ( socket -deskriptor) med dataöverföring i datanät SSL_read eller SSL_write kan avbryts när datakanalnivån är upptagen med Förnyad handskakning 25.1.2012 15 SSL_read och förnyad handskakning code = SSL_read(ssl, buf + offset, size - offset); switch (SSL_get_error(ssl, code)) { case SSL_ERROR_NONE: /* update the offset value */ offset += code; break; case SSL_ERROR_ZERO_RETURN: /* react to the SSL connection being closed */ do_cleanup(ssl); break; case SSL_ERROR_WANT_READ: /* handle this in an application specific way to retry the SSL_read */ break; case SSL_ERROR_WANT_WRITE: /* handle this in an application specific way to retry the SSL_read */ break; default: /* an error occurred. shutdown the connection */ shutdown_connection(ssl); } 25.1.2012 16
Returvärden från anrop av SSL_get_error SSL_ERROR_WANT_READ betyder SSL_read/SSL_write kunde inte fullbordas och underliggande datakanalförbindelse kunde inte fullborda en read -begäran Förnyat anrop av samma SSL_read/SSL_write SSL_ERROR_WANT_WRITE betyder SSL_read/SSL_write kunde inte fullbordas och underliggande datakanalförbindelse kunde inte fullborda en write -begäran Förnyat anrop av samma SSL_read/SSL_write 25.1.2012 17 Returvärden från anrop av SSL_get_error SSL_ERROR_ZERO_RETURN betyder SSL_read/SSL_write misslyckades pga avslutad SSL-session. Den underliggande datakanalförbindelsen kan ännu vara öppen städa upp efter den avslutade SSLförbindelsen med anrop av do_cleanup(ssl) 25.1.2012 18
Blockerad IN/UT-hantering för SSL-förbindelse Blockeringen sker på den underliggande datakanalnivån Vid förnyad SSL-handskakning som kan ske närsomhelst Anrop av SSL_read kan skicka data till kommunikationspartnern Anrop av SSL_write kan hämta data från kommunikationspartnern 25.1.2012 19 Blockerad IN/UT-hantering för SSL-förbindelse Samma anrop av SSL_read/SSL_write bör förnyas om SSL_get_error returnerar SSL_ERROR_WANT_READ eller SSL_ERROR_WANT_WRITE 25.1.2012 20
Oblockerad IN/UT-hantering för SSL-förbindelse Om underliggande datakanalnivå inte kan hantera en begäran att skicka/ta emot data, rapporteras detta omedelbart utan väntetid Invecklad IN/UT-hantering Exempel: void data_tranfer(ssl *A, SSL *B); för dataöverföring mellan SSLförbindelserna A och B 25.1.2012 21 void data_tranfer(ssl *A, SSL *B); Bufferutrymmen A2B för data avläst från A för att skickas till B. A2B_len-värdet (initialiseras till 0) anger antalet byte i A2B B2A för data avläst från B för att skickas till A. B2A_len-värdet (initialiseras till 0) anger antalet byte i B2A 25.1.2012 22
void data_tranfer(ssl *A, SSL *B); Markerings- flaggor have_data_a2b, have_data_b2a (initialiseras till 0) Tillgänglighets- flaggor can_read_a, can_write_b, osv (initialiseras till 0) Blockerings- flaggor T.ex. write_waiton_read_b hissad betyder att den senaste SSL_write för B måste anropas på nytt efter att B är tillgänglig för att hämta data (dessa flaggor initialiseras till 0) 25.1.2012 23