1{ lib, stdenv, fetchurl, buildPackages, perl, coreutils
2, withCryptodev ? false, cryptodev
3, enableSSL2 ? false
4, enableSSL3 ? false
5, static ? stdenv.hostPlatform.isStatic
6# Used to avoid cross compiling perl, for example, in darwin bootstrap tools.
7# This will cause c_rehash to refer to perl via the environment, but otherwise
8# will produce a perfectly functional openssl binary and library.
9, withPerl ? stdenv.hostPlatform == stdenv.buildPlatform
10, removeReferencesTo
11}:
12
13# Note: this package is used for bootstrapping fetchurl, and thus
14# cannot use fetchpatch! All mutable patches (generated by GitHub or
15# cgit) that are needed here should be included directly in Nixpkgs as
16# files.
17
18let
19 common = { version, sha256, patches ? [], withDocs ? false, extraMeta ? {} }:
20 stdenv.mkDerivation rec {
21 pname = "openssl";
22 inherit version;
23
24 src = fetchurl {
25 url = "https://www.openssl.org/source/${pname}-${version}.tar.gz";
26 inherit sha256;
27 };
28
29 inherit patches;
30
31 postPatch = ''
32 patchShebangs Configure
33 '' + lib.optionalString (lib.versionOlder version "1.1.1") ''
34 patchShebangs test/*
35 for a in test/t* ; do
36 substituteInPlace "$a" \
37 --replace /bin/rm rm
38 done
39 ''
40 # config is a configure script which is not installed.
41 + lib.optionalString (lib.versionAtLeast version "1.1.1") ''
42 substituteInPlace config --replace '/usr/bin/env' '${buildPackages.coreutils}/bin/env'
43 '' + lib.optionalString (lib.versionAtLeast version "1.1.1" && stdenv.hostPlatform.isMusl) ''
44 substituteInPlace crypto/async/arch/async_posix.h \
45 --replace '!defined(__ANDROID__) && !defined(__OpenBSD__)' \
46 '!defined(__ANDROID__) && !defined(__OpenBSD__) && 0'
47 ''
48 # Move ENGINESDIR into OPENSSLDIR for static builds, in order to move
49 # it to the separate etc output.
50 + lib.optionalString static ''
51 substituteInPlace Configurations/unix-Makefile.tmpl \
52 --replace 'ENGINESDIR=$(libdir)/engines-{- $sover_dirname -}' \
53 'ENGINESDIR=$(OPENSSLDIR)/engines-{- $sover_dirname -}'
54 '';
55
56 outputs = [ "bin" "dev" "out" "man" ]
57 ++ lib.optional withDocs "doc"
58 # Separate output for the runtime dependencies of the static build.
59 # Specifically, move OPENSSLDIR into this output, as its path will be
60 # compiled into 'libcrypto.a'. This makes it a runtime dependency of
61 # any package that statically links openssl, so we want to keep that
62 # output minimal.
63 ++ lib.optional static "etc";
64 setOutputFlags = false;
65 separateDebugInfo =
66 !stdenv.hostPlatform.isDarwin &&
67 !(stdenv.hostPlatform.useLLVM or false) &&
68 stdenv.cc.isGNU;
69
70 nativeBuildInputs = [ perl ]
71 ++ lib.optionals static [ removeReferencesTo ];
72 buildInputs = lib.optional withCryptodev cryptodev
73 # perl is included to allow the interpreter path fixup hook to set the
74 # correct interpreter in c_rehash.
75 ++ lib.optional withPerl perl;
76
77 # TODO(@Ericson2314): Improve with mass rebuild
78 configurePlatforms = [];
79 configureScript = {
80 armv5tel-linux = "./Configure linux-armv4 -march=armv5te";
81 armv6l-linux = "./Configure linux-armv4 -march=armv6";
82 armv7l-linux = "./Configure linux-armv4 -march=armv7-a";
83 x86_64-darwin = "./Configure darwin64-x86_64-cc";
84 aarch64-darwin = "./Configure darwin64-arm64-cc";
85 x86_64-linux = "./Configure linux-x86_64";
86 x86_64-solaris = "./Configure solaris64-x86_64-gcc";
87 riscv64-linux = "./Configure linux64-riscv64";
88 mipsel-linux = "./Configure linux-mips32";
89 mips64el-linux =
90 if stdenv.hostPlatform.isMips64n64
91 then "./Configure linux64-mips64"
92 else if stdenv.hostPlatform.isMips64n32
93 then "./Configure linux-mips64"
94 else throw "unsupported ABI for ${stdenv.hostPlatform.system}";
95 }.${stdenv.hostPlatform.system} or (
96 if stdenv.hostPlatform == stdenv.buildPlatform
97 then "./config"
98 else if stdenv.hostPlatform.isBSD && stdenv.hostPlatform.isx86_64
99 then "./Configure BSD-x86_64"
100 else if stdenv.hostPlatform.isBSD && stdenv.hostPlatform.isx86_32
101 then "./Configure BSD-x86" + lib.optionalString (stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf") "-elf"
102 else if stdenv.hostPlatform.isBSD
103 then "./Configure BSD-generic${toString stdenv.hostPlatform.parsed.cpu.bits}"
104 else if stdenv.hostPlatform.isMinGW
105 then "./Configure mingw${lib.optionalString
106 (stdenv.hostPlatform.parsed.cpu.bits != 32)
107 (toString stdenv.hostPlatform.parsed.cpu.bits)}"
108 else if stdenv.hostPlatform.isLinux
109 then "./Configure linux-generic${toString stdenv.hostPlatform.parsed.cpu.bits}"
110 else if stdenv.hostPlatform.isiOS
111 then "./Configure ios${toString stdenv.hostPlatform.parsed.cpu.bits}-cross"
112 else
113 throw "Not sure what configuration to use for ${stdenv.hostPlatform.config}"
114 );
115
116 # OpenSSL doesn't like the `--enable-static` / `--disable-shared` flags.
117 dontAddStaticConfigureFlags = true;
118 configureFlags = [
119 "shared" # "shared" builds both shared and static libraries
120 "--libdir=lib"
121 (if !static then
122 "--openssldir=etc/ssl"
123 else
124 # Move OPENSSLDIR to the 'etc' output for static builds. Prepend '/.'
125 # to the path to make it appear absolute before variable expansion,
126 # else the 'prefix' would be prepended to it.
127 "--openssldir=/.$(etc)/etc/ssl"
128 )
129 ] ++ lib.optionals withCryptodev [
130 "-DHAVE_CRYPTODEV"
131 "-DUSE_CRYPTODEV_DIGESTS"
132 ] ++ lib.optional enableSSL2 "enable-ssl2"
133 ++ lib.optional enableSSL3 "enable-ssl3"
134 # We select KTLS here instead of the configure-time detection (which we patch out).
135 # KTLS should work on FreeBSD 13+ as well, so we could enable it if someone tests it.
136 ++ lib.optional (stdenv.isLinux && lib.versionAtLeast version "3.0.0") "enable-ktls"
137 ++ lib.optional (lib.versionAtLeast version "1.1.1" && stdenv.hostPlatform.isAarch64) "no-afalgeng"
138 # OpenSSL needs a specific `no-shared` configure flag.
139 # See https://wiki.openssl.org/index.php/Compilation_and_Installation#Configure_Options
140 # for a comprehensive list of configuration options.
141 ++ lib.optional (lib.versionAtLeast version "1.1.1" && static) "no-shared"
142 ++ lib.optional (lib.versionAtLeast version "3.0.0" && static) "no-module"
143 # This introduces a reference to the CTLOG_FILE which is undesired when
144 # trying to build binaries statically.
145 ++ lib.optional static "no-ct"
146 ;
147
148 makeFlags = [
149 "MANDIR=$(man)/share/man"
150 # This avoids conflicts between man pages of openssl subcommands (for
151 # example 'ts' and 'err') man pages and their equivalent top-level
152 # command in other packages (respectively man-pages and moreutils).
153 # This is done in ubuntu and archlinux, and possiibly many other distros.
154 "MANSUFFIX=ssl"
155 ];
156
157 enableParallelBuilding = true;
158
159 postInstall =
160 (if static then ''
161 # OPENSSLDIR has a reference to self
162 remove-references-to -t $out $out/lib/*.a
163 '' else ''
164 # If we're building dynamic libraries, then don't install static
165 # libraries.
166 if [ -n "$(echo $out/lib/*.so $out/lib/*.dylib $out/lib/*.dll)" ]; then
167 rm "$out/lib/"*.a
168 fi
169
170 # 'etc' is a separate output on static builds only.
171 etc=$out
172 '') + lib.optionalString (!stdenv.hostPlatform.isWindows)
173 # Fix bin/c_rehash's perl interpreter line
174 #
175 # - openssl 1_0_2: embeds a reference to buildPackages.perl
176 # - openssl 1_1: emits "#!/usr/bin/env perl"
177 #
178 # In the case of openssl_1_0_2, reset the invalid reference and let the
179 # interpreter hook take care of it.
180 #
181 # In both cases, if withPerl = false, the intepreter line is expected be
182 # "#!/usr/bin/env perl"
183 ''
184 substituteInPlace $out/bin/c_rehash --replace ${buildPackages.perl}/bin/perl "/usr/bin/env perl"
185 '' + ''
186 mkdir -p $bin
187 mv $out/bin $bin/bin
188
189 mkdir $dev
190 mv $out/include $dev/
191
192 # remove dependency on Perl at runtime
193 rm -r $etc/etc/ssl/misc
194
195 rmdir $etc/etc/ssl/{certs,private}
196 '';
197
198 postFixup = lib.optionalString (!stdenv.hostPlatform.isWindows) ''
199 # Check to make sure the main output and the static runtime dependencies
200 # don't depend on perl
201 if grep -r '${buildPackages.perl}' $out $etc; then
202 echo "Found an erroneous dependency on perl ^^^" >&2
203 exit 1
204 fi
205 '';
206
207 meta = with lib; {
208 homepage = "https://www.openssl.org/";
209 description = "A cryptographic library that implements the SSL and TLS protocols";
210 license = licenses.openssl;
211 platforms = platforms.all;
212 } // extraMeta;
213 };
214
215in {
216
217
218 openssl_1_1 = common {
219 version = "1.1.1s";
220 sha256 = "sha256-xawB52Dub/Dath1rK70wFGck0GPrMiGAxvGKb3Tktqo=";
221 patches = [
222 ./1.1/nix-ssl-cert-file.patch
223
224 (if stdenv.hostPlatform.isDarwin
225 then ./use-etc-ssl-certs-darwin.patch
226 else ./use-etc-ssl-certs.patch)
227 ];
228 withDocs = true;
229 };
230
231 openssl_3 = common {
232 version = "3.0.7";
233 sha256 = "sha256-gwSdBComDmlvYkBqxcCL9wb9hDg/lFzyG9YentlcOW4=";
234 patches = [
235 ./3.0/nix-ssl-cert-file.patch
236
237 # openssl will only compile in KTLS if the current kernel supports it.
238 # This patch disables build-time detection.
239 ./3.0/openssl-disable-kernel-detection.patch
240
241 (if stdenv.hostPlatform.isDarwin
242 then ./use-etc-ssl-certs-darwin.patch
243 else ./use-etc-ssl-certs.patch)
244 ];
245
246 withDocs = true;
247
248 extraMeta = with lib; {
249 license = licenses.asl20;
250 };
251 };
252}