Mega Code Archive

 
Categories / Delphi / Ide Indy
 

OpenSSL with Delphi

Title: OpenSSL with Delphi Question: Using https, secure socket server or an end to end cipher channel is possible with 2 libraries from OpenSSL and 3 components from Indy. Answer: The OpenSSL Project is a collaborative effort to develop a robust, commercial-grade, full-featured, and Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) protocols as well as a full-strength general purpose cryptography library. The project is managed by a worldwide community of volunteers that use the Internet to communicate, plan, and develop the OpenSSL toolkit and its related documentation. Delphi also supports the toolkit since the integratin of Indy Sockets. Indy is developed by a large team of dedicated and active people and there are absolutely no costs to use Indy, or deploy an application that uses Indy. While Indy is open source, Indy also has commercial support options. Atozed Software offers both commercial support, as well as consulting on Indy. Every layer of Indy is pluggable, including RFC replies, encryption, authentication, encodings, and more. Delphi can use OpenSSL library invoking DLL. Indy supports Win and Linux as well the proof you can find in IdSSLOpenSSLHeaders.pas: const {$IFDEF LINUX} SSL_Indy_DLL_name = 'libindy_ssl.so'; {Do not localize...} SSL_DLL_name = 'libssl.so'; SSLCLIB_DLL_name = 'libcrypto.so'; {$ELSE} SSL_DLL_name = 'ssleay32.dll'; SSLCLIB_DLL_name = 'libeay32.dll'; {$ENDIF} Latest compile of the OpenSSL libraries with the Indy modifications built into you can find by intelicom.si. These files have been built from the OpenSSL version 0.9.6m source code from http://www.openssl.org Since intelicom published their recommendation regarding how to compile OpenSSL with the Indy modification, a couple of functions have been added to the OpenSSL exports, requiring the Indy functions to be renumbered. Version 0.9.6g compiled by Intelicom for Indy project seem to work correctly; Finally, you can retrieve the libeay32.dll and ssleay32.dll files from the zip folder and place them in your applications folder or system32 folder. So how can you start with an OpenSSL Project; I'll show you two possibilities one of them in the Demos\Indy\HTTPServer\ as a straight https example. Second is a whole project from DWS (DelphiWebStart) with a manual and the lib's of OpenSSL included, just download the source from: http://sourceforge.net/projects/delphiwebstart/ and open the projectgroup in d7, so it works with Indy 9.00.18 Both projects are routable, means if your router is set up correctly, SSL has all the routing necessary to achieve ip-forwarding, one way NAT or hoping over the net. Furthermore you have to set the certificate path in the ip_a.ini file: [CERT] ROOTCERT=cert\CA_indy_cert.pem SCERT=cert\client_indy_cacert.pem RSAKEY=cert\client_indy.pem OpenSSL includes a command line utility that can be used to perform a variety of cryptographic functions like generating your machine certificate in [CERT]. First you need a RootCA (selfsigned) // we genrate the private key of the CA: 1. openssl genrsa -des3 -out CA_pvk.pem 1024 // we sign the private to make a certificate of CA 2. openssl -new -x509 -days 365 -key CA_pvk.pem -out CA_crt.pem //CA_indy_cert // we need the host private key 3. openssl genrsa -des3 -out host_pvk.pem 1024 //client_indy.pem // we sign the host private from the CA (machine certificate) 4. openssl req -new key host_pvk.pem -out host_csr.pem 5. openssl ca -out host_crt.pem - in host_csr.pem -cert CA_crt.pem -keyfile CA_pvk.pem //client_indy_cacert.pem in this way we get [CERT] ROOTCERT=cert\CA_crt.pem SCERT=cert\host_crt.pem RSAKEY=cert\host_pvk.pem With the same openssl.exe shell you can verify your certificate chain, mean you will prove the signature of the certificate: But and there is a great caveat you must produce a hash from a ROOT_CA first: - openssl x509 -in CA_crt.pem -hash output 68e57cac then you copy the hash value in a new file name with 0 extension: copy CA_crt.pem 68e57cac.0 Now you're ready to verify: openssl verify -verbose -CAfile CA_crt.pem -CApath ./ host_crt.pem then you should get host_crt.pem: OK Working with Indy is straight. Indy implements more protocols than any other library and such mechanism like the Interceptor or the IOHandler are easy to use from an existing project, e.g. to enhance it with SSL: IdTCPServer1.IOHandler:= IdServerIOHandlerSSL1; But be carfully, Indy has no standard method to prove the certificate chain, you must do it with the event handler OnVerfyPeer() on your side! The change from indy 9 to 10 is obvious; the difference is that the connections's Intercept property has been moved into the IOHandler in indy 10, so you can call the IOHandler property before calling Connect() also assign the handler at design-time. Do note that the IOHandler has to be assigned before calling Connect() if you want to log the commands that Connect() sends internally: IdTCPServer1.IOHandler.Intercept:= idLogEvent; Its interface follows the blocking model. There are no event based state machines to manage. Everything happens in a sequence, just like accessing a file: IdTCPServer1.Bindings.DefaultPort:= SSL_PORT; IdServerIOHandlerSSL1.OnStatusInfo:= dwsInfoCallback; Hope you'll callBack ;) Last Version is 1.9. Major changes between DWS 1.8 and DWS 1.9: o Now OpenSSL 0.9.8g support o Several compilation issues fixed o Compilation switch between Indy 9 and 10 o Added support for hash ckecking MD5 of the OpenSSL Lib o Built in mutex check for single instance of DWS Server o Various example of certificate files included (3 files) o Rework of the app loader list with an open file dialog o Docu of install und use with Delphi 7.1 / Indy support o Fix loading and start file names with space o Industrialized use of exceptions / debug mode o Reworked parts of the ip_a.ini file o Extended message passing back to DWS Server At least how to get OpenSSL DDL version: function GetOpenSSLVersion: string; var v: cardinal; s: PChar; begin v:= SSLeay; s:= SSLeay_version(_SSLEAY_CFLAGS); result:= s + ' (' + IntToHex(v, 9) + ')'; end;