windows: fix constant value of WTD_STATEACTION_VERIFY A 0x01 was mistakenly changed to 0x10. This commit rectifies the issue, while also adding a test to ensure this functionality is behaving as expected. Fixes golang/go#46906 Change-Id: I833fe03e69a71283b4f7abb6cf640574d03f5d24 Reviewed-on: https://go-review.googlesource.com/c/sys/+/331010 Trust: Jason A. Donenfeld <Jason@zx2c4.com> Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index 0aaa0a3..fd75c09 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go
@@ -624,3 +624,80 @@ } } } + +func TestWinVerifyTrust(t *testing.T) { + system32, err := windows.GetSystemDirectory() + if err != nil { + t.Errorf("unable to find system32 directory: %v", err) + } + ntoskrnl := filepath.Join(system32, "ntoskrnl.exe") + ntoskrnl16, err := windows.UTF16PtrFromString(ntoskrnl) + if err != nil { + t.Fatalf("unable to get utf16 of ntoskrnl.exe: %v", err) + } + data := &windows.WinTrustData{ + Size: uint32(unsafe.Sizeof(windows.WinTrustData{})), + UIChoice: windows.WTD_UI_NONE, + RevocationChecks: windows.WTD_REVOKE_NONE, // No revocation checking, in case the tests don't have network connectivity. + UnionChoice: windows.WTD_CHOICE_FILE, + StateAction: windows.WTD_STATEACTION_VERIFY, + FileOrCatalogOrBlobOrSgnrOrCert: unsafe.Pointer(&windows.WinTrustFileInfo{ + Size: uint32(unsafe.Sizeof(windows.WinTrustFileInfo{})), + FilePath: ntoskrnl16, + }), + } + verifyErr := windows.WinVerifyTrustEx(windows.InvalidHWND, &windows.WINTRUST_ACTION_GENERIC_VERIFY_V2, data) + data.StateAction = windows.WTD_STATEACTION_CLOSE + closeErr := windows.WinVerifyTrustEx(windows.InvalidHWND, &windows.WINTRUST_ACTION_GENERIC_VERIFY_V2, data) + if verifyErr != nil { + t.Errorf("ntoskrnl.exe did not verify: %v", verifyErr) + } + if closeErr != nil { + t.Errorf("unable to free verification resources: %v", closeErr) + } + + // Now that we've verified legitimate ntoskrnl.exe verifies, let's corrupt it and see if it correctly fails. + + dir, err := ioutil.TempDir("", "go-build") + if err != nil { + t.Fatalf("failed to create temp directory: %v", err) + } + defer os.RemoveAll(dir) + corruptedNtoskrnl := filepath.Join(dir, "ntoskrnl.exe") + ntoskrnlBytes, err := ioutil.ReadFile(ntoskrnl) + if err != nil { + t.Fatalf("unable to read ntoskrnl.exe bytes: %v", err) + } + if len(ntoskrnlBytes) > 0 { + ntoskrnlBytes[len(ntoskrnlBytes)/2-1]++ + } + err = ioutil.WriteFile(corruptedNtoskrnl, ntoskrnlBytes, 0755) + if err != nil { + t.Fatalf("unable to write corrupted ntoskrnl.exe bytes: %v", err) + } + ntoskrnl16, err = windows.UTF16PtrFromString(corruptedNtoskrnl) + if err != nil { + t.Fatalf("unable to get utf16 of ntoskrnl.exe: %v", err) + } + data = &windows.WinTrustData{ + Size: uint32(unsafe.Sizeof(windows.WinTrustData{})), + UIChoice: windows.WTD_UI_NONE, + RevocationChecks: windows.WTD_REVOKE_NONE, // No revocation checking, in case the tests don't have network connectivity. + UnionChoice: windows.WTD_CHOICE_FILE, + StateAction: windows.WTD_STATEACTION_VERIFY, + FileOrCatalogOrBlobOrSgnrOrCert: unsafe.Pointer(&windows.WinTrustFileInfo{ + Size: uint32(unsafe.Sizeof(windows.WinTrustFileInfo{})), + FilePath: ntoskrnl16, + }), + } + verifyErr = windows.WinVerifyTrustEx(windows.InvalidHWND, &windows.WINTRUST_ACTION_GENERIC_VERIFY_V2, data) + data.StateAction = windows.WTD_STATEACTION_CLOSE + closeErr = windows.WinVerifyTrustEx(windows.InvalidHWND, &windows.WINTRUST_ACTION_GENERIC_VERIFY_V2, data) + if verifyErr != windows.Errno(windows.TRUST_E_BAD_DIGEST) { + t.Errorf("ntoskrnl.exe did not fail to verify as expected: %v", verifyErr) + } + if closeErr != nil { + t.Errorf("unable to free verification resources: %v", closeErr) + } + +}
diff --git a/windows/types_windows.go b/windows/types_windows.go index 1f73339..17f0331 100644 --- a/windows/types_windows.go +++ b/windows/types_windows.go
@@ -680,7 +680,7 @@ WTD_CHOICE_CERT = 5 WTD_STATEACTION_IGNORE = 0x00000000 - WTD_STATEACTION_VERIFY = 0x00000010 + WTD_STATEACTION_VERIFY = 0x00000001 WTD_STATEACTION_CLOSE = 0x00000002 WTD_STATEACTION_AUTO_CACHE = 0x00000003 WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004