by us@ulrich-simon.de:
If opts contains at least 2 intermediate certificates and for the first one the
validation process fails, the invalid chain is still added to the returned list.
The error variable will be overwritten in the verification of the 2nd intermediate
certificate.
Thus the function returns err == nil with 2 chains, even though only one is valid.
The missing error handling can be found in:
crypto/x509/verify.go:285-304
nextIntermediate:
for _, intermediateNum := range possibleIntermediates {
intermediate := opts.Intermediates.certs[intermediateNum]
for _, cert := range currentChain {
if cert == intermediate {
continue nextIntermediate
}
}
err = intermediate.isValid(intermediateCertificate, currentChain, opts)
if err != nil {
continue
}
var childChains [][]*Certificate
childChains, ok := cache[intermediateNum]
if !ok {
childChains, err = intermediate.buildChains(cache, appendToFreshChain(currentChain, intermediate), opts)
cache[intermediateNum] = childChains
}
chains = append(chains, childChains...)
}
In line 300, the returned err in "childChains, err =
intermediate.buildChains(..)" is not handled and might be overwritten in the next
loop in line 293.
Proposed Solution: Insert @line 301: "if err != nil { continue }"
I hope my observation is right and it helps :-) .
by us@ulrich-simon.de:
If opts contains at least 2 intermediate certificates and for the first one the validation process fails, the invalid chain is still added to the returned list. The error variable will be overwritten in the verification of the 2nd intermediate certificate. Thus the function returns err == nil with 2 chains, even though only one is valid. The missing error handling can be found in: crypto/x509/verify.go:285-304 nextIntermediate: for _, intermediateNum := range possibleIntermediates { intermediate := opts.Intermediates.certs[intermediateNum] for _, cert := range currentChain { if cert == intermediate { continue nextIntermediate } } err = intermediate.isValid(intermediateCertificate, currentChain, opts) if err != nil { continue } var childChains [][]*Certificate childChains, ok := cache[intermediateNum] if !ok { childChains, err = intermediate.buildChains(cache, appendToFreshChain(currentChain, intermediate), opts) cache[intermediateNum] = childChains } chains = append(chains, childChains...) } In line 300, the returned err in "childChains, err = intermediate.buildChains(..)" is not handled and might be overwritten in the next loop in line 293. Proposed Solution: Insert @line 301: "if err != nil { continue }" I hope my observation is right and it helps :-) .