Handle updating root certs ourselves

Eliminates dependency on updroots.exe, and way faster too.
This commit is contained in:
Adam Demasi 2024-10-22 18:39:53 +10:30
parent 06088da68d
commit e8c0308c37
No known key found for this signature in database
GPG key ID: 5D3B26B3D58C7D91
6 changed files with 98 additions and 25 deletions

View file

@ -39,15 +39,6 @@ In the WSL environment, run the following command to install build dependencies.
sudo apt install make nsis nsis-pluginapi mingw-w64-i686-dev
```
You will also need to extract a copy of updroots.exe from [this update](http://download.windowsupdate.com/d/msdownload/update/software/secu/2015/03/rvkroots_3f2ce4676450c06f109b5b4e68bec252873ccc21.exe). You can do this manually using 7-Zip, placing the exe at `setup/updroots.exe`, or run the following in WSL:
```bash
sudo apt install cabextract
curl -L http://download.windowsupdate.com/d/msdownload/update/software/secu/2015/03/rvkroots_3f2ce4676450c06f109b5b4e68bec252873ccc21.exe -o /tmp/rvkroots.exe
cabextract -d setup -F updroots.exe /tmp/rvkroots.exe
rm /tmp/rvkroots.exe
```
When opening the solution for the first time, Visual Studio will ask if you want to retarget it against the latest Windows SDK. Select No Upgrade.
### Testing

View file

@ -69,7 +69,8 @@ LDFLAGS = \
-loleaut32 \
-ladvapi32 \
-lgdi32 \
-lmsimg32
-lmsimg32 \
-lcrypt32
RCFLAGS = \
-F pe-i386 \

69
nsisplugin/UpdateRoots.c Normal file
View file

@ -0,0 +1,69 @@
#include <windows.h>
#include <nsis/pluginapi.h>
#include <wincrypt.h>
#include "HResult.h"
PLUGIN_METHOD(UpdateRoots) {
PLUGIN_INIT();
HRESULT hr = E_FAIL;
WCHAR stateStr[1024], store[1024], path[1024];
popstring(stateStr);
popstring(store);
popstring(path);
if (!stateStr || !store || !path) {
pushint(E_INVALIDARG);
return;
}
BOOL add;
if (lstrcmpi(stateStr, L"/update") == 0) {
add = TRUE;
} else if (lstrcmpi(stateStr, L"/delete") == 0) {
add = FALSE;
} else {
pushint(E_INVALIDARG);
return;
}
HCERTSTORE srcStore = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, CERT_STORE_READONLY_FLAG, path);
if (!srcStore) {
TRACE(L"CertOpenStore for %ls failed: %08x", path, hr);
hr = HRESULT_FROM_WIN32(GetLastError());
goto end;
}
HCERTSTORE dstStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, store);
if (!dstStore) {
hr = HRESULT_FROM_WIN32(GetLastError());
TRACE(L"CertOpenStore for %ls failed: %08x", store, hr);
goto end;
}
PCCERT_CONTEXT cert = NULL;
while ((cert = CertEnumCertificatesInStore(srcStore, cert)) != NULL) {
BOOL result = add
? CertAddCertificateContextToStore(dstStore, cert, CERT_STORE_ADD_REPLACE_EXISTING, NULL)
: CertDeleteCertificateFromStore(CertDuplicateCertificateContext(cert));
if (!result) {
TRACE(L"cert %ls in %ls failed: %d\n", add ? L"add" : L"delete", store, GetLastError());
hr = HRESULT_FROM_WIN32(GetLastError());
goto end;
}
}
hr = S_OK;
end:
if (srcStore) {
CertCloseStore(srcStore, 0);
}
if (dstStore) {
CertCloseStore(dstStore, 0);
}
pushint(hr);
}

View file

@ -114,6 +114,7 @@ LangString Update ${LANG_ENGLISH} "Update"
LangString PrepTool ${LANG_ENGLISH} "Preparation Tool"
LangString PUS ${LANG_ENGLISH} "Platform Update Supplement"
LangString SHA2 ${LANG_ENGLISH} "SHA-2 Code Signing Support Update"
LangString CTL ${LANG_ENGLISH} "Certificate Trust List"
LangString SectionWES09 ${LANG_ENGLISH} "Enable Windows Embedded 2009 updates"
LangString SectionWHS2011U4 ${LANG_ENGLISH} "Windows Home Server 2011 Update Rollup 4"

View file

@ -53,24 +53,36 @@ Function ConfigureCrypto
FunctionEnd
!macro _DownloadSST name
!insertmacro Download "Certificate Trust List (${name})" "${TRUSTEDR}/${name}.sst" "${name}.sst" 0
!insertmacro Download "$(CTL) (${name})" "${TRUSTEDR}/${name}.sst" "${name}.sst" 0
!macroend
Function DownloadRoots
!insertmacro DetailPrint "$(Downloading)Certificate Trust List..."
!insertmacro _DownloadSST "authroots"
!insertmacro _DownloadSST "delroots"
!insertmacro _DownloadSST "roots"
!insertmacro _DownloadSST "updroots"
!insertmacro _DownloadSST "disallowedcert"
!insertmacro DetailPrint "$(Downloading)$(CTL)..."
!insertmacro _DownloadSST authroots
!insertmacro _DownloadSST delroots
!insertmacro _DownloadSST roots
!insertmacro _DownloadSST updroots
!insertmacro _DownloadSST disallowedcert
FunctionEnd
!macro _InstallRoots state store file
LegacyUpdateNSIS::UpdateRoots ${state} ${store} "${file}"
Pop $0
${If} $0 != 0
LegacyUpdateNSIS::MessageForHresult $0
Pop $1
StrCpy $2 "$(CTL) (${file})"
MessageBox MB_USERICON "$(MsgBoxInstallFailed)" /SD IDOK
SetErrorLevel $0
Abort
${EndIf}
!macroend
Function UpdateRoots
File "updroots.exe"
!insertmacro DetailPrint "$(Installing)Certificate Trust List..."
!insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" authroots.sst'
!insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" updroots.sst'
!insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" -l roots.sst'
!insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" -d delroots.sst'
!insertmacro ExecWithErrorHandling "Certificate Trust List" '"$OUTDIR\updroots.exe" -l -u disallowedcert.sst'
!insertmacro DetailPrint "$(Installing)$(CTL)..."
!insertmacro _InstallRoots /update AuthRoot authroots.sst
!insertmacro _InstallRoots /update AuthRoot updroots.sst
!insertmacro _InstallRoots /update Root roots.sst
!insertmacro _InstallRoots /delete AuthRoot delroots.sst
!insertmacro _InstallRoots /update Disallowed disallowedcert.sst
FunctionEnd

View file

@ -33,7 +33,6 @@ ReserveFile "..\${VSBUILD32}\LegacyUpdate.dll"
ReserveFile "..\x64\${VSBUILD64}\LegacyUpdate.dll"
ReserveFile "..\launcher\obj\LegacyUpdate32.exe"
ReserveFile "..\launcher\obj\LegacyUpdate64.exe"
ReserveFile "updroots.exe"
Var /GLOBAL UninstallInstalled