at master 16 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 buildPackages, 6 perl, 7 coreutils, 8 writeShellScript, 9 makeBinaryWrapper, 10 withCryptodev ? false, 11 cryptodev, 12 withZlib ? false, 13 zlib, 14 enableSSL2 ? false, 15 enableSSL3 ? false, 16 enableMD2 ? false, 17 enableKTLS ? stdenv.hostPlatform.isLinux, 18 # change this to a value between 0 and 5 (as of OpenSSL 3.5) 19 # if null, default is used, changes the permitted algorithms 20 # and key lengths in the default config 21 # see: https://docs.openssl.org/3.5/man3/SSL_CTX_set_security_level/ 22 securityLevel ? null, 23 static ? stdenv.hostPlatform.isStatic, 24 # path to openssl.cnf file. will be placed in $etc/etc/ssl/openssl.cnf to replace the default 25 conf ? null, 26 removeReferencesTo, 27 testers, 28}: 29 30# Note: this package is used for bootstrapping fetchurl, and thus 31# cannot use fetchpatch! All mutable patches (generated by GitHub or 32# cgit) that are needed here should be included directly in Nixpkgs as 33# files. 34 35# check from time to time, if this range is still correct 36assert (securityLevel == null) || (securityLevel >= 0 && securityLevel <= 5); 37 38let 39 common = 40 { 41 version, 42 hash, 43 patches ? [ ], 44 withDocs ? false, 45 extraMeta ? { }, 46 }: 47 stdenv.mkDerivation (finalAttrs: { 48 pname = "openssl"; 49 inherit version; 50 51 src = fetchurl { 52 url = 53 if lib.versionOlder version "3.0" then 54 let 55 versionFixed = builtins.replaceStrings [ "." ] [ "_" ] version; 56 in 57 "https://github.com/openssl/openssl/releases/download/OpenSSL_${versionFixed}/openssl-${version}.tar.gz" 58 else 59 "https://github.com/openssl/openssl/releases/download/openssl-${version}/openssl-${version}.tar.gz"; 60 inherit hash; 61 }; 62 63 inherit patches; 64 65 postPatch = '' 66 patchShebangs Configure 67 '' 68 + lib.optionalString (lib.versionOlder version "1.1.1") '' 69 patchShebangs test/* 70 for a in test/t* ; do 71 substituteInPlace "$a" \ 72 --replace /bin/rm rm 73 done 74 '' 75 # config is a configure script which is not installed. 76 + lib.optionalString (lib.versionAtLeast version "1.1.1") '' 77 substituteInPlace config --replace '/usr/bin/env' '${buildPackages.coreutils}/bin/env' 78 '' 79 + lib.optionalString (lib.versionAtLeast version "1.1.1" && stdenv.hostPlatform.isMusl) '' 80 substituteInPlace crypto/async/arch/async_posix.h \ 81 --replace '!defined(__ANDROID__) && !defined(__OpenBSD__)' \ 82 '!defined(__ANDROID__) && !defined(__OpenBSD__) && 0' 83 '' 84 # Move ENGINESDIR into OPENSSLDIR for static builds, in order to move 85 # it to the separate etc output. 86 + lib.optionalString static '' 87 substituteInPlace Configurations/unix-Makefile.tmpl \ 88 --replace 'ENGINESDIR=$(libdir)/engines-{- $sover_dirname -}' \ 89 'ENGINESDIR=$(OPENSSLDIR)/engines-{- $sover_dirname -}' 90 ''; 91 92 outputs = [ 93 "bin" 94 "dev" 95 "out" 96 "man" 97 ] 98 ++ lib.optional withDocs "doc" 99 # Separate output for the runtime dependencies of the static build. 100 # Specifically, move OPENSSLDIR into this output, as its path will be 101 # compiled into 'libcrypto.a'. This makes it a runtime dependency of 102 # any package that statically links openssl, so we want to keep that 103 # output minimal. 104 ++ lib.optional static "etc"; 105 setOutputFlags = false; 106 separateDebugInfo = 107 !stdenv.hostPlatform.isDarwin 108 && !stdenv.hostPlatform.isAndroid 109 && !(stdenv.hostPlatform.useLLVM or false) 110 && stdenv.cc.isGNU; 111 112 nativeBuildInputs = 113 lib.optional (!stdenv.hostPlatform.isWindows) makeBinaryWrapper 114 ++ [ perl ] 115 ++ lib.optionals static [ removeReferencesTo ]; 116 buildInputs = lib.optional withCryptodev cryptodev ++ lib.optional withZlib zlib; 117 118 # TODO(@Ericson2314): Improve with mass rebuild 119 configurePlatforms = [ ]; 120 configureScript = 121 { 122 armv5tel-linux = "./Configure linux-armv4 -march=armv5te"; 123 armv6l-linux = "./Configure linux-armv4 -march=armv6"; 124 armv7l-linux = "./Configure linux-armv4 -march=armv7-a"; 125 x86_64-darwin = "./Configure darwin64-x86_64-cc"; 126 aarch64-darwin = "./Configure darwin64-arm64-cc"; 127 x86_64-linux = "./Configure linux-x86_64"; 128 x86_64-solaris = "./Configure solaris64-x86_64-gcc"; 129 powerpc-linux = "./Configure linux-ppc"; 130 powerpc64-linux = "./Configure linux-ppc64"; 131 riscv32-linux = "./Configure ${ 132 if lib.versionAtLeast version "3.2" then "linux32-riscv32" else "linux-latomic" 133 }"; 134 riscv64-linux = "./Configure linux64-riscv64"; 135 } 136 .${stdenv.hostPlatform.system} or ( 137 if stdenv.hostPlatform == stdenv.buildPlatform then 138 "./config" 139 else if stdenv.hostPlatform.isBSD then 140 if stdenv.hostPlatform.isx86_64 then 141 "./Configure BSD-x86_64" 142 else if stdenv.hostPlatform.isx86_32 then 143 "./Configure BSD-x86" + lib.optionalString stdenv.hostPlatform.isElf "-elf" 144 else 145 "./Configure BSD-generic${toString stdenv.hostPlatform.parsed.cpu.bits}" 146 else if stdenv.hostPlatform.isMinGW then 147 "./Configure mingw${ 148 lib.optionalString (stdenv.hostPlatform.parsed.cpu.bits != 32) ( 149 toString stdenv.hostPlatform.parsed.cpu.bits 150 ) 151 }" 152 else if stdenv.hostPlatform.isLinux then 153 if stdenv.hostPlatform.isx86_64 then 154 "./Configure linux-x86_64" 155 else if stdenv.hostPlatform.isMicroBlaze then 156 "./Configure linux-latomic" 157 else if stdenv.hostPlatform.isMips32 then 158 "./Configure linux-mips32" 159 else if stdenv.hostPlatform.isMips64n32 then 160 "./Configure linux-mips64" 161 else if stdenv.hostPlatform.isMips64n64 then 162 "./Configure linux64-mips64" 163 else 164 "./Configure linux-generic${toString stdenv.hostPlatform.parsed.cpu.bits}" 165 else if stdenv.hostPlatform.isiOS then 166 "./Configure ios${toString stdenv.hostPlatform.parsed.cpu.bits}-cross" 167 else 168 throw "Not sure what configuration to use for ${stdenv.hostPlatform.config}" 169 ); 170 171 # OpenSSL doesn't like the `--enable-static` / `--disable-shared` flags. 172 dontAddStaticConfigureFlags = true; 173 configureFlags = [ 174 "shared" # "shared" builds both shared and static libraries 175 "--libdir=lib" 176 ( 177 if !static then 178 "--openssldir=etc/ssl" 179 else 180 # Move OPENSSLDIR to the 'etc' output for static builds. Prepend '/.' 181 # to the path to make it appear absolute before variable expansion, 182 # else the 'prefix' would be prepended to it. 183 "--openssldir=/.$(etc)/etc/ssl" 184 ) 185 ] 186 ++ lib.optionals withCryptodev [ 187 "-DHAVE_CRYPTODEV" 188 "-DUSE_CRYPTODEV_DIGESTS" 189 ] 190 # enable optimized EC curve primitives on x86_64, 191 # can provide a 2x up to 4x speedup at best 192 # with combined PQC and conventional crypto handshakes 193 # starting with 3.5 its nice to speed things up for free 194 ++ lib.optional stdenv.hostPlatform.isx86_64 "enable-ec_nistp_64_gcc_128" 195 # useful to set e.g. 256 bit security level with setting this to 5 196 ++ lib.optional ( 197 securityLevel != null 198 ) "-DOPENSSL_TLS_SECURITY_LEVEL=${builtins.toString securityLevel}" 199 ++ lib.optional enableMD2 "enable-md2" 200 ++ lib.optional enableSSL2 "enable-ssl2" 201 ++ lib.optional enableSSL3 "enable-ssl3" 202 # We select KTLS here instead of the configure-time detection (which we patch out). 203 # KTLS should work on FreeBSD 13+ as well, so we could enable it if someone tests it. 204 ++ lib.optional (lib.versionAtLeast version "3.0.0" && enableKTLS) "enable-ktls" 205 ++ lib.optional (lib.versionAtLeast version "1.1.1" && stdenv.hostPlatform.isAarch64) "no-afalgeng" 206 # OpenSSL needs a specific `no-shared` configure flag. 207 # See https://wiki.openssl.org/index.php/Compilation_and_Installation#Configure_Options 208 # for a comprehensive list of configuration options. 209 ++ lib.optional (lib.versionAtLeast version "1.1.1" && static) "no-shared" 210 ++ lib.optional (lib.versionAtLeast version "3.0.0" && static) "no-module" 211 # This introduces a reference to the CTLOG_FILE which is undesired when 212 # trying to build binaries statically. 213 ++ lib.optional static "no-ct" 214 ++ lib.optional withZlib "zlib" 215 # /dev/crypto support has been dropped in OpenBSD 5.7. 216 # 217 # OpenBSD's ports does this too, 218 # https://github.com/openbsd/ports/blob/a1147500c76970fea22947648fb92a093a529d7c/security/openssl/3.3/Makefile#L25. 219 # 220 # https://github.com/openssl/openssl/pull/10565 indicated the 221 # intent was that this would be configured properly automatically, 222 # but that doesn't appear to be the case. 223 ++ lib.optional stdenv.hostPlatform.isOpenBSD "no-devcryptoeng" 224 ++ lib.optionals (stdenv.hostPlatform.isMips && stdenv.hostPlatform ? gcc.arch) [ 225 # This is necessary in order to avoid openssl adding -march 226 # flags which ultimately conflict with those added by 227 # cc-wrapper. Openssl assumes that it can scan CFLAGS to 228 # detect any -march flags, using this perl code: 229 # 230 # && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}}) 231 # 232 # The following bogus CFLAGS environment variable triggers the 233 # the code above, inhibiting `./Configure` from adding the 234 # conflicting flags. 235 "CFLAGS=-march=${stdenv.hostPlatform.gcc.arch}" 236 ]; 237 238 makeFlags = [ 239 "MANDIR=$(man)/share/man" 240 # This avoids conflicts between man pages of openssl subcommands (for 241 # example 'ts' and 'err') man pages and their equivalent top-level 242 # command in other packages (respectively man-pages and moreutils). 243 # This is done in ubuntu and archlinux, and possibly many other distros. 244 "MANSUFFIX=ssl" 245 ]; 246 247 enableParallelBuilding = true; 248 249 postInstall = 250 ( 251 if static then 252 '' 253 # OPENSSLDIR has a reference to self 254 remove-references-to -t $out $out/lib/*.a 255 '' 256 else 257 '' 258 # If we're building dynamic libraries, then don't install static 259 # libraries. 260 if [ -n "$(echo $out/lib/*.so $out/lib/*.dylib $out/lib/*.dll)" ]; then 261 rm "$out/lib/"*.a 262 fi 263 264 # 'etc' is a separate output on static builds only. 265 etc=$out 266 '' 267 ) 268 + '' 269 mkdir -p $bin 270 mv $out/bin $bin/bin 271 272 '' 273 + 274 lib.optionalString (!stdenv.hostPlatform.isWindows) 275 # makeWrapper is broken for windows cross (https://github.com/NixOS/nixpkgs/issues/120726) 276 '' 277 # c_rehash is a legacy perl script with the same functionality 278 # as `openssl rehash` 279 # this wrapper script is created to maintain backwards compatibility without 280 # depending on perl 281 makeWrapper $bin/bin/openssl $bin/bin/c_rehash \ 282 --add-flags "rehash" 283 '' 284 + '' 285 286 mkdir $dev 287 mv $out/include $dev/ 288 289 # remove dependency on Perl at runtime 290 rm -r $etc/etc/ssl/misc 291 292 rmdir $etc/etc/ssl/{certs,private} 293 '' 294 + lib.optionalString (conf != null) '' 295 cat ${conf} > $etc/etc/ssl/openssl.cnf 296 ''; 297 298 allowedImpureDLLs = [ "CRYPT32.dll" ]; 299 300 postFixup = 301 lib.optionalString (!stdenv.hostPlatform.isWindows) '' 302 # Check to make sure the main output and the static runtime dependencies 303 # don't depend on perl 304 if grep -r '${buildPackages.perl}' $out $etc; then 305 echo "Found an erroneous dependency on perl ^^^" >&2 306 exit 1 307 fi 308 '' 309 + lib.optionalString (lib.versionAtLeast version "3.3.0") '' 310 # cleanup cmake helpers for now (for OpenSSL >= 3.3), only rely on pkg-config. 311 # pkg-config gets its paths fixed correctly 312 rm -rf $dev/lib/cmake 313 ''; 314 315 passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; 316 317 meta = { 318 homepage = "https://www.openssl.org/"; 319 changelog = "https://github.com/openssl/openssl/blob/openssl-${version}/CHANGES.md"; 320 description = "Cryptographic library that implements the SSL and TLS protocols"; 321 license = lib.licenses.openssl; 322 mainProgram = "openssl"; 323 maintainers = with lib.maintainers; [ thillux ]; 324 teams = [ lib.teams.stridtech ]; 325 pkgConfigModules = [ 326 "libcrypto" 327 "libssl" 328 "openssl" 329 ]; 330 platforms = lib.platforms.all; 331 } 332 // extraMeta; 333 }); 334 335in 336{ 337 # intended version "policy": 338 # - 1.1 as long as some package exists, which does not build without it 339 # (tracking issue: https://github.com/NixOS/nixpkgs/issues/269713) 340 # try to remove in 24.05 for the first time, if possible then 341 # - latest 3.x LTS 342 # - latest 3.x non-LTS as preview/for development 343 # 344 # - other versions in between only when reasonable need is stated for some package 345 # - backport every security critical fix release e.g. 3.0.y -> 3.0.y+1 but no new version, e.g. 3.1 -> 3.2 346 347 # If you do upgrade here, please update in pkgs/top-level/release.nix 348 # the permitted insecure version to ensure it gets cached for our users 349 # and backport this to stable release (at time of writing this 23.11). 350 openssl_1_1 = common { 351 version = "1.1.1w"; 352 hash = "sha256-zzCYlQy02FOtlcCEHx+cbT3BAtzPys1SHZOSUgi3asg="; 353 patches = [ 354 ./1.1/nix-ssl-cert-file.patch 355 356 ( 357 if stdenv.hostPlatform.isDarwin then ./use-etc-ssl-certs-darwin.patch else ./use-etc-ssl-certs.patch 358 ) 359 ]; 360 withDocs = true; 361 extraMeta = { 362 knownVulnerabilities = [ 363 "OpenSSL 1.1 is reaching its end of life on 2023/09/11 and cannot be supported through the NixOS 23.11 release cycle. https://www.openssl.org/blog/blog/2023/03/28/1.1.1-EOL/" 364 ]; 365 }; 366 }; 367 368 openssl_3 = common { 369 version = "3.0.17"; 370 hash = "sha256-39135OobV/86bb3msL3D8x21rJnn/dTq+eH7tuwtuM4="; 371 372 patches = [ 373 ./3.0/nix-ssl-cert-file.patch 374 375 # openssl will only compile in KTLS if the current kernel supports it. 376 # This patch disables build-time detection. 377 ./3.0/openssl-disable-kernel-detection.patch 378 379 ( 380 if stdenv.hostPlatform.isDarwin then ./use-etc-ssl-certs-darwin.patch else ./use-etc-ssl-certs.patch 381 ) 382 ]; 383 384 withDocs = true; 385 386 extraMeta = { 387 license = lib.licenses.asl20; 388 }; 389 }; 390 391 openssl_3_5 = common { 392 version = "3.5.1"; 393 hash = "sha256-UpBDsVz/pfNgd6TQr4Pz3jmYBxgdYHRB1zQZbYibZB8="; 394 395 patches = [ 396 ./3.0/nix-ssl-cert-file.patch 397 398 # openssl will only compile in KTLS if the current kernel supports it. 399 # This patch disables build-time detection. 400 ./3.0/openssl-disable-kernel-detection.patch 401 402 ( 403 if stdenv.hostPlatform.isDarwin then 404 ./3.5/use-etc-ssl-certs-darwin.patch 405 else 406 ./3.5/use-etc-ssl-certs.patch 407 ) 408 ]; 409 410 withDocs = true; 411 412 extraMeta = { 413 license = lib.licenses.asl20; 414 }; 415 }; 416}