diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a38834494..514117a5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -153,7 +153,10 @@ jobs: - name: Install .NET SDK uses: actions/setup-dotnet@v3 with: - dotnet-version: 7.x.x + # .NET 5 is deprecated and removed from GitHub Actions, we need to manually install it + dotnet-version: | + 5.x.x + 7.x.x - name: Setup MSBuild uses: microsoft/setup-msbuild@v1.1.2 diff --git a/EasyPost/EasyPost.csproj b/EasyPost/EasyPost.csproj index 3b48d2dae..d592835c3 100644 --- a/EasyPost/EasyPost.csproj +++ b/EasyPost/EasyPost.csproj @@ -45,8 +45,10 @@ false - false - + + true + true + ..\EasyPostNETStrongNameSigning.pub false @@ -61,9 +63,9 @@ + README.md true / - README.md diff --git a/EasyPostNETStrongNameSigning.pub b/EasyPostNETStrongNameSigning.pub new file mode 100644 index 000000000..26cb33c26 Binary files /dev/null and b/EasyPostNETStrongNameSigning.pub differ diff --git a/Makefile b/Makefile index 7fa74fda9..a6ec526f1 100644 --- a/Makefile +++ b/Makefile @@ -38,13 +38,6 @@ docs: format: dotnet dotnet-format --no-restore -## install-cert - Install the PFX certificate to your system (Windows only) -# @parameters: -# cert= - The certificate to use for signing the built assets. -# pass= - The password for the certificate. -install-cert: - scripts\install_cert.bat ${cert} ${pass} - ## install-tools - Install required dotnet tools install-tools: dotnet new tool-manifest || exit 0 @@ -67,10 +60,11 @@ lint-scripts: ## prep-release - Build, sign and package the project for distribution, signing with the provided certificate (Windows only) # @parameters: -# cert= - The certificate to use for signing the built assets. -# pass= - The password for the certificate. +# sncert= - The strong-name certificate to use for signing the built assets. +# cert= - The authenticity certificate to use for signing the built assets. +# pass= - The password for the authenticity certificate. prep-release: - scripts\build_release_nuget.bat EasyPost ${cert} ${pass} EasyPost Release + scripts\build_release_nuget.bat EasyPost ${sncert} ${cert} ${pass} EasyPost Release ## publish - Publish a specific NuGet file to nuget.org (Windows only) # @parameters: @@ -102,14 +96,6 @@ setup-win: setup-unix: bash scripts/setup.sh -## sign - Sign all generated DLLs and NuGet packages with the provided certificate (Windows only) -# @parameters: -# cert= - The certificate to use for signing the built assets. -# pass= - The password for the certificate. -sign: - install-cert cert=${cert} pass=${pass} - scripts\sign_assemblies.bat ${cert} ${pass} EasyPost - ## test - Test the project test: dotnet test @@ -125,4 +111,4 @@ test-fw: uninstall-scanner: dotnet tool uninstall security-scan -.PHONY: help build build-test-fw build-prod clean coverage coverage-check docs format install-cert install-tools install lint lint-scripts pre-release publish-all publish release restore scan setup-win setup-unix sign test test-fw uninstall-scanner +.PHONY: help build build-test-fw build-prod clean coverage coverage-check docs format install-tools install lint lint-scripts pre-release publish-all publish release restore scan setup-win setup-unix test test-fw uninstall-scanner diff --git a/scripts/build_release_nuget.bat b/scripts/build_release_nuget.bat index ddf66070d..e4155f729 100644 --- a/scripts/build_release_nuget.bat +++ b/scripts/build_release_nuget.bat @@ -11,28 +11,29 @@ :: Parse command line arguments SET projectName=%1 -SET certFile=%2 -SET certPass=%3 -SET containerName=%4 -SET buildMode=%5 +SET strongNameCertFile=%2 +SET authCertFile=%3 +SET authCertPass=%4 +SET containerName=%5 +SET buildMode=%6 :: Delete old files CALL "scripts\delete_old_assemblies.bat" -:: Install certificate (needed to automate signing later on) -CALL "scripts\install_cert.bat" %certFile% %certPass% %containerName% || GOTO :commandFailed - :: Restore dependencies and build solution CALL "scripts\build_project.bat" %buildMode% || GOTO :commandFailed -:: Sign the DLLs -CALL "scripts\sign_dlls.bat" %certFile% %certPass% %containerName% || GOTO :commandFailed +:: Strong-name the DLLs +CALL "scripts\strong_name_dlls.bat" %strongNameCertFile% || GOTO :commandFailed + +:: Sign the DLLs for authenticity +CALL "scripts\sign_dlls.bat" %authCertFile% %authCertPass% || GOTO :commandFailed :: Package the DLLs in a NuGet package (will fail if DLLs are missing) CALL "scripts\pack_nuget.bat" %projectName% || GOTO :commandFailed -:: Sign the NuGet package -CALL "scripts\sign_nuget.bat" %certFile% %certPass% || GOTO :commandFailed +:: Sign the NuGet package for authenticity +CALL "scripts\sign_nuget.bat" %authCertFile% %authCertPass% || GOTO :commandFailed SET nugetFileName= FOR /R %%F IN (*.nupkg) DO ( SET nugetFileName="%%F" diff --git a/scripts/install_cert.bat b/scripts/install_cert.bat deleted file mode 100644 index a55f7e16a..000000000 --- a/scripts/install_cert.bat +++ /dev/null @@ -1,28 +0,0 @@ -:: This script will install a provided PFX certificate to the system. - -:: Requirements: -:: - dotnet is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files\dotnet) -:: - SnInstallPfx (https://github.com/honzajscz/SnInstallPfx) is installed on the machine and is accessible everywhere (added to PATH) - -@ECHO OFF - -:: Parse command line arguments -SET certFile=%1 -SET certPass=%2 -SET containerName=%3 - -:: Install certificate -@ECHO: -@ECHO (Re-)Installing certificate to system... -sn -d %containerName% -SnInstallPfx %certFile% %certPass% %containerName% || GOTO :commandFailed - -EXIT /B 0 - -:commandFailed -@ECHO Command failed. -GOTO :exitWithError - -:exitWithError -@ECHO Exiting... -EXIT /B 1 diff --git a/scripts/sign_dlls.bat b/scripts/sign_dlls.bat index e52fd01a1..faaed8971 100644 --- a/scripts/sign_dlls.bat +++ b/scripts/sign_dlls.bat @@ -1,8 +1,7 @@ -:: This script will find and sign any DLLs with a provided PFX certificate +:: This script will find and sign any DLLs with a provided PFX certificate for authenticity :: Requirements: :: - dotnet is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files\dotnet) -:: - sn.exe is installed on the machine and is accessible everywhere (added to PATH) :: - signtool is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64) @ECHO OFF @@ -10,15 +9,11 @@ :: Parse command line arguments SET certFile=%1 SET certPass=%2 -SET containerName=%3 -:: Sign all DLLs found in the lib folder +:: Sign all DLLs found in the lib folder with our certificate to guarantee authenticity @ECHO: -@ECHO Signing DLLs with certificate... +@ECHO Signing DLLs with %certFile% for authenticity... FOR /R "lib" %%F IN (*.dll) DO ( - REM We need to run the DLLs through both sn.exe and signtool to get complete the signing process - REM sn erroneously triggers command failed if we put a fallback on this - sn -Rca "%%F" %containerName% signtool sign /f %certFile% /p %certPass% /v /tr http://timestamp.digicert.com?alg=sha256 /td SHA256 /fd SHA256 "%%F" || GOTO :commandFailed ) diff --git a/scripts/sign_nuget.bat b/scripts/sign_nuget.bat index 4b109c469..c7190c3bf 100644 --- a/scripts/sign_nuget.bat +++ b/scripts/sign_nuget.bat @@ -1,4 +1,4 @@ -:: This script will find and sign any NuGet packages with a provided PFX certificate +:: This script will find and sign any NuGet packages with a provided PFX certificate for authenticity :: Requirements: :: - NuGet is installed on the machine and is accessible everywhere (added to PATH) @@ -9,9 +9,9 @@ SET certFile=%1 SET certPass=%2 -:: Sign all NuGet packages found +:: Sign all NuGet packages found with our certificate to guarantee authenticity @ECHO: -@ECHO Signing NuGet package with %certFile%... +@ECHO Signing NuGet package with %certFile% for authenticity... :: Should only be one .nupkg file at this point, since we deleted the old ones FOR /R %%F IN (*.nupkg) DO ( nuget sign "%%F" -Timestamper http://timestamp.digicert.com -CertificatePath "%certFile%" -CertificatePassword "%certPass%" || GOTO :commandFailed diff --git a/scripts/strong_name_dlls.bat b/scripts/strong_name_dlls.bat new file mode 100644 index 000000000..4d44c209d --- /dev/null +++ b/scripts/strong_name_dlls.bat @@ -0,0 +1,28 @@ +:: This script will find and finish strong-naming any DLLs with a provided PFX certificate + +:: Requirements: +:: - dotnet is installed on the machine and is accessible everywhere (added to PATH) (might be in C:\Program Files\dotnet) +:: - sn.exe is installed on the machine and is accessible everywhere (added to PATH) + +@ECHO OFF + +:: Parse command line arguments +SET certFile=%1 + +:: Strong-name all DLLs found in the lib folder +@ECHO: +@ECHO Strong-naming (finishing delayed signing) DLLs with %certFile%... +FOR /R "lib" %%F IN (*.dll) DO ( + REM sn erroneously triggers command failed if we put a fallback on this + sn -Ra "%%F" %certFile% +) + +EXIT /B 0 + +:commandFailed +@ECHO Command failed. +GOTO :exitWithError + +:exitWithError +@ECHO Exiting... +EXIT /B 1