]> www.wagner.pp.ru Git - sites/home_page.git/blob - articles/openssl-mingw.html
*** empty log message ***
[sites/home_page.git] / articles / openssl-mingw.html
1 <HTML><HEAD>
2 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=koi8-r">
3 <TITLE>Building OpenSSL for Windows with Mingw32</TITLE>
4 <META NAME="DESCRIPTION" CONTENT="Summary of experience of building both
5 stable and development versions of OpenSSL for Windows"> </HEAD><BODY>
6 <H1>Building OpenSSL for Windows with Mingw32</H1>
7 <p><font size="+3" color="red">This page is about outdated version of
8 OpenSSL and is kept for historical purposes only. OpenSSL 1.x.x supports
9 cross-compiling out of the box</font></p>
10 <p>
11 If you want to get OpenSSL libraries (either .dll or static libraries),
12 usable by native Windows compilers, you can use entirely free GNU
13 compiler, downloadable from internet.
14 </p>
15 <p>
16 OpenSSL is written on plain old C, which means that as long as compilers
17 use common object file format, you can easily link object files and
18 static libraries, produced by one compiler, with another.
19 </p>
20 <p>
21 GNU MinGW32 compiler uses COFF object format, same as Microsoft Visual
22 studio. It just has different naming convention. Rename libssl.a,
23 produced with MinGW to ssl.lib, and you can use it in MSVC.
24 </p>
25 <H2>Build environments</H2>
26 <p>
27 OpenSSL distribution includes file mingw.bat to build dll version with
28 MinGW. Forget about it. It is outdated, unsupported and soon to be
29 removed.
30 </p>
31 <p>Better to use unix style configure-make-make install approach. For
32 this approach you'll need unix-like shell, perl and some utilities.
33 </p>
34 <p>There are three possible choices for the build environment:
35 </p>
36 <ol>
37 <li><p>Use minimal needed set of utilites. You'll need:</p>
38 <ul>
39 <li>mingw32 compiler from <a href="http://www.mingw.org">mingw.org</a>
40 <li>Minimal system (MSYS) from same site
41 <li>Win32 version of Perl from <a
42 href="http://www.activestate.com">ActiveState</a>
43 </ul><p>
44 This would take less than 100Mb on your disk and let your build lots of
45 interesting things other than OpenSSL.</p>
46 </li>
47 <li><p>Use Cygwin toolchain. Yes, you can build native win32 programs,
48 which don't depend on cygwin.dll with cygwin compiler.
49 You'll need cygwin perl, make, coreutils and all some packages from
50 cygwin  which have mingw in its name (from development section) You
51 don-t need C++ compiler, but, probably would like to use mingw zlib. 
52 </p><p>I
53 recommend to use this way only if you already have cygwin and
54 accustomized to use it.
55 </p>
56 </li>
57 <li><p>Compile all thing on nearby Linux/Unix machine using cross-compiler.
58 If you use Debian GNU/Linux, you need just to install packages mingw32,
59 mingw32-runtime and mingw32-binutils. You typically have make, perl and
60 coreutils on Linux system. On other Unixes you probably will need to
61 build mingw32 cross-compiler from gcc sources.
62 </p>
63 <p>
64 I wouldn't cover building and  installing cross-compiler here.
65 </p>
66 </li>
67 It is also possible to combine cygwin compiler and shell with
68 ActiveState perl, but I wouldn't recommend to do so.
69 <h2>Building static version</h2>
70 <p>
71 Download and unpack sources of openssl. It comes in the tar.gz archive.
72 Any build environment mentioned above includes <tt>tar</tt> program
73 which is used to unpack archives.
74 </p>
75 <p>
76 Open command window (or terminal window on Unix), make sure that
77 cygwin (or all of msys, mingw and ActiveState perl) directories are in
78 your  PATH (on Unix cross compiler automatically installed into PATH and
79 perl is already there), 
80 change into top-level  directory of unpacked source.
81 <p>
82 Open Configure script with text editor, find line
83 </p>
84 <pre>
85 $IsMK1MF=1 if ($target eq "mingw" &amp;&amp; $^O ne "cygwin" &amp;&amp; !is_msys());
86 </pre>
87 <p>
88 and comment it out (or delete altogether). If you are using Cygwin perl,
89 you can omit this step. Condition would be false anyway. But function
90 is_msys() might not work properly, and of course it wouldn't work when
91 cross-compiling for Unix.
92 </p>
93 <tt>Configure</tt> script. On *nix you can just start 
94 </p>
95 <pre>
96 ./Configure mingw
97 </pre>
98 <p>
99 With cygwin or ActiveState perl you'll have to feed this script to perl
100 </p>
101 <pre>
102 perl Configure mingw
103 </pre>
104 <p>
105 Soon you get message "Configured for mingw".
106 </p>
107 <p>
108 Now, you are ready to run make. In the cygwin or msys environment just
109 type make. On unix, if you type just  make, native compiler would be
110 invoked. You have to specify crosscompiler in the CC makefile variable:
111 </p>
112 <pre>
113  make CC=i586-mingw32msvc-gcc RANLIB=i586-mingw32msvc-ranlib
114 </pre>
115 <p>
116 With current stable (0.9.8d) verything should go fine until rehash
117 target would be invoked. With development branch (0.9.9) you can go into
118 some trouble - it is development version, it supposed to be buggy. See
119 <a href="#troubleshooting">Troubleshooting</a> section below for some
120 hints.
121 </p>
122 <p>
123 When make tells &quot;Doing certs&quot; it would probably complain about
124 'openssl' program not found in msys and about inability to run program
125 on Unix. You can safely ignore that for a while.
126 </p>
127 <p>
128 After build is finished you should have <tt>openssl.exe</tt> file in the
129 apps directory, and two library files <tt>libssl.a</tt> and
130 <tt>libcrypto.a</tt> in the toplevel directory.
131 </p>
132 <p>
133 If you are on native Win32 system, you may run test suite typing
134 </p>
135 <pre>
136 make test
137 </pre>
138 <p>
139 If you are doing build on Unix and want to run test, you have to find
140 windows system to do so. This system should have MSYS and perl
141 installed.
142 </p>
143 <h2>Doing shared build</h2>
144 <p>
145 You are probably not interesting in static build. Probably you want to
146 have OpenSSL dlls which can be used with some native Win32 application
147 such as <a href="http://www.miranda-im.org">Miranda IM</a>.
148 </p>
149 <p>
150 To achieve this, you have to add <b>shared</b> parameter to
151 <tt>Configure</tt>.
152 <pre>
153  perl Configure mingw shared
154 </pre>
155 <p>
156 But there bad thing happens:
157 </p>
158 <p>
159 everything is compiled, cryptoeay32-0.9.8.dll is built, but when it
160 comes to building something that depends on this dll (such as
161 ssleay32-0.9.8.dll), you get lot of complaints about unresolved symbols.
162 </p>
163 <p>
164 If you examine dll with dumpbin tool from MSVC you'll see that it
165 doesn't export anything.
166 </p>
167 <p>
168 Fix is quite simple:
169 </p>
170 <p>
171 Open Configure script with text editor, find line with mingw
172 configuration option:
173
174 <pre>
175 &quot;mingw&quot;,&quot;gcc:-mno-cygwin -DL_ENDIAN....
176 </pre>
177
178 Find  fragment which defines options for dll building (it lloks like
179 <pre>
180 :-mno-cygwin -shared:
181 </pre>
182 and add there <tt>-Wl,--export-all</tt>, so section would look like:
183 <pre>
184 :-mno-cygwin -Wl,--export-all -shared:
185 </pre>
186
187 Then rerun <tt>Configure mingw shared</tt> and make.
188 Anything should run fine except certificate rehash.
189 <H2>Defining openssl directory</H2> 
190 <p>
191 There is some things, which OpenSSL searches in the compiled-in
192 directory - configuration files and certificates. Path for openssl
193 directory can be seen by issuing a command:
194 </p>
195 <pre>
196 openssl version -d
197 </pre>
198 <p>
199 Typically, it is unix-style path <tt>/usr/local/ssl</tt>. It is evident
200 that there is little use of such path on Windows system. But it is not
201 absolutely useless - if you have just one logical drive in your Windows
202 machine, you can create there  <tt>c:\usr\local\ssl</tt> directory
203 there, and OpenSSL would find its configuration file as long as current
204 working directory of your OpenSSL application is on the C: drive.
205 </p>
206 <p>
207 But it is better to define actual path during Configure stage. This is
208 done via Configure option <tt>--openssldir</tt>.
209 </p>
210 <pre>
211  perl Configure mingw shared --openssldir=c:/OpenSSL
212 </pre>
213 <p>
214 There is another option - <tt>--prefix</tt> which is taken into account
215 during make install, and used for search for dynamically loadable engine
216 modules. But if you have working configuration file, you can always
217 write <tt>dynamic_path</tt> there.
218 </p>
219 <p>
220 There is a method to override location of configuration file.
221 You can specify exact filename (not just directory name, but filename)
222 in the <TT>OPENSSL_CONF</TT> environment variable.
223 </p>
224 <h2>Installing runtime modules of OpenSSL</h2>
225 <p>
226 There is no need to use <tt>make install</tt> under Windows.
227 You just cope <tt>openssl.exe</tt> and two dlls (in case of shared
228 build) into some dir in the your PATH. On Unix shared libraries go into
229 <i>prefix</i>/<tt>lib</tt> directory, and executable files into
230 <i>prefix</i>/<tt>bin</tt> and only bin has to be added to PATH.
231 So does standard OpenSSL installation procedure. 
232 </p>
233 <p>
234 On Windows application search for DLLs using the same PATH as system
235 uses to find executable files, but prepends directory where program
236 itself resides. So if you throw executable and the dlls into same
237 directory, it is guaranteed, that application would find those dlls.
238 </p>
239 <h2>Compiling 3rd party applications with OpenSSL</h2>
240 <p>
241 Typically, one compiles OpenSSL in order to use it in some programs.
242 This can be windows-only programs, such as Miranda IM, or ports of Unix
243 software such as PostgreSQL.
244 </p>
245 <p>
246 In both cases you need to have include files and import libraries for
247 DLLs available for you compiler. (you may choose to use static
248 libraries, but DLLs are better - they allow to quickly upgrade OpenSSL
249 in case of security update without recompiling all the applications).
250 </p>
251 <p>After you have built OpenSSL, there is include directory with openssl
252 subdirectory. Copy this subdirectory with all its content into include
253 directory of your compiler.
254 </p>
255 <p>
256 Then, copy libssl.dll.a and libcrypto.dll.a to the library directory of
257 your compiler.  Now you can use -lssl.dll -lcrypto.dll command line
258 options for you Mingw32 compiler to link with OpenSSL libraries.
259 </p>
260 <p>
261 Typically, windows applications expect something other than these names.
262 For instance, PostgreSQL build system expects these libraries to be
263 named libeay32.a for libcrypto and libssleay32.a for libssl. 
264 You can just rename libraries appropriately, or copy them (they are
265 quite small because contains just references to DLL, not actual code).
266 </p>
267 <p>
268 If you want to use openssl with Microsoft Visual Studio, you can just
269 rename libcrypto.dll.a into libeay32.lib, and libssl.dll.a into
270 ssleay32.lib. Microsoft .lib files are really ar archives and are
271 compatible with mingw static libraries.
272 </p>
273 <h2><a name="trobuleshooting">Troubleshouting development version of
274 OpenSSL</h2>
275 <h3>Case 1. ws2tcpip incompatible with winsock</h3>
276 <p>
277 With OpenSSL cvs of Oct-20-2006 I've encountered problems that
278 compilation fails with message "ws2tcpip.h is not compatible with
279 winsock.h".
280 </p>
281 <p>
282 Problem is that Windows has two versions of its TCPIP code winsock.h and
283 winsock2.h. If you want to use newer version, you have to use
284 winsock2.h. If your include winsock2.h, and then winsock.h everything is
285 good - winsock.h sees if you have included winsock2 and does nothing. So
286 you can use IPV6 functions declared in ws2tcpip.h etc. 
287 </p>
288 <p>
289 But windows.h file which comes with Mingw32 runtime includes winsock.h
290 for some constants and types. So, if you haven't included winsock2.h
291 prior to first inclusion of windows.h, and than want to include
292 ws2tcpip.h,  compilation fails.
293 </p>
294 <p>
295 OpenSSL includes winsock2.h and ws2tcpip.h via local include file
296 e_os.h. But  windows.h is included not only via this file, but also via
297 rand.h. So, if some code file includes rand.h (directly, or indirectly,
298 via engine.h for example), prior to e_os.h, you are in trouble.
299 </p>
300 <p>
301 Solution is simple - find out where offending file is included, and
302 add <tt>#include "e_os.h"</tt> on the previous line. I've found
303 three such files - <tt>ssl/ssl_sess.c</tt>, <tt>apps/apps.c</tt> and
304 <tt>test/randtest.c</tt>.
305 </p>
306 <p>Hopefully OpenSSL core team would fix this problem soon.
307 </p>
308 <h3>Case 2. Duplicate extern</h3>
309 <p>
310 I've also found than compilation fails on the file
311 <tt>engines/ccgost/gost_eng.c</tt> with message &quot;Duplicate
312 extern&quot;. Solution is very simple. Just remove offending 
313 <tt>__declspec(dllexport)</tt> declartions exactly where compiler
314 reports error.
315 </p>
316 <p>
317 Since I'm author of ccgost code, I can tell you exact story how this
318 error crawl into OpenSSL.
319 </p>
320 <p>
321 There is macros IMPLEMENT_DINAMIC_CHECK_FUNCTION and
322 IMPLEMENT_DYNAMIC_BIND_FUNCTION intended for use by engine writers.
323 </p>
324 <p>
325 Before June 2006 these macros don't have any win32 specific things.
326 Probably people just didn't use engines on Win32. So, we have to add
327 export declarations in order to OpenSSL to be able to load our engine on
328 Win32. 
329 </p>
330 <p>
331 Then we forget about it for a while and haven't tested development
332 version on Win32. 
333 </p>
334 <p>
335 Meanwhile core developers have added OPENSSL_EXPORT to definitions of
336 these macros (this happened on 0.9.8b in stable and nearly at the same
337 time in development branch). We've fixed it in our engine for stable
338 version (available at <a
339 href="http://www.cryptocom.ru/OpenSource/OpenSSL_eng.html">www.cryptocom.ru</a>,
340 but have forgotte to check development version. Then our engine was
341 accepted into development distribution, and nobody cares to test it
342 under Win32 until Oct 20.
343 </p>
344 </BODY>
345 </HTML>