Merge pull request #268619 from tweag/lib-descriptions
[NixPkgs.git] / pkgs / development / libraries / openssl / default.nix
blob3aeafccb1edb222265cb2c819467922ec013dd93
1 { lib, stdenv, fetchurl, buildPackages, perl, coreutils, writeShellScript
2 , makeWrapper
3 , withCryptodev ? false, cryptodev
4 , withZlib ? false, zlib
5 , enableSSL2 ? false
6 , enableSSL3 ? false
7 , enableKTLS ? stdenv.isLinux
8 , static ? stdenv.hostPlatform.isStatic
9 # path to openssl.cnf file. will be placed in $etc/etc/ssl/openssl.cnf to replace the default
10 , conf ? null
11 , removeReferencesTo
12 , testers
15 # Note: this package is used for bootstrapping fetchurl, and thus
16 # cannot use fetchpatch! All mutable patches (generated by GitHub or
17 # cgit) that are needed here should be included directly in Nixpkgs as
18 # files.
20 let
21   common = { version, hash, patches ? [], withDocs ? false, extraMeta ? {} }:
22    stdenv.mkDerivation (finalAttrs: {
23     pname = "openssl";
24     inherit version;
26     src = fetchurl {
27       url = "https://www.openssl.org/source/${finalAttrs.pname}-${version}.tar.gz";
28       inherit hash;
29     };
31     inherit patches;
33     postPatch = ''
34       patchShebangs Configure
35     '' + lib.optionalString (lib.versionOlder version "1.1.1") ''
36       patchShebangs test/*
37       for a in test/t* ; do
38         substituteInPlace "$a" \
39           --replace /bin/rm rm
40       done
41     ''
42     # config is a configure script which is not installed.
43     + lib.optionalString (lib.versionAtLeast version "1.1.1") ''
44       substituteInPlace config --replace '/usr/bin/env' '${buildPackages.coreutils}/bin/env'
45     '' + lib.optionalString (lib.versionAtLeast version "1.1.1" && stdenv.hostPlatform.isMusl) ''
46       substituteInPlace crypto/async/arch/async_posix.h \
47         --replace '!defined(__ANDROID__) && !defined(__OpenBSD__)' \
48                   '!defined(__ANDROID__) && !defined(__OpenBSD__) && 0'
49     ''
50     # Move ENGINESDIR into OPENSSLDIR for static builds, in order to move
51     # it to the separate etc output.
52     + lib.optionalString static ''
53       substituteInPlace Configurations/unix-Makefile.tmpl \
54         --replace 'ENGINESDIR=$(libdir)/engines-{- $sover_dirname -}' \
55                   'ENGINESDIR=$(OPENSSLDIR)/engines-{- $sover_dirname -}'
56     '';
58     outputs = [ "bin" "dev" "out" "man" ]
59       ++ lib.optional withDocs "doc"
60       # Separate output for the runtime dependencies of the static build.
61       # Specifically, move OPENSSLDIR into this output, as its path will be
62       # compiled into 'libcrypto.a'. This makes it a runtime dependency of
63       # any package that statically links openssl, so we want to keep that
64       # output minimal.
65       ++ lib.optional static "etc";
66     setOutputFlags = false;
67     separateDebugInfo =
68       !stdenv.hostPlatform.isDarwin &&
69       !(stdenv.hostPlatform.useLLVM or false) &&
70       stdenv.cc.isGNU;
72     nativeBuildInputs =
73          lib.optional (!stdenv.hostPlatform.isWindows) makeWrapper
74       ++ [ perl ]
75       ++ lib.optionals static [ removeReferencesTo ];
76     buildInputs = lib.optional withCryptodev cryptodev
77       ++ lib.optional withZlib zlib;
79     # TODO(@Ericson2314): Improve with mass rebuild
80     configurePlatforms = [];
81     configureScript = {
82         armv5tel-linux = "./Configure linux-armv4 -march=armv5te";
83         armv6l-linux = "./Configure linux-armv4 -march=armv6";
84         armv7l-linux = "./Configure linux-armv4 -march=armv7-a";
85         x86_64-darwin  = "./Configure darwin64-x86_64-cc";
86         aarch64-darwin = "./Configure darwin64-arm64-cc";
87         x86_64-linux = "./Configure linux-x86_64";
88         x86_64-solaris = "./Configure solaris64-x86_64-gcc";
89         riscv64-linux = "./Configure linux64-riscv64";
90       }.${stdenv.hostPlatform.system} or (
91         if stdenv.hostPlatform == stdenv.buildPlatform
92           then "./config"
93         else if stdenv.hostPlatform.isBSD
94           then if stdenv.hostPlatform.isx86_64 then "./Configure BSD-x86_64"
95           else if stdenv.hostPlatform.isx86_32
96             then "./Configure BSD-x86" + lib.optionalString (stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf") "-elf"
97           else "./Configure BSD-generic${toString stdenv.hostPlatform.parsed.cpu.bits}"
98         else if stdenv.hostPlatform.isMinGW
99           then "./Configure mingw${lib.optionalString
100                                      (stdenv.hostPlatform.parsed.cpu.bits != 32)
101                                      (toString stdenv.hostPlatform.parsed.cpu.bits)}"
102         else if stdenv.hostPlatform.isLinux
103           then if stdenv.hostPlatform.isx86_64 then "./Configure linux-x86_64"
104           else if stdenv.hostPlatform.isMips32 then "./Configure linux-mips32"
105           else if stdenv.hostPlatform.isMips64n32 then "./Configure linux-mips64"
106           else if stdenv.hostPlatform.isMips64n64 then "./Configure linux64-mips64"
107           else "./Configure linux-generic${toString stdenv.hostPlatform.parsed.cpu.bits}"
108         else if stdenv.hostPlatform.isiOS
109           then "./Configure ios${toString stdenv.hostPlatform.parsed.cpu.bits}-cross"
110         else
111           throw "Not sure what configuration to use for ${stdenv.hostPlatform.config}"
112       );
114     # OpenSSL doesn't like the `--enable-static` / `--disable-shared` flags.
115     dontAddStaticConfigureFlags = true;
116     configureFlags = [
117       "shared" # "shared" builds both shared and static libraries
118       "--libdir=lib"
119       (if !static then
120          "--openssldir=etc/ssl"
121        else
122          # Move OPENSSLDIR to the 'etc' output for static builds. Prepend '/.'
123          # to the path to make it appear absolute before variable expansion,
124          # else the 'prefix' would be prepended to it.
125          "--openssldir=/.$(etc)/etc/ssl"
126       )
127     ] ++ lib.optionals withCryptodev [
128       "-DHAVE_CRYPTODEV"
129       "-DUSE_CRYPTODEV_DIGESTS"
130     ] ++ lib.optional enableSSL2 "enable-ssl2"
131       ++ lib.optional enableSSL3 "enable-ssl3"
132       # We select KTLS here instead of the configure-time detection (which we patch out).
133       # KTLS should work on FreeBSD 13+ as well, so we could enable it if someone tests it.
134       ++ lib.optional (lib.versionAtLeast version "3.0.0" && enableKTLS) "enable-ktls"
135       ++ lib.optional (lib.versionAtLeast version "1.1.1" && stdenv.hostPlatform.isAarch64) "no-afalgeng"
136       # OpenSSL needs a specific `no-shared` configure flag.
137       # See https://wiki.openssl.org/index.php/Compilation_and_Installation#Configure_Options
138       # for a comprehensive list of configuration options.
139       ++ lib.optional (lib.versionAtLeast version "1.1.1" && static) "no-shared"
140       ++ lib.optional (lib.versionAtLeast version "3.0.0" && static) "no-module"
141       # This introduces a reference to the CTLOG_FILE which is undesired when
142       # trying to build binaries statically.
143       ++ lib.optional static "no-ct"
144       ++ lib.optional withZlib "zlib"
145       ++ lib.optionals (stdenv.hostPlatform.isMips && stdenv.hostPlatform ? gcc.arch) [
146       # This is necessary in order to avoid openssl adding -march
147       # flags which ultimately conflict with those added by
148       # cc-wrapper.  Openssl assumes that it can scan CFLAGS to
149       # detect any -march flags, using this perl code:
150       #
151       #   && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})
152       #
153       # The following bogus CFLAGS environment variable triggers the
154       # the code above, inhibiting `./Configure` from adding the
155       # conflicting flags.
156       "CFLAGS=-march=${stdenv.hostPlatform.gcc.arch}"
157     ];
159     makeFlags = [
160       "MANDIR=$(man)/share/man"
161       # This avoids conflicts between man pages of openssl subcommands (for
162       # example 'ts' and 'err') man pages and their equivalent top-level
163       # command in other packages (respectively man-pages and moreutils).
164       # This is done in ubuntu and archlinux, and possiibly many other distros.
165       "MANSUFFIX=ssl"
166     ];
168     enableParallelBuilding = true;
170     postInstall =
171     (if static then ''
172       # OPENSSLDIR has a reference to self
173       remove-references-to -t $out $out/lib/*.a
174     '' else ''
175       # If we're building dynamic libraries, then don't install static
176       # libraries.
177       if [ -n "$(echo $out/lib/*.so $out/lib/*.dylib $out/lib/*.dll)" ]; then
178           rm "$out/lib/"*.a
179       fi
181       # 'etc' is a separate output on static builds only.
182       etc=$out
183     '') + ''
184       mkdir -p $bin
185       mv $out/bin $bin/bin
187     '' + lib.optionalString (!stdenv.hostPlatform.isWindows)
188       # makeWrapper is broken for windows cross (https://github.com/NixOS/nixpkgs/issues/120726)
189     ''
190       # c_rehash is a legacy perl script with the same functionality
191       # as `openssl rehash`
192       # this wrapper script is created to maintain backwards compatibility without
193       # depending on perl
194       makeWrapper $bin/bin/openssl $bin/bin/c_rehash \
195         --add-flags "rehash"
196     '' + ''
198       mkdir $dev
199       mv $out/include $dev/
201       # remove dependency on Perl at runtime
202       rm -r $etc/etc/ssl/misc
204       rmdir $etc/etc/ssl/{certs,private}
206       ${lib.optionalString (conf != null) "cat ${conf} > $etc/etc/ssl/openssl.cnf"}
207     '';
209     postFixup = lib.optionalString (!stdenv.hostPlatform.isWindows) ''
210       # Check to make sure the main output and the static runtime dependencies
211       # don't depend on perl
212       if grep -r '${buildPackages.perl}' $out $etc; then
213         echo "Found an erroneous dependency on perl ^^^" >&2
214         exit 1
215       fi
216     '';
218     passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
220     meta = with lib; {
221       homepage = "https://www.openssl.org/";
222       changelog = "https://github.com/openssl/openssl/blob/openssl-${version}/CHANGES.md";
223       description = "A cryptographic library that implements the SSL and TLS protocols";
224       license = licenses.openssl;
225       mainProgram = "openssl";
226       maintainers = with maintainers; [ thillux ];
227       pkgConfigModules = [
228         "libcrypto"
229         "libssl"
230         "openssl"
231       ];
232       platforms = platforms.all;
233     } // extraMeta;
234   });
236 in {
238   # If you do upgrade here, please update in pkgs/top-level/release.nix
239   # the permitted insecure version to ensure it gets cached for our users
240   # and backport this to stable release (23.05).
241   openssl_1_1 = common {
242     version = "1.1.1w";
243     hash = "sha256-zzCYlQy02FOtlcCEHx+cbT3BAtzPys1SHZOSUgi3asg=";
244     patches = [
245       ./1.1/nix-ssl-cert-file.patch
247       (if stdenv.hostPlatform.isDarwin
248        then ./use-etc-ssl-certs-darwin.patch
249        else ./use-etc-ssl-certs.patch)
250     ];
251     withDocs = true;
252     extraMeta = {
253       knownVulnerabilities = [
254         "OpenSSL 1.1 is reaching its end of life on 2023/09/11 and cannot be supported through the NixOS 23.05 release cycle. https://www.openssl.org/blog/blog/2023/03/28/1.1.1-EOL/"
255       ];
256     };
257   };
259   openssl_3 = common {
260     version = "3.0.12";
261     hash = "sha256-+Tyejt3l6RZhGd4xdV/Ie0qjSGNmL2fd/LoU0La2m2E=";
263     patches = [
264       ./3.0/nix-ssl-cert-file.patch
266       # openssl will only compile in KTLS if the current kernel supports it.
267       # This patch disables build-time detection.
268       ./3.0/openssl-disable-kernel-detection.patch
270       (if stdenv.hostPlatform.isDarwin
271        then ./use-etc-ssl-certs-darwin.patch
272        else ./use-etc-ssl-certs.patch)
273     ];
275     withDocs = true;
277     extraMeta = with lib; {
278       license = licenses.asl20;
279     };
280   };
282   openssl_3_1 = common {
283     version = "3.1.4";
284     hash = "sha256-hAr1Nmq5tSK95SWCa+PvD7Cvgcap69hMqmAP6hcx7uM=";
286     patches = [
287       ./3.0/nix-ssl-cert-file.patch
289       # openssl will only compile in KTLS if the current kernel supports it.
290       # This patch disables build-time detection.
291       ./3.0/openssl-disable-kernel-detection.patch
293       (if stdenv.hostPlatform.isDarwin
294        then ./use-etc-ssl-certs-darwin.patch
295        else ./use-etc-ssl-certs.patch)
296     ];
298     withDocs = true;
300     extraMeta = with lib; {
301       license = licenses.asl20;
302     };
303   };