Skip to content

Commit f599f48

Browse files
committed
fix(client): use dedicated cert cache
aims to solve race condition when NewDefault() from certmagic is used https://github.com/ipfs/kubo/pull/10521/files/e6e0b7a1dc350430c64438417bc5ed4a38171895#diff-52740993e6a197feddd69dc9db132b0b7babd2cf3c0b337bde3476b779c07a77
1 parent 97f25ad commit f599f48

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

client/acme.go

+38-3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ type P2PForgeCertMgr struct {
4242
certCheckMx sync.RWMutex
4343
}
4444

45+
var (
46+
defaultCertCache *certmagic.Cache
47+
defaultCertCacheMu sync.Mutex
48+
)
49+
4550
func isRelayAddr(a multiaddr.Multiaddr) bool {
4651
found := false
4752
multiaddr.ForEach(a, func(c multiaddr.Component) bool {
@@ -182,6 +187,35 @@ func WithLogger(log *zap.SugaredLogger) P2PForgeCertMgrOptions {
182187
}
183188
}
184189

190+
// newCertmagicConfig is p2p-forge/client-specific version of
191+
// certmagic.NewDefault() that ensures we have our own cert cache. This is
192+
// necessary to ensure cert maintenance spawned by NewCache does not share
193+
// global certmagic.Default.Storage, and certmagic.Default.Logger and uses
194+
// storage path specific to p2p-forge, and no other instance of certmagic in
195+
// golang application.
196+
func newCertmagicConfig(mgrCfg *P2PForgeCertMgrConfig) *certmagic.Config {
197+
clog := mgrCfg.log.Desugar()
198+
199+
defaultCertCacheMu.Lock()
200+
if defaultCertCache == nil {
201+
defaultCertCache = certmagic.NewCache(certmagic.CacheOptions{
202+
GetConfigForCert: func(certmagic.Certificate) (*certmagic.Config, error) {
203+
// default getter that does not depend on certmagic defaults
204+
// and respects Config.Storage path
205+
return newCertmagicConfig(mgrCfg), nil
206+
},
207+
Logger: clog,
208+
})
209+
}
210+
certCache := defaultCertCache
211+
defaultCertCacheMu.Unlock()
212+
213+
return certmagic.New(certCache, certmagic.Config{
214+
Storage: mgrCfg.storage,
215+
Logger: clog,
216+
})
217+
}
218+
185219
// NewP2PForgeCertMgr handles the creation and management of certificates that are automatically granted by a forge
186220
// to a libp2p host.
187221
//
@@ -217,9 +251,8 @@ func NewP2PForgeCertMgr(opts ...P2PForgeCertMgrOptions) (*P2PForgeCertMgr, error
217251
mgrCfg.storage = &certmagic.FileStorage{Path: defaultStorageLocation}
218252
}
219253

220-
certCfg := certmagic.NewDefault()
221-
certCfg.Storage = mgrCfg.storage
222-
certCfg.Logger = mgrCfg.log.Desugar()
254+
certCfg := newCertmagicConfig(mgrCfg)
255+
223256
hostChan := make(chan host.Host, 1)
224257
provideHost := func(host host.Host) { hostChan <- host }
225258
hasHostChan := make(chan struct{})
@@ -249,7 +282,9 @@ func NewP2PForgeCertMgr(opts ...P2PForgeCertMgrOptions) (*P2PForgeCertMgr, error
249282
allowPrivateForgeAddresses: mgrCfg.allowPrivateForgeAddresses,
250283
},
251284
TrustedRoots: mgrCfg.trustedRoots,
285+
Logger: certCfg.Logger,
252286
})
287+
253288
certCfg.Issuers = []certmagic.Issuer{myACME}
254289

255290
mgr := &P2PForgeCertMgr{

0 commit comments

Comments
 (0)