MASARYKOVA UNIVERZITA FAKULTA INFORMATIKY Bakalářská práce Grafické rozhraní pro OpenSSL Petr Lefner Brno, 2006 Prohlášení Prohlašuji, že tato práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj. Poděkování Na tomto místě bych rád vyjádřil své poděkování dr. Zdeňku Říhovi za poskytnuté rady a vstřícný postoj v projednávaných otázkách řešení této práce. Vedoucí práce: Ing. Mgr. Zdeněk Říha, Ph.D. ii Shrnutí Tento dokument se snaží motivovat k pokročilejší práci s knihovnou OpenSSL jejím úvodním představením z hlediska celkové struktury a významu. V následujících dvou kapitolách stručný průnik do poskytovaného API doplňuje řada příkladů a postupů, jimiž je napomoženo programátorovi k seznámení se s klíčovými úkoly implementace zabezpečené síťové komunikace v OpenSSL. Přiloženo je také CD obsahující zdrojový kód aplikace pro Microsoft Visual Studio .NET, která prostřednictvím grafického uživatelského rozhraní prezentuje OpenSSL v praxi. Svou funkčností je postavena na zdrojových kódech aplikace openssl, dodávaných společně s balíkem zdrojových kódů knihovny. Klíčová slova OpenSSL, tutoriál, SSLeay, crypto, API, příklady, šifra, certifikát, SSL/TLS spojení, bezpečnost Keywords OpenSSL, tutorial, SSLeay, crypto, API, examples, cipher, certificate, SSL/TLS connection, security iii Obsah 1 Úvod 2 1.1 Anotace.....................................................................................................................2 1.2 Cíl práce...................................................................................................................2 2 Struktura knihovny 3 2.1 Moduly a hierarchie...............................................................................................3 2.2 Moduly SSLeay.......................................................................................................6 2.3 Moduly crypto – symetrické šifrování................................................................7 2.4 Moduly crypto – asymetrické šifrování..............................................................9 2.5 Moduly crypto – hašování....................................................................................9 2.6 Moduly crypto – certifikáty................................................................................10 2.7 Moduly crypto – podpůrné.................................................................................10 2.8 Moduly crypto – vstup/výstup, kódování.......................................................11 2.9 Moduly crypto – interní funkce.........................................................................12 2.10 Aplikace openssl.................................................................................................13 3 SSLeay API (výběr) 14 3.1 Funkce volby metody protokolu SSL_METHOD.............................................14 3.2 Funkce šifer, SSL_CIPHER_*..............................................................................15 3.3 Funkce kontextu, SSL_CTX_*.............................................................................15 3.4 Funkce SSL/TLS relace, SSL_SESSION_*.........................................................22 3.5 Funkce SSL/TLS spojení, SSL_* ........................................................................23 3.6 Datová struktura SSL_METHOD.......................................................................29 3.7 Datová struktura SSL_CIPHER..........................................................................29 3.8 Datová struktura SSL_CTX.................................................................................30 3.9 Datová struktura SSL_SESSION.........................................................................31 3.10 Datová struktura SSL..........................................................................................35 4 crypto API (výběr) 37 4.1 BIO..........................................................................................................................37 4.2 ERR.........................................................................................................................42 4.3 X.509.......................................................................................................................43 5 Závěr 49 6 Literatura 50 Příloha A: Specifikace WinSSL 52 Cíl..................................................................................................................................52 Charakteristika...........................................................................................................52 GUI...............................................................................................................................52 Koncepce řešení..........................................................................................................52 Omezení.......................................................................................................................55 1 1 Úvod 1.1 Anotace Ochrana abstraktních hodnot v moderní informační době dosáhla tak vlivného postavení, že jako bezpečnostní cíl ji nelze stavět na nižší příčku, než požadavek na ochranu hodnot materiálních. Ve sféře Internetu a počítačové komunikace jako takové se cesty k jejímu naplnění rozvinuly do podoby obsáhlé škály bezpečnostních protokolů, složitých výpočtů a standardů, aby se sešly do série schopných projektů různého charakteru. Jedním z nich je právě OpenSSL se svou nespočetnou základnou uživatelů a mnoha příklady reálného nasazení na malých klientských stanicích i velkých podnikových serverech mnoha platforem. Tato práce je strukturována jako dokumentační analýza knihovny OpenSSL, současně ovšem nápadně připomíná tutoriál čili výukový dokument. V první fázi totiž představuje knihovnu z hlediska modularity, kdy metodicky vychází z koncepce programů jazyka C, v kterém je knihovna napsána, a letmo seznamuje čtenáře s dílčími knihovnami balíku OpenSSL distribuovaného ve verzi 0.9.8a. V druhé fázi přechází text k samotnému programování a analýze API historicky nejstarší části OpenSSL, totiž knihovny SSLeay. Zde výklad sleduje funkce a datové struktury tak, jakoby čtenář začínal s psaním klientského nebo serverovského programu schopného vytvářet bezpečná síťová spojení podle variant protokolu SSL. V poslední fázi práce je podobným způsobem zdokumentována knihovna crypto, zajišťující „background“ hlavní knihovně SSLeay. Vzhledem k jejímu nesmírnému rozsahu se ale zaměřuje pouze na některé její důležitější partie – knihovny ERR, BIO a X509. Praktickou součástí práce je aplikace prezentující schopnosti konzolového programu openssl; její podrobnější dokumentace je zařazena v příloze. 1.2 Cíl práce Text dokumentu je koncipován jako analýza struktury knihovny OpenSSL i jejího rozhraní. Svou formou se však snaží ulehčit orientaci v široké škále exportovaných funkcí či datových struktur. Zjednodušeným výkladem principů jejich použití a uvedením názorných příkladů tak navíc druhotně usiluje o motivaci neobeznámeného čtenáře k hlubšímu studiu projektu OpenSSL. 2 2 Struktura knihovny V této kapitole bude přiblížena modulární struktura knihovny OpenSSL. V krátkých popisech se snaží nastínit hierarchii a zamýšlený význam hlavních modulů. 2.1 Moduly a hierarchie Knihovna OpenSSL je sloučením tří oddělených komponent. Historický základ představují knihovny crypto a SSLeay (SSL/TLS). S nárůstem složitosti se později izoluje ještě balík aplikací pod označením openssl. Schéma knihovny OpenSSL 2.1.1 Knihovna SSLeay Implementuje specifikace kryptografických protokolů Secure Sockets Layer (SSL v2.0 a SSL v3.0) a Transport Layer Security (TLS 1.0, RFC 2246) pro 3 zabezpečenou komunikaci v síti Internet. Je klíčovým pilířem celého projektu, ačkoli poskytované API nemusí být jediným použitelným rozhraním v OpenSSL (nižší rozhraní nejsou omezeny třídami viditelnosti). V hierarchii ovšem vystupuje nejvýše. Funkce a datové struktury tohoto API se exportují s prefixem „SSL_“, podrobněji budou popsány v kapitole „SSLeay API“. SSLeay pro realizaci svého účelu interně používá funkce a datové struktury z rozhraní knihovny crypto, popsané v kapitole 2.1.2. 2.1.2 Knihovna crypto Implementuje jednotlivé kryptografické algoritmy používané knihovnou SSLeay. Každá taková implementace je separovatelná, lze také říci, že crypto je sestavena z řady volitelně vkládaných kryptografických podknihoven. Součást API dotváří několik podpůrných knihoven, vlastní zpracování vstupněvýstupního rozhraní a další spíše interně používané funkce. 2.1.2.1 Kryptografické knihovny Jednotlivé knihovny implementují algoritmy symetrické, asymetrické a hašovací kryptografie, a funkce pro práci s certifikáty. Jejich konkrétní seznam je uveden v kapitolách „Moduly crypto“. Následující tabulky udávají prefixy funkcí a datových struktur exportovaných do API knihovny crypto pro jednotlivé podknihovny. Tabulka 1: Knihovny symetrické kryptografie Knihovna Prefix blowfish BF_ cast CAST_ des DES_ idea idea_ rc2 RC2_ rc4 RC4_ rc5 RC5_ Tabulka 2: Knihovny asymetrické kryptografie Knihovna Prefix dsa DSA_ dh DH_ rsa RSA_ Tabulka 3: Knihovny pro práci s certifikáty Knihovna Prefix x509 X509_ x509v3 X509V3_ 4 Tabulka 4: Knihovny hašovacích funkcí Knihovna Prefix Knihovna Prefix hmac HMAC_ mdc2 MDC2_ md2 MD2_ ripemd RIPEMD160_ md4 MD4_ sha SHA_, SHA1_ md5 MD5_ 2.1.2.2 Podpůrné knihovny Knihovny Err pro záznam a hlášení chyb, Rand pro generování náhodných čísel a knihovna Threads pro podporu OpenSSL v aplikacích pracujících ve vláknech. Do API exportují funkce a datové struktury s odpovídajícími prefixy podle tabulky. Tabulka 5: Podpůrné knihovny Knihovna Prefix err ERR_ rand RAND_ threads CRYPTO_ 2.1.2.3 Knihovny vstupu a výstupu Pro dosažení přenositelnosti mezi platformami je zavedeno vlastní abstrakcí I/O rozhraní BIO. Vzhledem k nasazení OpenSSL především do sféry internetové komunikace je BIO doplněno dalšími knihovnami pro kódování dat – PEM zavádí funkce pro práci s daty ve formátu PEM (zde ve smyslu „kódováno v base64 a ohraničeno hlavičkami“) podle specifikace Privacy Enhanced Mail. Podobně ASN1 implementuje standard Abstract Syntax Notation One (ASN.1, X.680:1995). PKCS7 a PKCS12 implementují standardy Cryptographic Message Syntax Standard a Personal Information Exchange Syntax Standard z rodiny standardů PKCS (Public Key Cryptography Standards). Knihovna EVP (Digital Envelope Library) je wrapper k dříve zmiňovaným kryptografickým funkcím z crypto API. Autoři doporučují jeho použití namísto přímého volání funkcí z API podknihoven. Odpovídající prefixy funkcí a datových struktur exportovaných do API jsou v tabulce. 5 Tabulka 6: Knihovny vstupu a výstupu, kódovaní Knihovna Prefix Knihovna Prefix asn1 ASN1_ pem PEM_ bio BIO_ pkcs7 PKCS7_ evp EVP_ pkcs12 PKCS12_ 2.1.2.4 Interní knihovny Šifrovací algoritmy často vyžadují celočíselné výrazy o vysokých řádech, sadu operací k tomu poskytuje knihovna Bignum (BN). Lhash implementuje datovou strukturu hašovací tabulka. Nejen pro potřeby knihovny BIO je zavedena knihovna Buffer, která implementuje jednoduchý znakový buffer. Odpovídající prefixy jsou uvedeny v tabulce. Tabulka 7: Interní knihovny Knihovna Prefix bignum BN_ lhash LHASH_, lh_ buffer BUF_MEM_ 2.1.3 Balík aplikací openssl Vyčlenil se jako souhrn binárních spustitelných souborů a jejich zdrojových kódů reprezentujících knihovnu OpenSSL programově. Zdrojové kódy programů jsou sestaveny tak, že je možné kompilovat každý program zvlášť do jednotlivých binárních souborů nebo vytvořit jediný spustitelný soubor ze zvolených aplikací. Tento soubor se spouští ve třech režimech. Pokud je jeho název (v prostředí DOS bez přípony) „openssl“, spustí program uvedený svým názvem v prvním parametru. Bez uvedení parametru spustí svůj interpret a očekává příkazy. Nakonec je také možné soubor přejmenovat na název zvolené aplikace a efekt je stejný jako v prvním případě. Stručný popis programů je uveden v dalších kapitolách. 2.2 Moduly SSLeay SSLeay jako hlavní knihovna svými moduly zpřístupní i API knihovny crypto. 6 Ze série inkluzí postačí ve většině případů použít pouze globální hlavičkový soubor ssl.h. 2.2.1 ssl.h Hlavní hlavičkový soubor SSLeay API sám připojuje i níže uvedené soubory knihovny a všechny potřebné hlavičkové soubory z rozhraní knihovny crypto. 2.2.2 ssl2.h Implementace protokolu SSL 2.0. Vkládáno v ssl.h. 2.2.3 ssl3.h Implementace protokolu SSL 3.0. Vkládáno v ssl.h. 2.2.4 ssl23.h Kombinace protokolů SSL 2.0 a SSL 3.0 Vkládáno v ssl.h. 2.2.5 tls1.h Implementace protokolu TLS 1.0. Vkládáno v ssl.h. 2.2.6 kssl.h Podpora mechanismu Kerberos podle RFC 2712. Implicitně vkládáno v ssl.h. 2.3 Moduly crypto – symetrické šifrování 2.3.1 blowfish.h Bloková šifra užívající klíče z roku 1993, která se v současné době řadí mezi nejrychlejší šifry ve své kategorii. Viz [S1] (stránky autora algoritmu). 2.3.2 cast.h Další bloková šifra používající klíče z roku 1996. Existuje ve dvou variantách, CAST-128 a CAST-256. Knihovna crypto v diskutované verzi OpenSSL implementuje pouze první z uvedených variant, v níž je velikost bloku nastavena na 64 bitů a největší délka klíče může být 128 bitů. Viz RFC 2144. 7 2.3.3 des.h Data Encryption Standard (DES), známá šifra z počátku 70. let minulého století. Nedoporučuje se její použití vzhledem k malé délce klíče. Od verze 0.9.7 knihovny OpenSSL je k dispozici také zpětně kompatibilní modul vázaný se starší verzí implementace DES – des_old.h. V současné verzi 0.9.8a obsahuje 15 módů/variant šifry (včetně Tripple-DES, DESX a unixovského crypt) tak, že vyhovuje ANSI X3.106 (módy operací pro DES); implementován je i nástupce známý jako Advanced Encryption Standard (AES)1 . Tabulka 8: Symetrické šifry OpenSSL [3] Algoritm us Typ Délka klíče (implicitně) Rychlost k DES Podporované módy Blowfish blokový (128bit) 3x ecb, cbc, 3ecb, 3cbc, cfb, ofb CAST blokový 128bit 1.5x ecb, cbc, cfb, ofb DES blokový 8bit 1x ecb, cbc, cfb, ofb, pcbc AES blokový 128bit >3x ecb, cbc, cfb, ofb IDEA blokový (128bit) 1x ecb, cbc, cfb, ofb RC2 blokový (128bit) 1x ecb, cbc, cfb, ofb RC4 proudový (128bit) 4x ecb RC5 blokový (128bit) 2x ecb, cbc, cfb, ofb 2.3.4 idea.h International Data Encryption Algorithm (IDEA), bloková šifra z roku 1991 nahrazující DES. Před jejím nasazením v komerční sféře je třeba vzít v potaz důsledky plynoucí z patentové ochrany, která platí pro vybrané evropské země do r. 2010 a pro USA/Japonsko do r. 2011. 2.3.5 rc2.h Bloková šifra z roku 1987, slabší předchůdce RC šifer. Původní implementace v knihovně se inspiruje příspěvkem z Usenet fóra sci.crypt z roku 1996, kterým byla odhalena specifikace této šifry. Současná verze již vyhovuje originální specifikaci (viz RFC 2268). 1 Implementace AES ovšem není dosud oficiálně zdokumentována, tabulka tak uvádí odvozená fakta. 8 2.3.6 rc4.h ARCFOUR, stále ještě prakticky použitelná a používaná proudová šifra. Knihovna implementuje neoficiální verzi specifikace. 2.3.7 rc5.h Bloková šifra z roku 1994, v crypto je podporována pouze kombinace 64bitový blok, 8, 12 nebo 16 cyklů, a nejvýše 255 bitů dlouhý klíč. Algoritmus je patentován v USA, datum expirace není stanoveno. 2.4 Moduly crypto – asymetrické šifrování 2.4.1 dsa.h Digital Signature Algorithm (DSA), implementace vyhovuje standardům FIPS 186 pro DSS a ANSI X9.30. 2.4.2 dh.h Diffie-Hellmanův protokol výměny klíčů podle RFC 2631 a PKCS #3. 2.4.3 rsa.h RSA public-key encryption algorithm, implementace podle specifikace SSL a standardu PKCS #1 v2.0. Umí generovat nové páry veřejných a soukromých klíčů. 2.5 Moduly crypto – hašování 2.5.1 hmac.h Keyed-hash message authentication code (HMAC), podle RFC 2104. 2.5.2 md2.h Message Digest Algorithm 2 (MD2), hašovací funkce podle RFC 1319. 2.5.3 md4.h MD4, hašovací funkce podle RFC 1320. 2.5.4 md5.h MD5, hašovací funkce podle RFC 1321. Vzhledem k nálezům několika příkladů kolizních posloupností již není považována za dostatečně dokonalou a 9 od verze 0.9.8 (z června 2005) autoři doporučují v aplikacích používat k podpisu certifikátů apod. raději RIPEMD-160 nebo SHA-1 a vyšší. 2.5.5 mdc2.h Modification Detection code (MDC2), hašovací funkce podle ISO/IEC 10118-2 s DES. Originální specifikace je pod patentovou ochranou, která má vypršet až v roce 2007. Z tohoto důvodu je implicitně pro překlad vynechána a není k dispozici ani např. v OpenSSL dodávaném s RedHat v7.1 v USA. 2.5.6 ripemd.h RACE Integrity Primitives Evaluation Message Digest (RIPEMD-160), hašovací algoritmus podle ISO/IEC 10118-3:2003. 2.5.7 sha.h SHA-1, Secure Hash Algorithm. Implementace vyhovuje FIPS PUB 180-1 (Secure Hash Standard) a ANSI.X9.30. Pro možnost zpětné kompatibility je definována i předchozí verze – SHA (SHA-0) (podle FIPS PUB 180). Od verze 0.9.8 sem spadá také implementace algoritmů SHA-224, SHA-256, SHA-384 a SHA-512 (podle FIPS 180-2). 2.6 Moduly crypto – certifikáty 2.6.1x509.h Funkce pro práci s certifikáty a CRL (Certificate Revocation List) podle RFC 3280 resp. ITU-T Recommendation X.509 (1997 E), a také související Certificate Request podle RFC2896. Obsahuje i rutiny pro převod mezi datovými formáty PEM a DER a podporu pro systém SPKI provozovaný v Netscape. K realizaci zabezpečení modul používá šifru RSA, DH nebo DSA z knihoven asymetrické kryptografie dh.h, rsa.h a dsa.h. 2.6.2x509v3.h Zavádí podporu pro používání rozšíření X.509 v3 a CRL v2 podle RFC 3280. 10 2.7 Moduly crypto – podpůrné 2.7.1err.h Chybový systém pro OpenSSL používaný řadou modulů. Chyby se ukládají do fronty asociované se svým procesním vláknem, lze jim definovat řetězce pro chybová hlášení s přesným názvem knihovny a funkce, v níž k chybě došlo. Protože je koncipován nezávisle na OpenSSL, je možné tuto knihovnu použít i ve vlastních programech. 2.7.2threads.h Podpora knihovny OpenSSL v multithreadových programech – zamykání sdílených dat a dynamické zámky. Přestože některé partie kódu dynamické zámky údajně potřebují pro lepší výkonnost, nejsou zatím v diskutované verzi aktivně používány. 2.7.3rand.h Generátor pseudonáhodných čísel nutný především pro generování klíčů. Iniciální hodnoty pro generátor musí dodat aplikace např. z pohybu myši, knihovna ale nabízí jejich ukládání do souboru a odtud je i číst. 2.7.4opensslv.h Definuje verzi knihovny. 2.7.5ui.h Představuje interface pro uživatelské rozhraní nad zbytkem knihovny, aby bylo možné ji ovládat v nejrůznějších podobách. 2.8 Moduly crypto – vstup/výstup, kódování 2.8.1asn1.h Abstract Syntax Notation One (ASN.1). Standard neurčuje kódování popisované informace, v OpenSSL se ovšem pracuje s formátem DER (Distinguished Encoding Rules). DER je specializovaný model formátu BER (Basic Encoding Rules), knihovna asn1 je tedy schopná přistupovat i k datům v základním formátu. Zavedené funkce jsou nutné pro X509 (patří mezi ně rutiny pro podepisování struktur asociovaných s X.509), PKCS7 a PKCS12. 11 2.8.2bio.h Wrapper (nebo přesněji abstrakce) nad vstupem a výstupem s ohledem na platformní odlišnosti. Vedle práce se soubory přináší možnost transparentně ustavovat a jinak spravovat nekryptovaná síťová spojení i kryptovaná SSL spojení. Koncepce rozlišuje dva typy jednotek – zdrojové/zakončovací jednotky, jimiž mohou být různé I/O kanály (soubor, soket, paměťový buffer aj.), a filtry připojované k jednotkám prvního typu. Řazení jednotek do řetězu zajišťuje transparentnost operací, což přináší více pohodlí do kódu programu. BIO je primárním prvkem pro veškeré I/O v OpenSSL a podobně jako ERR je schopná samostatného využití. 2.8.3evp.h Digital Envelope Library, wrapper ke kryptografickým knihovnám pro jednodušší a přehlednější kód. Nabízí také algoritmus Base64. 2.8.4pem.h Rutiny ke kódování digitálních dat podle Privacy Enhanced Mail. 2.8.5pkcs7.h Rutiny ke kódování dat podle PKCS #7, používající ASN.1 popisy. 2.8.6pkcs12.h Rutiny ke kódování dat podle PKCS #12, používající ASN.1 popisy. 2.9 Moduly crypto – interní funkce 2.9.1bn.h Knihovna pro aritmetiku s čísly teoreticky neomezené svým bitovým rozsahem. Obsahuje také generátor prvočísel a rutinu k testování na prvočíslo. Samostatná knihovna, v OpenSSL nutná např. pro knihovny RSA, SHA a DH. 2.9.2buffer.h Implementace jednoduchého bufferu znaků. 2.9.3lhash.h Lhash Table Library, dynamická hašovací tabulka. Knihovna ji používá 12 především pro spravování SSL/TLS relací. 2.9.4object.h Pomocná knihovna pro ASN1. Jedná se o sadu funkcí překládajících objektové identifikátory na konkrétní datové typy. 2.9.5stack.h Implementace datového typu „zásobník“. 2.9.6txt_db.h Knihovna pro spravování jednoduché textové databáze udržované v paměti. Vznikla v rámci účelu odzkoušet správu certifikátů (aplikace openssl). 2.9.7conf.h Není uvedena jako podpůrná knihovna, přesto jako podpůrná vznikla. Jde o jednoduchý systém pro spravování konfigurace programů nad OpenSSL prostřednictvím souboru nebo proměnných prostředí. Jako většina popsaných modulů, je i CONF nezávisle využitelná. 2.10 Aplikace openssl Aplikace openssl je program příkazové řádky reprezentující OpenSSL. Lze jím ➢ vytvářet parametry klíčů pro RSA, DH a DSA, ➢ zpracovávat a vytvářet certifikáty X.509, Certificate Signing Request a Certificate Revocation List ➢ počítat hash zprávy (Message Digest) ➢ šifrovat a dešifrovat pomocí běžných algoritmů symetrické kryptografie ➢ provozovat zkušební SSL/TLS server se zkušebním SSL/TLS klientem ➢ šifrovat/dešifrovat, ověřovat a podepisovat S/MIME e-mailové zprávy 13 3 SSLeay API (výběr) Tato kapitola představuje knihovnu SSLeay z pohledu její užitečnosti. Přibližuje stěžejní příklady použití v několika jmenovaných kategoriích, jež se snaží naznačit eventuální cesty k řešení hledaného problému. Přestože tedy nese název vhodný spíše k řádnému výčtu funkcí a datových struktur, smysl by měl být (alespoň částečně) podobný; pouze ve vybraných případech tento zvolený způsob prezentace knihovny prolíná do synopse a popisu poskytovaných funkcí a datových struktur. 3.1 Funkce volby metody protokolu SSL_METHOD Funkce vztahující se k objektu SSL_METHOD V knihovně OpenSSL každé SSL/TLS spojení staví svoje parametry na tzv. SSL kontextu. Funkce volby metody protokolu se uplatňují při přípravě tohoto kontextu, tj. při vytváření struktury SSL_CTX. Mají za úkol vymezit interní okruh operací tak, aby byl implementován příslušný protokol SSLv2, SSLv3 nebo (D)TLSv1. Pro každý případ protokolu je zavedena trojice funkcí – dvě jsou dedikovány pro kontext použitelný v režimu serveru respektive klienta, jedna pro případ kontextu univerzálního. Dohromady je tedy zavedeno dvanáct funkcí. Příklad: Vytvoření klientského kontextu protokolu typu SSL 3.0 pomocí SSLv3_client_method(), jaký se může objevit např. v rámci úkolu „vytvoření SSLv3 spojení klient-server“: SSL_METHOD* meth = SSLv3_client_method(); // set-up the method SSL_CTX *ctx = SSL_CTX_new(meth); // set-up SSL context SSL *connection = SSL_new(ctx); // set-up the connection ... Ilustrace 1: SSLv3_client_method() Viz také: SSL_CTX_new(), SSL_CTX_set_ssl_version(), SSL_METHOD in 3.6 14 3.2 Funkce šifer, SSL_CIPHER_* Funkce zaměřené na manipulaci s šiframi (objekty SSL_CIPHER) V této partii rozhraní SSLeay exportuje čtveřici funkcí informujících o atributech objektu SSL_CIPHER. Jejich sémantický dopad na vlastní proces není nijak přímo čitelný; svou roli hrají v dohodě klienta a serveru na metodě, jíž budou následující spojení zabezpečena. K vráceným informacím náleží slovní popis (SSL_CIPHER_get_description()), název (SSL_CIPHER_get_name()), bitový rozsah klíče (SSL_CIPHER_get_bits()) a verze protokolu v němž je šifra registrována (SSL_CIPHER_get_version()). Viz také: SSL_CIPHER in 3.7 3.3 Funkce kontextu, SSL_CTX_* Funkce zaměřené na manipulaci s SSL kontextem (objekt SSL_CTX) Okolo sedmdesátky funkcí vesměs simuluje zapouzdřenost objektu SSL_CTX, tj. přiřazuje nebo získává hodnoty interních atributů, jimiž se knihovna řídí při zakládání SSL/TLS spojení, vzájemné autentizaci obou stran či šifrování jejich komunikace – stručněji řečeno, při implementaci ostatních cílů plynoucích ze specifikace toho kterého protokolu. 3.3.1 Vytvoření kontextu: SSL_CTX_new() Synopse: SSL_CTX *SSL_CTX_new(SSL_METHOD *method) Nový SSL kontext (strukturu SSL_CTX, viz kapitola 3.8) pro daný protokol vytvoří SSL_CTX_new(); tento „konstruktor“ (či přesněji „simulace konstruktoru v jazyce C“) přiřadí atributům struktury určitou implicitní hodnotu, takže je připraven pro tvorbu objektů SSL, které v OpenSSL popisují vlastní SSL/TLS spojení. Alokovaný objekt pak přizpůsobí stanoveným požadavkům jeho následná inicializace. Její průběh, popsaný kapitolou 3.8, doplňují některými detaily následující kapitoly. Příklady: Ilustrace 1 Viz také: SSL_CTX in 3.8, SSL_new() 3.3.2 Přiřazení soukromého klíče: SSL_CTX_use_Private_Key() Jedním z mnoha úkolů pro implementaci některého z SSL protokolů je zajištění důvěryhodnosti mezi komunikujícími stranami prostředky asymetrické 15 kryptografie. V OpenSSL je toho dosaženo inicializací kontextu a provedením handshake podle specifikace nastaveného protokolu (viz kapitola 3.8). V rámci autentizace mezi klientem a serverem je tak použito soukromého klíče. V knihovně jsou k dispozici dvě trojice funkcí, kterými je ke kontextu připojen konkrétní klíč; funkce se liší očekávaným typem klíče (RSA nebo jiný) a zdrojem (paměť, soubor, struktura EVP_PKEY).2 Příklady: Ilustrace 2, Ilustrace 3 3.3.3 Heslo šifrovaného PEM souboru: SSL_CTX_set_default_password_cb() Synopse: void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_passwd_cb *cb) void SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx, void* u) int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) Soukromý klíč vystupující v autentizaci bývá chráněn svým heslem. Knihovna jej od aplikace získává voláním callback funkce pem_passwd_cb()3 pokaždé před uložením nebo načtením klíče. Tento callback nastavuje kontextu právě SSL_CTX_set_default_password_cb(). Příklady: Ilustrace 2 3.3.4 Připojení certifikátu: SSL_CTX_use_certificate() Poslední nevyhnutelný krok v autentizaci mezi klientem a serverem představuje použití certifikátu připojeného ke kontextu. V inicializaci je proto k dispozici trojice funkcí načítajících certifikát z různých zdrojů (paměť, soubor, struktura X_509) a pro přípravu k autentizaci kompletním řetězem certifikátů funkce SSL_CTX_add_extra_chain_cert() nahrávající řetěz po jednotlivých souborech.2 Příklad č. 2 připojuje celý strom certifikátů uložený v jednom souboru pouze pomocí SSL_CTX_use_certificate_chain_file(). Příklady: Ilustrace 2, Ilustrace 3 2 Tyto funkce mají také svou obdobu mezi funkcemi pro strukturu SSL – jejich název se liší prefixem (SSL_* místo SSL_CTX_*). Sémanticky se nejedná o redundanci, protože změny kontextu se aplikují na spojení pouze při SSL_new(). 3 Parametr rwflag je roven 0, pokud se bude klíč dešifrovat. 16 Ilustrace 2: Inicializace SSL kontextu pro připojení klienta k autentizovanému serveru #define CERTFILE „client_cert.pem“ #define KEYFILE „client_pkey.pem“ static char* PASSWORD = „password“; int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata); /* Initialize given SSL_CTX */ void _init_ssl_ctx(SSL_CTX* ctx) { /* enable SSLv2 or SSLv3 */ SSL_METHOD meth_sslv23 = SSLv23_method(); SSL_CTX_set_ssl_version(ctx, meth_sslv23); /* load certificate chain */ SSL_CTX_use_certificate_chain_file(ctx, CERTFILE); /* load private key */ SSL_CTX_use_PrivateKey_file(ctx, KEYFILE, SSL_FILETYPE_PEM); /* set the password callback */ SSL_CTX_set_default_passwd_cb(ctx, password_cb); /* set trusted CAs */ SSL_CTX_load_verify_locations(ctx, CA_LIST, 0); } /* password callback */ int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) { int len = size=0) { /* The extension stays at th cell in the STACK OF(X509_EXTENSION) stack of the X509 structure. So let's get it: */ ext = X509_get_ext(cert, pos); if (ext) { /* print-out extension values using a memory BIO*/ BIO* bio_buf = BIO_new(BIO_s_mem()); X509V3_EXT_print(bio_buf, ext, 0, 0); /* move them to ASCII buffer and print to stdout*/ BIO_gets(bio_buf, values, 255); fprintf(stdout, „subjectAltName value is %s\n“, values); BIO_vfree(bio_buf); } } 47 Ilustrace 14: X509_get_ext_d2i(), sk_GENERAL_NAME_*(), ASN1_STRING_data(): Extrakce X.509v3 rozšíření z certifikátu X509 *cert; STACK_OF(GENERAL_NAME) *gens; char *value; int i; /* prepare structures */ cert = X509_new(); /* Load certificate prom PEM-formatted file. Note that a password callback * will be needed as the 3d parameter if the certificate was encrypted. */ PEM_read_X509( fopen(„mycert.pem“, „r“), &cert, NULL, NULL); /* obtain the field by its NID name (see objects.h) - extract subjectAltName, * dNSName print separately */ /* First obtain whole the stack of that extension's unions */ gens = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i (cert, NID_subject_alt_name, if (gens) { for (i=0; i < sk_GENERAL_NAME_num( gens ); i++) { gen = sk_GENERAL_NAME_value( gens, i); /* check gen to have dNSName subfield, if so, extract it */ if (gen->type == GEN_DNS) { fprintf (stdout, "\t Found subjectAltName:dNSName: "); buf = ASN1_STRING_data(gen->d.dNSName); if (buf) { fprintf (stdout, "%s\n", buf); /* Freeing of 'buf' is recommended! */ free (buf); buf = NULL; } } else { /* Extension not present */ } /* free-up ! */ X509_free(cert); fclose(fp); 48 5 Závěr Složitost a rozsah knihovny OpenSSL je ve skutečnosti mnohem vetší, než zachytil tento dokument. Výsledná práce specifickým způsobem analyzuje knihovnu na problému, jak s její pomocí vytvořit spojení podle protokolu SSL 2.0/3.0 nebo TLS 1.0 a jak toto spojení zabezpečit pomocí certifikátů. Z takového úkolu se odvíjí řada dílčích problémů, proto text (alespoň částečně) seznamuje s knihovnami BIO, ERR a X509. Samotná implementace uvedeného problému nevyžaduje tak široce rozvedený návod, ovšem pouze za předpokladu, že programátor nepotřebuje více proniknout do teoretické stránky projektu OpenSSL. Tímto směrem nebyla práce koncipována, na druhou stranu tak bohužel její omezený rozsah nedovolil seznámit s okolnostmi instalace, konfigurace a kompilace knihovny, ani s dalšími stěžejními významy OpenSSL. Prostoru se nedostalo všem článkům sofistikovaného mechanismu knihovny crypto ve spojení s problematikou managementu certifikátů – např. konfigurace serveru pracujícího jako entita PKI infrastruktury, v níž lze vydávat a autorizovat certifikáty. Zcela mimo spektrum zájmu práce je uvedení OpenSSL jako toolkit produktu, navzdory frekventovanosti takového využití: na Internetu jsou k nalezení návody konfigurace známého webového serveru Apache, kterou je povýšen na CA uzel v síti PKI; prostředkem je zde právě OpenSSL a jeho balík aplikačních nástrojů. I přes malý úhel záběru práce je tato výchozím bodem k dalšímu seznámení se s OpenSSL. Motivací budiž její univerzálnost, díky které se lze setkat s jejím obsazením do role nadstavby protokolům HTTP pro zabezpečené webové servery (projekt modSSL i jeho rodičovská alternativa ApacheSSL tvořící rozhraní k Apache serveru), a protokolům SMTP, POP a IMAP pro komunikaci elektronickou poštou (MTA/MDA program pine). 49 6 Literatura Stručné, přehledné informace ● Transport Layer Security, Wikipedia, http://en.wikipedia.org/wiki/Ssl (březen 2006) Dokumentace ● [D1] YOUNG, E., aj.: OpenSSL documents, The OpenSSL Project, říjen 2005. Dostupné na URL http://www.openssl.org/docs/ (březen 2006) ● [D2] GLENN, A.T.: SSLeay documentation, Columbia University, leden 1999. Dostupné na URL http://www.columbia.edu/~ariel/ssleay/ssleay.html (březen 2006) ● [D3] YOUNG, E., aj.: OpenSSL 0.9.8a, The OpenSSL Project, říjen 2005. Dostupné na URL http://www.openssl.org/source/openssl- 0.9.8a.tar.gz (březen 2006) ● [D4] HUDSON,T.J., YOUNG, E.: SSLeay Programmer Reference, School of Psychology, The University Of Queensland, leden 1996. Dostupné na URL http://www2.psy.uq.edu.au/~ftp/Crypto/ssl.html (březen 2006) Příklady ● [EX1] RESCORLA, E.: An introduction to OpenSSL programming (Part I), RTFM, Inc., říjen 2001. Dostupné na URL http://www.rtfm.com/openssl-examples/part1.pdf (březen 2006) ● [EX2] RESCORLA, E.: An introduction to OpenSSL programming (Part II), RTFM, Inc., leden 2002. Dostupné na URL http://www.rtfm.com/openssl-examples/part2.pdf (březen 2006) Specifikace ● [S1] SCHNEIER, B.: The Blowfish Encryption Algorithm. Dostupné na URL http://www.schneier.com/blowfish.html (duben 2006) ● [S2] SSL 2.0 specification, Netscape, únor 1995. Dostupné na URL http://wp.netscape.com/eng/security/SSL_2.html (březen 2006) ● [S3] SSL 3.0 specification, Netscape, listopad 1996. Dostupné na URL 50 http://wp.netscape.com/eng/ssl3/index.html (březen 2006) ● [S4] DIERKS, T., ALLEN, C.: The TLS Protocol Version 1.0, IETF, leden 1999.Dostupné na URL http://www.ietf.org/rfc/rfc2246.txt (březen 2006) ● [S5] RESCORLA, E.: HTTP Over TLS, RFC 2818, květen 2000. Dostupné na URL http://www.ietf.org/rfc/rfc2818.txt (březen 2006) 51 Příloha A: Specifikace WinSSL Cíl Aplikace poskytuje běžnou funkčnost nástroje openssl knihovny OpenSSL ve formě grafického uživatelského rozhraní. Charakteristika Aplikace WinSSL disponuje většinou funkcí nabízených nástrojem openssl jako příkazy interpretu, konkrétně podle následujícího seznamu: ✔ asn1parse ✔ dhparam ✔ genrsa ✔ rand ✔ ca ✔ dsa ✔ ocsp ✔ req ✔ ciphers ✔ dsaparam ✔ passwd ✔ rsa ✔ crl ✔ enc ✔ pkcs12 ✔ rsautl ✔ crl2pkcs7 ✔ gendh ✔ pkcs7 ✔ smime ✔ dgst ✔ dendsa ✔ pkcs8 ✔ verify ✔ x509 Prostřednictvím grafického rozhraní uživatel může zvolit vybraný příkaz, specifikuje parametry převzaté ze souvisejícího příkazu nástroje openssl a následně nechat aplikaci příkaz provést. Po jeho dokončení program informuje o výsledku. GUI Grafické rozhraní tvoří soustava nabídek v menu, uspořádaná podle charakteru na dialogy a průvodce. Dialogy zastupují příkazy s malým počet parametrů, průvodci naopak příkazy s tolika nastaveními (parametry), že by bylo nepřehledné je uspořádat pouze na jednom formuláři. Koncepce řešení Vývojovým prostředím je Microsoft Visual Studio .NET Professional 2003, za programovací jazyk je zvoleno C++ s kompilátorem dodávaným společně s vývojovým prostředím. Wrapper k openssl aplikacím Přístup ke knihovným funkcím, jež plní své dílčí úkoly v implementaci každého z příkazů, zajišťuje wrapper openssl_win. Je implementován jako modifikace 52 existujícího modulu openssl.c (tedy zdrojového kódu nástroje openssl), upraveného pro potřeby WinSSL. Příkazy jsou vykonávány voláním funkce main() z wrapperu. Její deklarace se shoduje s klasickou deklarací funkce main() v programu jazyka C, pracujícího s parametry příkazové řádky* . WinSSL modifikuje původní zdrojový kód nástroje openssl tak, aby mohl simulovat jeho spouštění z příkazové řádky: v parametrech předává vektor argumentů a jeho velikost. Ve funkci main() dojde k jejich zpracování a provedení příslušného příkazu. O výsledku příkazu informuje návratová hodnota funkce main(): nenulová hodnota znamená chybu. Bližší popis chyby získá z fronty chyb knihovny OpenSSL funkce ossl_wrapper_get_last_err_string(), exportovaná v rozhraní wrapperu. Třída OSSL_OPS OSSL_OPS je abstraktní třídou uchovávající nastavení příkazu. Jelikož nastavení pro jednotlivé příkazy se liší, implementují se potomci této třídy pro jednotlivé příkazy, a to ve vlastním jmenném prostoru. Pro formální oddělení používaných parametrů jsou symbolické názvy parametrů definovány ve jmenném prostoru „Options“ v rámci jmenného prostoru příkazu. Existence objektu třídy ‒ viz níže. Třída CCmdBase Pro příkazy je definována abstraktní třída CCmdBase, jejíž potomci používají jako atribut relevantního potomka třídy OSSL_OPS. Třída spouští funkci main() z wrapperu k aplikacím openssl, udržuje nastavení. Existence objektu třídy ‒ viz níže. Třída CwizardBase Třída definuje dialogového průvodce, který uživatel vyvolá z menu aplikace. Opět je abstraktní; potomci, kteří ji implementují, představují specifické průvodce jednotlivých příkazů. Pro spuštění průvodce se použije metoda CwizardBase::Start(), která postupně vybírá objekty typu System::Windows::Forms::Form (formuláře) * Důvodem je snaha co nejméně modifikovat originální zdrojový kód nástroje openssl. Ten je dedikován pro práci v textovém režimu a pomocí argumentů příkazové řádky ovládá další příkazy (aplikace openssl). 53 z atributu actions a vkládá je do implicitního dialogu průvodce. Tento dialog obsahuje tlačítka „Cancel“, „Back“ a „Next“ (resp. „Finish“, je-li vkládaný formulář posledním prvkem ve vektoru formulářů v actions). Atribut actions typu ACTMAP představuje mapu akcí. Akce vymezuje svým významem učitou množinu parametrů příkazu, s kterými může být spojena (pro většinu příkazů je pouze jedna akce použitelná se všemi parametry, ale např. příkaz ocsp definuje tři akce, které mají svůj okruh parametrů), určená svým jménem (jako hašovací klíč) a vektorem formulářů, které nastavují související parametry (pro většinu příkazů pouze jeden formulář). Dialogu příkazu v charakteristice GUI odpovídá akce s jednoprvkovým vektorem, průvodci pak akce s víceprvkovým vektorem formulářů. Ilustrace A.1: Ze zdrojového kódu: implementace akcí a sad formulářů, které jsou s akcemi spojeny public __gc struct SContext { System::Collections::ArrayList * options; System::Windows::Forms::Form * form; }; typedef SContext PAGE; typedef ArrayList PAGES; // collection of PAGE* typedef ArrayList __gc * PPAGES; // pointer to PAGES typedef SortedList ACTMAP; // map of pairs Stisknutím tlačítka „Next“ nebo „Finish“ se vyvolá událost, kterou zpracuje handler CwizardBase::Step() ‒ ten uloží dostupná nastavení podle údajů z formuláře. Stiskem „Finish“ se navíc vytvoří instance z potomka třídy CcmdBase (jako atribut CwizardBase), do níž se zkopírují nastavení z formuláře, a zavolá se metoda CcmdBase::Run(), která použije funkce main() z wrapperu openssl_win k provedení příkazu. Po dokončení metody objekt implementující CCmdBase (potomek) zanikne a aplikace informuje o výsledku. V případě chyby nabídne akci opakovat, v případě úspěchu nebo odmítnutí dalšího pokusu celý objekt vzniklý z potomoka CWizardBase sám sebe uvolní. Průvodci WinSSL poskytuje příkazy ca, crl, ocsp, x509 a enc ve formě průvodců. Následující tabulka spojuje každý z těchto příkazů s implementovanou akcí. Tabulka A.1: Implementované příkazy Příkaz Název příkazu Akce req X.509 CSR Create certificate request 54 Příkaz Název příkazu Akce Management Create self-signed certificate ca Certificate Authority management Sign certificate request Sign self-signed certificate Sign Netscape SPKAC x509 X.509 certificate data management Sign to create self-signed certificate Sign using CA Certificate conversions ocsp Online Certificate Status Protocol utility Create OCSP request Parse OCSP response enc Encoding with ciphers Encryption/decryption with symmetric ciphers Dialogy Příkazy ze seznamu v úvodu tohoto textu, které nezmiňuje tabulka výše, aplikace WinSSL implementuje jako dialogy, tj. potomky třídy CWizardBase, definující jedinou akci s jedním formulářem. Omezení ● Platforma: Win32 pro OS Windows XP libovolné verze ● Paměťová náročnost: min. 10MB ● Závislosti: OpenSSL v0.9.8a, NET Framework v1.1+ 55