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>
diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go
index f6776d8..0e4666b 100644
--- a/windows/syscall_windows_test.go
+++ b/windows/syscall_windows_test.go
@@ -627,16 +627,10 @@
 }
 
 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 @@
 		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 @@
 		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)
diff --git a/windows/testdata/README b/windows/testdata/README
new file mode 100644
index 0000000..07cc50f
--- /dev/null
+++ b/windows/testdata/README
@@ -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
diff --git a/windows/testdata/ev-signed-file.exe b/windows/testdata/ev-signed-file.exe
new file mode 100644
index 0000000..916edfa
--- /dev/null
+++ b/windows/testdata/ev-signed-file.exe
Binary files differ