From 3ddcbc91382dbb0f184074542cb7e1a28b96a9e9 Mon Sep 17 00:00:00 2001 From: zachmann Date: Fri, 22 Aug 2025 11:45:20 +0200 Subject: [PATCH 1/6] [trust resolver] refactor TrustAnchors types --- trustresolver.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/trustresolver.go b/trustresolver.go index 5b938ef..14a5d6b 100644 --- a/trustresolver.go +++ b/trustresolver.go @@ -142,7 +142,7 @@ func (m *JWSMessages) UnmarshalJSON(data []byte) error { // TrustResolver is type for resolving trust chains from a StartingEntity to one or multiple TrustAnchors type TrustResolver struct { - TrustAnchors []TrustAnchor + TrustAnchors TrustAnchors StartingEntity string Types []string trustTree trustTree @@ -222,7 +222,7 @@ func (r *TrustResolver) Resolve() { includedEntityTypes: strset.New(starting.Metadata.GuessEntityTypes()...), subordinateIDs: strset.New(starting.Subject), } - r.trustTree.resolve(r.TrustAnchors) + r.trustTree.resolve(r.TrustAnchors.EntityIDs()) if err = r.cacheSetTrustTree(); err != nil { internal.Log(err.Error()) } @@ -314,15 +314,15 @@ type trustTree struct { subordinateIDs *strset.Set } -func (t *trustTree) resolve(anchors TrustAnchors) { +func (t *trustTree) resolve(anchors []string) { if t.Entity == nil { return } t.updateExpirationTime() - // Early return if entity is issued by a trust anchor - if sliceutils.SliceContains(t.Entity.Issuer, anchors.EntityIDs()) { + // Early return if the entity is issued by a trust anchor + if sliceutils.SliceContains(t.Entity.Issuer, anchors) { return } @@ -335,7 +335,7 @@ func (t *trustTree) updateExpirationTime() { } } -func (t *trustTree) resolveAuthorities(anchors TrustAnchors) { +func (t *trustTree) resolveAuthorities(anchors []string) { if len(t.Entity.AuthorityHints) > 0 { t.Authorities = make([]trustTree, len(t.Entity.AuthorityHints)) } @@ -354,7 +354,7 @@ func (t *trustTree) resolveAuthorities(anchors TrustAnchors) { } } -func (t *trustTree) resolveAuthority(authorityID string, anchors TrustAnchors) (trustTree, error) { +func (t *trustTree) resolveAuthority(authorityID string, anchors []string) (trustTree, error) { authorityStmt, err := GetEntityConfiguration(authorityID) if err != nil { return trustTree{}, err @@ -416,7 +416,7 @@ func (t *trustTree) updateExpirationTimeFromSubordinate(subordinateStmt *EntityS } func (t *trustTree) createAuthorityTrustTree( - authorityStmt, subordinateStmt *EntityStatement, authorityID string, anchors TrustAnchors, + authorityStmt, subordinateStmt *EntityStatement, authorityID string, anchors []string, ) trustTree { entityTypes := t.includedEntityTypes.Copy() entityTypes.Add(authorityStmt.Metadata.GuessEntityTypes()...) From e4b7d9962709f23bb693efecd96fa870c1e0632e Mon Sep 17 00:00:00 2001 From: zachmann Date: Fri, 22 Aug 2025 11:46:04 +0200 Subject: [PATCH 2/6] [cache] add Delete method to Cache interface and implement it --- cache/cache.go | 12 ++++++++++++ cache/redis.go | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/cache/cache.go b/cache/cache.go index 635d577..aa3484e 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -16,6 +16,7 @@ import ( type Cache interface { Get(key string, target any) (bool, error) Set(key string, value any, expiration time.Duration) error + Delete(key string) error } // cacheWrapper is a type implementing the Cache interface and providing an @@ -58,6 +59,12 @@ func (c cacheWrapper) Set(key string, value any, expiration time.Duration) error return nil } +// Delete implements the Cache interface +func (c cacheWrapper) Delete(key string) error { + c.c.Delete(key) + return nil +} + var cacheCache Cache func init() { @@ -100,3 +107,8 @@ func Set(key string, value any, duration time.Duration) error { func Get(key string, target any) (bool, error) { return cacheCache.Get(key, target) } + +// Delete deletes the value for the given key from the cache +func Delete(key string) error { + return cacheCache.Delete(key) +} diff --git a/cache/redis.go b/cache/redis.go index db101ad..9034c7a 100644 --- a/cache/redis.go +++ b/cache/redis.go @@ -35,6 +35,11 @@ func (c redisCache) Set(key string, value any, expiration time.Duration) error { return c.client.Set(c.ctx, key, data, expiration).Err() } +// Delete implements the Cache in terface +func (c redisCache) Delete(key string) error { + return c.client.Del(c.ctx, key).Err() +} + // UseRedisCache creates a new redis cache with the passed options and sets it to be used func UseRedisCache(options *redis.Options) error { rdb := redis.NewClient(options) From f29f6cff30844ed06320fdeb8ec40318c1f0e3b3 Mon Sep 17 00:00:00 2001 From: zachmann Date: Fri, 22 Aug 2025 11:47:00 +0200 Subject: [PATCH 3/6] [trust resolver] delete cache entry for trust tree chains when caching a new trust tree --- trustresolver.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/trustresolver.go b/trustresolver.go index 14a5d6b..2d4622f 100644 --- a/trustresolver.go +++ b/trustresolver.go @@ -296,6 +296,9 @@ func (r TrustResolver) cacheSetTrustTree() error { if err != nil { return err } + if err = cache.Delete(cache.Key(cache.KeyTrustTreeChains, string(hash))); err != nil { + return err + } return cache.Set( cache.Key(cache.KeyTrustTree, string(hash)), r.trustTree, unixtime.Until(r.trustTree.expiresAt), From 60e7c1627d310658e182d15c2753dd31e785ac4e Mon Sep 17 00:00:00 2001 From: zachmann Date: Fri, 22 Aug 2025 11:48:10 +0200 Subject: [PATCH 4/6] [trust resolver] fix signature verification not failing if the leaf entity could not be verified; --- trustresolver.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/trustresolver.go b/trustresolver.go index 2d4622f..9908fca 100644 --- a/trustresolver.go +++ b/trustresolver.go @@ -230,7 +230,9 @@ func (r *TrustResolver) Resolve() { // VerifySignatures verifies the signatures of the internal trust tree func (r *TrustResolver) VerifySignatures() { - r.trustTree.verifySignatures(r.TrustAnchors) + if !r.trustTree.verifySignatures(r.TrustAnchors) { + r.trustTree = trustTree{} + } if err := r.cacheSetTrustTree(); err != nil { internal.Log(err.Error()) } From 3886d6804920ee74a0079a195b897f0599197596 Mon Sep 17 00:00:00 2001 From: zachmann Date: Fri, 22 Aug 2025 11:48:43 +0200 Subject: [PATCH 5/6] [trust resolver] fix signature verification for single entity trust chains --- trustresolver.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/trustresolver.go b/trustresolver.go index 9908fca..dfbc750 100644 --- a/trustresolver.go +++ b/trustresolver.go @@ -505,15 +505,18 @@ func (t *trustTree) verifySignatures(anchors TrustAnchors) bool { if t.signaturesVerified { return true } - if t.Subordinate != nil { + if t.Entity.Issuer == t.Entity.Subject { for _, ta := range anchors { - if utils.Equal(ta.EntityID, t.Entity.Issuer, t.Entity.Subject, t.Subordinate.Issuer) { + if ta.EntityID == t.Entity.Issuer { // t is about a TA jwks := ta.JWKS if jwks.Set == nil { jwks = t.Entity.JWKS } - t.signaturesVerified = t.Entity.Verify(jwks) && t.Subordinate.Verify(jwks) + t.signaturesVerified = t.Entity.Verify(jwks) + if t.signaturesVerified && t.Subordinate != nil { + t.signaturesVerified = t.Subordinate.Verify(jwks) + } return t.signaturesVerified } } From 7c3b96f4036b97670fafc00c7152c1d6ef17c6cc Mon Sep 17 00:00:00 2001 From: zachmann Date: Fri, 22 Aug 2025 11:53:30 +0200 Subject: [PATCH 6/6] [trust resolver] fix possible seg fault; fix tests --- trustresolver.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/trustresolver.go b/trustresolver.go index dfbc750..ec3eade 100644 --- a/trustresolver.go +++ b/trustresolver.go @@ -505,6 +505,9 @@ func (t *trustTree) verifySignatures(anchors TrustAnchors) bool { if t.signaturesVerified { return true } + if t.Entity == nil { + return false + } if t.Entity.Issuer == t.Entity.Subject { for _, ta := range anchors { if ta.EntityID == t.Entity.Issuer {