From e4835f759a92c970c0d4b32c5867fb92bead1eb1 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Tue, 3 Dec 2024 11:18:14 +0000 Subject: [PATCH] Load libtrust KeyIDs from certificate bundle Resolves issue where legacy Key IDs were not loaded from CA bundles, necessitating use of JWKS JSON Signed-off-by: Brad Davidson --- registry/auth/token/accesscontroller.go | 3 +++ registry/auth/token/util.go | 27 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/registry/auth/token/accesscontroller.go b/registry/auth/token/accesscontroller.go index e86989538..734554985 100644 --- a/registry/auth/token/accesscontroller.go +++ b/registry/auth/token/accesscontroller.go @@ -346,6 +346,9 @@ func newAccessController(options map[string]interface{}) (auth.AccessController, if key := GetRFC7638Thumbprint(rootCert.PublicKey); key != "" { trustedKeys[key] = rootCert.PublicKey } + if key := GetLibtrustKeyID(rootCert.PublicKey); key != "" { + trustedKeys[key] = rootCert.PublicKey + } } if jwks != nil { diff --git a/registry/auth/token/util.go b/registry/auth/token/util.go index 29b8811fd..998908cd1 100644 --- a/registry/auth/token/util.go +++ b/registry/auth/token/util.go @@ -1,13 +1,17 @@ package token import ( + "bytes" "crypto" "crypto/ecdsa" "crypto/rsa" "crypto/sha256" + "crypto/x509" + "encoding/base32" "encoding/base64" "fmt" "math/big" + "strings" ) // actionSet is a special type of stringSet. @@ -84,3 +88,26 @@ func GetRFC7638Thumbprint(publickey crypto.PublicKey) string { return hashAndEncode(payload) } + +// Returns a libtrust-compatible Key ID, for backwards compatibility +// with JWT headers expected by distribution/v2 +func GetLibtrustKeyID(publickey crypto.PublicKey) string { + keyBytes, err := x509.MarshalPKIXPublicKey(publickey) + if err != nil { + return "" + } + + sum := sha256.Sum256(keyBytes) + b64 := strings.TrimRight(base32.StdEncoding.EncodeToString(sum[:30]), "=") + + var buf bytes.Buffer + var i int + for i = 0; i < len(b64)/4-1; i++ { + start := i * 4 + end := start + 4 + buf.WriteString(b64[start:end] + ":") + } + buf.WriteString(b64[i*4:]) + + return buf.String() +}