mirror of
https://github.com/golang/sys.git
synced 2026-01-29 07:02:06 +03:00
windows: re-enable TestWinVerifyTrust with newly signed file
Rather than disabling this test, let's just not make it rely on Microsoft files, whose signing validity period we can't depend on. Instead, we include our own EV-signed artifact, with a Digicert timestamp using a certificate valid for a decade. Fixes golang/go#49651. Fixes golang/go#49266. For golang/go#46906. Change-Id: Idadba346810017b8f769d6fac1ddd357d4dee93c Reviewed-on: https://go-review.googlesource.com/c/sys/+/366655 Trust: Jason A. Donenfeld <Jason@zx2c4.com> Trust: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> Reviewed-by: Bryan C. Mills <bcmills@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
@@ -627,16 +627,10 @@ func TestCommandLineRecomposition(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWinVerifyTrust(t *testing.T) {
|
||||
t.Skip("skipping fragile test; see https://golang.org/issue/49266 and https://golang.org/issue/49651")
|
||||
|
||||
system32, err := windows.GetSystemDirectory()
|
||||
evsignedfile := `.\testdata\ev-signed-file.exe`
|
||||
evsignedfile16, err := windows.UTF16PtrFromString(evsignedfile)
|
||||
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)
|
||||
t.Fatalf("unable to get utf16 of %s: %v", evsignedfile, err)
|
||||
}
|
||||
data := &windows.WinTrustData{
|
||||
Size: uint32(unsafe.Sizeof(windows.WinTrustData{})),
|
||||
@@ -646,39 +640,39 @@ func TestWinVerifyTrust(t *testing.T) {
|
||||
StateAction: windows.WTD_STATEACTION_VERIFY,
|
||||
FileOrCatalogOrBlobOrSgnrOrCert: unsafe.Pointer(&windows.WinTrustFileInfo{
|
||||
Size: uint32(unsafe.Sizeof(windows.WinTrustFileInfo{})),
|
||||
FilePath: ntoskrnl16,
|
||||
FilePath: evsignedfile16,
|
||||
}),
|
||||
}
|
||||
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)
|
||||
t.Errorf("%s did not verify: %v", evsignedfile, 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.
|
||||
// Now that we've verified the legitimate file 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)
|
||||
corruptedEvsignedfile := filepath.Join(dir, "corrupted-file")
|
||||
evsignedfileBytes, err := ioutil.ReadFile(evsignedfile)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to read ntoskrnl.exe bytes: %v", err)
|
||||
t.Fatalf("unable to read %s bytes: %v", evsignedfile, err)
|
||||
}
|
||||
if len(ntoskrnlBytes) > 0 {
|
||||
ntoskrnlBytes[len(ntoskrnlBytes)/2-1]++
|
||||
if len(evsignedfileBytes) > 0 {
|
||||
evsignedfileBytes[len(evsignedfileBytes)/2-1]++
|
||||
}
|
||||
err = ioutil.WriteFile(corruptedNtoskrnl, ntoskrnlBytes, 0755)
|
||||
err = ioutil.WriteFile(corruptedEvsignedfile, evsignedfileBytes, 0755)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to write corrupted ntoskrnl.exe bytes: %v", err)
|
||||
}
|
||||
ntoskrnl16, err = windows.UTF16PtrFromString(corruptedNtoskrnl)
|
||||
evsignedfile16, err = windows.UTF16PtrFromString(corruptedEvsignedfile)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get utf16 of ntoskrnl.exe: %v", err)
|
||||
}
|
||||
@@ -690,14 +684,14 @@ func TestWinVerifyTrust(t *testing.T) {
|
||||
StateAction: windows.WTD_STATEACTION_VERIFY,
|
||||
FileOrCatalogOrBlobOrSgnrOrCert: unsafe.Pointer(&windows.WinTrustFileInfo{
|
||||
Size: uint32(unsafe.Sizeof(windows.WinTrustFileInfo{})),
|
||||
FilePath: ntoskrnl16,
|
||||
FilePath: evsignedfile16,
|
||||
}),
|
||||
}
|
||||
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)
|
||||
t.Errorf("%s did not fail to verify as expected: %v", corruptedEvsignedfile, verifyErr)
|
||||
}
|
||||
if closeErr != nil {
|
||||
t.Errorf("unable to free verification resources: %v", closeErr)
|
||||
|
||||
21
windows/testdata/README
vendored
Normal file
21
windows/testdata/README
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
This folder contains various pre-generated artifacts for testing. Descriptions
|
||||
of each follow below.
|
||||
|
||||
## ev-signed-file.exe
|
||||
|
||||
This was generated with:
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("Hello Gophers!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
And then a simple clang/mingw compilation:
|
||||
|
||||
i686-w64-mingw32-gcc -Os -s a.c
|
||||
|
||||
After, it was copied to a Windows computer where it was signed with an EV
|
||||
certificate using:
|
||||
|
||||
signtool sign /sha1 <ID of certificate> /fd sha256 /tr http://timestamp.digicert.com /td sha256 /d "Go Project EV Signing Test" a.exe
|
||||
BIN
windows/testdata/ev-signed-file.exe
vendored
Normal file
BIN
windows/testdata/ev-signed-file.exe
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user