Skip to content

Commit 5ea9aa0

Browse files
authored
Merge commit from fork
Fix registry token authentication bug
2 parents 939a525 + 6ed60b0 commit 5ea9aa0

File tree

2 files changed

+59
-6
lines changed

2 files changed

+59
-6
lines changed

registry/auth/token/token.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,18 @@ func verifyCertChain(header jose.Header, roots *x509.CertPool) (signingKey crypt
212212
return
213213
}
214214

215-
func verifyJWK(header jose.Header, verifyOpts VerifyOptions) (signingKey crypto.PublicKey, err error) {
215+
func verifyJWK(header jose.Header, verifyOpts VerifyOptions) (crypto.PublicKey, error) {
216216
jwk := header.JSONWebKey
217-
signingKey = jwk.Key
218217

219218
// Check to see if the key includes a certificate chain.
220219
if len(jwk.Certificates) == 0 {
221220
// The JWK should be one of the trusted root keys.
222-
if _, trusted := verifyOpts.TrustedKeys[jwk.KeyID]; !trusted {
221+
key, trusted := verifyOpts.TrustedKeys[jwk.KeyID]
222+
if !trusted {
223223
return nil, errors.New("untrusted JWK with no certificate chain")
224224
}
225225
// The JWK is one of the trusted keys.
226-
return
226+
return key, nil
227227
}
228228

229229
opts := x509.VerifyOptions{
@@ -245,9 +245,8 @@ func verifyJWK(header jose.Header, verifyOpts VerifyOptions) (signingKey crypto.
245245
if err != nil {
246246
return nil, err
247247
}
248-
signingKey = getCertPubKey(chains)
249248

250-
return
249+
return getCertPubKey(chains), nil
251250
}
252251

253252
func getCertPubKey(chains [][]*x509.Certificate) crypto.PublicKey {

registry/auth/token/token_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,3 +646,57 @@ func TestNewAccessControllerPemBlock(t *testing.T) {
646646
t.Fatal("accessController has the wrong number of certificates")
647647
}
648648
}
649+
650+
// This test makes sure the untrusted key can not be used in token verification.
651+
func TestVerifyJWKWithTrustedKey(t *testing.T) {
652+
// Generate a test key pair
653+
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
654+
if err != nil {
655+
t.Fatal(err)
656+
}
657+
pubKey := privKey.Public()
658+
659+
// Create a JWK with no certificates
660+
jwk := &jose.JSONWebKey{
661+
Key: privKey,
662+
KeyID: "test-key-id",
663+
Use: "sig",
664+
Algorithm: string(jose.ES256),
665+
}
666+
667+
// Create verify options with our public key as trusted
668+
verifyOpts := VerifyOptions{
669+
TrustedKeys: map[string]crypto.PublicKey{
670+
"test-key-id": pubKey,
671+
},
672+
}
673+
674+
// Create test header
675+
header := jose.Header{
676+
JSONWebKey: jwk,
677+
}
678+
679+
// Test the verifyJWK function
680+
returnedKey, err := verifyJWK(header, verifyOpts)
681+
if err != nil {
682+
t.Fatalf("Expected no error, got: %v", err)
683+
}
684+
685+
// Verify the returned key matches our trusted key
686+
if returnedKey != pubKey {
687+
t.Error("Returned key does not match the trusted key")
688+
}
689+
690+
// Test with untrusted key
691+
verifyOpts.TrustedKeys = map[string]crypto.PublicKey{
692+
"different-key-id": pubKey,
693+
}
694+
695+
_, err = verifyJWK(header, verifyOpts)
696+
if err == nil {
697+
t.Error("Expected error for untrusted key, got none")
698+
}
699+
if err.Error() != "untrusted JWK with no certificate chain" {
700+
t.Errorf("Expected 'untrusted JWK with no certificate chain' error, got: %v", err)
701+
}
702+
}

0 commit comments

Comments
 (0)