Skip to content

Instantly share code, notes, and snippets.

@maruno
Created October 4, 2012 13:39
Show Gist options
  • Save maruno/3833581 to your computer and use it in GitHub Desktop.
Save maruno/3833581 to your computer and use it in GitHub Desktop.
Documentatie manual ciphers OpenSSL
\begin{abstract}
Voor de module cryptografie werd gevraagd om een bestaande cryptografie-toepassing aan te passen.
Onze keuze is gegaan naar het aanpassen van OpenSSL, waarbij gevraagd werd om het mogelijk te maken
om een algoritme te kiezen in de client en enkele benchmarks uit te voeren. In dit document
beschrijven we onze vindingen en hoe we hier gekomen zijn.
\end{abstract}
\section{Technische aanpassingen voor manuele selectie}
\subsection{Benodigde aanpassingen}
Er zijn in principe twee dingen nodig om het mogelijk te maken om manuele selectie van een algoritme
op de client uit te voeren:
\begin{itemize}
\item Een callback implementeren om een keuze te laten maken door de eindgebruiker
\item De communicatie aanpassen zodat de client op de hoogte raakt van de beschikbare keuzes
\end{itemize}
\subsection{Callback}
Het was vrij eenvoudig om een extra callback toe te voegen aan de SSL-struct. De callback is een
functie-pointer met als argument de SSL-struct. Een vrij simpele implementatie van deze callback
maakt het mogelijk om met behulp van standaard functies de gebruiker een algoritme in te laten
voeren.
De callback wordt alleen aangeroepen door de client indien deze gezet is en ook alleen dan zal alle
aanvullende communicatie beschreven in subsectie~\vref{subsec:communicatie} uitgevoerd worden.
\subsection{Communicatie}
\label{subsec:communicatie}
\subsubsection{Handshake protocol berichten}
Standaard gebruikt TLS een communicatie-structuur met het handshake-protocol waarbij de client zijn
voorkeur algoritmes verzend in het ClientHello-bericht en reageert de server hierop met een
ServerHello waarin de server reeds een keuze heeft gemaakt. Om het mogelijk te maken dat we als
client een keuze kunnen maken zullen we twee extra berichten moeten toevoegen in het
handshake-protocol:
\begin{itemize}
\item RequestCipherList, verstuurd door de client om de cipherlist op te halen
\item CipherList, antwoord van de server op RequestCipherList
\end{itemize}
Naast deze twee berichten zal de bestaande communicatie met ClientHello en ServerHello blijven
bestaan omdat aan deze functionaliteit wezenlijk niks veranderd. De twee extra berichten zijn
simpelweg op te nemen voor de al bestaande berichten in de handshake en het standaard gedrag kan
gebruikt worden indien de client geen RequestCipherList stuurt.
\subsubsection{Technische realisatie}
Het handshake-protocol maakt het makkelijk mogelijk om onze extra berichten in te voegen omdat we
simpelweg twee extra messagetypes in kunnen voeren. Helaas was OpenSSL niet zo makkelijk om dit
vervolgens te implementeren.
OpenSSL gebruikt intern een state-machine om de handshake door te lopen. Het toevoegen van een paar
extra states was niet het grootste werk, de bewerkingen achter de states zijn echter aardig
complex. OpenSSL is vrij hardcoded opgezet en gaat uit van een preciese workflow die niet afwijkt
en bewerkt continue twee buffers. Een bewerking in een state kan afhankelijk zijn van wat 3 states
eerder in een buffer gezet is, etc. Hierdoor hebben we enkele initialisatie-routines moeten
afsplitsen van functies als ssl3_send_server_hello.
Het is ons uiteindelijk gelukt om onze eigen berichten toe te voegen aan de handshake maar het
verdere verloop van de handshake is verloren gegaan. De callback wordt aangeroepen en de cipherlist
wordt opgehaald maar het vervolg van de handshake lukt niet. De reden hiervoor is dat om de een of
andere reden de read-buffer niet actief is geworden op de server, waardoor de server enkel
nul-bytes ontvangt.
\section{Overpeinzingen}
OpenSSL is een erg grote en complexe bibliotheek die door de AIVD en Fox-IT vanwege deze redenen
niet aan een security audit onderworpen kon worden. Wij hebben bij de uitvoering van deze opdracht
ook veel problemen gehad met deze aard van OpenSSL.
De publieke API van OpenSSL is een nette C-API met documentatie maar intern is dit geheel anders en
is er geen documentatie en vaak geen code commentaar aanwezig om uit te leggen wat de code doet. Er
is een ontwerp op basis van het continue hergebruik van twee buffers maar hier dient men zelf
achter te komen. Toen ons het ontwerp met de twee buffers duidelijk werd liepen we nog vaak aan
tegen de weinigzeggende variablenamen en preprocessor-macro's als d,p,l en l2n3 terwijl deze
essentieel zijn omdat alle functies afhankelijk van voorgaande aanroepingen zijn.
Gezien de AIVD en Fox-IT geen begin konden maken aan een security audit van OpenSSL is het in onze
mening vanuit school erg optimistisch bekeken om ervan uit te gaan dat een student het makkelijk
kan aanpassen. Tijdens het college werd genoemd dat de server een cipher-lijst stuurt en de client
deze kiest, wellicht dat deze misconceptie bijdraagt aan de veronderstelde moeilijkheidsgraad van
deze opdracht: enkel de callback implementeren was goed te doen.
Binnen de overheid wordt PolarSSL gebruikt in plaats van OpenSSL omdat deze makkelijk te auditen
was vanwege zijn compactheid en modulariteit. Een korte vergelijking tussen code uit OpenSSL en
PolarSSL toonde ons dat PolarSSL veel beter gedocumenteerd en te begrijpen is. Ons advies is om
PolarSSL te gebruiken indien de gevraagde functionaliteit echt nodig is.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment