[dev.boringcrypto.go1.13] all: merge go1.13.14 into dev.boringcrypto.go1.13

Change-Id: Ie532ad15830ecdd60f6223369b3cf11e9834f296
diff --git a/src/cmd/compile/internal/ssa/deadstore.go b/src/cmd/compile/internal/ssa/deadstore.go
index 69616b3..1cbba02 100644
--- a/src/cmd/compile/internal/ssa/deadstore.go
+++ b/src/cmd/compile/internal/ssa/deadstore.go
@@ -73,9 +73,11 @@
 		}
 
 		// Walk backwards looking for dead stores. Keep track of shadowed addresses.
-		// An "address" is an SSA Value which encodes both the address and size of
-		// the write. This code will not remove dead stores to the same address
-		// of different types.
+		// A "shadowed address" is a pointer and a size describing a memory region that
+		// is known to be written. We keep track of shadowed addresses in the shadowed
+		// map, mapping the ID of the address to the size of the shadowed region.
+		// Since we're walking backwards, writes to a shadowed region are useless,
+		// as they will be immediately overwritten.
 		shadowed.clear()
 		v := last
 
@@ -93,17 +95,13 @@
 				sz = v.AuxInt
 			}
 			if shadowedSize := int64(shadowed.get(v.Args[0].ID)); shadowedSize != -1 && shadowedSize >= sz {
-				// Modify store into a copy
+				// Modify the store/zero into a copy of the memory state,
+				// effectively eliding the store operation.
 				if v.Op == OpStore {
 					// store addr value mem
 					v.SetArgs1(v.Args[2])
 				} else {
 					// zero addr mem
-					typesz := v.Args[0].Type.Elem().Size()
-					if sz != typesz {
-						f.Fatalf("mismatched zero/store sizes: %d and %d [%s]",
-							sz, typesz, v.LongString())
-					}
 					v.SetArgs1(v.Args[1])
 				}
 				v.Aux = nil
diff --git a/src/cmd/compile/internal/ssa/debug_test.go b/src/cmd/compile/internal/ssa/debug_test.go
index 73a0afb..d3aaa48 100644
--- a/src/cmd/compile/internal/ssa/debug_test.go
+++ b/src/cmd/compile/internal/ssa/debug_test.go
@@ -49,11 +49,11 @@
 // optimizedLibs usually means "not running in a noopt test builder".
 var optimizedLibs = (!strings.Contains(gogcflags, "-N") && !strings.Contains(gogcflags, "-l"))
 
-// TestNexting go-builds a file, then uses a debugger (default gdb, optionally delve)
+// TestNexting go-builds a file, then uses a debugger (default delve, optionally gdb)
 // to next through the generated executable, recording each line landed at, and
 // then compares those lines with reference file(s).
 // Flag -u updates the reference file(s).
-// Flag -d changes the debugger to delve (and uses delve-specific reference files)
+// Flag -g changes the debugger to gdb (and uses gdb-specific reference files)
 // Flag -v is ever-so-slightly verbose.
 // Flag -n is for dry-run, and prints the shell and first debug commands.
 //
@@ -83,9 +83,9 @@
 // to indicate normalization of Strings, (hex) addresses, and numbers.
 // "O" is an explicit indication that we expect it to be optimized out.
 // For example:
-/*
-	if len(os.Args) > 1 { //gdb-dbg=(hist/A,cannedInput/A) //dlv-dbg=(hist/A,cannedInput/A)
-*/
+//
+// 	if len(os.Args) > 1 { //gdb-dbg=(hist/A,cannedInput/A) //dlv-dbg=(hist/A,cannedInput/A)
+//
 // TODO: not implemented for Delve yet, but this is the plan
 //
 // After a compiler change that causes a difference in the debug behavior, check
@@ -93,7 +93,7 @@
 // go test debug_test.go -args -u
 // (for Delve)
 // go test debug_test.go -args -u -d
-
+//
 func TestNexting(t *testing.T) {
 	skipReasons := "" // Many possible skip reasons, list all that apply
 	if testing.Short() {
@@ -108,7 +108,13 @@
 		// Various architectures tend to differ slightly sometimes, and keeping them
 		// all in sync is a pain for people who don't have them all at hand,
 		// so limit testing to amd64 (for now)
-		skipReasons += "not run when testing gdb (-g) unless forced (-f) or linux-amd64"
+		skipReasons += "not run when testing gdb (-g) unless forced (-f) or linux-amd64; "
+	}
+
+	if !*useGdb && !*force && testenv.Builder() == "linux-386-longtest" {
+		// The latest version of Delve does support linux/386. However, the version currently
+		// installed in the linux-386-longtest builder does not. See golang.org/issue/39309.
+		skipReasons += "not run when testing delve on linux-386-longtest builder unless forced (-f); "
 	}
 
 	if *useGdb {
diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index 19496a3..05d995f 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -8,5 +8,5 @@
 	golang.org/x/arch v0.0.0-20190815191158-8a70ba74b3a1
 	golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c
 	golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 // indirect
-	golang.org/x/tools v0.0.0-20190611154301-25a4f137592f
+	golang.org/x/tools v0.0.0-20200615191743-991d59a616de
 )
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index 9aa94ee..44c1ac8 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -15,6 +15,6 @@
 golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190611154301-25a4f137592f h1:6awn5JC4pwVI5HiBqs7MDtRxnwV9PpO5iSA9v6P09pA=
-golang.org/x/tools v0.0.0-20190611154301-25a4f137592f/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20200615191743-991d59a616de h1:kFKSx8iHlOzmtGWtfJW+b2UzcJ+rMWHHyUBpjrZq8To=
+golang.org/x/tools v0.0.0-20200615191743-991d59a616de/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 5d8a717..1c79226 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -4886,45 +4886,6 @@
 	tg.grepBothNot("PASS", "something passed")
 }
 
-// Issue 9737: verify that GOARM and GO386 affect the computed build ID.
-func TestBuildIDContainsArchModeEnv(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-
-	var tg *testgoData
-	testWith := func(before, after func()) func(*testing.T) {
-		return func(t *testing.T) {
-			tg = testgo(t)
-			defer tg.cleanup()
-			tg.tempFile("src/mycmd/x.go", `package main
-func main() {}`)
-			tg.setenv("GOPATH", tg.path("."))
-
-			tg.cd(tg.path("src/mycmd"))
-			tg.setenv("GOOS", "linux")
-			before()
-			tg.run("install", "mycmd")
-			after()
-			tg.wantStale("mycmd", "stale dependency", "should be stale after environment variable change")
-		}
-	}
-
-	t.Run("386", testWith(func() {
-		tg.setenv("GOARCH", "386")
-		tg.setenv("GO386", "387")
-	}, func() {
-		tg.setenv("GO386", "sse2")
-	}))
-
-	t.Run("arm", testWith(func() {
-		tg.setenv("GOARCH", "arm")
-		tg.setenv("GOARM", "5")
-	}, func() {
-		tg.setenv("GOARM", "7")
-	}))
-}
-
 func TestTestRegexps(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
diff --git a/src/cmd/go/testdata/script/build_cache_arch_mode.txt b/src/cmd/go/testdata/script/build_cache_arch_mode.txt
new file mode 100644
index 0000000..7e751d0
--- /dev/null
+++ b/src/cmd/go/testdata/script/build_cache_arch_mode.txt
@@ -0,0 +1,27 @@
+# Issue 9737: verify that GOARM and GO386 affect the computed build ID
+
+[short] skip
+
+# 386
+cd $GOPATH/src/mycmd
+env GOOS=linux
+env GOARCH=386
+env GO386=387
+go install mycmd
+env GO386=sse2
+stale mycmd
+
+# arm
+cd $GOPATH/src/mycmd
+env GOOS=linux
+env GOARCH=arm
+env GOARM=5
+go install mycmd
+env GOARM=7
+stale mycmd
+
+
+-- mycmd/x.go --
+package main
+
+func main() {}
\ No newline at end of file
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
index f59e95d..5f9f771 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
@@ -722,7 +722,7 @@
 	// '#' is alternate format for several verbs.
 	// ' ' is spacer for numbers
 	{'%', noFlag, 0},
-	{'b', numFlag, argInt | argFloat | argComplex | argPointer},
+	{'b', sharpNumFlag, argInt | argFloat | argComplex | argPointer},
 	{'c', "-", argRune | argInt},
 	{'d', numFlag, argInt | argPointer},
 	{'e', sharpNumFlag, argFloat | argComplex},
@@ -732,6 +732,7 @@
 	{'g', sharpNumFlag, argFloat | argComplex},
 	{'G', sharpNumFlag, argFloat | argComplex},
 	{'o', sharpNumFlag, argInt | argPointer},
+	{'O', sharpNumFlag, argInt | argPointer},
 	{'p', "-#", argPointer},
 	{'q', " -+.0#", argRune | argInt | argString},
 	{'s', " -+.0", argString},
@@ -740,8 +741,8 @@
 	{'U', "-#", argRune | argInt},
 	{'v', allFlags, anyType},
 	{'w', noFlag, anyType},
-	{'x', sharpNumFlag, argRune | argInt | argString | argPointer},
-	{'X', sharpNumFlag, argRune | argInt | argString | argPointer},
+	{'x', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex},
+	{'X', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex},
 }
 
 // okPrintfArg compares the formatState to the arguments actually present,
diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt
index e873ad4..8c3ed65 100644
--- a/src/cmd/vendor/modules.txt
+++ b/src/cmd/vendor/modules.txt
@@ -26,7 +26,7 @@
 # golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82
 golang.org/x/sys/unix
 golang.org/x/sys/windows
-# golang.org/x/tools v0.0.0-20190611154301-25a4f137592f
+# golang.org/x/tools v0.0.0-20200615191743-991d59a616de
 golang.org/x/tools/go/analysis
 golang.org/x/tools/go/analysis/internal/analysisflags
 golang.org/x/tools/go/analysis/internal/facts
diff --git a/src/cmd/vet/testdata/print/print.go b/src/cmd/vet/testdata/print/print.go
index 7a4783a..fca5949 100644
--- a/src/cmd/vet/testdata/print/print.go
+++ b/src/cmd/vet/testdata/print/print.go
@@ -81,8 +81,8 @@
 	fmt.Printf("%T %T", 3, i)
 	fmt.Printf("%U %U", 3, i)
 	fmt.Printf("%v %v", 3, i)
-	fmt.Printf("%x %x %x %x", 3, i, "hi", s)
-	fmt.Printf("%X %X %X %X", 3, i, "hi", s)
+	fmt.Printf("%x %x %x %x %x %x %x", 3, i, "hi", s, x, c, fslice)
+	fmt.Printf("%X %X %X %X %X %X %X", 3, i, "hi", s, x, c, fslice)
 	fmt.Printf("%.*s %d %g", 3, "hi", 23, 2.3)
 	fmt.Printf("%s", &stringerv)
 	fmt.Printf("%v", &stringerv)
@@ -125,7 +125,6 @@
 	fmt.Printf("%t", 23)                        // ERROR "Printf format %t has arg 23 of wrong type int"
 	fmt.Printf("%U", x)                         // ERROR "Printf format %U has arg x of wrong type float64"
 	fmt.Printf("%x", nil)                       // ERROR "Printf format %x has arg nil of wrong type untyped nil"
-	fmt.Printf("%X", 2.3)                       // ERROR "Printf format %X has arg 2.3 of wrong type float64"
 	fmt.Printf("%s", stringerv)                 // ERROR "Printf format %s has arg stringerv of wrong type .*print.ptrStringer"
 	fmt.Printf("%t", stringerv)                 // ERROR "Printf format %t has arg stringerv of wrong type .*print.ptrStringer"
 	fmt.Printf("%s", embeddedStringerv)         // ERROR "Printf format %s has arg embeddedStringerv of wrong type .*print.embeddedStringer"
diff --git a/src/crypto/x509/root_windows.go b/src/crypto/x509/root_windows.go
index ebf159c..94669f2 100644
--- a/src/crypto/x509/root_windows.go
+++ b/src/crypto/x509/root_windows.go
@@ -88,6 +88,9 @@
 		switch status {
 		case syscall.CERT_TRUST_IS_NOT_TIME_VALID:
 			return CertificateInvalidError{c, Expired, ""}
+		case syscall.CERT_TRUST_IS_NOT_VALID_FOR_USAGE:
+			return CertificateInvalidError{c, IncompatibleUsage, ""}
+		// TODO(filippo): surface more error statuses.
 		default:
 			return UnknownAuthorityError{c, nil, nil}
 		}
@@ -138,11 +141,19 @@
 	return nil
 }
 
+// windowsExtKeyUsageOIDs are the C NUL-terminated string representations of the
+// OIDs for use with the Windows API.
+var windowsExtKeyUsageOIDs = make(map[ExtKeyUsage][]byte, len(extKeyUsageOIDs))
+
+func init() {
+	for _, eku := range extKeyUsageOIDs {
+		windowsExtKeyUsageOIDs[eku.extKeyUsage] = []byte(eku.oid.String() + "\x00")
+	}
+}
+
 // systemVerify is like Verify, except that it uses CryptoAPI calls
 // to build certificate chains and verify them.
 func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
-	hasDNSName := opts != nil && len(opts.DNSName) > 0
-
 	storeCtx, err := createStoreContext(c, opts)
 	if err != nil {
 		return nil, err
@@ -152,17 +163,26 @@
 	para := new(syscall.CertChainPara)
 	para.Size = uint32(unsafe.Sizeof(*para))
 
-	// If there's a DNSName set in opts, assume we're verifying
-	// a certificate from a TLS server.
-	if hasDNSName {
-		oids := []*byte{
-			&syscall.OID_PKIX_KP_SERVER_AUTH[0],
-			// Both IE and Chrome allow certificates with
-			// Server Gated Crypto as well. Some certificates
-			// in the wild require them.
-			&syscall.OID_SERVER_GATED_CRYPTO[0],
-			&syscall.OID_SGC_NETSCAPE[0],
+	keyUsages := opts.KeyUsages
+	if len(keyUsages) == 0 {
+		keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
+	}
+	oids := make([]*byte, 0, len(keyUsages))
+	for _, eku := range keyUsages {
+		if eku == ExtKeyUsageAny {
+			oids = nil
+			break
 		}
+		if oid, ok := windowsExtKeyUsageOIDs[eku]; ok {
+			oids = append(oids, &oid[0])
+		}
+		// Like the standard verifier, accept SGC EKUs as equivalent to ServerAuth.
+		if eku == ExtKeyUsageServerAuth {
+			oids = append(oids, &syscall.OID_SERVER_GATED_CRYPTO[0])
+			oids = append(oids, &syscall.OID_SGC_NETSCAPE[0])
+		}
+	}
+	if oids != nil {
 		para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_OR
 		para.RequestedUsage.Usage.Length = uint32(len(oids))
 		para.RequestedUsage.Usage.UsageIdentifiers = &oids[0]
@@ -208,7 +228,7 @@
 		return nil, err
 	}
 
-	if hasDNSName {
+	if opts != nil && len(opts.DNSName) > 0 {
 		err = checkChainSSLServerPolicy(c, chainCtx, opts)
 		if err != nil {
 			return nil, err
diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
index a30f644..5a60532 100644
--- a/src/crypto/x509/verify.go
+++ b/src/crypto/x509/verify.go
@@ -193,23 +193,32 @@
 	// can be used for constructing verification chains.
 	IsBoring func(*Certificate) bool
 
-	DNSName       string
+	// DNSName, if set, is checked against the leaf certificate with
+	// Certificate.VerifyHostname or the platform verifier.
+	DNSName string
+
+	// Intermediates is an optional pool of certificates that are not trust
+	// anchors, but can be used to form a chain from the leaf certificate to a
+	// root certificate.
 	Intermediates *CertPool
-	Roots         *CertPool // if nil, the system roots are used
-	CurrentTime   time.Time // if zero, the current time is used
-	// KeyUsage specifies which Extended Key Usage values are acceptable. A leaf
-	// certificate is accepted if it contains any of the listed values. An empty
-	// list means ExtKeyUsageServerAuth. To accept any key usage, include
-	// ExtKeyUsageAny.
-	//
-	// Certificate chains are required to nest these extended key usage values.
-	// (This matches the Windows CryptoAPI behavior, but not the spec.)
+	// Roots is the set of trusted root certificates the leaf certificate needs
+	// to chain up to. If nil, the system roots or the platform verifier are used.
+	Roots *CertPool
+
+	// CurrentTime is used to check the validity of all certificates in the
+	// chain. If zero, the current time is used.
+	CurrentTime time.Time
+
+	// KeyUsages specifies which Extended Key Usage values are acceptable. A
+	// chain is accepted if it allows any of the listed values. An empty list
+	// means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny.
 	KeyUsages []ExtKeyUsage
+
 	// MaxConstraintComparisions is the maximum number of comparisons to
 	// perform when checking a given certificate's name constraints. If
 	// zero, a sensible default is used. This limit prevents pathological
 	// certificates from consuming excessive amounts of CPU time when
-	// validating.
+	// validating. It does not apply to the platform verifier.
 	MaxConstraintComparisions int
 }
 
@@ -719,8 +728,9 @@
 // needed. If successful, it returns one or more chains where the first
 // element of the chain is c and the last element is from opts.Roots.
 //
-// If opts.Roots is nil and system roots are unavailable the returned error
-// will be of type SystemRootsError.
+// If opts.Roots is nil, the platform verifier might be used, and
+// verification details might differ from what is described below. If system
+// roots are unavailable the returned error will be of type SystemRootsError.
 //
 // Name constraints in the intermediates will be applied to all names claimed
 // in the chain, not just opts.DNSName. Thus it is invalid for a leaf to claim
@@ -728,9 +738,11 @@
 // the name being validated. Note that DirectoryName constraints are not
 // supported.
 //
-// Extended Key Usage values are enforced down a chain, so an intermediate or
-// root that enumerates EKUs prevents a leaf from asserting an EKU not in that
-// list.
+//
+// Extended Key Usage values are enforced nested down a chain, so an intermediate
+// or root that enumerates EKUs prevents a leaf from asserting an EKU not in that
+// list. (While this is not specified, it is common practice in order to limit
+// the types of certificates a CA can issue.)
 //
 // WARNING: this function doesn't do any revocation checking.
 func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
index 86fe76a..bbb68db 100644
--- a/src/crypto/x509/verify_test.go
+++ b/src/crypto/x509/verify_test.go
@@ -21,34 +21,24 @@
 )
 
 type verifyTest struct {
-	leaf                 string
-	intermediates        []string
-	roots                []string
-	currentTime          int64
-	dnsName              string
-	systemSkip           bool
-	keyUsages            []ExtKeyUsage
-	testSystemRootsError bool
-	sha2                 bool
-	ignoreCN             bool
+	name          string
+	leaf          string
+	intermediates []string
+	roots         []string
+	currentTime   int64
+	dnsName       string
+	systemSkip    bool
+	systemLax     bool
+	keyUsages     []ExtKeyUsage
+	ignoreCN      bool
 
-	errorCallback  func(*testing.T, int, error) bool
+	errorCallback  func(*testing.T, error)
 	expectedChains [][]string
 }
 
 var verifyTests = []verifyTest{
 	{
-		leaf:                 googleLeaf,
-		intermediates:        []string{giag2Intermediate},
-		currentTime:          1395785200,
-		dnsName:              "www.google.com",
-		testSystemRootsError: true,
-
-		// Without any roots specified we should get a system roots
-		// error.
-		errorCallback: expectSystemRootsError,
-	},
-	{
+		name:          "Valid",
 		leaf:          googleLeaf,
 		intermediates: []string{giag2Intermediate},
 		roots:         []string{geoTrustRoot},
@@ -60,6 +50,7 @@
 		},
 	},
 	{
+		name:          "MixedCase",
 		leaf:          googleLeaf,
 		intermediates: []string{giag2Intermediate},
 		roots:         []string{geoTrustRoot},
@@ -71,6 +62,7 @@
 		},
 	},
 	{
+		name:          "HostnameMismatch",
 		leaf:          googleLeaf,
 		intermediates: []string{giag2Intermediate},
 		roots:         []string{geoTrustRoot},
@@ -80,6 +72,7 @@
 		errorCallback: expectHostnameError("certificate is valid for"),
 	},
 	{
+		name:          "IPMissing",
 		leaf:          googleLeaf,
 		intermediates: []string{giag2Intermediate},
 		roots:         []string{geoTrustRoot},
@@ -89,6 +82,7 @@
 		errorCallback: expectHostnameError("doesn't contain any IP SANs"),
 	},
 	{
+		name:          "Expired",
 		leaf:          googleLeaf,
 		intermediates: []string{giag2Intermediate},
 		roots:         []string{geoTrustRoot},
@@ -98,6 +92,7 @@
 		errorCallback: expectExpired,
 	},
 	{
+		name:        "MissingIntermediate",
 		leaf:        googleLeaf,
 		roots:       []string{geoTrustRoot},
 		currentTime: 1395785200,
@@ -109,6 +104,7 @@
 		errorCallback: expectAuthorityUnknown,
 	},
 	{
+		name:          "RootInIntermediates",
 		leaf:          googleLeaf,
 		intermediates: []string{geoTrustRoot, giag2Intermediate},
 		roots:         []string{geoTrustRoot},
@@ -119,31 +115,50 @@
 			{"Google", "Google Internet Authority", "GeoTrust"},
 		},
 		// CAPI doesn't build the chain with the duplicated GeoTrust
-		// entry so the results don't match. Thus we skip this test
-		// until that's fixed.
-		systemSkip: true,
+		// entry so the results don't match.
+		systemLax: true,
 	},
 	{
+		name:          "dnssec-exp",
 		leaf:          dnssecExpLeaf,
 		intermediates: []string{startComIntermediate},
 		roots:         []string{startComRoot},
 		currentTime:   1302726541,
 
-		expectedChains: [][]string{
-			{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
-		},
-	},
-	{
-		leaf:          dnssecExpLeaf,
-		intermediates: []string{startComIntermediate, startComRoot},
-		roots:         []string{startComRoot},
-		currentTime:   1302726541,
+		// The StartCom root is not trusted by Windows when the default
+		// ServerAuth EKU is requested.
+		systemSkip: true,
 
 		expectedChains: [][]string{
 			{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
 		},
 	},
 	{
+		name:          "dnssec-exp/AnyEKU",
+		leaf:          dnssecExpLeaf,
+		intermediates: []string{startComIntermediate},
+		roots:         []string{startComRoot},
+		currentTime:   1302726541,
+		keyUsages:     []ExtKeyUsage{ExtKeyUsageAny},
+
+		expectedChains: [][]string{
+			{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
+		},
+	},
+	{
+		name:          "dnssec-exp/RootInIntermediates",
+		leaf:          dnssecExpLeaf,
+		intermediates: []string{startComIntermediate, startComRoot},
+		roots:         []string{startComRoot},
+		currentTime:   1302726541,
+		systemSkip:    true, // see dnssec-exp test
+
+		expectedChains: [][]string{
+			{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
+		},
+	},
+	{
+		name:          "InvalidHash",
 		leaf:          googleLeafWithInvalidHash,
 		intermediates: []string{giag2Intermediate},
 		roots:         []string{geoTrustRoot},
@@ -152,50 +167,52 @@
 
 		// The specific error message may not occur when using system
 		// verification.
-		systemSkip:    true,
+		systemLax:     true,
 		errorCallback: expectHashError,
 	},
+	// EKULeaf tests use an unconstrained chain leading to a leaf certificate
+	// with an E-mail Protection EKU but not a Server Auth one, checking that
+	// the EKUs on the leaf are enforced.
 	{
-		// The default configuration should reject an S/MIME chain.
-		leaf:        smimeLeaf,
-		roots:       []string{smimeIntermediate},
-		currentTime: 1339436154,
+		name:          "EKULeaf",
+		leaf:          smimeLeaf,
+		intermediates: []string{smimeIntermediate},
+		roots:         []string{smimeRoot},
+		currentTime:   1594673418,
 
-		// Key usage not implemented for Windows yet.
-		systemSkip:    true,
 		errorCallback: expectUsageError,
 	},
 	{
-		leaf:        smimeLeaf,
-		roots:       []string{smimeIntermediate},
-		currentTime: 1339436154,
-		keyUsages:   []ExtKeyUsage{ExtKeyUsageServerAuth},
+		name:          "EKULeafExplicit",
+		leaf:          smimeLeaf,
+		intermediates: []string{smimeIntermediate},
+		roots:         []string{smimeRoot},
+		currentTime:   1594673418,
+		keyUsages:     []ExtKeyUsage{ExtKeyUsageServerAuth},
 
-		// Key usage not implemented for Windows yet.
-		systemSkip:    true,
 		errorCallback: expectUsageError,
 	},
 	{
-		leaf:        smimeLeaf,
-		roots:       []string{smimeIntermediate},
-		currentTime: 1339436154,
-		keyUsages:   []ExtKeyUsage{ExtKeyUsageEmailProtection},
+		name:          "EKULeafValid",
+		leaf:          smimeLeaf,
+		intermediates: []string{smimeIntermediate},
+		roots:         []string{smimeRoot},
+		currentTime:   1594673418,
+		keyUsages:     []ExtKeyUsage{ExtKeyUsageEmailProtection},
 
-		// Key usage not implemented for Windows yet.
-		systemSkip: true,
 		expectedChains: [][]string{
-			{"Ryan Hurst", "GlobalSign PersonalSign 2 CA - G2"},
+			{"CORPORATIVO FICTICIO ACTIVO", "EAEko Herri Administrazioen CA - CA AAPP Vascas (2)", "IZENPE S.A."},
 		},
 	},
 	{
+		name:          "SGCIntermediate",
 		leaf:          megaLeaf,
 		intermediates: []string{comodoIntermediate1},
 		roots:         []string{comodoRoot},
 		currentTime:   1360431182,
 
-		// CryptoAPI can find alternative validation paths so we don't
-		// perform this test with system validation.
-		systemSkip: true,
+		// CryptoAPI can find alternative validation paths.
+		systemLax: true,
 		expectedChains: [][]string{
 			{"mega.co.nz", "EssentialSSL CA", "COMODO Certification Authority"},
 		},
@@ -203,6 +220,7 @@
 	{
 		// Check that a name constrained intermediate works even when
 		// it lists multiple constraints.
+		name:          "MultipleConstraints",
 		leaf:          nameConstraintsLeaf,
 		intermediates: []string{nameConstraintsIntermediate1, nameConstraintsIntermediate2},
 		roots:         []string{globalSignRoot},
@@ -221,17 +239,16 @@
 	{
 		// Check that SHA-384 intermediates (which are popping up)
 		// work.
+		name:          "SHA-384",
 		leaf:          moipLeafCert,
 		intermediates: []string{comodoIntermediateSHA384, comodoRSAAuthority},
 		roots:         []string{addTrustRoot},
 		currentTime:   1397502195,
 		dnsName:       "api.moip.com.br",
 
-		// CryptoAPI can find alternative validation paths so we don't
-		// perform this test with system validation.
-		systemSkip: true,
+		// CryptoAPI can find alternative validation paths.
+		systemLax: true,
 
-		sha2: true,
 		expectedChains: [][]string{
 			{
 				"api.moip.com.br",
@@ -244,11 +261,12 @@
 	{
 		// Putting a certificate as a root directly should work as a
 		// way of saying “exactly this”.
+		name:        "LeafInRoots",
 		leaf:        selfSigned,
 		roots:       []string{selfSigned},
 		currentTime: 1471624472,
 		dnsName:     "foo.example",
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 
 		expectedChains: [][]string{
 			{"Acme Co"},
@@ -257,11 +275,12 @@
 	{
 		// Putting a certificate as a root directly should not skip
 		// other checks however.
+		name:        "LeafInRootsInvalid",
 		leaf:        selfSigned,
 		roots:       []string{selfSigned},
 		currentTime: 1471624472,
 		dnsName:     "notfoo.example",
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 
 		errorCallback: expectHostnameError("certificate is valid for"),
 	},
@@ -269,87 +288,95 @@
 		// The issuer name in the leaf doesn't exactly match the
 		// subject name in the root. Go does not perform
 		// canonicalization and so should reject this. See issue 14955.
+		name:        "IssuerSubjectMismatch",
 		leaf:        issuerSubjectMatchLeaf,
 		roots:       []string{issuerSubjectMatchRoot},
 		currentTime: 1475787715,
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 
 		errorCallback: expectSubjectIssuerMismatcthError,
 	},
 	{
 		// An X.509 v1 certificate should not be accepted as an
 		// intermediate.
+		name:          "X509v1Intermediate",
 		leaf:          x509v1TestLeaf,
 		intermediates: []string{x509v1TestIntermediate},
 		roots:         []string{x509v1TestRoot},
 		currentTime:   1481753183,
-		systemSkip:    true,
+		systemSkip:    true, // does not chain to a system root
 
 		errorCallback: expectNotAuthorizedError,
 	},
 	{
 		// If any SAN extension is present (even one without any DNS
 		// names), the CN should be ignored.
+		name:        "IgnoreCNWithSANs",
 		leaf:        ignoreCNWithSANLeaf,
 		dnsName:     "foo.example.com",
 		roots:       []string{ignoreCNWithSANRoot},
 		currentTime: 1486684488,
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 
 		errorCallback: expectHostnameError("certificate is not valid for any names"),
 	},
 	{
 		// Test that excluded names are respected.
+		name:          "ExcludedNames",
 		leaf:          excludedNamesLeaf,
 		dnsName:       "bender.local",
 		intermediates: []string{excludedNamesIntermediate},
 		roots:         []string{excludedNamesRoot},
 		currentTime:   1486684488,
-		systemSkip:    true,
+		systemSkip:    true, // does not chain to a system root
 
 		errorCallback: expectNameConstraintsError,
 	},
 	{
 		// Test that unknown critical extensions in a leaf cause a
 		// verify error.
+		name:          "CriticalExtLeaf",
 		leaf:          criticalExtLeafWithExt,
 		dnsName:       "example.com",
 		intermediates: []string{criticalExtIntermediate},
 		roots:         []string{criticalExtRoot},
 		currentTime:   1486684488,
-		systemSkip:    true,
+		systemSkip:    true, // does not chain to a system root
 
 		errorCallback: expectUnhandledCriticalExtension,
 	},
 	{
 		// Test that unknown critical extensions in an intermediate
 		// cause a verify error.
+		name:          "CriticalExtIntermediate",
 		leaf:          criticalExtLeaf,
 		dnsName:       "example.com",
 		intermediates: []string{criticalExtIntermediateWithExt},
 		roots:         []string{criticalExtRoot},
 		currentTime:   1486684488,
-		systemSkip:    true,
+		systemSkip:    true, // does not chain to a system root
 
 		errorCallback: expectUnhandledCriticalExtension,
 	},
 	{
 		// Test that invalid CN are ignored.
+		name:        "InvalidCN",
 		leaf:        invalidCNWithoutSAN,
 		dnsName:     "foo,invalid",
 		roots:       []string{invalidCNRoot},
 		currentTime: 1540000000,
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 
 		errorCallback: expectHostnameError("Common Name is not a valid hostname"),
 	},
 	{
 		// Test that valid CN are respected.
+		name:        "ValidCN",
 		leaf:        validCNWithoutSAN,
 		dnsName:     "foo.example.com",
 		roots:       []string{invalidCNRoot},
 		currentTime: 1540000000,
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 
 		expectedChains: [][]string{
 			{"foo.example.com", "Test root"},
@@ -357,31 +384,34 @@
 	},
 	// Replicate CN tests with ignoreCN = true
 	{
+		name:        "IgnoreCNWithSANs/ignoreCN",
 		leaf:        ignoreCNWithSANLeaf,
 		dnsName:     "foo.example.com",
 		roots:       []string{ignoreCNWithSANRoot},
 		currentTime: 1486684488,
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 		ignoreCN:    true,
 
 		errorCallback: expectHostnameError("certificate is not valid for any names"),
 	},
 	{
+		name:        "InvalidCN/ignoreCN",
 		leaf:        invalidCNWithoutSAN,
 		dnsName:     "foo,invalid",
 		roots:       []string{invalidCNRoot},
 		currentTime: 1540000000,
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 		ignoreCN:    true,
 
 		errorCallback: expectHostnameError("Common Name is not a valid hostname"),
 	},
 	{
+		name:        "ValidCN/ignoreCN",
 		leaf:        validCNWithoutSAN,
 		dnsName:     "foo.example.com",
 		roots:       []string{invalidCNRoot},
 		currentTime: 1540000000,
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 		ignoreCN:    true,
 
 		errorCallback: expectHostnameError("not valid for any names"),
@@ -389,11 +419,12 @@
 	{
 		// A certificate with an AKID should still chain to a parent without SKID.
 		// See Issue 30079.
+		name:        "AKIDNoSKID",
 		leaf:        leafWithAKID,
 		roots:       []string{rootWithoutSKID},
 		currentTime: 1550000000,
 		dnsName:     "example",
-		systemSkip:  true,
+		systemSkip:  true, // does not chain to a system root
 
 		expectedChains: [][]string{
 			{"Acme LLC", "Acme Co"},
@@ -401,98 +432,70 @@
 	},
 }
 
-func expectHostnameError(msg string) func(*testing.T, int, error) bool {
-	return func(t *testing.T, i int, err error) (ok bool) {
+func expectHostnameError(msg string) func(*testing.T, error) {
+	return func(t *testing.T, err error) {
 		if _, ok := err.(HostnameError); !ok {
-			t.Errorf("#%d: error was not a HostnameError: %v", i, err)
-			return false
+			t.Fatalf("error was not a HostnameError: %v", err)
 		}
 		if !strings.Contains(err.Error(), msg) {
-			t.Errorf("#%d: HostnameError did not contain %q: %v", i, msg, err)
+			t.Fatalf("HostnameError did not contain %q: %v", msg, err)
 		}
-		return true
 	}
 }
 
-func expectExpired(t *testing.T, i int, err error) (ok bool) {
+func expectExpired(t *testing.T, err error) {
 	if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != Expired {
-		t.Errorf("#%d: error was not Expired: %v", i, err)
-		return false
+		t.Fatalf("error was not Expired: %v", err)
 	}
-	return true
 }
 
-func expectUsageError(t *testing.T, i int, err error) (ok bool) {
+func expectUsageError(t *testing.T, err error) {
 	if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != IncompatibleUsage {
-		t.Errorf("#%d: error was not IncompatibleUsage: %v", i, err)
-		return false
+		t.Fatalf("error was not IncompatibleUsage: %v", err)
 	}
-	return true
 }
 
-func expectAuthorityUnknown(t *testing.T, i int, err error) (ok bool) {
+func expectAuthorityUnknown(t *testing.T, err error) {
 	e, ok := err.(UnknownAuthorityError)
 	if !ok {
-		t.Errorf("#%d: error was not UnknownAuthorityError: %v", i, err)
-		return false
+		t.Fatalf("error was not UnknownAuthorityError: %v", err)
 	}
 	if e.Cert == nil {
-		t.Errorf("#%d: error was UnknownAuthorityError, but missing Cert: %v", i, err)
-		return false
+		t.Fatalf("error was UnknownAuthorityError, but missing Cert: %v", err)
 	}
-	return true
 }
 
-func expectSystemRootsError(t *testing.T, i int, err error) bool {
-	if _, ok := err.(SystemRootsError); !ok {
-		t.Errorf("#%d: error was not SystemRootsError: %v", i, err)
-		return false
-	}
-	return true
-}
-
-func expectHashError(t *testing.T, i int, err error) bool {
+func expectHashError(t *testing.T, err error) {
 	if err == nil {
-		t.Errorf("#%d: no error resulted from invalid hash", i)
-		return false
+		t.Fatalf("no error resulted from invalid hash")
 	}
 	if expected := "algorithm unimplemented"; !strings.Contains(err.Error(), expected) {
-		t.Errorf("#%d: error resulting from invalid hash didn't contain '%s', rather it was: %v", i, expected, err)
-		return false
+		t.Fatalf("error resulting from invalid hash didn't contain '%s', rather it was: %v", expected, err)
 	}
-	return true
 }
 
-func expectSubjectIssuerMismatcthError(t *testing.T, i int, err error) (ok bool) {
+func expectSubjectIssuerMismatcthError(t *testing.T, err error) {
 	if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != NameMismatch {
-		t.Errorf("#%d: error was not a NameMismatch: %v", i, err)
-		return false
+		t.Fatalf("error was not a NameMismatch: %v", err)
 	}
-	return true
 }
 
-func expectNameConstraintsError(t *testing.T, i int, err error) (ok bool) {
+func expectNameConstraintsError(t *testing.T, err error) {
 	if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != CANotAuthorizedForThisName {
-		t.Errorf("#%d: error was not a CANotAuthorizedForThisName: %v", i, err)
-		return false
+		t.Fatalf("error was not a CANotAuthorizedForThisName: %v", err)
 	}
-	return true
 }
 
-func expectNotAuthorizedError(t *testing.T, i int, err error) (ok bool) {
+func expectNotAuthorizedError(t *testing.T, err error) {
 	if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != NotAuthorizedToSign {
-		t.Errorf("#%d: error was not a NotAuthorizedToSign: %v", i, err)
-		return false
+		t.Fatalf("error was not a NotAuthorizedToSign: %v", err)
 	}
-	return true
 }
 
-func expectUnhandledCriticalExtension(t *testing.T, i int, err error) (ok bool) {
+func expectUnhandledCriticalExtension(t *testing.T, err error) {
 	if _, ok := err.(UnhandledCriticalExtension); !ok {
-		t.Errorf("#%d: error was not an UnhandledCriticalExtension: %v", i, err)
-		return false
+		t.Fatalf("error was not an UnhandledCriticalExtension: %v", err)
 	}
-	return true
 }
 
 func certificateFromPEM(pemBytes string) (*Certificate, error) {
@@ -503,107 +506,91 @@
 	return ParseCertificate(block.Bytes)
 }
 
-func testVerify(t *testing.T, useSystemRoots bool) {
-	defer func(savedIgnoreCN bool) {
-		ignoreCN = savedIgnoreCN
-	}(ignoreCN)
-	for i, test := range verifyTests {
-		if useSystemRoots && test.systemSkip {
-			continue
-		}
-		if runtime.GOOS == "windows" && test.testSystemRootsError {
-			continue
-		}
+func testVerify(t *testing.T, test verifyTest, useSystemRoots bool) {
+	defer func(savedIgnoreCN bool) { ignoreCN = savedIgnoreCN }(ignoreCN)
 
-		ignoreCN = test.ignoreCN
-		opts := VerifyOptions{
-			Intermediates: NewCertPool(),
-			DNSName:       test.dnsName,
-			CurrentTime:   time.Unix(test.currentTime, 0),
-			KeyUsages:     test.keyUsages,
-		}
+	ignoreCN = test.ignoreCN
+	opts := VerifyOptions{
+		Intermediates: NewCertPool(),
+		DNSName:       test.dnsName,
+		CurrentTime:   time.Unix(test.currentTime, 0),
+		KeyUsages:     test.keyUsages,
+	}
 
-		if !useSystemRoots {
-			opts.Roots = NewCertPool()
-			for j, root := range test.roots {
-				ok := opts.Roots.AppendCertsFromPEM([]byte(root))
-				if !ok {
-					t.Errorf("#%d: failed to parse root #%d", i, j)
-					return
-				}
-			}
-		}
-
-		for j, intermediate := range test.intermediates {
-			ok := opts.Intermediates.AppendCertsFromPEM([]byte(intermediate))
+	if !useSystemRoots {
+		opts.Roots = NewCertPool()
+		for j, root := range test.roots {
+			ok := opts.Roots.AppendCertsFromPEM([]byte(root))
 			if !ok {
-				t.Errorf("#%d: failed to parse intermediate #%d", i, j)
-				return
+				t.Fatalf("failed to parse root #%d", j)
 			}
 		}
+	}
 
-		leaf, err := certificateFromPEM(test.leaf)
-		if err != nil {
-			t.Errorf("#%d: failed to parse leaf: %v", i, err)
-			return
+	for j, intermediate := range test.intermediates {
+		ok := opts.Intermediates.AppendCertsFromPEM([]byte(intermediate))
+		if !ok {
+			t.Fatalf("failed to parse intermediate #%d", j)
 		}
+	}
 
-		var oldSystemRoots *CertPool
-		if test.testSystemRootsError {
-			oldSystemRoots = systemRootsPool()
-			systemRoots = nil
-			opts.Roots = nil
-		}
+	leaf, err := certificateFromPEM(test.leaf)
+	if err != nil {
+		t.Fatalf("failed to parse leaf: %v", err)
+	}
 
-		chains, err := leaf.Verify(opts)
+	chains, err := leaf.Verify(opts)
 
-		if test.testSystemRootsError {
-			systemRoots = oldSystemRoots
-		}
-
-		if test.errorCallback == nil && err != nil {
-			t.Errorf("#%d: unexpected error: %v", i, err)
-		}
-		if test.errorCallback != nil {
-			if !test.errorCallback(t, i, err) {
-				return
+	if test.errorCallback == nil && err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	if test.errorCallback != nil {
+		if useSystemRoots && test.systemLax {
+			if err == nil {
+				t.Fatalf("expected error")
 			}
+		} else {
+			test.errorCallback(t, err)
 		}
+	}
 
-		if len(chains) != len(test.expectedChains) {
-			t.Errorf("#%d: wanted %d chains, got %d", i, len(test.expectedChains), len(chains))
-		}
+	if len(chains) != len(test.expectedChains) {
+		t.Errorf("wanted %d chains, got %d", len(test.expectedChains), len(chains))
+	}
 
-		// We check that each returned chain matches a chain from
-		// expectedChains but an entry in expectedChains can't match
-		// two chains.
-		seenChains := make([]bool, len(chains))
-	NextOutputChain:
-		for _, chain := range chains {
-		TryNextExpected:
-			for j, expectedChain := range test.expectedChains {
-				if seenChains[j] {
-					continue
-				}
-				if len(chain) != len(expectedChain) {
-					continue
-				}
-				for k, cert := range chain {
-					if !strings.Contains(nameToKey(&cert.Subject), expectedChain[k]) {
-						continue TryNextExpected
-					}
-				}
-				// we matched
-				seenChains[j] = true
-				continue NextOutputChain
+	// We check that each returned chain matches a chain from
+	// expectedChains but an entry in expectedChains can't match
+	// two chains.
+	seenChains := make([]bool, len(chains))
+NextOutputChain:
+	for _, chain := range chains {
+	TryNextExpected:
+		for j, expectedChain := range test.expectedChains {
+			if seenChains[j] {
+				continue
 			}
-			t.Errorf("#%d: No expected chain matched %s", i, chainToDebugString(chain))
+			if len(chain) != len(expectedChain) {
+				continue
+			}
+			for k, cert := range chain {
+				if !strings.Contains(nameToKey(&cert.Subject), expectedChain[k]) {
+					continue TryNextExpected
+				}
+			}
+			// we matched
+			seenChains[j] = true
+			continue NextOutputChain
 		}
+		t.Errorf("no expected chain matched %s", chainToDebugString(chain))
 	}
 }
 
 func TestGoVerify(t *testing.T) {
-	testVerify(t, false)
+	for _, test := range verifyTests {
+		t.Run(test.name, func(t *testing.T) {
+			testVerify(t, test, false)
+		})
+	}
 }
 
 func TestSystemVerify(t *testing.T) {
@@ -611,7 +598,14 @@
 		t.Skipf("skipping verify test using system APIs on %q", runtime.GOOS)
 	}
 
-	testVerify(t, true)
+	for _, test := range verifyTests {
+		t.Run(test.name, func(t *testing.T) {
+			if test.systemSkip {
+				t.SkipNow()
+			}
+			testVerify(t, test, true)
+		})
+	}
 }
 
 func chainToDebugString(chain []*Certificate) string {
@@ -648,8 +642,7 @@
 PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
 hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
 const giag2Intermediate = `-----BEGIN CERTIFICATE-----
 MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
@@ -674,8 +667,7 @@
 HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
 WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
 yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
 const googleLeaf = `-----BEGIN CERTIFICATE-----
 MIIEdjCCA16gAwIBAgIIcR5k4dkoe04wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
@@ -702,8 +694,7 @@
 orKqTuAPzXK7imQk6+OycYABbqCtC/9qmwRd8wwn7sF97DtYfK8WuNHtFalCAwyi
 8LxJJYJCLWoMhZ+V8GZm+FOex5qkQAjnZrtNlbQJ8ro4r+rpKXtmMFFhfa+7L+PA
 Kom08eUK8skxAzfDDijZPh10VtJ66uBoiDPdT+uCBehcBIcmSTrKjFGX
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
 // googleLeafWithInvalidHash is the same as googleLeaf, but the signature
 // algorithm in the certificate contains a nonsense OID.
@@ -732,8 +723,7 @@
 orKqTuAPzXK7imQk6+OycYABbqCtC/9qmwRd8wwn7sF97DtYfK8WuNHtFalCAwyi
 8LxJJYJCLWoMhZ+V8GZm+FOex5qkQAjnZrtNlbQJ8ro4r+rpKXtmMFFhfa+7L+PA
 Kom08eUK8skxAzfDDijZPh10VtJ66uBoiDPdT+uCBehcBIcmSTrKjFGX
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
 const dnssecExpLeaf = `-----BEGIN CERTIFICATE-----
 MIIGzTCCBbWgAwIBAgIDAdD6MA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ
@@ -858,58 +848,127 @@
 -----END CERTIFICATE-----`
 
 const smimeLeaf = `-----BEGIN CERTIFICATE-----
-MIIFBjCCA+6gAwIBAgISESFvrjT8XcJTEe6rBlPptILlMA0GCSqGSIb3DQEBBQUA
-MFQxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSowKAYD
-VQQDEyFHbG9iYWxTaWduIFBlcnNvbmFsU2lnbiAyIENBIC0gRzIwHhcNMTIwMTIz
-MTYzNjU5WhcNMTUwMTIzMTYzNjU5WjCBlDELMAkGA1UEBhMCVVMxFjAUBgNVBAgT
-DU5ldyBIYW1zcGhpcmUxEzARBgNVBAcTClBvcnRzbW91dGgxGTAXBgNVBAoTEEds
-b2JhbFNpZ24sIEluYy4xEzARBgNVBAMTClJ5YW4gSHVyc3QxKDAmBgkqhkiG9w0B
-CQEWGXJ5YW4uaHVyc3RAZ2xvYmFsc2lnbi5jb20wggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQC4ASSTvavmsFQAob60ukSSwOAL9nT/s99ltNUCAf5fPH5j
-NceMKxaQse2miOmRRIXaykcq1p/TbI70Ztce38r2mbOwqDHHPVi13GxJEyUXWgaR
-BteDMu5OGyWNG1kchVsGWpbstT0Z4v0md5m1BYFnxB20ebJyOR2lXDxsFK28nnKV
-+5eMj76U8BpPQ4SCH7yTMG6y0XXsB3cCrBKr2o3TOYgEKv+oNnbaoMt3UxMt9nSf
-9jyIshjqfnT5Aew3CUNMatO55g5FXXdIukAweg1YSb1ls05qW3sW00T3d7dQs9/7
-NuxCg/A2elmVJSoy8+MLR8JSFEf/aMgjO/TyLg/jAgMBAAGjggGPMIIBizAOBgNV
-HQ8BAf8EBAMCBaAwTQYDVR0gBEYwRDBCBgorBgEEAaAyASgKMDQwMgYIKwYBBQUH
-AgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMCQGA1Ud
-EQQdMBuBGXJ5YW4uaHVyc3RAZ2xvYmFsc2lnbi5jb20wCQYDVR0TBAIwADAdBgNV
-HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwQwYDVR0fBDwwOjA4oDagNIYyaHR0
-cDovL2NybC5nbG9iYWxzaWduLmNvbS9ncy9nc3BlcnNvbmFsc2lnbjJnMi5jcmww
-VQYIKwYBBQUHAQEESTBHMEUGCCsGAQUFBzAChjlodHRwOi8vc2VjdXJlLmdsb2Jh
-bHNpZ24uY29tL2NhY2VydC9nc3BlcnNvbmFsc2lnbjJnMi5jcnQwHQYDVR0OBBYE
-FFWiECe0/L72eVYqcWYnLV6SSjzhMB8GA1UdIwQYMBaAFD8V0m18L+cxnkMKBqiU
-bCw7xe5lMA0GCSqGSIb3DQEBBQUAA4IBAQAhQi6hLPeudmf3IBF4IDzCvRI0FaYd
-BKfprSk/H0PDea4vpsLbWpA0t0SaijiJYtxKjlM4bPd+2chb7ejatDdyrZIzmDVy
-q4c30/xMninGKokpYA11/Ve+i2dvjulu65qasrtQRGybAuuZ67lrp/K3OMFgjV5N
-C3AHYLzvNU4Dwc4QQ1BaMOg6KzYSrKbABRZajfrpC9uiePsv7mDIXLx/toBPxWNl
-a5vJm5DrZdn7uHdvBCE6kMykbOLN5pmEK0UIlwKh6Qi5XD0pzlVkEZliFkBMJgub
-d/eF7xeg7TKPWC5xyOFp9SdMolJM7LTC3wnSO3frBAev+q/nGs9Xxyvs
+MIIIPDCCBiSgAwIBAgIQaMDxFS0pOMxZZeOBxoTJtjANBgkqhkiG9w0BAQsFADCB
+nTELMAkGA1UEBhMCRVMxFDASBgNVBAoMC0laRU5QRSBTLkEuMTowOAYDVQQLDDFB
+WlogWml1cnRhZ2lyaSBwdWJsaWtvYSAtIENlcnRpZmljYWRvIHB1YmxpY28gU0NB
+MTwwOgYDVQQDDDNFQUVrbyBIZXJyaSBBZG1pbmlzdHJhemlvZW4gQ0EgLSBDQSBB
+QVBQIFZhc2NhcyAoMikwHhcNMTcwNzEyMDg1MzIxWhcNMjEwNzEyMDg1MzIxWjCC
+AQwxDzANBgNVBAoMBklaRU5QRTE4MDYGA1UECwwvWml1cnRhZ2lyaSBrb3Jwb3Jh
+dGlib2EtQ2VydGlmaWNhZG8gY29ycG9yYXRpdm8xQzBBBgNVBAsMOkNvbmRpY2lv
+bmVzIGRlIHVzbyBlbiB3d3cuaXplbnBlLmNvbSBub2xhIGVyYWJpbGkgamFraXRl
+a28xFzAVBgNVBC4TDi1kbmkgOTk5OTk5ODlaMSQwIgYDVQQDDBtDT1JQT1JBVElW
+TyBGSUNUSUNJTyBBQ1RJVk8xFDASBgNVBCoMC0NPUlBPUkFUSVZPMREwDwYDVQQE
+DAhGSUNUSUNJTzESMBAGA1UEBRMJOTk5OTk5ODlaMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAwVOMwUDfBtsH0XuxYnb+v/L774jMH8valX7RPH8cl2Lb
+SiqSo0RchW2RGA2d1yuYHlpChC9jGmt0X/g66/E/+q2hUJlfJtqVDJFwtFYV4u2S
+yzA3J36V4PRkPQrKxAsbzZriFXAF10XgiHQz9aVeMMJ9GBhmh9+DK8Tm4cMF6i8l
++AuC35KdngPF1x0ealTYrYZplpEJFO7CiW42aLi6vQkDR2R7nmZA4AT69teqBWsK
+0DZ93/f0G/3+vnWwNTBF0lB6dIXoaz8OMSyHLqGnmmAtMrzbjAr/O/WWgbB/BqhR
+qjJQ7Ui16cuDldXaWQ/rkMzsxmsAox0UF+zdQNvXUQIDAQABo4IDBDCCAwAwgccG
+A1UdEgSBvzCBvIYVaHR0cDovL3d3dy5pemVucGUuY29tgQ9pbmZvQGl6ZW5wZS5j
+b22kgZEwgY4xRzBFBgNVBAoMPklaRU5QRSBTLkEuIC0gQ0lGIEEwMTMzNzI2MC1S
+TWVyYy5WaXRvcmlhLUdhc3RlaXogVDEwNTUgRjYyIFM4MUMwQQYDVQQJDDpBdmRh
+IGRlbCBNZWRpdGVycmFuZW8gRXRvcmJpZGVhIDE0IC0gMDEwMTAgVml0b3JpYS1H
+YXN0ZWl6MB4GA1UdEQQXMBWBE2ZpY3RpY2lvQGl6ZW5wZS5ldXMwDgYDVR0PAQH/
+BAQDAgXgMCkGA1UdJQQiMCAGCCsGAQUFBwMCBggrBgEFBQcDBAYKKwYBBAGCNxQC
+AjAdBgNVHQ4EFgQUyeoOD4cgcljKY0JvrNuX2waFQLAwHwYDVR0jBBgwFoAUwKlK
+90clh/+8taaJzoLSRqiJ66MwggEnBgNVHSAEggEeMIIBGjCCARYGCisGAQQB8zkB
+AQEwggEGMDMGCCsGAQUFBwIBFidodHRwOi8vd3d3Lml6ZW5wZS5jb20vcnBhc2Nh
+Y29ycG9yYXRpdm8wgc4GCCsGAQUFBwICMIHBGoG+Wml1cnRhZ2lyaWEgRXVza2Fs
+IEF1dG9ub21pYSBFcmtpZGVnb2tvIHNla3RvcmUgcHVibGlrb2tvIGVyYWt1bmRl
+ZW4gYmFybmUtc2FyZWV0YW4gYmFrYXJyaWsgZXJhYmlsIGRhaXRla2UuIFVzbyBy
+ZXN0cmluZ2lkbyBhbCBhbWJpdG8gZGUgcmVkZXMgaW50ZXJuYXMgZGUgRW50aWRh
+ZGVzIGRlbCBTZWN0b3IgUHVibGljbyBWYXNjbzAyBggrBgEFBQcBAQQmMCQwIgYI
+KwYBBQUHMAGGFmh0dHA6Ly9vY3NwLml6ZW5wZS5jb20wOgYDVR0fBDMwMTAvoC2g
+K4YpaHR0cDovL2NybC5pemVucGUuY29tL2NnaS1iaW4vY3JsaW50ZXJuYTIwDQYJ
+KoZIhvcNAQELBQADggIBAIy5PQ+UZlCRq6ig43vpHwlwuD9daAYeejV0Q+ZbgWAE
+GtO0kT/ytw95ZEJMNiMw3fYfPRlh27ThqiT0VDXZJDlzmn7JZd6QFcdXkCsiuv4+
+ZoXAg/QwnA3SGUUO9aVaXyuOIIuvOfb9MzoGp9xk23SMV3eiLAaLMLqwB5DTfBdt
+BGI7L1MnGJBv8RfP/TL67aJ5bgq2ri4S8vGHtXSjcZ0+rCEOLJtmDNMnTZxancg3
+/H5edeNd+n6Z48LO+JHRxQufbC4mVNxVLMIP9EkGUejlq4E4w6zb5NwCQczJbSWL
+i31rk2orsNsDlyaLGsWZp3JSNX6RmodU4KAUPor4jUJuUhrrm3Spb73gKlV/gcIw
+bCE7mML1Kss3x1ySaXsis6SZtLpGWKkW2iguPWPs0ydV6RPhmsCxieMwPPIJ87vS
+5IejfgyBae7RSuAIHyNFy4uI5xwvwUFf6OZ7az8qtW7ImFOgng3Ds+W9k1S2CNTx
+d0cnKTfA6IpjGo8EeHcxnIXT8NPImWaRj0qqonvYady7ci6U4m3lkNSdXNn1afgw
+mYust+gxVtOZs1gk2MUCgJ1V1X+g7r/Cg7viIn6TLkLrpS1kS1hvMqkl9M+7XqPo
+Qd95nJKOkusQpy99X4dF/lfbYAQnnjnqh3DLD2gvYObXFaAYFaiBKTiMTV2X72F+
 -----END CERTIFICATE-----`
 
 const smimeIntermediate = `-----BEGIN CERTIFICATE-----
-MIIEFjCCAv6gAwIBAgILBAAAAAABL07hL1IwDQYJKoZIhvcNAQEFBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0MTMxMDAw
-MDBaFw0xOTA0MTMxMDAwMDBaMFQxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMSowKAYDVQQDEyFHbG9iYWxTaWduIFBlcnNvbmFsU2lnbiAy
-IENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBa0H5Nez4
-En3dIlFpX7e5E0YndxQ74xOBbz7kdBd+DLX0LOQMjVPU3DAgKL9ujhH+ZhHkURbH
-3X/94TQSUL/z2JjsaQvS0NqyZXHhM5eeuquzOJRzEQ8+odETzHg2G0Erv7yjSeww
-gkwDWDJnYUDlOjYTDUEG6+i+8Mn425reo4I0E277wD542kmVWeW7+oHv5dZo9e1Q
-yWwiKTEP6BEQVVSBgThXMG4traSSDRUt3T1eQTZx5EObpiBEBO4OTqiBTJfg4vEI
-YgkXzKLpnfszTB6YMDpR9/QS6p3ANB3kfAb+t6udSO3WCst0DGrwHDLBFGDR4UeY
-T5KGGnI7cWL7AgMBAAGjgeUwgeIwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI
-MAYBAf8CAQAwHQYDVR0OBBYEFD8V0m18L+cxnkMKBqiUbCw7xe5lMEcGA1UdIARA
-MD4wPAYEVR0gADA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWdu
-LmNvbS9yZXBvc2l0b3J5LzAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmds
-b2JhbHNpZ24ubmV0L3Jvb3QuY3JsMB8GA1UdIwQYMBaAFGB7ZhpFDZfKiVAvfQTN
-NKj//P1LMA0GCSqGSIb3DQEBBQUAA4IBAQBDc3nMpMxJMQMcYUCB3+C73UpvwDE8
-eCOr7t2F/uaQKKcyqqstqLZc6vPwI/rcE9oDHugY5QEjQzIBIEaTnN6P0vege2IX
-eCOr7t2F/uaQKKcyqqstqLZc6vPwI/rcE9oDHugY5QEjQzIBIEaTnN6P0vege2IX
-YEvTWbWwGdPytDFPYIl3/6OqNSXSnZ7DxPcdLJq2uyiga8PB/TTIIHYkdM2+1DE0
-7y3rH/7TjwDVD7SLu5/SdOfKskuMPTjOEvz3K161mymW06klVhubCIWOro/Gx1Q2
-2FQOZ7/2k4uYoOdBTSlb8kTAuzZNgIE0rB2BIYCTz/P6zZIKW0ogbRSH
+MIIHNzCCBSGgAwIBAgIQJMXIqlZvjuhMvqcFXOFkpDALBgkqhkiG9w0BAQswODEL
+MAkGA1UEBhMCRVMxFDASBgNVBAoMC0laRU5QRSBTLkEuMRMwEQYDVQQDDApJemVu
+cGUuY29tMB4XDTEwMTAyMDA4MjMzM1oXDTM3MTIxMjIzMDAwMFowgZ0xCzAJBgNV
+BAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjE6MDgGA1UECwwxQVpaIFppdXJ0
+YWdpcmkgcHVibGlrb2EgLSBDZXJ0aWZpY2FkbyBwdWJsaWNvIFNDQTE8MDoGA1UE
+AwwzRUFFa28gSGVycmkgQWRtaW5pc3RyYXppb2VuIENBIC0gQ0EgQUFQUCBWYXNj
+YXMgKDIpMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoIM7nEdI0N1h
+rR5T4xuV/usKDoMIasaiKvfLhbwxaNtTt+a7W/6wV5bv3svQFIy3sUXjjdzV1nG2
+To2wo/YSPQiOt8exWvOapvL21ogiof+kelWnXFjWaKJI/vThHYLgIYEMj/y4HdtU
+ojI646rZwqsb4YGAopwgmkDfUh5jOhV2IcYE3TgJAYWVkj6jku9PLaIsHiarAHjD
+PY8dig8a4SRv0gm5Yk7FXLmW1d14oxQBDeHZ7zOEXfpafxdEDO2SNaRJjpkh8XRr
+PGqkg2y1Q3gT6b4537jz+StyDIJ3omylmlJsGCwqT7p8mEqjGJ5kC5I2VnjXKuNn
+soShc72khWZVUJiJo5SGuAkNE2ZXqltBVm5Jv6QweQKsX6bkcMc4IZok4a+hx8FM
+8IBpGf/I94pU6HzGXqCyc1d46drJgDY9mXa+6YDAJFl3xeXOOW2iGCfwXqhiCrKL
+MYvyMZzqF3QH5q4nb3ZnehYvraeMFXJXDn+Utqp8vd2r7ShfQJz01KtM4hgKdgSg
+jtW+shkVVN5ng/fPN85ovfAH2BHXFfHmQn4zKsYnLitpwYM/7S1HxlT61cdQ7Nnk
+3LZTYEgAoOmEmdheklT40WAYakksXGM5VrzG7x9S7s1Tm+Vb5LSThdHC8bxxwyTb
+KsDRDNJ84N9fPDO6qHnzaL2upQ43PycCAwEAAaOCAdkwggHVMIHHBgNVHREEgb8w
+gbyGFWh0dHA6Ly93d3cuaXplbnBlLmNvbYEPaW5mb0BpemVucGUuY29tpIGRMIGO
+MUcwRQYDVQQKDD5JWkVOUEUgUy5BLiAtIENJRiBBMDEzMzcyNjAtUk1lcmMuVml0
+b3JpYS1HYXN0ZWl6IFQxMDU1IEY2MiBTODFDMEEGA1UECQw6QXZkYSBkZWwgTWVk
+aXRlcnJhbmVvIEV0b3JiaWRlYSAxNCAtIDAxMDEwIFZpdG9yaWEtR2FzdGVpejAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUwKlK90cl
+h/+8taaJzoLSRqiJ66MwHwYDVR0jBBgwFoAUHRxlDqjyJXu0kc/ksbHmvVV0bAUw
+OgYDVR0gBDMwMTAvBgRVHSAAMCcwJQYIKwYBBQUHAgEWGWh0dHA6Ly93d3cuaXpl
+bnBlLmNvbS9jcHMwNwYIKwYBBQUHAQEEKzApMCcGCCsGAQUFBzABhhtodHRwOi8v
+b2NzcC5pemVucGUuY29tOjgwOTQwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2Ny
+bC5pemVucGUuY29tL2NnaS1iaW4vYXJsMjALBgkqhkiG9w0BAQsDggIBAMbjc3HM
+3DG9ubWPkzsF0QsktukpujbTTcGk4h20G7SPRy1DiiTxrRzdAMWGjZioOP3/fKCS
+M539qH0M+gsySNie+iKlbSZJUyE635T1tKw+G7bDUapjlH1xyv55NC5I6wCXGC6E
+3TEP5B/E7dZD0s9E4lS511ubVZivFgOzMYo1DO96diny/N/V1enaTCpRl1qH1OyL
+xUYTijV4ph2gL6exwuG7pxfRcVNHYlrRaXWfTz3F6NBKyULxrI3P/y6JAtN1GqT4
+VF/+vMygx22n0DufGepBwTQz6/rr1ulSZ+eMnuJiTXgh/BzQnkUsXTb8mHII25iR
+0oYF2qAsk6ecWbLiDpkHKIDHmML21MZE13MS8NSvTHoqJO4LyAmDe6SaeNHtrPlK
+b6mzE1BN2ug+ZaX8wLA5IMPFaf0jKhb/Cxu8INsxjt00brsErCc9ip1VNaH0M4bi
+1tGxfiew2436FaeyUxW7Pl6G5GgkNbuUc7QIoRy06DdU/U38BxW3uyJMY60zwHvS
+FlKAn0OvYp4niKhAJwaBVN3kowmJuOU5Rid+TUnfyxbJ9cttSgzaF3hP/N4zgMEM
+5tikXUskeckt8LUK96EH0QyssavAMECUEb/xrupyRdYWwjQGvNLq6T5+fViDGyOw
+k+lzD44wofy8paAy9uC9Owae0zMEzhcsyRm7
+-----END CERTIFICATE-----`
+
+const smimeRoot = `-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
 -----END CERTIFICATE-----`
 
 var megaLeaf = `-----BEGIN CERTIFICATE-----
@@ -1315,50 +1374,7 @@
 cw3ESZzThBwWqvPOtJdpXdm+r57pDW8qD+/0lY8wfImMNkQAyCUCLg/1Lxt/hrBj
 -----END CERTIFICATE-----`
 
-const issuerSubjectMatchRoot = `
-Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number: 161640039802297062 (0x23e42c281e55ae6)
-    Signature Algorithm: sha256WithRSAEncryption
-        Issuer: O=Golang, CN=Root ca
-        Validity
-            Not Before: Jan  1 00:00:00 2015 GMT
-            Not After : Jan  1 00:00:00 2025 GMT
-        Subject: O=Golang, CN=Root ca
-        Subject Public Key Info:
-            Public Key Algorithm: rsaEncryption
-                Public-Key: (1024 bit)
-                Modulus:
-                    00:e9:0e:7f:11:0c:e6:5a:e6:86:83:70:f6:51:07:
-                    2e:02:78:11:f5:b2:24:92:38:ee:26:62:02:c7:94:
-                    f1:3e:a1:77:6a:c0:8f:d5:22:68:b6:5d:e2:4c:da:
-                    e0:85:11:35:c2:92:72:49:8d:81:b4:88:97:6b:b7:
-                    fc:b2:44:5b:d9:4d:06:70:f9:0c:c6:8f:e9:b3:df:
-                    a3:6a:84:6c:43:59:be:9d:b2:d0:76:9b:c3:d7:fa:
-                    99:59:c3:b8:e5:f3:53:03:bd:49:d6:b3:cc:a2:43:
-                    fe:ad:c2:0b:b9:01:b8:56:29:94:03:24:a7:0d:28:
-                    21:29:a9:ae:94:5b:4a:f9:9f
-                Exponent: 65537 (0x10001)
-        X509v3 extensions:
-            X509v3 Key Usage: critical
-                Certificate Sign
-            X509v3 Extended Key Usage:
-                TLS Web Server Authentication, TLS Web Client Authentication
-            X509v3 Basic Constraints: critical
-                CA:TRUE
-            X509v3 Subject Key Identifier:
-                40:37:D7:01:FB:40:2F:B8:1C:7E:54:04:27:8C:59:01
-    Signature Algorithm: sha256WithRSAEncryption
-         6f:84:df:49:e0:99:d4:71:66:1d:32:86:56:cb:ea:5a:6b:0e:
-         00:6a:d1:5a:6e:1f:06:23:07:ff:cb:d1:1a:74:e4:24:43:0b:
-         aa:2a:a0:73:75:25:82:bc:bf:3f:a9:f8:48:88:ac:ed:3a:94:
-         3b:0d:d3:88:c8:67:44:61:33:df:71:6c:c5:af:ed:16:8c:bf:
-         82:f9:49:bb:e3:2a:07:53:36:37:25:77:de:91:a4:77:09:7f:
-         6f:b2:91:58:c4:05:89:ea:8e:fa:e1:3b:19:ef:f8:f6:94:b7:
-         7b:27:e6:e4:84:dd:2b:f5:93:f5:3c:d8:86:c5:38:01:56:5c:
-         9f:6d
------BEGIN CERTIFICATE-----
+const issuerSubjectMatchRoot = `-----BEGIN CERTIFICATE-----
 MIICIDCCAYmgAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwIzEPMA0GA1UE
 ChMGR29sYW5nMRAwDgYDVQQDEwdSb290IGNhMB4XDTE1MDEwMTAwMDAwMFoXDTI1
 MDEwMTAwMDAwMFowIzEPMA0GA1UEChMGR29sYW5nMRAwDgYDVQQDEwdSb290IGNh
@@ -1373,53 +1389,7 @@
 eyfm5ITdK/WT9TzYhsU4AVZcn20=
 -----END CERTIFICATE-----`
 
-const issuerSubjectMatchLeaf = `
-Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number: 16785088708916013734 (0xe8f09d3fe25beaa6)
-    Signature Algorithm: sha256WithRSAEncryption
-        Issuer: O=Golang, CN=Root CA
-        Validity
-            Not Before: Jan  1 00:00:00 2015 GMT
-            Not After : Jan  1 00:00:00 2025 GMT
-        Subject: O=Golang, CN=Leaf
-        Subject Public Key Info:
-            Public Key Algorithm: rsaEncryption
-                Public-Key: (1024 bit)
-                Modulus:
-                    00:db:46:7d:93:2e:12:27:06:48:bc:06:28:21:ab:
-                    7e:c4:b6:a2:5d:fe:1e:52:45:88:7a:36:47:a5:08:
-                    0d:92:42:5b:c2:81:c0:be:97:79:98:40:fb:4f:6d:
-                    14:fd:2b:13:8b:c2:a5:2e:67:d8:d4:09:9e:d6:22:
-                    38:b7:4a:0b:74:73:2b:c2:34:f1:d1:93:e5:96:d9:
-                    74:7b:f3:58:9f:6c:61:3c:c0:b0:41:d4:d9:2b:2b:
-                    24:23:77:5b:1c:3b:bd:75:5d:ce:20:54:cf:a1:63:
-                    87:1d:1e:24:c4:f3:1d:1a:50:8b:aa:b6:14:43:ed:
-                    97:a7:75:62:f4:14:c8:52:d7
-                Exponent: 65537 (0x10001)
-        X509v3 extensions:
-            X509v3 Key Usage: critical
-                Digital Signature, Key Encipherment
-            X509v3 Extended Key Usage:
-                TLS Web Server Authentication, TLS Web Client Authentication
-            X509v3 Basic Constraints: critical
-                CA:FALSE
-            X509v3 Subject Key Identifier:
-                9F:91:16:1F:43:43:3E:49:A6:DE:6D:B6:80:D7:9F:60
-            X509v3 Authority Key Identifier:
-                keyid:40:37:D7:01:FB:40:2F:B8:1C:7E:54:04:27:8C:59:01
-
-    Signature Algorithm: sha256WithRSAEncryption
-         8d:86:05:da:89:f5:1d:c5:16:14:41:b9:34:87:2b:5c:38:99:
-         e3:d9:5a:5b:7a:5b:de:0b:5c:08:45:09:6f:1c:9d:31:5f:08:
-         ca:7a:a3:99:da:83:0b:22:be:4f:02:35:91:4e:5d:5c:37:bf:
-         89:22:58:7d:30:76:d2:2f:d0:a0:ee:77:9e:77:c0:d6:19:eb:
-         ec:a0:63:35:6a:80:9b:80:1a:80:de:64:bc:40:38:3c:22:69:
-         ad:46:26:a2:3d:ea:f4:c2:92:49:16:03:96:ae:64:21:b9:7c:
-         ee:64:91:47:81:aa:b4:0c:09:2b:12:1a:b2:f3:af:50:b3:b1:
-         ce:24
------BEGIN CERTIFICATE-----
+const issuerSubjectMatchLeaf = `-----BEGIN CERTIFICATE-----
 MIICODCCAaGgAwIBAgIJAOjwnT/iW+qmMA0GCSqGSIb3DQEBCwUAMCMxDzANBgNV
 BAoTBkdvbGFuZzEQMA4GA1UEAxMHUm9vdCBDQTAeFw0xNTAxMDEwMDAwMDBaFw0y
 NTAxMDEwMDAwMDBaMCAxDzANBgNVBAoTBkdvbGFuZzENMAsGA1UEAxMETGVhZjCB
@@ -1432,11 +1402,9 @@
 hvcNAQELBQADgYEAjYYF2on1HcUWFEG5NIcrXDiZ49laW3pb3gtcCEUJbxydMV8I
 ynqjmdqDCyK+TwI1kU5dXDe/iSJYfTB20i/QoO53nnfA1hnr7KBjNWqAm4AagN5k
 vEA4PCJprUYmoj3q9MKSSRYDlq5kIbl87mSRR4GqtAwJKxIasvOvULOxziQ=
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
-const x509v1TestRoot = `
------BEGIN CERTIFICATE-----
+const x509v1TestRoot = `-----BEGIN CERTIFICATE-----
 MIICIDCCAYmgAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwIzEPMA0GA1UE
 ChMGR29sYW5nMRAwDgYDVQQDEwdSb290IENBMB4XDTE1MDEwMTAwMDAwMFoXDTI1
 MDEwMTAwMDAwMFowIzEPMA0GA1UEChMGR29sYW5nMRAwDgYDVQQDEwdSb290IENB
@@ -1451,8 +1419,7 @@
 /1JmacUUofl+HusHuLkDxmadogI=
 -----END CERTIFICATE-----`
 
-const x509v1TestIntermediate = `
------BEGIN CERTIFICATE-----
+const x509v1TestIntermediate = `-----BEGIN CERTIFICATE-----
 MIIByjCCATMCCQCCdEMsT8ykqTANBgkqhkiG9w0BAQsFADAjMQ8wDQYDVQQKEwZH
 b2xhbmcxEDAOBgNVBAMTB1Jvb3QgQ0EwHhcNMTUwMTAxMDAwMDAwWhcNMjUwMTAx
 MDAwMDAwWjAwMQ8wDQYDVQQKEwZHb2xhbmcxHTAbBgNVBAMTFFguNTA5djEgaW50
@@ -1465,8 +1432,7 @@
 x5Wlq1u3YDL/j6s1nU2dQ3ySB/oP7J+vQ9V4QeM+
 -----END CERTIFICATE-----`
 
-const x509v1TestLeaf = `
------BEGIN CERTIFICATE-----
+const x509v1TestLeaf = `-----BEGIN CERTIFICATE-----
 MIICMzCCAZygAwIBAgIJAPo99mqJJrpJMA0GCSqGSIb3DQEBCwUAMDAxDzANBgNV
 BAoTBkdvbGFuZzEdMBsGA1UEAxMUWC41MDl2MSBpbnRlcm1lZGlhdGUwHhcNMTUw
 MTAxMDAwMDAwWhcNMjUwMTAxMDAwMDAwWjArMQ8wDQYDVQQKEwZHb2xhbmcxGDAW
@@ -1481,8 +1447,7 @@
 /jt8qszOXCv2vYdUTPNuPqufXLWMoirpuXrr1liJDmedCcAHepY/
 -----END CERTIFICATE-----`
 
-const ignoreCNWithSANRoot = `
------BEGIN CERTIFICATE-----
+const ignoreCNWithSANRoot = `-----BEGIN CERTIFICATE-----
 MIIDPzCCAiegAwIBAgIIJkzCwkNrPHMwDQYJKoZIhvcNAQELBQAwMDEQMA4GA1UE
 ChMHVEVTVElORzEcMBoGA1UEAxMTKipUZXN0aW5nKiogUm9vdCBDQTAeFw0xNTAx
 MDEwMDAwMDBaFw0yNTAxMDEwMDAwMDBaMDAxEDAOBgNVBAoTB1RFU1RJTkcxHDAa
@@ -1503,8 +1468,7 @@
 BJ6bvwEAasFiLGP6Zbdmxb2hIA==
 -----END CERTIFICATE-----`
 
-const ignoreCNWithSANLeaf = `
------BEGIN CERTIFICATE-----
+const ignoreCNWithSANLeaf = `-----BEGIN CERTIFICATE-----
 MIIDaTCCAlGgAwIBAgIJAONakvRTxgJhMA0GCSqGSIb3DQEBCwUAMDAxEDAOBgNV
 BAoTB1RFU1RJTkcxHDAaBgNVBAMTEyoqVGVzdGluZyoqIFJvb3QgQ0EwHhcNMTUw
 MTAxMDAwMDAwWhcNMjUwMTAxMDAwMDAwWjAsMRAwDgYDVQQKEwdURVNUSU5HMRgw
@@ -1526,8 +1490,7 @@
 xZbqP3Krgjj4XNaXjg==
 -----END CERTIFICATE-----`
 
-const excludedNamesLeaf = `
------BEGIN CERTIFICATE-----
+const excludedNamesLeaf = `-----BEGIN CERTIFICATE-----
 MIID4DCCAsigAwIBAgIHDUSFtJknhzANBgkqhkiG9w0BAQsFADCBnjELMAkGA1UE
 BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUxvcyBHYXRvczEU
 MBIGA1UECgwLTmV0ZmxpeCBJbmMxLTArBgNVBAsMJFBsYXRmb3JtIFNlY3VyaXR5
@@ -1549,11 +1512,9 @@
 qKlWE+0S16+pzsWvKn831uylqwIb8ANBPsCX4aM4muFBHavSWAHgRO+P+yXVw8Q+
 VQDnMHUe5PbZd1/+1KKVs1K/CkBCtoHNHp1d/JT+2zUQJphwja9CcgfFdVhSnHL4
 oEEOFtqVMIuQfR2isi08qW/JGOHc4sFoLYB8hvdaxKWSE19A
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
-const excludedNamesIntermediate = `
------BEGIN CERTIFICATE-----
+const excludedNamesIntermediate = `-----BEGIN CERTIFICATE-----
 MIIDzTCCArWgAwIBAgIHDUSFqYeczDANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UE
 BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUxvcyBHYXRvczEU
 MBIGA1UECgwLTmV0ZmxpeCBJbmMxLTArBgNVBAsMJFBsYXRmb3JtIFNlY3VyaXR5
@@ -1577,8 +1538,7 @@
 zMBX1/lk4wkFckeUIlkD55Y=
 -----END CERTIFICATE-----`
 
-const excludedNamesRoot = `
------BEGIN CERTIFICATE-----
+const excludedNamesRoot = `-----BEGIN CERTIFICATE-----
 MIIEGTCCAwGgAwIBAgIHDUSFpInn/zANBgkqhkiG9w0BAQsFADCBozELMAkGA1UE
 BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCUxvcyBHYXRvczEU
 MBIGA1UECgwLTmV0ZmxpeCBJbmMxLTArBgNVBAsMJFBsYXRmb3JtIFNlY3VyaXR5
@@ -1603,46 +1563,16 @@
 +NQCZDd5eFeU8PpNX7rgaYE4GPq+EEmLVCBYmdctr8QVdqJ//8Xu3+1phjDy
 -----END CERTIFICATE-----`
 
-const invalidCNRoot = `
------BEGIN CERTIFICATE-----
+const invalidCNRoot = `-----BEGIN CERTIFICATE-----
 MIIBFjCBvgIJAIsu4r+jb70UMAoGCCqGSM49BAMCMBQxEjAQBgNVBAsMCVRlc3Qg
 cm9vdDAeFw0xODA3MTExODMyMzVaFw0yODA3MDgxODMyMzVaMBQxEjAQBgNVBAsM
 CVRlc3Qgcm9vdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABF6oDgMg0LV6YhPj
 QXaPXYCc2cIyCdqp0ROUksRz0pOLTc5iY2nraUheRUD1vRRneq7GeXOVNn7uXONg
 oCGMjNwwCgYIKoZIzj0EAwIDRwAwRAIgDSiwgIn8g1lpruYH0QD1GYeoWVunfmrI
 XzZZl0eW/ugCICgOfXeZ2GGy3wIC0352BaC3a8r5AAb2XSGNe+e9wNN6
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
-const invalidCNWithoutSAN = `
-Certificate:
-    Data:
-        Version: 1 (0x0)
-        Serial Number:
-            07:ba:bc:b7:d9:ab:0c:02:fe:50:1d:4e:15:a3:0d:e4:11:16:14:a2
-        Signature Algorithm: ecdsa-with-SHA256
-        Issuer: OU = Test root
-        Validity
-            Not Before: Jul 11 18:35:21 2018 GMT
-            Not After : Jul  8 18:35:21 2028 GMT
-        Subject: CN = "foo,invalid"
-        Subject Public Key Info:
-            Public Key Algorithm: id-ecPublicKey
-                Public-Key: (256 bit)
-                pub:
-                    04:a7:a6:7c:22:33:a7:47:7f:08:93:2d:5f:61:35:
-                    2e:da:45:67:76:f2:97:73:18:b0:01:12:4a:1a:d5:
-                    b7:6f:41:3c:bb:05:69:f4:06:5d:ff:eb:2b:a7:85:
-                    0b:4c:f7:45:4e:81:40:7a:a9:c6:1d:bb:ba:d9:b9:
-                    26:b3:ca:50:90
-                ASN1 OID: prime256v1
-                NIST CURVE: P-256
-    Signature Algorithm: ecdsa-with-SHA256
-         30:45:02:21:00:85:96:75:b6:72:3c:67:12:a0:7f:86:04:81:
-         d2:dd:c8:67:50:d7:5f:85:c0:54:54:fc:e6:6b:45:08:93:d3:
-         2a:02:20:60:86:3e:d6:28:a6:4e:da:dd:6e:95:89:cc:00:76:
-         78:1c:03:80:85:a6:5a:0b:eb:c5:f3:9c:2e:df:ef:6e:fa
------BEGIN CERTIFICATE-----
+const invalidCNWithoutSAN = `-----BEGIN CERTIFICATE-----
 MIIBJDCBywIUB7q8t9mrDAL+UB1OFaMN5BEWFKIwCgYIKoZIzj0EAwIwFDESMBAG
 A1UECwwJVGVzdCByb290MB4XDTE4MDcxMTE4MzUyMVoXDTI4MDcwODE4MzUyMVow
 FjEUMBIGA1UEAwwLZm9vLGludmFsaWQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
@@ -1650,38 +1580,9 @@
 90VOgUB6qcYdu7rZuSazylCQMAoGCCqGSM49BAMCA0gAMEUCIQCFlnW2cjxnEqB/
 hgSB0t3IZ1DXX4XAVFT85mtFCJPTKgIgYIY+1iimTtrdbpWJzAB2eBwDgIWmWgvr
 xfOcLt/vbvo=
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
-const validCNWithoutSAN = `
-Certificate:
-    Data:
-        Version: 1 (0x0)
-        Serial Number:
-            07:ba:bc:b7:d9:ab:0c:02:fe:50:1d:4e:15:a3:0d:e4:11:16:14:a4
-        Signature Algorithm: ecdsa-with-SHA256
-        Issuer: OU = Test root
-        Validity
-            Not Before: Jul 11 18:47:24 2018 GMT
-            Not After : Jul  8 18:47:24 2028 GMT
-        Subject: CN = foo.example.com
-        Subject Public Key Info:
-            Public Key Algorithm: id-ecPublicKey
-                Public-Key: (256 bit)
-                pub:
-                    04:a7:a6:7c:22:33:a7:47:7f:08:93:2d:5f:61:35:
-                    2e:da:45:67:76:f2:97:73:18:b0:01:12:4a:1a:d5:
-                    b7:6f:41:3c:bb:05:69:f4:06:5d:ff:eb:2b:a7:85:
-                    0b:4c:f7:45:4e:81:40:7a:a9:c6:1d:bb:ba:d9:b9:
-                    26:b3:ca:50:90
-                ASN1 OID: prime256v1
-                NIST CURVE: P-256
-    Signature Algorithm: ecdsa-with-SHA256
-         30:44:02:20:53:6c:d7:b7:59:61:51:72:a5:18:a3:4b:0d:52:
-         ea:15:fa:d0:93:30:32:54:4b:ed:0f:58:85:b8:a8:1a:82:3b:
-         02:20:14:77:4b:0e:7e:4f:0a:4f:64:26:97:dc:d0:ed:aa:67:
-         1d:37:85:da:b4:87:ba:25:1c:2a:58:f7:23:11:8b:3d
------BEGIN CERTIFICATE-----
+const validCNWithoutSAN = `-----BEGIN CERTIFICATE-----
 MIIBJzCBzwIUB7q8t9mrDAL+UB1OFaMN5BEWFKQwCgYIKoZIzj0EAwIwFDESMBAG
 A1UECwwJVGVzdCByb290MB4XDTE4MDcxMTE4NDcyNFoXDTI4MDcwODE4NDcyNFow
 GjEYMBYGA1UEAwwPZm9vLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D
@@ -1689,48 +1590,9 @@
 p4ULTPdFToFAeqnGHbu62bkms8pQkDAKBggqhkjOPQQDAgNHADBEAiBTbNe3WWFR
 cqUYo0sNUuoV+tCTMDJUS+0PWIW4qBqCOwIgFHdLDn5PCk9kJpfc0O2qZx03hdq0
 h7olHCpY9yMRiz0=
------END CERTIFICATE-----
-`
+-----END CERTIFICATE-----`
 
-const (
-	rootWithoutSKID = `
-Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number:
-            78:29:2a:dc:2f:12:39:7f:c9:33:93:ea:61:39:7d:70
-        Signature Algorithm: ecdsa-with-SHA256
-        Issuer: O = Acme Co
-        Validity
-            Not Before: Feb  4 22:56:34 2019 GMT
-            Not After : Feb  1 22:56:34 2029 GMT
-        Subject: O = Acme Co
-        Subject Public Key Info:
-            Public Key Algorithm: id-ecPublicKey
-                Public-Key: (256 bit)
-                pub:
-                    04:84:a6:8c:69:53:af:87:4b:39:64:fe:04:24:e6:
-                    d8:fc:d6:46:39:35:0e:92:dc:48:08:7e:02:5f:1e:
-                    07:53:5c:d9:e0:56:c5:82:07:f6:a3:e2:ad:f6:ad:
-                    be:a0:4e:03:87:39:67:0c:9c:46:91:68:6b:0e:8e:
-                    f8:49:97:9d:5b
-                ASN1 OID: prime256v1
-                NIST CURVE: P-256
-        X509v3 extensions:
-            X509v3 Key Usage: critical
-                Digital Signature, Key Encipherment, Certificate Sign
-            X509v3 Extended Key Usage:
-                TLS Web Server Authentication
-            X509v3 Basic Constraints: critical
-                CA:TRUE
-            X509v3 Subject Alternative Name:
-                DNS:example
-    Signature Algorithm: ecdsa-with-SHA256
-         30:46:02:21:00:c6:81:61:61:42:8d:37:e7:d0:c3:72:43:44:
-         17:bd:84:ff:88:81:68:9a:99:08:ab:3c:3a:c0:1e:ea:8c:ba:
-         c0:02:21:00:de:c9:fa:e5:5e:c6:e2:db:23:64:43:a9:37:42:
-         72:92:7f:6e:89:38:ea:9e:2a:a7:fd:2f:ea:9a:ff:20:21:e7
------BEGIN CERTIFICATE-----
+const rootWithoutSKID = `-----BEGIN CERTIFICATE-----
 MIIBbzCCARSgAwIBAgIQeCkq3C8SOX/JM5PqYTl9cDAKBggqhkjOPQQDAjASMRAw
 DgYDVQQKEwdBY21lIENvMB4XDTE5MDIwNDIyNTYzNFoXDTI5MDIwMTIyNTYzNFow
 EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABISm
@@ -1739,49 +1601,9 @@
 BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MBIGA1UdEQQLMAmCB2V4YW1wbGUwCgYI
 KoZIzj0EAwIDSQAwRgIhAMaBYWFCjTfn0MNyQ0QXvYT/iIFompkIqzw6wB7qjLrA
 AiEA3sn65V7G4tsjZEOpN0Jykn9uiTjqniqn/S/qmv8gIec=
------END CERTIFICATE-----
-`
-	leafWithAKID = `
-	Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number:
-            f0:8a:62:f0:03:84:a2:cf:69:63:ad:71:3b:b6:5d:8c
-        Signature Algorithm: ecdsa-with-SHA256
-        Issuer: O = Acme Co
-        Validity
-            Not Before: Feb  4 23:06:52 2019 GMT
-            Not After : Feb  1 23:06:52 2029 GMT
-        Subject: O = Acme LLC
-        Subject Public Key Info:
-            Public Key Algorithm: id-ecPublicKey
-                Public-Key: (256 bit)
-                pub:
-                    04:5a:4e:4d:fb:ff:17:f7:b6:13:e8:29:45:34:81:
-                    39:ff:8c:9c:d9:8c:0a:9f:dd:b5:97:4c:2b:20:91:
-                    1c:4f:6b:be:53:27:66:ec:4a:ad:08:93:6d:66:36:
-                    0c:02:70:5d:01:ca:7f:c3:29:e9:4f:00:ba:b4:14:
-                    ec:c5:c3:34:b3
-                ASN1 OID: prime256v1
-                NIST CURVE: P-256
-        X509v3 extensions:
-            X509v3 Key Usage: critical
-                Digital Signature, Key Encipherment
-            X509v3 Extended Key Usage:
-                TLS Web Server Authentication
-            X509v3 Basic Constraints: critical
-                CA:FALSE
-            X509v3 Authority Key Identifier:
-                keyid:C2:2B:5F:91:78:34:26:09:42:8D:6F:51:B2:C5:AF:4C:0B:DE:6A:42
+-----END CERTIFICATE-----`
 
-            X509v3 Subject Alternative Name:
-                DNS:example
-    Signature Algorithm: ecdsa-with-SHA256
-         30:44:02:20:64:e0:ba:56:89:63:ce:22:5e:4f:22:15:fd:3c:
-         35:64:9a:3a:6b:7b:9a:32:a0:7f:f7:69:8c:06:f0:00:58:b8:
-         02:20:09:e4:9f:6d:8b:9e:38:e1:b6:01:d5:ee:32:a4:94:65:
-         93:2a:78:94:bb:26:57:4b:c7:dd:6c:3d:40:2b:63:90
------BEGIN CERTIFICATE-----
+const leafWithAKID = `-----BEGIN CERTIFICATE-----
 MIIBjTCCATSgAwIBAgIRAPCKYvADhKLPaWOtcTu2XYwwCgYIKoZIzj0EAwIwEjEQ
 MA4GA1UEChMHQWNtZSBDbzAeFw0xOTAyMDQyMzA2NTJaFw0yOTAyMDEyMzA2NTJa
 MBMxETAPBgNVBAoTCEFjbWUgTExDMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
@@ -1791,9 +1613,7 @@
 ssWvTAveakIwEgYDVR0RBAswCYIHZXhhbXBsZTAKBggqhkjOPQQDAgNHADBEAiBk
 4LpWiWPOIl5PIhX9PDVkmjpre5oyoH/3aYwG8ABYuAIgCeSfbYueOOG2AdXuMqSU
 ZZMqeJS7JldLx91sPUArY5A=
------END CERTIFICATE-----
-`
-)
+-----END CERTIFICATE-----`
 
 var unknownAuthorityErrorTests = []struct {
 	cert     string
@@ -2124,3 +1944,33 @@
 	}
 	t.Logf("verification took %v", time.Since(start))
 }
+
+func TestSystemRootsError(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("Windows does not use (or support) systemRoots")
+	}
+
+	defer func(oldSystemRoots *CertPool) { systemRoots = oldSystemRoots }(systemRootsPool())
+
+	opts := VerifyOptions{
+		Intermediates: NewCertPool(),
+		DNSName:       "www.google.com",
+		CurrentTime:   time.Unix(1395785200, 0),
+	}
+
+	if ok := opts.Intermediates.AppendCertsFromPEM([]byte(giag2Intermediate)); !ok {
+		t.Fatalf("failed to parse intermediate")
+	}
+
+	leaf, err := certificateFromPEM(googleLeaf)
+	if err != nil {
+		t.Fatalf("failed to parse leaf: %v", err)
+	}
+
+	systemRoots = nil
+
+	_, err = leaf.Verify(opts)
+	if _, ok := err.(SystemRootsError); !ok {
+		t.Errorf("error was not SystemRootsError: %v", err)
+	}
+}
diff --git a/src/database/sql/driver/driver.go b/src/database/sql/driver/driver.go
index 316e7ce..a0ba7ec 100644
--- a/src/database/sql/driver/driver.go
+++ b/src/database/sql/driver/driver.go
@@ -255,12 +255,9 @@
 // SessionResetter may be implemented by Conn to allow drivers to reset the
 // session state associated with the connection and to signal a bad connection.
 type SessionResetter interface {
-	// ResetSession is called while a connection is in the connection
-	// pool. No queries will run on this connection until this method returns.
-	//
-	// If the connection is bad this should return driver.ErrBadConn to prevent
-	// the connection from being returned to the connection pool. Any other
-	// error will be discarded.
+	// ResetSession is called prior to executing a query on the connection
+	// if the connection has been used before. If the driver returns ErrBadConn
+	// the connection is discarded.
 	ResetSession(ctx context.Context) error
 }
 
diff --git a/src/database/sql/fakedb_test.go b/src/database/sql/fakedb_test.go
index c0371f3..378ed77 100644
--- a/src/database/sql/fakedb_test.go
+++ b/src/database/sql/fakedb_test.go
@@ -393,12 +393,19 @@
 
 func (c *fakeConn) ResetSession(ctx context.Context) error {
 	c.dirtySession = false
+	c.currTx = nil
 	if c.isBad() {
 		return driver.ErrBadConn
 	}
 	return nil
 }
 
+var _ validator = (*fakeConn)(nil)
+
+func (c *fakeConn) IsValid() bool {
+	return !c.isBad()
+}
+
 func (c *fakeConn) Close() (err error) {
 	drv := fdriver.(*fakeDriver)
 	defer func() {
@@ -731,6 +738,9 @@
 func (s *fakeStmt) Exec(args []driver.Value) (driver.Result, error) {
 	panic("Using ExecContext")
 }
+
+var errFakeConnSessionDirty = errors.New("fakedb: session is dirty")
+
 func (s *fakeStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
 	if s.panic == "Exec" {
 		panic(s.panic)
@@ -743,7 +753,7 @@
 		return nil, driver.ErrBadConn
 	}
 	if s.c.isDirtyAndMark() {
-		return nil, errors.New("fakedb: session is dirty")
+		return nil, errFakeConnSessionDirty
 	}
 
 	err := checkSubsetTypes(s.c.db.allowAny, args)
@@ -857,7 +867,7 @@
 		return nil, driver.ErrBadConn
 	}
 	if s.c.isDirtyAndMark() {
-		return nil, errors.New("fakedb: session is dirty")
+		return nil, errFakeConnSessionDirty
 	}
 
 	err := checkSubsetTypes(s.c.db.allowAny, args)
@@ -890,6 +900,37 @@
 				}
 			}
 		}
+		if s.table == "tx_status" && s.colName[0] == "tx_status" {
+			txStatus := "autocommit"
+			if s.c.currTx != nil {
+				txStatus = "transaction"
+			}
+			cursor := &rowsCursor{
+				parentMem: s.c,
+				posRow:    -1,
+				rows: [][]*row{
+					[]*row{
+						{
+							cols: []interface{}{
+								txStatus,
+							},
+						},
+					},
+				},
+				cols: [][]string{
+					[]string{
+						"tx_status",
+					},
+				},
+				colType: [][]string{
+					[]string{
+						"string",
+					},
+				},
+				errPos: -1,
+			}
+			return cursor, nil
+		}
 
 		t.mu.Lock()
 
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index 5c5b7dc..25e2418 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -421,7 +421,6 @@
 	// It is closed during db.Close(). The close tells the connectionOpener
 	// goroutine to exit.
 	openerCh          chan struct{}
-	resetterCh        chan *driverConn
 	closed            bool
 	dep               map[finalCloser]depSet
 	lastPut           map[*driverConn]string // stacktrace of last conn's put; debug only
@@ -458,10 +457,10 @@
 
 	sync.Mutex  // guards following
 	ci          driver.Conn
+	needReset   bool // The connection session should be reset before use if true.
 	closed      bool
 	finalClosed bool // ci.Close has been called
 	openStmt    map[*driverStmt]bool
-	lastErr     error // lastError captures the result of the session resetter.
 
 	// guarded by db.mu
 	inUse      bool
@@ -486,6 +485,41 @@
 	return dc.createdAt.Add(timeout).Before(nowFunc())
 }
 
+// resetSession checks if the driver connection needs the
+// session to be reset and if required, resets it.
+func (dc *driverConn) resetSession(ctx context.Context) error {
+	dc.Lock()
+	defer dc.Unlock()
+
+	if !dc.needReset {
+		return nil
+	}
+	if cr, ok := dc.ci.(driver.SessionResetter); ok {
+		return cr.ResetSession(ctx)
+	}
+	return nil
+}
+
+// validator was introduced for Go1.15, but backported to Go1.14.
+type validator interface {
+	IsValid() bool
+}
+
+// validateConnection checks if the connection is valid and can
+// still be used. It also marks the session for reset if required.
+func (dc *driverConn) validateConnection(needsReset bool) bool {
+	dc.Lock()
+	defer dc.Unlock()
+
+	if needsReset {
+		dc.needReset = true
+	}
+	if cv, ok := dc.ci.(validator); ok {
+		return cv.IsValid()
+	}
+	return true
+}
+
 // prepareLocked prepares the query on dc. When cg == nil the dc must keep track of
 // the prepared statements in a pool.
 func (dc *driverConn) prepareLocked(ctx context.Context, cg stmtConnGrabber, query string) (*driverStmt, error) {
@@ -511,19 +545,6 @@
 	return ds, nil
 }
 
-// resetSession resets the connection session and sets the lastErr
-// that is checked before returning the connection to another query.
-//
-// resetSession assumes that the embedded mutex is locked when the connection
-// was returned to the pool. This unlocks the mutex.
-func (dc *driverConn) resetSession(ctx context.Context) {
-	defer dc.Unlock() // In case of panic.
-	if dc.closed {    // Check if the database has been closed.
-		return
-	}
-	dc.lastErr = dc.ci.(driver.SessionResetter).ResetSession(ctx)
-}
-
 // the dc.db's Mutex is held.
 func (dc *driverConn) closeDBLocked() func() error {
 	dc.Lock()
@@ -713,14 +734,12 @@
 	db := &DB{
 		connector:    c,
 		openerCh:     make(chan struct{}, connectionRequestQueueSize),
-		resetterCh:   make(chan *driverConn, 50),
 		lastPut:      make(map[*driverConn]string),
 		connRequests: make(map[uint64]chan connRequest),
 		stop:         cancel,
 	}
 
 	go db.connectionOpener(ctx)
-	go db.connectionResetter(ctx)
 
 	return db
 }
@@ -1058,23 +1077,6 @@
 	}
 }
 
-// connectionResetter runs in a separate goroutine to reset connections async
-// to exported API.
-func (db *DB) connectionResetter(ctx context.Context) {
-	for {
-		select {
-		case <-ctx.Done():
-			close(db.resetterCh)
-			for dc := range db.resetterCh {
-				dc.Unlock()
-			}
-			return
-		case dc := <-db.resetterCh:
-			dc.resetSession(ctx)
-		}
-	}
-}
-
 // Open one new connection
 func (db *DB) openNewConnection(ctx context.Context) {
 	// maybeOpenNewConnctions has already executed db.numOpen++ before it sent
@@ -1155,14 +1157,13 @@
 			conn.Close()
 			return nil, driver.ErrBadConn
 		}
-		// Lock around reading lastErr to ensure the session resetter finished.
-		conn.Lock()
-		err := conn.lastErr
-		conn.Unlock()
-		if err == driver.ErrBadConn {
+
+		// Reset the session if required.
+		if err := conn.resetSession(ctx); err == driver.ErrBadConn {
 			conn.Close()
 			return nil, driver.ErrBadConn
 		}
+
 		return conn, nil
 	}
 
@@ -1204,18 +1205,22 @@
 			if !ok {
 				return nil, errDBClosed
 			}
-			if ret.err == nil && ret.conn.expired(lifetime) {
+			// Only check if the connection is expired if the strategy is cachedOrNewConns.
+			// If we require a new connection, just re-use the connection without looking
+			// at the expiry time. If it is expired, it will be checked when it is placed
+			// back into the connection pool.
+			// This prioritizes giving a valid connection to a client over the exact connection
+			// lifetime, which could expire exactly after this point anyway.
+			if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) {
 				ret.conn.Close()
 				return nil, driver.ErrBadConn
 			}
 			if ret.conn == nil {
 				return nil, ret.err
 			}
-			// Lock around reading lastErr to ensure the session resetter finished.
-			ret.conn.Lock()
-			err := ret.conn.lastErr
-			ret.conn.Unlock()
-			if err == driver.ErrBadConn {
+
+			// Reset the session if required.
+			if err := ret.conn.resetSession(ctx); err == driver.ErrBadConn {
 				ret.conn.Close()
 				return nil, driver.ErrBadConn
 			}
@@ -1275,13 +1280,23 @@
 // putConn adds a connection to the db's free pool.
 // err is optionally the last error that occurred on this connection.
 func (db *DB) putConn(dc *driverConn, err error, resetSession bool) {
+	if err != driver.ErrBadConn {
+		if !dc.validateConnection(resetSession) {
+			err = driver.ErrBadConn
+		}
+	}
 	db.mu.Lock()
 	if !dc.inUse {
+		db.mu.Unlock()
 		if debugGetPut {
 			fmt.Printf("putConn(%v) DUPLICATE was: %s\n\nPREVIOUS was: %s", dc, stack(), db.lastPut[dc])
 		}
 		panic("sql: connection returned that was never out")
 	}
+
+	if err != driver.ErrBadConn && dc.expired(db.maxLifetime) {
+		err = driver.ErrBadConn
+	}
 	if debugGetPut {
 		db.lastPut[dc] = stack()
 	}
@@ -1305,41 +1320,13 @@
 	if putConnHook != nil {
 		putConnHook(db, dc)
 	}
-	if db.closed {
-		// Connections do not need to be reset if they will be closed.
-		// Prevents writing to resetterCh after the DB has closed.
-		resetSession = false
-	}
-	if resetSession {
-		if _, resetSession = dc.ci.(driver.SessionResetter); resetSession {
-			// Lock the driverConn here so it isn't released until
-			// the connection is reset.
-			// The lock must be taken before the connection is put into
-			// the pool to prevent it from being taken out before it is reset.
-			dc.Lock()
-		}
-	}
 	added := db.putConnDBLocked(dc, nil)
 	db.mu.Unlock()
 
 	if !added {
-		if resetSession {
-			dc.Unlock()
-		}
 		dc.Close()
 		return
 	}
-	if !resetSession {
-		return
-	}
-	select {
-	default:
-		// If the resetterCh is blocking then mark the connection
-		// as bad and continue on.
-		dc.lastErr = driver.ErrBadConn
-		dc.Unlock()
-	case db.resetterCh <- dc:
-	}
 }
 
 // Satisfy a connRequest or put the driverConn in the idle pool and return true
@@ -1701,7 +1688,11 @@
 // beginDC starts a transaction. The provided dc must be valid and ready to use.
 func (db *DB) beginDC(ctx context.Context, dc *driverConn, release func(error), opts *TxOptions) (tx *Tx, err error) {
 	var txi driver.Tx
+	keepConnOnRollback := false
 	withLock(dc, func() {
+		_, hasSessionResetter := dc.ci.(driver.SessionResetter)
+		_, hasConnectionValidator := dc.ci.(validator)
+		keepConnOnRollback = hasSessionResetter && hasConnectionValidator
 		txi, err = ctxDriverBegin(ctx, opts, dc.ci)
 	})
 	if err != nil {
@@ -1713,12 +1704,13 @@
 	// The cancel function in Tx will be called after done is set to true.
 	ctx, cancel := context.WithCancel(ctx)
 	tx = &Tx{
-		db:          db,
-		dc:          dc,
-		releaseConn: release,
-		txi:         txi,
-		cancel:      cancel,
-		ctx:         ctx,
+		db:                 db,
+		dc:                 dc,
+		releaseConn:        release,
+		txi:                txi,
+		cancel:             cancel,
+		keepConnOnRollback: keepConnOnRollback,
+		ctx:                ctx,
 	}
 	go tx.awaitDone()
 	return tx, nil
@@ -1980,6 +1972,11 @@
 	// Use atomic operations on value when checking value.
 	done int32
 
+	// keepConnOnRollback is true if the driver knows
+	// how to reset the connection's session and if need be discard
+	// the connection.
+	keepConnOnRollback bool
+
 	// All Stmts prepared for this transaction. These will be closed after the
 	// transaction has been committed or rolled back.
 	stmts struct {
@@ -2005,7 +2002,10 @@
 	// transaction is closed and the resources are released.  This
 	// rollback does nothing if the transaction has already been
 	// committed or rolled back.
-	tx.rollback(true)
+	// Do not discard the connection if the connection knows
+	// how to reset the session.
+	discardConnection := !tx.keepConnOnRollback
+	tx.rollback(discardConnection)
 }
 
 func (tx *Tx) isDone() bool {
@@ -2016,14 +2016,10 @@
 // that has already been committed or rolled back.
 var ErrTxDone = errors.New("sql: transaction has already been committed or rolled back")
 
-// close returns the connection to the pool and
-// must only be called by Tx.rollback or Tx.Commit.
-func (tx *Tx) close(err error) {
-	tx.cancel()
-
-	tx.closemu.Lock()
-	defer tx.closemu.Unlock()
-
+// closeLocked returns the connection to the pool and
+// must only be called by Tx.rollback or Tx.Commit while
+// closemu is Locked and tx already canceled.
+func (tx *Tx) closeLocked(err error) {
 	tx.releaseConn(err)
 	tx.dc = nil
 	tx.txi = nil
@@ -2090,6 +2086,15 @@
 	if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) {
 		return ErrTxDone
 	}
+
+	// Cancel the Tx to release any active R-closemu locks.
+	// This is safe to do because tx.done has already transitioned
+	// from 0 to 1. Hold the W-closemu lock prior to rollback
+	// to ensure no other connection has an active query.
+	tx.cancel()
+	tx.closemu.Lock()
+	defer tx.closemu.Unlock()
+
 	var err error
 	withLock(tx.dc, func() {
 		err = tx.txi.Commit()
@@ -2097,16 +2102,31 @@
 	if err != driver.ErrBadConn {
 		tx.closePrepared()
 	}
-	tx.close(err)
+	tx.closeLocked(err)
 	return err
 }
 
+var rollbackHook func()
+
 // rollback aborts the transaction and optionally forces the pool to discard
 // the connection.
 func (tx *Tx) rollback(discardConn bool) error {
 	if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) {
 		return ErrTxDone
 	}
+
+	if rollbackHook != nil {
+		rollbackHook()
+	}
+
+	// Cancel the Tx to release any active R-closemu locks.
+	// This is safe to do because tx.done has already transitioned
+	// from 0 to 1. Hold the W-closemu lock prior to rollback
+	// to ensure no other connection has an active query.
+	tx.cancel()
+	tx.closemu.Lock()
+	defer tx.closemu.Unlock()
+
 	var err error
 	withLock(tx.dc, func() {
 		err = tx.txi.Rollback()
@@ -2117,7 +2137,7 @@
 	if discardConn {
 		err = driver.ErrBadConn
 	}
-	tx.close(err)
+	tx.closeLocked(err)
 	return err
 }
 
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
index f68cefe..a799093 100644
--- a/src/database/sql/sql_test.go
+++ b/src/database/sql/sql_test.go
@@ -80,6 +80,11 @@
 		exec(t, db, "CREATE|magicquery|op=string,millis=int32")
 		exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
 	}
+	if name == "tx_status" {
+		// Magic table name and column, known by fakedb_test.go.
+		exec(t, db, "CREATE|tx_status|tx_status=string")
+		exec(t, db, "INSERT|tx_status|tx_status=invalid")
+	}
 	return db
 }
 
@@ -437,6 +442,7 @@
 		}
 		t.Fatal(err)
 	}
+	tx.keepConnOnRollback = false
 
 	// This will trigger the *fakeConn.Prepare method which will take time
 	// performing the query. The ctxDriverPrepare func will check the context
@@ -449,6 +455,35 @@
 	waitForFree(t, db, 5*time.Second, 0)
 }
 
+// TestTxContextWaitNoDiscard is the same as TestTxContextWait, but should not discard
+// the final connection.
+func TestTxContextWaitNoDiscard(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Millisecond)
+	defer cancel()
+
+	tx, err := db.BeginTx(ctx, nil)
+	if err != nil {
+		// Guard against the context being canceled before BeginTx completes.
+		if err == context.DeadlineExceeded {
+			t.Skip("tx context canceled prior to first use")
+		}
+		t.Fatal(err)
+	}
+
+	// This will trigger the *fakeConn.Prepare method which will take time
+	// performing the query. The ctxDriverPrepare func will check the context
+	// after this and close the rows and return an error.
+	_, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
+	if err != context.DeadlineExceeded {
+		t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
+	}
+
+	waitForFree(t, db, 5*time.Second, 1)
+}
+
 // TestUnsupportedOptions checks that the database fails when a driver that
 // doesn't implement ConnBeginTx is used with non-default options and an
 // un-cancellable context.
@@ -1521,6 +1556,37 @@
 	}
 }
 
+// TestConnIsValid verifies that a database connection that should be discarded,
+// is actually discarded and does not re-enter the connection pool.
+// If the IsValid method from *fakeConn is removed, this test will fail.
+func TestConnIsValid(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	db.SetMaxOpenConns(1)
+
+	ctx := context.Background()
+
+	c, err := db.Conn(ctx)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = c.Raw(func(raw interface{}) error {
+		dc := raw.(*fakeConn)
+		dc.stickyBad = true
+		return nil
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	c.Close()
+
+	if len(db.freeConn) > 0 && db.freeConn[0].ci.(*fakeConn).stickyBad {
+		t.Fatal("bad connection returned to pool; expected bad connection to be discarded")
+	}
+}
+
 // Tests fix for issue 2542, that we release a lock when querying on
 // a closed connection.
 func TestIssue2542Deadlock(t *testing.T) {
@@ -2654,6 +2720,159 @@
 	}
 }
 
+// Issue 34755: Ensure that a Tx cannot commit after a rollback.
+func TestTxCannotCommitAfterRollback(t *testing.T) {
+	db := newTestDB(t, "tx_status")
+	defer closeDB(t, db)
+
+	// First check query reporting is correct.
+	var txStatus string
+	err := db.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if g, w := txStatus, "autocommit"; g != w {
+		t.Fatalf("tx_status=%q, wanted %q", g, w)
+	}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	tx, err := db.BeginTx(ctx, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Ignore dirty session for this test.
+	// A failing test should trigger the dirty session flag as well,
+	// but that isn't exactly what this should test for.
+	tx.txi.(*fakeTx).c.skipDirtySession = true
+
+	defer tx.Rollback()
+
+	err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if g, w := txStatus, "transaction"; g != w {
+		t.Fatalf("tx_status=%q, wanted %q", g, w)
+	}
+
+	// 1. Begin a transaction.
+	// 2. (A) Start a query, (B) begin Tx rollback through a ctx cancel.
+	// 3. Check if 2.A has committed in Tx (pass) or outside of Tx (fail).
+	sendQuery := make(chan struct{})
+	hookTxGrabConn = func() {
+		cancel()
+		<-sendQuery
+	}
+	rollbackHook = func() {
+		close(sendQuery)
+	}
+	defer func() {
+		hookTxGrabConn = nil
+		rollbackHook = nil
+	}()
+
+	err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
+	if err != nil {
+		// A failure here would be expected if skipDirtySession was not set to true above.
+		t.Fatal(err)
+	}
+	if g, w := txStatus, "transaction"; g != w {
+		t.Fatalf("tx_status=%q, wanted %q", g, w)
+	}
+}
+
+// Issue32530 encounters an issue where a connection may
+// expire right after it comes out of a used connection pool
+// even when a new connection is requested.
+func TestConnExpiresFreshOutOfPool(t *testing.T) {
+	execCases := []struct {
+		expired  bool
+		badReset bool
+	}{
+		{false, false},
+		{true, false},
+		{false, true},
+	}
+
+	t0 := time.Unix(1000000, 0)
+	offset := time.Duration(0)
+	offsetMu := sync.RWMutex{}
+
+	nowFunc = func() time.Time {
+		offsetMu.RLock()
+		defer offsetMu.RUnlock()
+		return t0.Add(offset)
+	}
+	defer func() { nowFunc = time.Now }()
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	db := newTestDB(t, "magicquery")
+	defer closeDB(t, db)
+
+	db.SetMaxOpenConns(1)
+
+	for _, ec := range execCases {
+		ec := ec
+		name := fmt.Sprintf("expired=%t,badReset=%t", ec.expired, ec.badReset)
+		t.Run(name, func(t *testing.T) {
+			db.clearAllConns(t)
+
+			db.SetMaxIdleConns(1)
+			db.SetConnMaxLifetime(10 * time.Second)
+
+			conn, err := db.conn(ctx, alwaysNewConn)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			afterPutConn := make(chan struct{})
+			waitingForConn := make(chan struct{})
+
+			go func() {
+				conn, err := db.conn(ctx, alwaysNewConn)
+				if err != nil {
+					t.Fatal(err)
+				}
+				db.putConn(conn, err, false)
+				close(afterPutConn)
+			}()
+			go func() {
+				for {
+					db.mu.Lock()
+					ct := len(db.connRequests)
+					db.mu.Unlock()
+					if ct > 0 {
+						close(waitingForConn)
+						return
+					}
+					time.Sleep(10 * time.Millisecond)
+				}
+			}()
+
+			<-waitingForConn
+
+			offsetMu.Lock()
+			if ec.expired {
+				offset = 11 * time.Second
+			} else {
+				offset = time.Duration(0)
+			}
+			offsetMu.Unlock()
+
+			conn.ci.(*fakeConn).stickyBad = ec.badReset
+
+			db.putConn(conn, err, true)
+
+			<-afterPutConn
+		})
+	}
+}
+
 // TestIssue20575 ensures the Rows from query does not block
 // closing a transaction. Ensure Rows is closed while closing a trasaction.
 func TestIssue20575(t *testing.T) {
diff --git a/src/net/dial_test.go b/src/net/dial_test.go
index 1bf96fd..42e5d68 100644
--- a/src/net/dial_test.go
+++ b/src/net/dial_test.go
@@ -154,7 +154,7 @@
 	return c, err
 }
 
-func dialClosedPort() (actual, expected time.Duration) {
+func dialClosedPort(t *testing.T) (actual, expected time.Duration) {
 	// Estimate the expected time for this platform.
 	// On Windows, dialing a closed port takes roughly 1 second,
 	// but other platforms should be instantaneous.
@@ -168,6 +168,7 @@
 
 	l, err := Listen("tcp", "127.0.0.1:0")
 	if err != nil {
+		t.Logf("dialClosedPort: Listen failed: %v", err)
 		return 999 * time.Hour, expected
 	}
 	addr := l.Addr().String()
@@ -183,6 +184,7 @@
 		}
 		elapsed := time.Now().Sub(startTime)
 		if i == 2 {
+			t.Logf("dialClosedPort: measured delay %v", elapsed)
 			return elapsed, expected
 		}
 	}
@@ -195,7 +197,7 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	closedPortDelay, expectClosedPortDelay := dialClosedPort()
+	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
 	if closedPortDelay > expectClosedPortDelay {
 		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
 	}
@@ -316,8 +318,14 @@
 			t.Errorf("#%d: got nil; want non-nil", i)
 		}
 
-		expectElapsedMin := tt.expectElapsed - 95*time.Millisecond
-		expectElapsedMax := tt.expectElapsed + 95*time.Millisecond
+		// We used to always use 95 milliseconds as the slop,
+		// but that was flaky on Windows.  See issue 35616.
+		slop := 95 * time.Millisecond
+		if fifth := tt.expectElapsed / 5; fifth > slop {
+			slop = fifth
+		}
+		expectElapsedMin := tt.expectElapsed - slop
+		expectElapsedMax := tt.expectElapsed + slop
 		if elapsed < expectElapsedMin {
 			t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectElapsedMin)
 		} else if elapsed > expectElapsedMax {
@@ -664,7 +672,7 @@
 		t.Skip("both IPv4 and IPv6 are required")
 	}
 
-	closedPortDelay, expectClosedPortDelay := dialClosedPort()
+	closedPortDelay, expectClosedPortDelay := dialClosedPort(t)
 	if closedPortDelay > expectClosedPortDelay {
 		t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
 	}
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 41d46dc..ac4ed23 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -408,6 +408,7 @@
 		}
 		if buf[0] == ',' {
 			buf = buf[1:]
+			continue
 		}
 		if buf[0] == '*' {
 			return condFalse
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index 762e88b..f3c240f 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -837,6 +837,15 @@
 			wantStatus:      200,
 			wantContentType: "text/css; charset=utf-8",
 		},
+		"if_none_match_malformed": {
+			file:      "testdata/style.css",
+			serveETag: `"foo"`,
+			reqHeader: map[string]string{
+				"If-None-Match": `,`,
+			},
+			wantStatus:      200,
+			wantContentType: "text/css; charset=utf-8",
+		},
 		"range_good": {
 			file:      "testdata/style.css",
 			serveETag: `"A"`,
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 8252e45..a66e798b 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -424,6 +424,16 @@
 	wants10KeepAlive bool               // HTTP/1.0 w/ Connection "keep-alive"
 	wantsClose       bool               // HTTP request has Connection "close"
 
+	// canWriteContinue is a boolean value accessed as an atomic int32
+	// that says whether or not a 100 Continue header can be written
+	// to the connection.
+	// writeContinueMu must be held while writing the header.
+	// These two fields together synchronize the body reader
+	// (the expectContinueReader, which wants to write 100 Continue)
+	// against the main writer.
+	canWriteContinue atomicBool
+	writeContinueMu  sync.Mutex
+
 	w  *bufio.Writer // buffers output in chunks to chunkWriter
 	cw chunkWriter
 
@@ -514,6 +524,7 @@
 
 func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
 func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }
+func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
 
 // declareTrailer is called for each Trailer header when the
 // response header is written. It notes that a header will need to be
@@ -876,21 +887,27 @@
 	resp       *response
 	readCloser io.ReadCloser
 	closed     bool
-	sawEOF     bool
+	sawEOF     atomicBool
 }
 
 func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
 	if ecr.closed {
 		return 0, ErrBodyReadAfterClose
 	}
-	if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked() {
-		ecr.resp.wroteContinue = true
-		ecr.resp.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
-		ecr.resp.conn.bufw.Flush()
+	w := ecr.resp
+	if !w.wroteContinue && w.canWriteContinue.isSet() && !w.conn.hijacked() {
+		w.wroteContinue = true
+		w.writeContinueMu.Lock()
+		if w.canWriteContinue.isSet() {
+			w.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
+			w.conn.bufw.Flush()
+			w.canWriteContinue.setFalse()
+		}
+		w.writeContinueMu.Unlock()
 	}
 	n, err = ecr.readCloser.Read(p)
 	if err == io.EOF {
-		ecr.sawEOF = true
+		ecr.sawEOF.setTrue()
 	}
 	return
 }
@@ -1309,7 +1326,7 @@
 	// because we don't know if the next bytes on the wire will be
 	// the body-following-the-timer or the subsequent request.
 	// See Issue 11549.
-	if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF {
+	if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.isSet() {
 		w.closeAfterReply = true
 	}
 
@@ -1554,6 +1571,17 @@
 		}
 		return 0, ErrHijacked
 	}
+
+	if w.canWriteContinue.isSet() {
+		// Body reader wants to write 100 Continue but hasn't yet.
+		// Tell it not to. The store must be done while holding the lock
+		// because the lock makes sure that there is not an active write
+		// this very moment.
+		w.writeContinueMu.Lock()
+		w.canWriteContinue.setFalse()
+		w.writeContinueMu.Unlock()
+	}
+
 	if !w.wroteHeader {
 		w.WriteHeader(StatusOK)
 	}
@@ -1866,6 +1894,7 @@
 			if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
 				// Wrap the Body reader with one that replies on the connection
 				req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
+				w.canWriteContinue.setTrue()
 			}
 		} else if req.Header.get("Expect") != "" {
 			w.sendExpectationFailed()
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 9ea95bc..6daeb65 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -577,6 +577,13 @@
 			// Convert v to type typ if v is assignable to a variable
 			// of type t in the language spec.
 			// See issue 28761.
+			if typ.Kind() == Interface {
+				// We must clear the destination before calling assignTo,
+				// in case assignTo writes (with memory barriers) to the
+				// target location used as scratch space. See issue 39541.
+				*(*uintptr)(addr) = 0
+				*(*uintptr)(add(addr, ptrSize, "typ.size == 2*ptrSize")) = 0
+			}
 			v = v.assignTo("reflect.MakeFunc", typ, addr)
 
 			// We are writing to stack. No write barrier.
@@ -2367,6 +2374,7 @@
 // assignTo returns a value v that can be assigned directly to typ.
 // It panics if v is not assignable to typ.
 // For a conversion to an interface type, target is a suggested scratch space to use.
+// target must be initialized memory (or nil).
 func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
 	if v.flag&flagMethod != 0 {
 		v = makeMethodValue(context, v)
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 7ae3eee..39876e2 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -543,6 +543,7 @@
 }
 
 // Information from the compiler about the layout of stack frames.
+// Note: this type must agree with reflect.bitVector.
 type bitvector struct {
 	n        int32 // # of bits
 	bytedata *uint8
diff --git a/test/fixedbugs/issue39459.go b/test/fixedbugs/issue39459.go
new file mode 100644
index 0000000..de78a17
--- /dev/null
+++ b/test/fixedbugs/issue39459.go
@@ -0,0 +1,22 @@
+// compile
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T struct { // big enough to be an unSSAable type
+	a, b, c, d, e, f int
+}
+
+func f(x interface{}, p *int) {
+	_ = *p // trigger nil check here, removing it from below
+	switch x := x.(type) {
+	case *T:
+		// Zero twice, so one of them will be removed by the deadstore pass
+		*x = T{}
+		*p = 0 // store op to prevent Zero ops from being optimized by the earlier opt pass rewrite rules
+		*x = T{}
+	}
+}
diff --git a/test/fixedbugs/issue39541.go b/test/fixedbugs/issue39541.go
new file mode 100644
index 0000000..fba5291
--- /dev/null
+++ b/test/fixedbugs/issue39541.go
@@ -0,0 +1,33 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "reflect"
+
+func sub(args []reflect.Value) []reflect.Value {
+	type A struct {
+		s int
+		t int
+	}
+	return []reflect.Value{reflect.ValueOf(A{1, 2})}
+}
+
+func main() {
+	f := reflect.MakeFunc(reflect.TypeOf((func() interface{})(nil)), sub).Interface().(func() interface{})
+	c := make(chan bool, 100)
+	for i := 0; i < 100; i++ {
+		go func() {
+			for j := 0; j < 10000; j++ {
+				f()
+			}
+			c <- true
+		}()
+	}
+	for i := 0; i < 100; i++ {
+		<-c
+	}
+}