]> www.wagner.pp.ru Git - sites/home_page.git/commitdiff
Added article about openssl
authorVictor Wagner <vitus@wagner.pp.ru>
Sun, 22 Oct 2006 20:07:05 +0000 (20:07 +0000)
committerVictor Wagner <vitus@wagner.pp.ru>
Sun, 22 Oct 2006 20:07:05 +0000 (20:07 +0000)
articles/openssl-mingw.html [new file with mode: 0644]

diff --git a/articles/openssl-mingw.html b/articles/openssl-mingw.html
new file mode 100644 (file)
index 0000000..9578562
--- /dev/null
@@ -0,0 +1,342 @@
+<HTML><HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=koi8-r">
+<TITLE>Building OpenSSL for Windows with Mingw32</TITLE>
+<META NAME="DESCRIPTION" CONTENT="Summary of experience of building both
+stable and development versions of OpenSSL for Windows"> </HEAD><BODY>
+<H1>Building OpenSSL for Windows with Mingw32</H1>
+<p>
+If you want to get OpenSSL libraries (either .dll or static libraries),
+usable by native Windows compilers, you can use entirely free GNU
+compiler, downloadable from internet.
+</p>
+<p>
+OpenSSL is written on plain old C, which means that as long as compilers
+use common object file format, you can easily link object files and
+static libraries, produced by one compiler, with another.
+</p>
+<p>
+GNU MinGW32 compiler uses COFF object format, same as Microsoft Visual
+studio. It just has different naming convention. Rename libssl.a,
+produced with MinGW to ssl.lib, and you can use it in MSVC.
+</p>
+<H2>Build environments</H2>
+<p>
+OpenSSL distribution includes file mingw.bat to build dll version with
+MinGW. Forget about it. It is outdated, unsupported and soon to be
+removed.
+</p>
+<p>Better to use unix style configure-make-make install approach. For
+this approach you'll need unix-like shell, perl and some utilities.
+</p>
+<p>There are three possible choices for the build environment:
+</p>
+<ol>
+<li><p>Use minimal needed set of utilites. You'll need:</p>
+<ul>
+<li>mingw32 compiler from <a href="http://www.mingw.org">mingw.org</a>
+<li>Minimal system (MSYS) from same site
+<li>Win32 version of Perl from <a
+href="http://www.activestate.com">ActiveState</a>
+</ul><p>
+This would take less than 100Mb on your disk and let your build lots of
+interesting things other than OpenSSL.</p>
+</li>
+<li><p>Use Cygwin toolchain. Yes, you can build native win32 programs,
+which don't depend on cygwin.dll with cygwin compiler.
+You'll need cygwin perl, make, coreutils and all some packages from
+cygwin  which have mingw in its name (from development section) You
+don-t need C++ compiler, but, probably would like to use mingw zlib. 
+</p><p>I
+recommend to use this way only if you already have cygwin and
+accustomized to use it.
+</p>
+</li>
+<li><p>Compile all thing on nearby Linux/Unix machine using cross-compiler.
+If you use Debian GNU/Linux, you need just to install packages mingw32,
+mingw32-runtime and mingw32-binutils. You typically have make, perl and
+coreutils on Linux system. On other Unixes you probably will need to
+build mingw32 cross-compiler from gcc sources.
+</p>
+<p>
+I wouldn't cover building and  installing cross-compiler here.
+</p>
+</li>
+It is also possible to combine cygwin compiler and shell with
+ActiveState perl, but I wouldn't recommend to do so.
+<h2>Building static version</h2>
+<p>
+Download and unpack sources of openssl. It comes in the tar.gz archive.
+Any build environment mentioned above includes <tt>tar</tt> program
+which is used to unpack archives.
+</p>
+<p>
+Open command window (or terminal window on Unix), make sure that
+cygwin (or all of msys, mingw and ActiveState perl) directories are in
+your  PATH (on Unix cross compiler automatically installed into PATH and
+perl is already there), 
+change into top-level  directory of unpacked source.
+<p>
+Open Configure script with text editor, find line
+</p>
+<pre>
+$IsMK1MF=1 if ($target eq "mingw" &amp;&amp; $^O ne "cygwin" &amp;&amp; !is_msys());
+</pre>
+<p>
+and comment it out (or delete altogether). If you are using Cygwin perl,
+you can omit this step. Condition would be false anyway. But function
+is_msys() might not work properly, and of course it wouldn't work when
+cross-compiling for Unix.
+</p>
+<tt>Configure</tt> script. On *nix you can just start 
+</p>
+<pre>
+./Configure mingw
+</pre>
+<p>
+With cygwin or ActiveState perl you'll have to feed this script to perl
+</p>
+<pre>
+perl Configure mingw
+</pre>
+<p>
+Soon you get message "Configured for mingw".
+</p>
+<p>
+Now, you are ready to run make. In the cygwin or msys environment just
+type make. On unix, if you type just  make, native compiler would be
+invoked. You have to specify crosscompiler in the CC makefile variable:
+</p>
+<pre>
+ make CC=i586-mingw32msvc-gcc RANLIB=i585-mingw32msvc-ranlib
+</pre>
+<p>
+With current stable (0.9.8d) verything should go fine until rehash
+target would be invoked. With development branch (0.9.9) you can go into
+some trouble - it is development version, it supposed to be buggy. See
+<a href="#troubleshooting">Troubleshooting</a> section below for some
+hints.
+</p>
+<p>
+When make tells &quot;Doing certs&quot; it would probably complain about
+'openssl' program not found in msys and about inability to run program
+on Unix. You can safely ignore that for a while.
+</p>
+<p>
+After build is finished you should have <tt>openssl.exe</tt> file in the
+apps directory, and two library files <tt>libssl.a</tt> and
+<tt>libcrypto.a</tt> in the toplevel directory.
+</p>
+<p>
+If you are on native Win32 system, you may run test suite typing
+</p>
+<pre>
+make test
+</pre>
+<p>
+If you are doing build on Unix and want to run test, you have to find
+windows system to do so. This system should have MSYS and perl
+installed.
+</p>
+<h2>Doing shared build</h2>
+<p>
+You are probably not interesting in static build. Probably you want to
+have OpenSSL dlls which can be used with some native Win32 application
+such as <a href="http://www.miranda-im.org">Miranda IM</a>.
+</p>
+<p>
+To achieve this, you have to add <b>shared</b> parameter to
+<tt>Configure</tt>.
+<pre>
+ perl Configure mingw shared
+</pre>
+<p>
+But there bad thing happens:
+</p>
+<p>
+everything is compiled, cryptoeay32-0.9.8.dll is built, but when it
+comes to building something that depends on this dll (such as
+ssleay32-0.9.8.dll), you get lot of complaints about unresolved symbols.
+</p>
+<p>
+If you examine dll with dumpbin tool from MSVC you'll see that it
+doesn't export anything.
+</p>
+<p>
+Fix is quite simple:
+</p>
+<p>
+Open Configure script with text editor, find line with mingw
+configuration option:
+
+<pre>
+&quot;mingw&quot;,&quot;gcc:-mno-cygwin -DL_ENDIAN....
+</pre>
+
+Find  fragment which defines options for dll building (it lloks like
+<pre>
+:-mno-cygwin -shared:
+</pre>
+and add there <tt>-Wl,--export-all</tt>, so section would look like:
+<pre>
+:-mno-cygwin -Wl,--export-all -shared:
+</pre>
+
+Then rerun <tt>Configure mingw shared</tt> and make.
+Anything should run fine except certificate rehash.
+<H2>Defining openssl directory</H2> 
+<p>
+There is some things, which OpenSSL searches in the compiled-in
+directory - configuration files and certificates. Path for openssl
+directory can be seen by issuing a command:
+</p>
+<pre>
+openssl version -d
+</pre>
+<p>
+Typically, it is unix-style path <tt>/usr/local/ssl</tt>. It is evident
+that there is little use of such path on Windows system. But it is not
+absolutely useless - if you have just one logical drive in your Windows
+machine, you can create there  <tt>c:\usr\local\ssl</tt> directory
+there, and OpenSSL would find its configuration file as long as current
+working directory of your OpenSSL application is on the C: drive.
+</p>
+<p>
+But it is better to define actual path during Configure stage. This is
+done via Configure option <tt>--openssldir</tt>.
+</p>
+<pre>
+ perl Configure mingw shared --openssldir=c:/OpenSSL
+</pre>
+<p>
+There is another option - <tt>--prefix</tt> which is taken into account
+during make install, and used for search for dynamically loadable engine
+modules. But if you have working configuration file, you can always
+write <tt>dynamic_path</tt> there.
+</p>
+<p>
+There is a method to override location of configuration file.
+You can specify exact filename (not just directory name, but filename)
+in the <TT>OPENSSL_CONF</TT> environment variable.
+</p>
+<h2>Installing runtime modules of OpenSSL</h2>
+<p>
+There is no need to use <tt>make install</tt> under Windows.
+You just cope <tt>openssl.exe</tt> and two dlls (in case of shared
+build) into some dir in the your PATH. On Unix shared libraries go into
+<i>prefix</i>/<tt>lib</tt> directory, and executable files into
+<i>prefix</i>/<tt>bin</tt> and only bin has to be added to PATH.
+So does standard OpenSSL installation procedure. 
+</p>
+<p>
+On Windows application search for DLLs using the same PATH as system
+uses to find executable files, but prepends directory where program
+itself resides. So if you throw executable and the dlls into same
+directory, it is guaranteed, that application would find those dlls.
+</p>
+<h2>Compiling 3rd party applications with OpenSSL</h2>
+<p>
+Typically, one compiles OpenSSL in order to use it in some programs.
+This can be windows-only programs, such as Miranda IM, or ports of Unix
+software such as PostgreSQL.
+</p>
+<p>
+In both cases you need to have include files and import libraries for
+DLLs available for you compiler. (you may choose to use static
+libraries, but DLLs are better - they allow to quickly upgrade OpenSSL
+in case of security update without recompiling all the applications).
+</p>
+<p>After you have built OpenSSL, there is include directory with openssl
+subdirectory. Copy this subdirectory with all its content into include
+directory of your compiler.
+</p>
+<p>
+Then, copy libssl.dll.a and libcrypto.dll.a to the library directory of
+your compiler.  Now you can use -lssl.dll -lcrypto.dll command line
+options for you Mingw32 compiler to link with OpenSSL libraries.
+</p>
+<p>
+Typically, windows applications expect something other than these names.
+For instance, PostgreSQL build system expects these libraries to be
+named libeay32.a for libcrypto and libssleay32.a for libssl. 
+You can just rename libraries appropriately, or copy them (they are
+quite small because contains just references to DLL, not actual code).
+</p>
+<p>
+If you want to use openssl with Microsoft Visual Studio, you can just
+rename libcrypto.dll.a into libeay32.lib, and libssl.dll.a into
+ssleay32.lib. Microsoft .lib files are really ar archives and are
+compatible with mingw static libraries.
+</p>
+<h2><a name="trobuleshooting">Troubleshouting development version of
+OpenSSL</h2>
+<h3>Case 1. ws2tcpip incompatible with winsock</h3>
+<p>
+With OpenSSL cvs of Oct-20-2006 I've encountered problems that
+compilation fails with message "ws2tcpip.h is not compatible with
+winsock.h".
+</p>
+<p>
+Problem is that Windows has two versions of its TCPIP code winsock.h and
+winsock2.h. If you want to use newer version, you have to use
+winsock2.h. If your include winsock2.h, and then winsock.h everything is
+good - winsock.h sees if you have included winsock2 and does nothing. So
+you can use IPV6 functions declared in ws2tcpip.h etc. 
+</p>
+<p>
+But windows.h file which comes with Mingw32 runtime includes winsock.h
+for some constants and types. So, if you haven't included winsock2.h
+prior to first inclusion of windows.h, and than want to include
+ws2tcpip.h,  compilation fails.
+</p>
+<p>
+OpenSSL includes winsock2.h and ws2tcpip.h via local include file
+e_os.h. But  windows.h is included not only via this file, but also via
+rand.h. So, if some code file includes rand.h (directly, or indirectly,
+via engine.h for example), prior to e_os.h, you are in trouble.
+</p>
+<p>
+Solution is simple - find out where offending file is included, and
+add <tt>#include "e_os.h"</tt> on the previous line. I've found
+three such files - <tt>ssl/ssl_sess.c</tt>, <tt>apps/apps.c</tt> and
+<tt>test/randtest.c</tt>.
+</p>
+<p>Hopefully OpenSSL core team would fix this problem soon.
+</p>
+<h3>Case 2. Duplicate extern</h3>
+<p>
+I've also found than compilation fails on the file
+<tt>engines/ccgost/gost_eng.c</tt> with message &quot;Duplicate
+extern&quot;. Solution is very simple. Just remove offending 
+<tt>__declspec(dllexport)</tt> declartions exactly where compiler
+reports error.
+</p>
+<p>
+Since I'm author of ccgost code, I can tell you exact story how this
+error crawl into OpenSSL.
+</p>
+<p>
+There is macros IMPLEMENT_DINAMIC_CHECK_FUNCTION and
+IMPLEMENT_DYNAMIC_BIND_FUNCTION intended for use by engine writers.
+</p>
+<p>
+Before June 2006 these macros don't have any win32 specific things.
+Probably people just didn't use engines on Win32. So, we have to add
+export declarations in order to OpenSSL to be able to load our engine on
+Win32. 
+</p>
+<p>
+Then we forget about it for a while and haven't tested development
+version on Win32. 
+</p>
+<p>
+Meanwhile core developers have added OPENSSL_EXPORT to definitions of
+these macros (this happened on 0.9.8b in stable and nearly at the same
+time in development branch). We've fixed it in our engine for stable
+version (available at <a
+href="http://www.cryptocom.ru/OpenSource/OpenSSL_eng.html">www.cryptocom.ru</a>,
+but have forgotte to check development version. Then our engine was
+accepted into development distribution, and nobody cares to test it
+under Win32 until Oct 20.
+</p>
+</BODY>
+</HTML>