Skip to content

Commit

Permalink
Update Windows installer for new OpenSSL versions
Browse files Browse the repository at this point in the history
On Windows, OpenSSL 3.3.2 (and maybe some previous versions) has
changed two things:

1. The way the OpenSSL packages are located from slproweb has changed
   => need to update install-openssl.ps1
2. After installation of OpenSSL, the layout of library files was
   also completely changed => need to update build-win-installer.ps1
   and libsrt.nsi

Before releasing SRT 1.5.4 and building the corresponding Windows
installer, it is recommended to upgrade OpenSSL on the build system,
i.e. run install-openssl.ps1
  • Loading branch information
lelegard committed Oct 11, 2024
1 parent e23497d commit 6d32d9e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 38 deletions.
59 changes: 51 additions & 8 deletions scripts/win-installer/build-win-installer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,53 @@ Write-Output "Windows version info: $VersionInfo"
#-----------------------------------------------------------------------------

# Locate OpenSSL root from local installation.
$SslRoot = @{
"x64" = "C:\Program Files\OpenSSL-Win64";
"Win32" = "C:\Program Files (x86)\OpenSSL-Win32"
# After version 3.something, OpenSSL has changed its installation layout.
# We have to look for OpenSSL libraries in various locations.
$SSL = @{
"x64" = @{
"alt" = "Win64";
"bits" = 64;
"root" = "C:\Program Files\OpenSSL-Win64"
};
"Win32" = @{
"alt" = "x86";
"bits" = 32;
"root" = "C:\Program Files (x86)\OpenSSL-Win32"
}
}

# Verify OpenSSL directories.
# Verify OpenSSL directories and static libraries.
Write-Output "Searching OpenSSL libraries ..."
$Missing = 0
foreach ($file in @($SslRoot["x64"], $SslRoot["Win32"])) {
if (-not (Test-Path $file)) {
Write-Output "**** Missing $file"
foreach ($arch in @("x64", "Win32")) {
$root = $SSL[$arch]["root"]
$bits = $SSL[$arch]["bits"]
$alt = $SSL[$arch]["alt"]
if (-not (Test-Path $root)) {
Write-Output "**** Missing $root"
$Missing = $Missing + 1
}
else {
foreach ($lib in @("ssl", "crypto")) {
foreach ($conf in @("MD", "MDd")) {
$name = "lib${lib}${conf}"
$SSL[$arch][$name] = ""
foreach ($try in @("$root\lib\VC\static\lib${lib}${bits}${conf}.lib",
"$root\lib\VC\${arch}\${conf}\lib${lib}_static.lib",
"$root\lib\VC\${alt}\${conf}\lib${lib}_static.lib")) {
if (Test-Path $try) {
$SSL[$arch][$name] = $try
New-Variable "lib${lib}${bits}${conf}" "$try"
break
}
}
if (-not $SSL[$arch][$name]) {
Write-Output "**** OpenSSL static library for $name not found"
$Missing = $Missing + 1
}
}
}
}
}
if ($Missing -gt 0) {
Exit-Script "Missing $Missing OpenSSL files, use install-openssl.ps1 to install OpenSSL"
Expand Down Expand Up @@ -157,7 +192,7 @@ foreach ($Platform in @("x64", "Win32")) {

# Run CMake.
Write-Output "Configuring build for platform $Platform ..."
$SRoot = $SslRoot[$Platform]
$SRoot = $SSL[$Platform]["root"]
& $CMake -S $RepoDir -B $BuildDir -A $Platform `
-DENABLE_STDCXX_SYNC=ON `
-DOPENSSL_ROOT_DIR="$SRoot" `
Expand Down Expand Up @@ -210,6 +245,14 @@ Write-Output "Building installer ..."
/DOutDir="$OutDir" `
/DBuildRoot="$TmpDir" `
/DRepoDir="$RepoDir" `
/Dlibssl32MD="$libssl32MD" `
/Dlibssl32MDd="$libssl32MDd" `
/Dlibcrypto32MD="$libcrypto32MD" `
/Dlibcrypto32MDd="$libcrypto32MDd" `
/Dlibssl64MD="$libssl64MD" `
/Dlibssl64MDd="$libssl64MDd" `
/Dlibcrypto64MD="$libcrypto64MD" `
/Dlibcrypto64MDd="$libcrypto64MDd" `
"$ScriptDir\libsrt.nsi"

if (-not (Test-Path $InstallExe)) {
Expand Down
61 changes: 41 additions & 20 deletions scripts/win-installer/install-openssl.ps1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#-----------------------------------------------------------------------------
#
# SRT - Secure, Reliable, Transport
# Copyright (c) 2021, Thierry Lelegard
# Copyright (c) 2021-2024, Thierry Lelegard
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -36,7 +36,26 @@ param(
)

Write-Output "OpenSSL download and installation procedure"
$OpenSSLHomePage = "http://slproweb.com/products/Win32OpenSSL.html"

# A bit of history: Where to load OpenSSL binaries from?
#
# The packages are built by "slproweb". The binaries are downloadable from
# their Web page at: http://slproweb.com/products/Win32OpenSSL.html
#
# Initially, the HTML for this page was built on server-side. This script
# grabbed the URL content, parse the HTML and extracted the URL of the
# binaries for the latest OpenSSL packages from the "href" of the links.
#
# At some point in 2024, the site changed policy. The Web page is no longer
# built on server-side, but on client-side. The downloaded HTML contains some
# JavaScript which dynamically builds the URL of the binaries for the latest
# OpenSSL binaries. The previous method now finds no valid package URL from
# the downloaded page (a full browser is needed to execute the JavaScript).
# The JavaScript downloads a JSON file which contains all references to
# the OpenSSL binaries. This script now uses the same method: download that
# JSON file and parse it.

$PackageList = "https://github.com/slproweb/opensslhashes/raw/master/win32_openssl_hashes.json"

# A function to exit this script.
function Exit-Script([string]$Message = "")
Expand All @@ -62,11 +81,11 @@ $TmpDir = "$RootDir\tmp"
# Without this, Invoke-WebRequest is awfully slow.
$ProgressPreference = 'SilentlyContinue'

# Get the HTML page for OpenSSL downloads.
# Get the JSON configuration file for OpenSSL downloads.
$status = 0
$message = ""
try {
$response = Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $OpenSSLHomePage
$response = Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $PackageList
$status = [int] [Math]::Floor($response.StatusCode / 100)
}
catch {
Expand All @@ -77,22 +96,27 @@ if ($status -ne 1 -and $status -ne 2) {
Exit-Script "Status code $($response.StatusCode), $($response.StatusDescription)"
}
else {
Exit-Script "#### Error accessing ${OpenSSLHomePage}: $message"
Exit-Script "#### Error accessing ${PackageList}: $message"
}
}
$config = ConvertFrom-Json $Response.Content

# Download and install MSI packages for 32 and 64 bit.
foreach ($bits in @(32, 64)) {

# Get the URL of the MSI installer from the JSON config.
$Url = $config.files | Get-Member | ForEach-Object {
$name = $_.name
$info = $config.files.$($_.name)
if (-not $info.light -and $info.installer -like "msi" -and $info.bits -eq $bits -and $info.arch -like "intel") {
$info.url
}
} | Select-Object -Last 1
if (-not $Url) {
Exit-Script "#### No MSI installer found for Win${bits}"
}

# Parse HTML page to locate the latest MSI files.
$Ref32 = $response.Links.href | Where-Object { $_ -like "*/Win32OpenSSL-*.msi" } | Select-Object -First 1
$Ref64 = $response.Links.href | Where-Object { $_ -like "*/Win64OpenSSL-*.msi" } | Select-Object -First 1

# Build the absolute URL's from base URL (the download page) and href links.
$Url32 = New-Object -TypeName 'System.Uri' -ArgumentList ([System.Uri]$OpenSSLHomePage, $Ref32)
$Url64 = New-Object -TypeName 'System.Uri' -ArgumentList ([System.Uri]$OpenSSLHomePage, $Ref64)

# Download and install one MSI package.
function Download-Install([string]$Url)
{
$MsiName = (Split-Path -Leaf $Url.toString())
$MsiName = (Split-Path -Leaf $Url)
$MsiPath = "$TmpDir\$MsiName"

if (-not $ForceDownload -and (Test-Path $MsiPath)) {
Expand All @@ -113,7 +137,4 @@ function Download-Install([string]$Url)
}
}

# Download and install the two MSI packages.
Download-Install $Url32
Download-Install $Url64
Exit-Script
18 changes: 8 additions & 10 deletions scripts/win-installer/libsrt.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ Caption "SRT Libraries Installer"
!define ProductName "libsrt"
!define Build32Dir "${BuildRoot}\build.Win32"
!define Build64Dir "${BuildRoot}\build.x64"
!define SSL32Dir "C:\Program Files (x86)\OpenSSL-Win32"
!define SSL64Dir "C:\Program Files\OpenSSL-Win64"

; Installer file information.
VIProductVersion ${VersionInfo}
Expand Down Expand Up @@ -142,26 +140,26 @@ Section "Install"
CreateDirectory "$INSTDIR\lib\Release-x64"
SetOutPath "$INSTDIR\lib\Release-x64"
File /oname=srt.lib "${Build64Dir}\Release\srt_static.lib"
File /oname=libcrypto.lib "${SSL64Dir}\lib\VC\static\libcrypto64MD.lib"
File /oname=libssl.lib "${SSL64Dir}\lib\VC\static\libssl64MD.lib"
File /oname=libcrypto.lib "${libcrypto64MD}"
File /oname=libssl.lib "${libssl64MD}"

CreateDirectory "$INSTDIR\lib\Debug-x64"
SetOutPath "$INSTDIR\lib\Debug-x64"
File /oname=srt.lib "${Build64Dir}\Debug\srt_static.lib"
File /oname=libcrypto.lib "${SSL64Dir}\lib\VC\static\libcrypto64MDd.lib"
File /oname=libssl.lib "${SSL64Dir}\lib\VC\static\libssl64MDd.lib"
File /oname=libcrypto.lib "${libcrypto64MDd}"
File /oname=libssl.lib "${libssl64MDd}"

CreateDirectory "$INSTDIR\lib\Release-Win32"
SetOutPath "$INSTDIR\lib\Release-Win32"
File /oname=srt.lib "${Build32Dir}\Release\srt_static.lib"
File /oname=libcrypto.lib "${SSL32Dir}\lib\VC\static\libcrypto32MD.lib"
File /oname=libssl.lib "${SSL32Dir}\lib\VC\static\libssl32MD.lib"
File /oname=libcrypto.lib "${libcrypto32MD}"
File /oname=libssl.lib "${libssl32MD}"

CreateDirectory "$INSTDIR\lib\Debug-Win32"
SetOutPath "$INSTDIR\lib\Debug-Win32"
File /oname=srt.lib "${Build32Dir}\Debug\srt_static.lib"
File /oname=libcrypto.lib "${SSL32Dir}\lib\VC\static\libcrypto32MDd.lib"
File /oname=libssl.lib "${SSL32Dir}\lib\VC\static\libssl32MDd.lib"
File /oname=libcrypto.lib "${libcrypto32MDd}"
File /oname=libssl.lib "${libssl32MDd}"

; Add an environment variable to installation root.
WriteRegStr HKLM ${EnvironmentKey} "LIBSRT" "$INSTDIR"
Expand Down

0 comments on commit 6d32d9e

Please sign in to comment.