crypto/x509: prevent chain cycles in Verify

It's possible to include a self-signed root certificate as an
intermediate and push Verify into a loop.

I already had a test for this so I thought that it was ok, but it
turns out that the test was void because the Verisign root certificate
doesn't contain the "IsCA" flag and so it wasn't an acceptable
intermediate certificate for that reason.

R=bradfitz
CC=golang-dev
https://golang.org/cl/4657080
This commit is contained in:
Adam Langley 2011-07-07 18:06:50 -04:00
parent 141f676bab
commit d1d466f620
2 changed files with 17 additions and 10 deletions

View File

@ -171,8 +171,14 @@ func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain [
chains = append(chains, appendToFreshChain(currentChain, root))
}
nextIntermediate:
for _, intermediateNum := range opts.Intermediates.findVerifiedParents(c) {
intermediate := opts.Intermediates.certs[intermediateNum]
for _, cert := range currentChain {
if cert == intermediate {
continue nextIntermediate
}
}
err = intermediate.isValid(intermediateCertificate, opts)
if err != nil {
continue

View File

@ -71,16 +71,6 @@ var verifyTests = []verifyTest{
[]string{"Google", "Thawte", "VeriSign"},
},
},
{
leaf: googleLeaf,
intermediates: []string{verisignRoot, thawteIntermediate},
roots: []string{verisignRoot},
currentTime: 1302726541,
expectedChains: [][]string{
[]string{"Google", "Thawte", "VeriSign"},
},
},
{
leaf: dnssecExpLeaf,
intermediates: []string{startComIntermediate},
@ -91,6 +81,17 @@ var verifyTests = []verifyTest{
[]string{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
},
},
{
leaf: dnssecExpLeaf,
intermediates: []string{startComIntermediate, startComRoot},
roots: []string{startComRoot},
currentTime: 1302726541,
expectedChains: [][]string{
[]string{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
[]string{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority", "StartCom Certification Authority"},
},
},
}
func expectHostnameError(t *testing.T, i int, err os.Error) (ok bool) {