1 # Copyright (c) 2021-2022 Yubico AB. All rights reserved. 2 # Use of this source code is governed by a BSD-style 3 # license that can be found in the LICENSE file. 4 # SPDX-License-Identifier: BSD-2-Clause 5 6 param( 7 [string]$CMakePath = "C:\Program Files\CMake\bin\cmake.exe", 8 [string]$GitPath = "C:\Program Files\Git\bin\git.exe", 9 [string]$SevenZPath = "C:\Program Files\7-Zip\7z.exe", 10 [string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe", 11 [string]$WinSDK = "", 12 [string]$Config = "Release", 13 [string]$Arch = "x64", 14 [string]$Type = "dynamic", 15 [string]$Fido2Flags = "" 16 ) 17 18 $ErrorActionPreference = "Stop" 19 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 20 21 . "$PSScriptRoot\const.ps1" 22 23 Function ExitOnError() { 24 if ($LastExitCode -ne 0) { 25 throw "A command exited with status $LastExitCode" 26 } 27 } 28 29 Function GitClone(${REPO}, ${BRANCH}, ${DIR}) { 30 Write-Host "Cloning ${REPO}..." 31 & $Git -c advice.detachedHead=false clone --quiet --depth=1 ` 32 --branch "${BRANCH}" "${REPO}" "${DIR}" 33 Write-Host "${REPO}'s ${BRANCH} HEAD is:" 34 & $Git -C "${DIR}" show -s HEAD 35 } 36 37 # Find Git. 38 $Git = $(Get-Command git -ErrorAction Ignore | ` 39 Select-Object -ExpandProperty Source) 40 if ([string]::IsNullOrEmpty($Git)) { 41 $Git = $GitPath 42 } 43 if (-Not (Test-Path $Git)) { 44 throw "Unable to find Git at $Git" 45 } 46 47 # Find CMake. 48 $CMake = $(Get-Command cmake -ErrorAction Ignore | ` 49 Select-Object -ExpandProperty Source) 50 if ([string]::IsNullOrEmpty($CMake)) { 51 $CMake = $CMakePath 52 } 53 if (-Not (Test-Path $CMake)) { 54 throw "Unable to find CMake at $CMake" 55 } 56 57 # Find 7z. 58 $SevenZ = $(Get-Command 7z -ErrorAction Ignore | ` 59 Select-Object -ExpandProperty Source) 60 if ([string]::IsNullOrEmpty($SevenZ)) { 61 $SevenZ = $SevenZPath 62 } 63 if (-Not (Test-Path $SevenZ)) { 64 throw "Unable to find 7z at $SevenZ" 65 } 66 67 # Find GPG. 68 $GPG = $(Get-Command gpg -ErrorAction Ignore | ` 69 Select-Object -ExpandProperty Source) 70 if ([string]::IsNullOrEmpty($GPG)) { 71 $GPG = $GPGPath 72 } 73 if (-Not (Test-Path $GPG)) { 74 throw "Unable to find GPG at $GPG" 75 } 76 77 # 10.0.261000.0 appear to have dropped ARM32 support, pin the SDK version 78 if ($Arch -eq "ARM" -and [string]::IsNullOrEmpty($WinSDK)) { 79 $WinSDK = '10.0.22621.0' 80 } 81 82 Write-Host "WinSDK: $WinSDK" 83 Write-Host "Config: $Config" 84 Write-Host "Arch: $Arch" 85 Write-Host "Type: $Type" 86 Write-Host "Git: $Git" 87 Write-Host "CMake: $CMake" 88 Write-Host "7z: $SevenZ" 89 Write-Host "GPG: $GPG" 90 91 # Create build directories. 92 New-Item -Type Directory "${BUILD}" -Force 93 New-Item -Type Directory "${BUILD}\${Arch}" -Force 94 New-Item -Type Directory "${BUILD}\${Arch}\${Type}" -Force 95 New-Item -Type Directory "${STAGE}\${LIBRESSL}" -Force 96 New-Item -Type Directory "${STAGE}\${LIBCBOR}" -Force 97 New-Item -Type Directory "${STAGE}\${ZLIB}" -Force 98 99 # Create GNUPGHOME with an empty common.conf to disable use-keyboxd. 100 # Recent default is to enable keyboxd which in turn ignores --keyring 101 # arguments. 102 $GpgHome = "${BUILD}\.gnupg" 103 New-Item -Type Directory "${GpgHome}" -Force 104 New-Item -Type File "${GpgHome}\common.conf" -Force 105 106 # Create output directories. 107 New-Item -Type Directory "${OUTPUT}" -Force 108 New-Item -Type Directory "${OUTPUT}\${Arch}" -Force 109 New-Item -Type Directory "${OUTPUT}\${Arch}\${Type}" -force 110 111 # Override Windows SDK version if $WinSDK is set. 112 if (-Not ([string]::IsNullOrEmpty($WinSDK))) { 113 $Arch = "$Arch,version=$WinSDK" 114 } 115 116 # Fetch and verify dependencies. 117 Push-Location ${BUILD} 118 try { 119 if (-Not (Test-Path .\${LIBRESSL})) { 120 if (-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) { 121 Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz ` 122 -OutFile .\${LIBRESSL}.tar.gz 123 } 124 if (-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) { 125 Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc ` 126 -OutFile .\${LIBRESSL}.tar.gz.asc 127 } 128 129 Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}" 130 & $GPG --homedir ${GpgHome} --list-keys 131 & $GPG --homedir ${GpgHome} --quiet --no-default-keyring ` 132 --keyring ./libressl.gpg ` 133 --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz 134 if ($LastExitCode -ne 0) { 135 throw "GPG signature verification failed" 136 } 137 & $SevenZ e .\${LIBRESSL}.tar.gz 138 & $SevenZ x .\${LIBRESSL}.tar 139 Remove-Item -Force .\${LIBRESSL}.tar 140 } 141 if (-Not (Test-Path .\${LIBCBOR})) { 142 GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}" 143 } 144 if (-Not (Test-Path .\${ZLIB})) { 145 GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}" 146 } 147 } catch { 148 throw "Failed to fetch and verify dependencies" 149 } finally { 150 Pop-Location 151 } 152 153 # Build LibreSSL. 154 Push-Location ${STAGE}\${LIBRESSL} 155 try { 156 & $CMake ..\..\..\${LIBRESSL} -A "${Arch}" ` 157 -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF ` 158 -DLIBRESSL_APPS=OFF -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` 159 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` 160 -DCMAKE_MSVC_RUNTIME_LIBRARY="${CMAKE_MSVC_RUNTIME_LIBRARY}" ` 161 -DCMAKE_INSTALL_PREFIX="${PREFIX}"; ` 162 ExitOnError 163 & $CMake --build . --config ${Config} --verbose; ExitOnError 164 & $CMake --build . --config ${Config} --target install --verbose; ` 165 ExitOnError 166 } catch { 167 throw "Failed to build LibreSSL" 168 } finally { 169 Pop-Location 170 } 171 172 # Build libcbor. 173 Push-Location ${STAGE}\${LIBCBOR} 174 try { 175 & $CMake ..\..\..\${LIBCBOR} -A "${Arch}" ` 176 -DWITH_EXAMPLES=OFF ` 177 -DBUILD_SHARED_LIBS="${SHARED}" ` 178 -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} /wd4703" ` 179 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} /wd4703" ` 180 -DCMAKE_INSTALL_PREFIX="${PREFIX}"; ` 181 ExitOnError 182 & $CMake --build . --config ${Config} --verbose; ExitOnError 183 & $CMake --build . --config ${Config} --target install --verbose; ` 184 ExitOnError 185 } catch { 186 throw "Failed to build libcbor" 187 } finally { 188 Pop-Location 189 } 190 191 # Build zlib. 192 Push-Location ${STAGE}\${ZLIB} 193 try { 194 & $CMake ..\..\..\${ZLIB} -A "${Arch}" ` 195 -DBUILD_SHARED_LIBS="${SHARED}" ` 196 -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` 197 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` 198 -DCMAKE_MSVC_RUNTIME_LIBRARY="${CMAKE_MSVC_RUNTIME_LIBRARY}" ` 199 -DCMAKE_INSTALL_PREFIX="${PREFIX}"; ` 200 ExitOnError 201 & $CMake --build . --config ${Config} --verbose; ExitOnError 202 & $CMake --build . --config ${Config} --target install --verbose; ` 203 ExitOnError 204 # Patch up zlib's various names. 205 if ("${Type}" -eq "Dynamic") { 206 ((Get-ChildItem -Path "${PREFIX}/lib") -Match "zlib[d]?.lib") | 207 Copy-Item -Destination "${PREFIX}/lib/zlib1.lib" -Force 208 ((Get-ChildItem -Path "${PREFIX}/bin") -Match "zlibd1.dll") | 209 Copy-Item -Destination "${PREFIX}/bin/zlib1.dll" -Force 210 } else { 211 ((Get-ChildItem -Path "${PREFIX}/lib") -Match "zlibstatic[d]?.lib") | 212 Copy-item -Destination "${PREFIX}/lib/zlib1.lib" -Force 213 } 214 } catch { 215 throw "Failed to build zlib" 216 } finally { 217 Pop-Location 218 } 219 220 # Build libfido2. 221 Push-Location ${STAGE} 222 try { 223 & $CMake ..\..\.. -A "${Arch}" ` 224 -DCMAKE_BUILD_TYPE="${Config}" ` 225 -DBUILD_SHARED_LIBS="${SHARED}" ` 226 -DCBOR_INCLUDE_DIRS="${PREFIX}\include" ` 227 -DCBOR_LIBRARY_DIRS="${PREFIX}\lib" ` 228 -DCBOR_BIN_DIRS="${PREFIX}\bin" ` 229 -DZLIB_INCLUDE_DIRS="${PREFIX}\include" ` 230 -DZLIB_LIBRARY_DIRS="${PREFIX}\lib" ` 231 -DZLIB_BIN_DIRS="${PREFIX}\bin" ` 232 -DCRYPTO_INCLUDE_DIRS="${PREFIX}\include" ` 233 -DCRYPTO_LIBRARY_DIRS="${PREFIX}\lib" ` 234 -DCRYPTO_BIN_DIRS="${PREFIX}\bin" ` 235 -DCRYPTO_LIBRARIES="${CRYPTO_LIB}" ` 236 -DCRYPTO_DLL="${CRYPTO_DLL}" ` 237 -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} ${Fido2Flags}" ` 238 -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} ${Fido2Flags}" ` 239 -DCMAKE_INSTALL_PREFIX="${PREFIX}"; ` 240 ExitOnError 241 & $CMake --build . --config ${Config} --verbose; ExitOnError 242 & $CMake --build . --config ${Config} --target regress --verbose; ` 243 ExitOnError 244 & $CMake --build . --config ${Config} --target install --verbose; ` 245 ExitOnError 246 # Copy DLLs. 247 if ("${SHARED}" -eq "ON") { 248 "cbor.dll", "${CRYPTO_DLL}.dll", "zlib1.dll" | ` 249 %{ Copy-Item "${PREFIX}\bin\$_" ` 250 -Destination "examples\${Config}" } 251 } 252 } catch { 253 throw "Failed to build libfido2" 254 } finally { 255 Pop-Location 256 } 257