You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 :-) .
The text was updated successfully, but these errors were encountered:
Cert verification is much more complex than I like and I don't exclude the possibility
of a bug in there, but do you have a case where this has gone wrong, or is it based on
inspection?
I'm trying to build a test case where an extra chain can be returned but no luck so far.
In the code, if there's no valid path from an intermediate to a root, then childChains
is intended to be empty. So the append should be a noop (note the "..." in the append
line).
My best guess for triggering a problem was this structure:
leaf -> issuer2 -> issuer2Parent
-> issuer1 -> root*
Both issuer1 and issuer2 are possible issuers for leaf. issuer2 is listed first and the
chain builds up to another parent, but no root. issuer1 is then considered and does
chain to a trusted root. (Where a trusted certificate is indicated by a *.)
However, this works as expected.
This is on inspection and I didn't really recognize the "...".
This "noop append" will wor. The function is built so that there are no chains returned
when there is err != nil.
Even the cache seems to work right if I think it through. Things are very dependend on
each other.
Unfortunatelly there are no source comments. I guess this is the advanced stuff...
Thanks for verifying :) .
by us@ulrich-simon.de:
The text was updated successfully, but these errors were encountered: