Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition on creating a full chain for a certificate #1255

Open
aaomidi opened this issue Dec 1, 2023 · 2 comments
Open

Race condition on creating a full chain for a certificate #1255

aaomidi opened this issue Dec 1, 2023 · 2 comments
Assignees

Comments

@aaomidi
Copy link
Contributor

aaomidi commented Dec 1, 2023

I've come across a race with how

compatibleLogsAndChain := func() (loglist3.LogList, []*x509.Certificate, error) {
d.mu.RLock()
defer d.mu.RUnlock()
vOpts := ctfe.NewCertValidationOpts(d.rootPool, time.Time{}, false, false, nil, nil, false, nil)
rootedChain, err := ctfe.ValidateChain(rawChain, vOpts)
builds the rootedChain.

ctfe.ValidateChain takes in the global root pool. This pool contains every single root that the application started with. Those get populated here:

// Merge individual root-pools into a unified one
d.rootPool = x509util.NewPEMCertPool()
for _, pool := range d.logRoots {
for _, c := range pool.RawCertificates() {
d.rootPool.AddCert(c)
}
}

The race condition is that PEMCertPool gets populated in an arbitrary order since the loop is over a map.

ctfe.ValidateChain builds various chains, and picks the first valid one:

// Verify might have found multiple paths to roots. Now we check that we have a path that
// uses all the certs in the order they were submitted so as to comply with RFC 6962
// requirements detailed in Section 3.1.
for _, verifiedChain := range verifiedChains {
if chainsEquivalent(chain, verifiedChain) {
return verifiedChain, nil
}
}

However, not every CT log necessarily has the same trust store, and the RootCompatible method will filter that CT log out.

The fix for this would be to consider the root pool per log so the constructed chain can be different per log.

@roger2hk
Copy link
Contributor

@aaomidi Is this issue fully addressed by #1258?

@aaomidi
Copy link
Contributor Author

aaomidi commented May 30, 2024

Not at all. That PR simply disabled this functionality to work around the bug.

The real solution requires making a trust anchor per log endpoint, or potentially getting rid of this feature entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants